After struggling with robots simulations in a grid world written in Matlab/Octave code I remembered how easy it is to program such a movement if the language allows to start with index “0”. Or in more mathematical words: a nice application of ring of integers modulo n (\(\mathbb{Z} / \mathbb{Z} n\)).

Ring of integers modulo n

The ring of integers modulo n is denoted as \(\mathbb{Z} / \mathbb{Z} n\) and denotes a set of numbers \(\{0, ..., n-1\}\).

Therefore, we could write the binary field as: \(\mathbb{Z} / \mathbb{Z} 2 = \{0,1\}\).

Some more examples:

\[\mathbb{Z} / \mathbb{Z} 3 = \{0,1,2\}\] \[\mathbb{Z} / \mathbb{Z} 4 = \{0,1,2,3\}\] \[\mathbb{Z} / \mathbb{Z} 5 = \{0,1,2,3,4\}\] \[...\]

The modulo (%, mod) after integer division is a positive integer (unlike the remainder) and tells us how much is left after dividing one integer by another without using e.g. floating point. Let us assume that we use \(\mathbb{Z} / \mathbb{Z} 3\). We will only end up with numbers \(x \in \{0,1,2\}\):

Ìn  [1]: 0 % 3
Out [1]: 0

Ìn  [2]: 1 % 3
Out [2]: 1

Ìn  [3]: 2 % 3
Out [3]: 2

Ìn  [4]: 3 % 3
Out [4]: 0

Ìn  [5]: 5 % 3
Out [5]: 2

Ìn  [6]: 7 % 3
Out [6]: 1

In [7]: 82934 % 3
Out[7]: 2

Application for grid world robotics

Back to what made me angry when using Matlab/octave or other programming languages that use 1 as their index for the first entry in an array. Let us assume that we move a robot around in a cyclic grid world (gridded torus). Once the robot has reached a side and we want to move further into that direction we will end up on the opposite site. This is similar to moving on a globe of Earth with grid coordinates on it (sry Flat Earth Society - but someone has to tell you ;)). This movement can be programmed extremely efficient using modulo if the programming language starts indexing arrays with 0. Here is a little example in JavaScript using math.js and plotly.js.

A grid with random initial position is created and then a function that updates the position using modulo is called every second:

// calculate next move
// using idx and current_idx for better explanation
var current_idx_x =  idx_x;
var current_idx_y =  idx_y;
grid._data[current_idx_x][current_idx_y] = 0;    

// maximum distance per step: 1
var move_distance_x = math.randomInt(-1,1);
var move_distance_y = math.randomInt(-1,1);
    
// using math.mod since % returns the remainder
var idx_x = math.mod((current_idx_x + move_distance_x),grid._size[0]);
var idx_y = math.mod((current_idx_y + move_distance_y), grid._size[1]);
grid._data[idx_x][idx_y] = 1;