## The k-odd and k-even numbers

Except it's not really a game. Instead, it's an interactive tool we came up with to help us explain how we solve some problems in the real world, sometimes. In this blog post, we aim to explore these problems and our approach to them, and what we can learn from them.

Let's say you have a Programmable Logic Controller (PLC) with (to keep it reasonable) 16 outputs. While the PLC likely has a test mode that makes it easy to activate each output in sequence, let's assume you do not know about it, but you do know how to write and run a program. Now, loading the program onto the PLC is likely the slowest part of the process, so doing them one at a time is, to say the least, highly suboptimal. Instead, we can start building a table of actuators and outputs, filling out the actuators first:

Actuator | Output |
---|---|

Red Indicator | |

Yellow Indicator | |

Green Indicator | |

Left Arm X | |

Left Arm Y | |

Left Arm Z | |

Left Arm Grab | |

Left Arm Flip | |

Right Arm X | |

Right Arm Y | |

Right Arm Z | |

Right Arm Grab | |

Right Arm Flip | |

Left Reject | |

Right Reject | |

Swapper |

Next up, we activate these in groups of 8 (half of our total outputs). The groups can be rather arbitrary, as long as they follow a specific overlap pattern, tho by using
what we're gonna be defining as k-odd or k-even numbers we can simplify it a lot, with k-odd being the easiest to use. We define k-odd numbers as being numbers that satisfy
`(x mod 2k) - (x mod k) = k`

, for example the 1-odd numbers are just `(x mod 2) - (x mod 1) = 1`

where `x mod 1`

simplifies to zero,
leaving us with `x mod 2 = 1`

(aka the odd numbers). Likewise, k-even numbers are those that satisfy `(x mod 2k) - (x mod k) = 0`

(for 1-even,
simplifies to the even numbers).

Since we're working with groups of 8, it is convenient to start with 8-odd numbers and go down from there, to 4-odd, to 2-odd, and finally to 1-odd, as it makes the readout easier (as binary numbers). The 8 first 8-odd numbers are: 8, 9, 10, 11, 12, 13, 14, and 15. We can activate these outputs, and write down a "1" for the actuators that moved, and "0" for the actuators that didn't:

Actuator | Output |
---|---|

Red Indicator | 1 |

Yellow Indicator | 1 |

Green Indicator | 1 |

Left Arm X | 0 |

Left Arm Y | 0 |

Left Arm Z | 0 |

Left Arm Grab | 1 |

Left Arm Flip | 0 |

Right Arm X | 0 |

Right Arm Y | 0 |

Right Arm Z | 0 |

Right Arm Grab | 1 |

Right Arm Flip | 0 |

Left Reject | 1 |

Right Reject | 1 |

Swapper | 1 |

Next up, we do the 8 first 4-odd numbers, they are: 4, 5, 6, 7, 12, 13, 14, and 15. Note that 4 of these overlap with the previous group. Then we note down a "1" on what activated, and a "0" on what didn't:

Actuator | Output |
---|---|

Red Indicator | 11 |

Yellow Indicator | 11 |

Green Indicator | 11 |

Left Arm X | 00 |

Left Arm Y | 00 |

Left Arm Z | 01 |

Left Arm Grab | 10 |

Left Arm Flip | 01 |

Right Arm X | 00 |

Right Arm Y | 00 |

Right Arm Z | 01 |

Right Arm Grab | 10 |

Right Arm Flip | 01 |

Left Reject | 10 |

Right Reject | 10 |

Swapper | 11 |

Now for the 2-odd numbers: 2, 3, 6, 7, 10, 11, 14, and 15. This time, 6 of these overlap with previous groups. We once again note them down, same as before:

Actuator | Output |
---|---|

Red Indicator | 111 |

Yellow Indicator | 111 |

Green Indicator | 110 |

Left Arm X | 000 |

Left Arm Y | 000 |

Left Arm Z | 010 |

Left Arm Grab | 100 |

Left Arm Flip | 011 |

Right Arm X | 001 |

Right Arm Y | 001 |

Right Arm Z | 010 |

Right Arm Grab | 100 |

Right Arm Flip | 011 |

Left Reject | 101 |

Right Reject | 101 |

Swapper | 110 |

Finally we are left with the odd numbers: 1, 3, 5, 7, 9, 11, 13, and 15. 7 of them overlap with previous groups. After noting them down, as before:

Actuator | Output |
---|---|

Red Indicator | 1111 |

Yellow Indicator | 1110 |

Green Indicator | 1101 |

Left Arm X | 0000 |

Left Arm Y | 0001 |

Left Arm Z | 0100 |

Left Arm Grab | 1000 |

Left Arm Flip | 0110 |

Right Arm X | 0010 |

Right Arm Y | 0011 |

Right Arm Z | 0101 |

Right Arm Grab | 1001 |

Right Arm Flip | 0111 |

Left Reject | 1010 |

Right Reject | 1011 |

Swapper | 1100 |

We can now read these out in decimal and sort them around:

Actuator | Output |
---|---|

Left Arm X | 0 |

Left Arm Y | 1 |

Right Arm X | 2 |

Right Arm Y | 3 |

Left Arm Z | 4 |

Right Arm Z | 5 |

Left Arm Flip | 6 |

Right Arm Flip | 7 |

Left Arm Grab | 8 |

Right Arm Grab | 9 |

Left Reject | 10 |

Right Reject | 11 |

Swapper | 12 |

Green Indicator | 13 |

Yellow Indicator | 14 |

Red Indicator | 15 |

This gives us our PLC output allocation table, and we only had to program our PLC 4 times, not 16! Also note that one of these never got activated, and yet we still found its output address.

The usefulness of the k-odd numbers is that we can easily go further, we can take it up to 32, 64, 128, even 256 outputs, or more. For those trying to play the "game" we introduced above, k-odd numbers are basically necessary for playing it fast, and indeed, we observed their usefulness by trying to optimize how we played it ourselves.

We hope others may find k-odd and k-even numbers useful, too!