The World of Astoria Bob

Create and Solve Number Puzzles

Course Outline

January 23
Algorithms and Pseudocode
Krypto card game
Insumnia and Countdown Numbers

January 30
Magic Squares
Kakuro
Yohaku
Other Arithmetic Square Puzzles

February 6
Crossnumber Puzzles
Crossword/number Hybrids
Crossword Puzzles
Short Exploration of Other Puzzle Types


Notes for Week 1

Algorithms

Facebook: To determine the order of posts you see (since posts are linear, and no longer in reverse chronological order as they were in the beginning), the good people at Meta have written a constantly-evolving algorithm that prioritizes certain variables. Though no one except the authors and their bosses really knows exactly what the algorithm is, it seems that the first priority is given to posts that have been "boosted" by the person or company that pays for it. After that, it seems that your posts are served mainly by your interest in that Facebook account (i.e. likes and engagement), or your interest in similar topics. It seems like the algorithm is updated more often than once a second, since if you refresh the screen, you get a different set of posts. Most people like this. It seems like magic and is entertaining to see this constant swirl of different posts. You can contribute to the algorithm by setting some parameters, such as searching for a particular page or person, updating your profile, or just liking certain posts either at random or for real. All these characteristics will be present in most of the algorithms we study in this class.

Here's a tidbit of the algorithm from the socialchamp.io folks:

Facebook Algorithm’s Four Ranking Factors

The Facebook algorithm ensures that all Facebook users get the most relevant updates, news, and information they are interested in. It is by no means an easy algorithm to crack, but some ranking factors are well known.

Inventory
So, the first factor is inventory. It includes all the content from the platform. It could be anything, a post from a close friend, family, all the groups you have joined, and all the pages fall under the example of inventory. In short, your inventory is all the posts that are available to display on your News Feed.

Signals
Signals are a significant part of the Facebook algorithm that tells Facebook about the post. Signals are further divided into two categories.

Predictions
Ever happened when you searched for a specific thing on Facebook, and then your news feed is bombarded with the same precise thing? That’s the prediction from Facebook. It not only impacts the ads but also assesses your Facebook profile, likes, dislikes, and the posts you are interested in. So that it can only show you the content you are likely to engage in. Predictions are basically how you react to the post.

Relevancy Score
Facebook assigns scores to all the content from the platform that displays how specific content is for the user. The higher score suggests the content that will be likely to show on your news feed.


Recipes: The quintessential algorithm is the recipe, whether it's for cooking something, or for success, or getting through the day. On my website I have a recipe for a no-bake cheesecake that illustrates the concepts of algorithms, such as the ingredient list (setting constants and variables), the instructions (the steps of the algorithm) and the parameters, such as when to stop doing something, how long to do something, etc. We'll take a quick look at this recipe to see how these things are stated, and you can check out any number of recipes at home for more examples.

Mr. Bob Problem: When I sub, I tend to substitute a Mr. Bob problem for whatever math the class is doing, or at least start the math time with one. These problems are usually just problems with bigger numbers than the class is already doing, with the objective that if they see that they are just employing a simple algorithm over and over again, then their regular problems will be cake, and they may gain some insight into large numbers and maybe even algorithms! We'll go over a first-grade Mr. Bob problem in class to illustrate both the standard school algorithm for solving integer addition problems, and two hypothetical brute force algorithms that will give us an idea of how these algorithms work, since we'll be using them throughout the course.

Here's the problem (I make these up as I'm at the board, so essentially the problem is random, like a computer would do if outputting problems for a worksheet):

     5,702,819,764,713
+ 6,433,694,588,018
––––––––––––––––––––––
 12,136,514,352,731

The commas in the answer is what I do last, after we have the answer (which we get by having one student at a time perform the algorithm for adding two one-digit numbers vertically), which shows the kids some place value concepts, and they love those big numbers!

School algorithm: Starting from the right, do this loop for each column until the last column – Add the top & bottom digits; if the sum is less than or equal to 9, then write down the sum, if it's greater than 9, then write down the ones digit and "carry" the tens digit to the next column. For the last (most left) column, add the top & bottom digits, and write down the sum regardless of size. If you want commas, then do the following loop – count 3 digits from the right and place a comma before (to the left of) the third digit – until you get to the end (the left). If there aren't 3 digits in the final step of the loop, then don't put down any commas, and don't put a comma to the left of the third digit if there is one.

Brute force algorithm #1: Set a constant to the correct answer. Set a variable to 1.1 x 1013 and increment by 1 until the variable equals 1.3 x 1013, checking at each step to see whether the variable equals exactly the answer. When you're done iterating, output the variable value that equaled the answer. 

Brute force algorithm #2: Set 14 constants to the values of the various digits in the answer. Then set 14 variables to 0 and for each variable, go through the digits from 0 to 9, checking each time to see whether the variable is equal to the corresponding constant for that place in the answer. When done iterating, output the variable values that match the corresponding constants.

In this case, the brute force algorithms may seem a little too much for the problem, and that may be true, but they illustrate the types of algorithms we will use for tougher problems later.

Solving Quadratic Equations: In school, students learn the quadratic formula and other tricks to find the roots of a quadratic equation. In this case, there are always two answers, so it's a little more difficult than the addition problem. We can use a brute force algorithm to survey the whole possible solution space, and then pick out the answers (within a certain margin of error) by applying criteria. Newton's method works like this, and we'll use a variant of it here.

Finding the Real Roots of a Quadratic Equation (mainly written by ChatGPT)

Start by specifying the quadratic equation in the form y = ax2 + bx + c, where a, b, and c are the coefficients of the equation.

Choose a starting value for the independent variable, x, that is to the left of the first root (if the roots are real).

Evaluate the value of the quadratic equation at the starting value of x.

Increment the value of x by 1 and evaluate the quadratic equation again. If the sign of the value has changed (i.e. from positive to negative or negative to positive), the root is in between the previous value of x and the current value of x. Record this root.

Continue incrementing the value of x by 1 and evaluating the quadratic equation until the sign of the value changes again. The second root is in between the previous value of x and the current value of x. Record this root.

When both roots have been found, the algorithm is complete. The roots can be expressed as "one root is in between [integer1] and [integer2], and the other root is in between [integer3] and [integer4]".

Though this example algorithm doesn't get you an exact answer, it is a good example of a simple brute force algorithm which goes through the possible solution space and records where the criteria for solution are met. Though there are many formulas and tricks to find the solution to quadratic (2nd order) polynomials, it is much harder to discern the roots of higher order polynomials. Here the brute force algorithm can perhaps come up with the solutions in a reasonable amount of time.

For example, here's a script that ChatGPT helped me write to find the roots of the polynomial x5 – 4x+ 3xx– x:

function findRoots(polynomial) {
  let x = -1;
  let y = polynomial(x);
  let EPSILON = 0.00001;
  let previousY = y;

  for (x; x <= 3; x += 0.1) {
    y = polynomial(x);
    if (Math.abs(y) < EPSILON) {
      console.log("Root found at x = " + x);
    } else if (y * previousY < 0) {
      console.log("Root found between " + (x - 0.1).toFixed(1) + " and " + x.toFixed(1));
    }
    previousY = y;
  }
}

// usage
findRoots(x => x ** 5 - 4 * x ** 4 + 3 * x ** 3 + x ** 2 - x);

It gives the results:

Root found between -0.6 and -0.5
Root found at x = -1.3877787807814457e-16
Root found between -0.0 and 0.1
Root found between 0.6 and 0.7
Root found at x = 0.9999999999999998
Root found between 1.0 and 1.1
Root found between 2.8 and 2.9

You can see that it counted some roots twice, and it didn't work exactly like explained above (the iteration step was 0.1 instead of 1), but it did get the roots right. In our day and age, the answer to this problem can be obtained extremely easily using apps like Desmos. Putting our polynomial into Desmos, it graphs it like so:

In the app, you can put the cursor on the points outlined in gray and it will tell you not only the roots, but the maxima and minima. Another great tool to solve problems!


Pseudocode

The next step is turning these algorithms into computer code, and often it's a good idea to start by using what's sometimes called pseudocode, which is like a meta-code – something between the actual code and the plain algorithm. It's sort of like Esperanto, not quite a specific language, but a language that has the basics. Let's take a quick look at pseudocode for the school algorithm for adding two integers of the same length vertically:

number_of_columns = digits_in_each_number;
sum[column] = array of column sums;
sum[1] = 0;

for (column = 1 to number_of_columns – 1)  do
   { sum[column] = topdigit + bottomdigit + sum[column];
   if sum[column] > 9 then
      { (sum[column] = sum[column] – 10;
      sum[column + 1] = 1; }

   else
      sum[column + 1] = 0; }

for (column = number_of_columns downto 1) do
write(sum[column]);

This pseudocode could then be translated into any programming language to be used in actual apps. Translation programs are hard to find, but these are starting to come on line. Pseudocode doesn't have any set syntax, which makes translation difficult, just like in human languages. But pseudocode is often easier to understand for the beginning programmer. It's a good exercise to convert the general algorithms into pseudocode to discover if you can actually code the algorithm on a computer.

Here's a translation into Javascript written mostly by ChatGPT that takes the digits in the two numbers as input from the user and performs the algorithm:

var digits_in_each_number = parseInt(prompt("Enter the number of digits in each number:"));
var topdigits = prompt("Enter the digits of the first number, separated by spaces:").split(" ").map(Number);
var bottomdigits = prompt("Enter the digits of the second number, separated by spaces:").split(" ").map(Number);
var number_of_columns = digits_in_each_number;
var sum = new Array(number_of_columns).fill(0);
sum[0] = 0;
for (var column = 0; column < number_of_columns - 1; column++) {
    var topdigit = topdigits[column] || 0;
    var bottomdigit = bottomdigits[column] || 0;
    sum[column] = topdigit + bottomdigit + sum[column];
    if (sum[column] > 9) {
        sum[column+1] += 1;
        sum[column] = sum[column] % 10;
    }
}
for (var column = number_of_columns - 1; column >= 0; column--) {
    document_write("Column " + (number_of_columns-column) + ": " + sum[column]);
}

And here's ChatGPT's translation of the original algorithmic language I used above directly into Javascript, which helped me learn where I made mistakes in the pseudocode:

var digits_in_each_number = parseInt(prompt("Enter the number of digits in each number:"));
var topdigits = prompt("Enter the digits of the first number, separated by spaces:").split(" ").map(Number);
var bottomdigits = prompt("Enter the digits of the second number, separated by spaces:").split(" ").map(Number);
var number_of_columns = digits_in_each_number;
var sum = new Array(number_of_columns).fill(0);
sum[number_of_columns-1] = topdigits[number_of_columns-1] + bottomdigits[number_of_columns-1];
for (var column = number_of_columns-2; column >= 0; column--) {
    var topdigit = topdigits[column] || 0;
    var bottomdigit = bottomdigits[column] || 0;
    var temp_sum = topdigit + bottomdigit + sum[column+1];
    if (temp_sum > 9) {
        sum[column] = temp_sum % 10;
        sum[column+1] = 1;
    }
    else {
        sum[column] = temp_sum;
    }
}

var output_string = "";
for (var i = 0; i < number_of_columns; i++) {
    output_string = sum[i].toString() + output_string;
    if (i != number_of_columns-1 && (i+1) % 3 == number_of_columns % 3) {
        output_string = "," + output_string;
    }
}
document.write(output_string);


Krypto Brute Force Exploration of Solutions Examples with 3 Cards

To simplify the procedure of finding Krypto solutions using brute force methods, let's cut the hand down to 3 cards, which has 192 different ways to play, some of which are redundant, but that doesn't matter with a sufficiently fast computer (even a phone is good enough). Appearing here is a listing of all 192 possibilities for the cards 8 6 3:

\[ (8 + 6) + 3 = 17 \] \[ (8 - 6) + 3 = 5 \] \[ (8 * 6) + 3 = 51 \] \[ (8 \div 6) + 3 = 4\frac{1}{3} \] \[ (8 + 6) - 3 = 11 \] \[ (8 - 6) - 3 = -1 \] \[ (8 * 6) - 3 = 45 \] \[ (8 \div 6) - 3 = -1\frac{2}{3} \] \[ (8 + 6) * 3 = 42 \] \[ (8 - 6) * 3 = 6 \] \[ (8 * 6) * 3 = 144 \] \[ (8 \div 6) * 3 = 4 \] \[ (8 + 6) \div 3 = 4\frac{2}{3} \] \[ (8 - 6) \div 3 = \frac{2}{3} \] \[ (8 * 6) \div 3 = 16 \] \[ (8 \div 6) \div 3 = \frac{4}{9} \] \[ 3 + (8 + 6) = 17 \] \[ 3 + (8 - 6) = 5 \] \[ 3 + (8 * 6) = 51 \] \[ 3 + (8 \div 6) = 4\frac{1}{3} \] \[ 3 - (8 + 6) = -11 \] \[ 3 - (8 - 6) = 1 \] \[ 3 - (8 * 6) = -45 \] \[ 3 - (8 \div 6) = 1\frac{2}{3} \] \[ 3 * (8 + 6) = 42 \] \[ 3 * (8 - 6) = 6 \] \[ 3 * (8 * 6) = 144 \] \[ 3 * (8 \div 6) = 4 \] \[ 3 \div (8 + 6) = \frac{3}{14} \] \[ 3 \div (8 - 6) = \frac{3}{2} \] \[ 3 \div (8 * 6) = \frac{1}{16} \] \[ 3 \div (8 \div 6) = 2\frac{1}{4} \] \[ (6 + 8) + 3 = 17 \] \[ (6 - 8) + 3 = 1 \] \[ (6 * 8) + 3 = 51 \] \[ (6 \div 8) + 3 = 3\frac{3}{4} \] \[ (6 + 8) - 3 = 11 \] \[ (6 - 8) - 3 = -5 \] \[ (6 * 8) - 3 = 45 \] \[ (6 \div 8) - 3 = -2\frac{1}{4} \] \[ (6 + 8) * 3 = 42 \] \[ (6 - 8) * 3 = -6 \] \[ (6 * 8) * 3 = 144 \] \[ (6 \div 8) * 3 = 2\frac{1}{4} \] \[ (6 + 8) \div 3 = 4\frac{2}{3} \] \[ (6 - 8) \div 3 = -\frac{2}{3} \] \[ (6 * 8) \div 3 = 16 \] \[ (6 \div 8) \div 3 = \frac{1}{4} \] \[ 3 + (6 + 8) = 17 \] \[ 3 + (6 - 8) = 1 \] \[ 3 + (6 * 8) = 51 \] \[ 3 + (6 \div 8) = 3\frac{3}{4} \] \[ 3 - (6 + 8) = -11 \] \[ 3 - (6 - 8) = 5 \] \[ 3 - (6 * 8) = -45 \] \[ 3 - (6 \div 8) = 2\frac{1}{4} \] \[ 3 * (6 + 8) = 42 \] \[ 3 * (6 - 8) = -6 \] \[ 3 * (6 * 8) = 144 \] \[ 3 * (6 \div 8) = 2\frac{1}{4} \] \[ 3 \div (6 + 8) = \frac{3}{14} \] \[ 3 \div (6 - 8) = -\frac{3}{2} \] \[ 3 \div (6 * 8) = \frac{1}{16} \] \[ 3 \div (6 \div 8) = 4 \] \[ (8 + 6) + 3 = 17 \] \[ (8 - 6) + 3 = 5 \] \[ (8 * 6) + 3 = 51 \] \[ (8 \div 6) + 3 = 4\frac{1}{3} \] \[ (8 + 6) - 3 = 11 \] \[ (8 - 6) - 3 = -1 \] \[ (8 * 6) - 3 = 45 \] \[ (8 \div 6) - 3 = -1\frac{2}{3} \] \[ (8 + 6) * 3 = 42 \] \[ (8 - 6) * 3 = 6 \] \[ (8 * 6) * 3 = 144 \] \[ (8 \div 6) * 3 = 4 \] \[ (8 + 6) \div 3 = 4\frac{2}{3} \] \[ (8 - 6) \div 3 = \frac{2}{3} \] \[ (8 * 6) \div 3 = 16 \] \[ (8 \div 6) \div 3 = \frac{4}{9} \] \[ 3 + (8 + 6) = 17 \] \[ 3 + (8 - 6) = 5 \] \[ 3 + (8 * 6) = 51 \] \[ 3 + (8 \div 6) = 4\frac{1}{3} \] \[ 3 - (8 + 6) = -11 \] \[ 3 - (8 - 6) = 1 \] \[ 3 - (8 * 6) = -45 \] \[ 3 - (8 \div 6) = 1\frac{2}{3} \] \[ 3 * (8 + 6) = 42 \] \[ 3 * (8 - 6) = 6 \] \[ 3 * (8 * 6) = 144 \] \[ 3 * (8 \div 6) = 4 \] \[ 3 \div (8 + 6) = \frac{3}{14} \] \[ 3 \div (8 - 6) = \frac{3}{2} \] \[ 3 \div (8 * 6) = \frac{1}{16} \] \[ 3 \div (8 \div 6) = 2\frac{1}{4} \]

(6 + 8) + 3 = 17
(6 – 8) + 3 = 1
(6 * 8) + 3 = 51
(6 ÷ 8) + 3 = 3 3/4
(6 + 8) – 3 = 11
(6 – 8) – 3 = -5
(6 * 8) – 3 = 45
(6 ÷ 8) – 3 = -2 1/4
(6 + 8) * 3 = 42
(6 – 8) * 3 = -6
(6 * 8) * 3 = 144
(6 ÷ 8) * 3 = 2 1/4
(6 + 8) ÷ 3 = 4 2/3
(6 – 8) ÷ 3 = -2/3
(6 * 8) ÷ 3 = 16
(6 ÷ 8) ÷ 3 = 1/4
3 + (6 + 8) = 17
3 + (6 – 8) = 1
3 + (6 * 8) = 51
3 + (6 ÷ 8) = 3 3/4
3 – (6 + 8) = -11
3 – (6 – 8) = 5
3 – (6 * 8) = -45
3 – (6 ÷ 8) = 2 1/4
3 * (6 + 8) = 42
3 * (6 – 8) = -6
3 * (6 * 8) = 144
3 * (6 ÷ 8) = 2 1/4
3 ÷ (6 + 8) = 3/14
3 ÷ (6 – 8) = -1 1/2
3 ÷ (6 * 8) = 1/16
3 ÷ (6 ÷ 8) = 4
(8 + 3) + 6 = 17
(8 – 3) + 6 = 11
(8 * 3) + 6 = 30
(8 ÷ 3) + 6 = 8 2/3
(8 + 3) – 6 = 5
(8 – 3) – 6 = -1
(8 * 3) – 6 = 18
(8 ÷ 3) – 6 = -3 1/3
(8 + 3) * 6 = 66
(8 – 3) * 6 = 30
(8 * 3) * 6 = 144
(8 ÷ 3) * 6 = 16
(8 + 3) ÷ 6 = 1 5/6
(8 – 3) ÷ 6 = 5/6
(8 * 3) ÷ 6 = 4
(8 ÷ 3) ÷ 6 = 4/9
6 + (8 + 3) = 17
6 + (8 – 3) = 11
6 + (8 * 3) = 30
6 + (8 ÷ 3) = 8 2/3
6 – (8 + 3) = -5
6 – (8 – 3) = 1
6 – (8 * 3) = -18
6 – (8 ÷ 3) = 3 1/3
6 * (8 + 3) = 66
6 * (8 – 3) = 30
6 * (8 * 3) = 144
6 * (8 ÷ 3) = 16
6 ÷ (8 + 3) = 6/11
6 ÷ (8 – 3) = 1 1/5
6 ÷ (8 * 3) = 1/4
6 ÷ (8 ÷ 3) = 2 1/4
(3 + 8) + 6 = 17
(3 – 8) + 6 = 1
(3 * 8) + 6 = 30
(3 ÷ 8) + 6 = 6 3/8
(3 + 8) – 6 = 5
(3 – 8) – 6 = -11
(3 * 8) – 6 = 18
(3 ÷ 8) – 6 = -5 5/8
(3 + 8) * 6 = 66
(3 – 8) * 6 = -30
(3 * 8) * 6 = 144
(3 ÷ 8) * 6 = 2 1/4
(3 + 8) ÷ 6 = 1 5/6
(3 – 8) ÷ 6 = -5/6
(3 * 8) ÷ 6 = 4
(3 ÷ 8) ÷ 6 = 1/16
6 + (3 + 8) = 17
6 + (3 – 8) = 1
6 + (3 * 8) = 30
6 + (3 ÷ 8) = 6 3/8
6 – (3 + 8) = -5
6 – (3 – 8) = 11
6 – (3 * 8) = -18
6 – (3 ÷ 8) = 5 5/8
6 * (3 + 8) = 33
6 * (3 – 8) = -15
6 * (3 * 8) = 72
6 * (3 ÷ 8) = 1 1/8
6 ÷ (3 + 8) = 6/11
6 ÷ (3 – 8) = -1 1/5
6 ÷ (3 * 8) = 1/4
6 ÷ (3 ÷ 8) = 16
(6 + 3) + 8 = 17
(6 – 3) + 8 = 11
(6 * 3) + 8 = 26
(6 ÷ 3) + 8 = 10
(6 + 3) – 8 = 1
(6 – 3) – 8 = -5
(6 * 3) – 8 = 10
(6 ÷ 3) – 8 = -6
(6 + 3) * 8 = 72
(6 – 3) * 8 = 24
(6 * 3) * 8 = 144
(6 ÷ 3) * 8 = 16
(6 + 3) ÷ 8 = 1 1/8
(6 – 3) ÷ 8 = 3/8
(6 * 3) ÷ 8 = 2 1/4
(6 ÷ 3) ÷ 8 = 1/4
8 + (6 + 3) = 17
8 + (6 – 3) = 11
8 + (6 * 3) = 26
8 + (6 ÷ 3) = 10
8 – (6 + 3) = -1
8 – (6 – 3) = 5
8 – (6 * 3) = -10
8 – (6 ÷ 3) = 6
8 * (6 + 3) = 72
8 * (6 – 3) = 24
8 * (6 * 3) = 144
8 * (6 ÷ 3) = 16
8 ÷ (6 + 3) = 8/9
8 ÷ (6 – 3) = 2 2/3
8 ÷ (6 * 3) = 4/9
8 ÷ (6 ÷ 3) = 4
(3 + 6) + 8 = 17
(3 – 6) + 8 = 5
(3 * 6) + 8 = 26
(3 ÷ 6) + 8 = 8 1/2
(3 + 6) – 8 = 1
(3 – 6) – 8 = -11
(3 * 6) – 8 = 10
(3 ÷ 6) – 8 = -7 1/2
(3 + 6) * 8 = 72
(3 – 6) * 8 = -24
(3 * 6) * 8 = 144
(3 ÷ 6) * 8 = 4
(3 + 6) ÷ 8 = 1 1/8
(3 – 6) ÷ 8 = -3/8
(3 * 6) ÷ 8 = 2.25
(3 ÷ 6) ÷ 8 = 1/16
8 + (3 + 6) = 17
8 + (3 – 6) = 5
8 + (3 * 6) = 26
8 + (3 ÷ 6) = 8 1/2
8 – (3 + 6) = -1
8 – (3 – 6) = 11
8 – (3 * 6) = -10
8 – (3 ÷ 6) = 7 1/2
8 * (3 + 6) = 72
8 * (3 – 6) = -24
8 * (3 * 6) = 144
8 * (3 ÷ 6) = 4
8 ÷ (3 + 6) = 8/9
8 ÷ (3 – 6) = -2 1/3
8 ÷ (3 * 6) = 4/9
8 ÷ (3 ÷ 6) = 16

In the case of the 3-card Krypto hand 8 6 3, if the target was 4, then you would have the following solutions:
\[ (8 \div 6) * 3 = 4 \] \[ 3 * (8 \div 6) = 4 \] \[ 3 \div (6 \div 8) = 4 \] \[ (8 * 3) \div 6 = 4 \] \[ (3 * 8) \div 6 = 4 \] \[ 8 \div (6 \div 3) = 4 \] \[ (3 \div 6) * 8 = 4 \] \[ 8 * (3 \div 6) = 4 \]

One can immediately see that several of these solutions are the same by order of operation rules. For instance, \((8 ÷ 6) * 3\) is the same as \(3 * (8 ÷ 6)\) using the commutative property of multiplication (the order of the operands does not affect the result). Similarly, \((8 * 3) ÷ 6 = (3 * 8) ÷ 6\) and \((3 ÷ 6) * 8 = 8 * (3 ÷ 6)\) by the commutative property of multiplication. If you're playing Krypto with the normal rules, all this means that you have a better chance at coming up with a solution quickly, since any valid solution counts for 2 points.

I really like the solutions that have fractional intermediate results, like \(3 ÷ (6 ÷ 8)\). Writing this out, you get \(\frac{3}{\frac{6}{8}}\), which equals \(\frac{3}{\frac{3}{4}}\), which when you multiply both the numerator and denominator of the fraction by 4, equals 4, the target. When playing the physical game, you do all this in your head. But if you use brute force algorithms and write out all the possibilities and all the solutions, you can glean more academic math out of the game.

For instance, what percentage of the total possible combinations of these three cards actually were solutions? Well, there are 192 possible solutions (counting equivalent math statements that have different orders of the operands), and there are (see above) 8 solutions to this game, where the target is 4. That makes 8/192 solutions, or 1 solution in 24 possibilities, or 4.16666...%, or about 4%. Being that a human can usually come up with a solution to these puzzles in a few seconds to about a minute, you might wonder if the computer route is worth it. Well, as the dcode.fr Krypto solver shows, when you make the game harder, by having 5 cards and a target, it gets a little harder to come up with a solution quickly, as you may have noticed if you've tried the card game (as I have!), and the solver usually gets you ALL the solutions in less than a second! This allows considerably more interesting math and investigations to occur, if you're inclined, which is what this course is all about!

Summing up, the brute-force method can get you solutions to relatively complicated puzzles that would take the average person much longer to achieve, if they could achieve it at all. In addition, computer exploration of these puzzles allows more questions to be asked, allowing for more learning. For instance, what if we wanted to know if the target was possible, given the 3 cards drawn? Using our exhaustive list of possible combinations of the 3 numbers on the cards with arithmetic operators, we could have said for sure that 4 was a valid target. What if we had drawn a 22 as the target? Well, looking at our list, 22 is not a possible outcome of combining our cards with the 4 basic arithmetic operators, so we wouldn't have to sweat it figuring out a solution – there is none.

It gets much better. We could start to play the game with a wider spectrum of targets, given our knowledge that negative numbers and rational numbers are possible targets for the 3 cards 3, 6 & 8. There are Krypto variant decks out there with fractions and negative numbers, and we could easily create a computer version that allowed not only for these, but for additional operators, irrational numbers and more.

I asked ChatGPT to write a script to give all the results, in order, with no repeats, so we could for instance figure out which targets are possible, and which aren't. We could use this information to design different variations of the puzzle/game that might be fun. Here are the results of the script, with some extra results from the info above:

-45, -30, -18, -15, -11, -10, -7.5, -6, -5 5/8, -5, -3 1/3, -2 1/4, -1 2/3, -1 1/2, -1, -5/6, 1/16, 1/4, 3/14, 4/9, 6/11, 1, 1 1/8, 1 1/2, 1 2/3, 1 5/6, 2 1/4, 3 1/3, 3 3/4, 4, 4 1/3, 4 2/3, 5, 5 5/8, 6, 6 3/8, 7 1/2, 8 1/2, 8 2/3, 10, 11, 16, 17, 18, 24, 26, 30, 33, 42, 45, 51, 66, 72, 144

If we take out the fractional results, we have the following integer results possible with a 8 6 3 hand:

-45, -30, -18, -15, -11, -10, -6, -5, -1, 1, 4, 5, 6, 10, 11, 16, 17, 18, 24, 26, 30, 33, 42, 45, 51, 66, 72, 144

if we allow negative numbers. Without negatives, we get:

1, 4, 5, 6, 10, 11, 16, 17, 18, 24, 26, 30, 33, 42, 45, 51, 66, 72, 144

I can imagine a variant of Krypto that only allowed these targets. In fact, the INSUMNIA app has an option to only allow possible targets. Or you could be challenged to figure out if a target was possible; maybe you would get extra points if you could figure this out.

Finally, we could imagine playing the game not only guessing the arithmetic operators necessary to combine the cards to meet the target, but perhaps guessing the cards necessary to meet a known target and a given set of operators. And my personal favorite – we could allow for guesses that came closest to the target to get points, or allow combinations that don't meet the target but satisfy some rule to gain points.

INSUMNIA

Well, a friend of mine and I did produce a variation of Krypto that is electronic, and will run in a browser. (We didn't know that Krypto existed!) It doesn't use a straight brute force algorithm to get solutions, but something close. It uses 4 cards and a target, and is played in single-player mode. The game is called insumnia, and we even put it on the Apple App Store for a while. It's available on this website, here. We'll give it a whirl, and the homework will be coming up with other variations of Krypto that could be used to learn even more math.

COUNTDOWN NUMBERS GAME

The British television series Countdown is a game show that has a numbers portion that is a variant of Krypto, using 6 cards instead of five. Besides the official show videos, there are tons of apps and calculators that allow you to play the game. The dcode.fr Countdown Number Game page has a few variants, including one that allows fractions, negative numbers, and the power (exponent) operator!! We'll take a quick look at this awesome game, and also a quick look at a free app called Countdown6.