# Play a fun math game with Linux commands

Last Updated on June 18, 2024 by Jim Hall

I like to play puzzle games as a way to take a break when I’m working. One game that I like to play is borrowed from a UK quiz show called *Countdown* where players are given several random numbers, plus a random target number, and they need to use simple arithmetic to get within 10 of the target number, using the list of numbers at most one time. I find this is a fun math quiz to play on my own, and I’ve written a short script that generates the numbers, to test myself if I can get the target number.

The original game has the random numbers on a set of cards: the “Small” numbers 1 to 10 are included twice and the “Large” numbers 25, 50, 75, and 100 are listed just once. Players can ask for a combination of six numbers picked from “Small” and “Large.” The target number is a randomly generated number from 101 to 999, picked by a computer. I find the game is the most fun with two “Large” and four “Small” numbers; the game is much harder with other combinations, but I’m just in it for fun.

## Small numbers

Let’s start by generating the “Small” numbers. This list contains the numbers 1 to 10, twice. The `seq`

command can generate a list of numbers in any range. If you specify two numbers as arguments, `seq`

will start and end with those values. Just one number will start counting from 1 until it reaches that value. You can also add a third argument to include a “step” or increment value. You can see the usage in these three examples:

```
$ seq 3
1
2
3
$ seq 2 5
2
3
4
5
$ seq 3 2 10
3
5
7
9
```

To list the “Small” numbers, we just need to use `seq`

twice:

```
$ seq 10; seq 10
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
```

To pick just four numbers at random from this list, we first need to use the `shuf`

command. This randomizes its input, displaying the lines in random order. After that, the `head`

command can pick off just the first four values from the shuffled list:

```
$ (seq 10; seq 10) | shuf | head -4
3
6
3
8
```

Because `shuf`

shuffles the lines from the input, we’ll get a different set of four “Small” number every time we run this command:

```
$ (seq 10; seq 10) | shuf | head -4
7
3
2
4
```

## Large numbers

We can use the same method to pick just two random values from the “Large” numbers. Again, the `seq`

command can generate the list for us, like this:

```
$ seq 25 25 100
25
50
75
100
```

And we can use `shuf`

to randomize the list, and `head`

to print just the first two numbers from the randomized list:

```
$ seq 25 25 100 | shuf | head -2
75
100
```

Every time we run this command, the “Large” numbers will be different:

```
$ seq 25 25 100 | shuf | head -2
50
25
```

## Target number

We could use a similar method with `seq`

to list the numbers from 101 to 999, and `shuf`

and `head`

to randomize the list and print just one number, but that’s a lot of numbers to print out. But since we just need to generate *one* random number, we can use another way to get a random value in that range.

The Bash shell will generate a new random value with the `RANDOM`

variable. Every time you reference this variable, Bash will expand it to be a random number in the range 0 to 32,767:

```
$ echo $RANDOM
10884
$ echo $RANDOM
23346
```

Bash also supports simple arithmetic operations, using the `$((`

and `))`

expansion. One of these arithmetic operators is *modulo* (`%`

) or the remainder after division. That means *7 modulo 3* is the remainder after dividing 7 by 3, which is 2 with a *remainder of 1* (the modulo is 1). The range 101 to 999 is 899 numbers (including the first and last numbers in the list, just as the range 3 to 5 is three numbers: 3, 4, and 5) so let’s start by calculating the modulo of a random number by 899:

```
$ echo $(( RANDOM % 899 ))
380
```

Note that arithmetic expansion in Bash automatically expands any variables between the `$((`

and `))`

, so we don’t need to write it as `$RANDOM`

, but can just use `RANDOM`

since the arithmetic expansion will reference the value of `RANDOM`

anyway.

The modulo of 899 will return numbers from 0 to 898, but we want numbers from 101 to 999. That means we need to add 101 to the modulo, like this:

```
$ echo $(( RANDOM % 899 + 101 ))
493
```

## Putting it all together

With these pieces to print out four random “Small” numbers and two “Large” numbers, we can write a script to do this every time we want to play the Numbers game:

```
#!/bin/bash
echo "The numbers are:"
seq 25 25 100 | shuf | head -2
(seq 10; seq 10) | shuf | head -4
echo "The target number is:"
echo $(( RANDOM % 899 + 101 ))
```

This includes some extra `echo`

statements to label the output for us, but otherwise this is what we wrote above for the “Small” and “Large” numbers. Save this into a file named `numbers`

and every time you want to play the game, just run the script like this:

```
$ bash numbers
The numbers are:
75
100
4
8
3
6
The target number is:
452
```

By the way, I can get close to that, but I don’t think I can get it exactly:

```
4 x 100 = 400
8 x 3 = 24
75 - 24 = 51
400 + 51 = 451
```

Let’s try it again with a new list of numbers:

```
$ bash numbers
The numbers are:
50
100
2
7
4
8
The target number is:
457
```

That one is easy and just requires a few steps to solve:

```
4 x 100 = 400
50 + 7 = 57
400 + 57 = 457
```

Try this fun game for yourself and see how close you can get to your target number.