Code patternsAdvanced: wrapping cells of a known widthPick the largest by a race

Pick the largest by a race

Finds which of many numbers is the largest, without comparing any two of them.

Watch it run

The form “Two digits of four bits” works on 31 cells; the named ones are “result 0”, “high 0”, “low 0”, “result 1”, “high 1”, “low 1”, “result 2”, “high 2”, “low 2”, “result 3”, “high 3”, “low 3” and “scratch”. Press Play, drag the step slider forwards and back, or edit the scores:

The figure needs JavaScript. The program below is the result for the example values.

Add 1 to every number at the same time, again and again. The first one to reach the top was the largest. "Add 1 to all" is one flat loop: one step, however many numbers there are.

"Has anyone arrived?" is a scan (see find a zero cell or a marker). The numbers are stored as "distance still to go", so an arrival is a zero cell, and [>>>>>] slides over all the others and stops on it. If nobody has arrived it stops on an empty frame at the end, and a marker there says "go round again".

A race over the whole value would take up to 256 rounds. So each number is split into two digits of 4 bits. The race is run on the high digits first, 16 rounds at most; only the winners of that race take part in the race on the low digits.

The first of several equal numbers wins, because the scan comes from the left.

The code

This is the program the figure ran, written by the generators for these values and this cell size. It is brainfuck as it stands: copy it, or open it in the playground, where you can change it:

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+[-<<<<<<<<<<<<<<<<<<<<<<<<<+>>>---------------->-------------------------------->+>>>---------------->-------------------------------->+>>>---------------->-------------------------------->+>>>---------------->-------------------------------->>>>>>]<<<<+[>>>>+[-<<<<<<<<<<<<<<<<<<<<<<+>>>>>+>>>>>+>>>>>+>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<[>>>>>]<<]<[>>>>++++++++++++++++<>>>>>[>>>>>]<<<]>[>>>>+[-<<<<<<<<<<<<<<<<<<<<<+>>>>>+>>>>>+>>>>>+>>>>>>]<<<<<<<<<<<<<<<<<<<<<[>>>>>]<<<]>+<<[<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>->>>>+[-<<<<<<<<<<<<<<<<<<<<<<<<<->>>>>->>>>>->>>>>->>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<[-]>[-]>>>>[-]>[-]>>>>[-]>[-]>>>>[-]>[-]
Open in the playground663 characters

What it needs

Common mistakes
  • Racing on whole values. With 512 numbers a round is about 515 steps; 200 rounds are 100,000 steps.
  • Forgetting the empty frames at both ends: the scan needs a place to stop, and the walk home needs one too.

What it costs

A plain step is one command. An optimised step is one step of an interpreter that folds runs of the same command and flat loops. Choose the values and watch the two bars; What costs what explains how cost is counted:

The figure needs JavaScript. The table below has the measured steps.

Cost as a formula, and measured
Table 1. The cost as a function of the values.
FormPlain stepsOptimised steps
Two digits of four bitshundreds to thousandsabout (numbers + 3) per round; at most 32 rounds
The naive way: count down and test each onegrows with numbers × (255 − best)about 10 per number per round; 255 − best rounds
Table 2. Measured when this page was written.
FormValuesBitsCharactersPlain stepsOptimised steps
Two digits of four bitsthe scores = 93, 41, 207, 15086633,89162
Two digits of four bitsthe scores = 3, 1, 2, 0, 3, … (8)81,1759,604384
Two digits of four bitsthe scores = 255, 255840741230
The naive way: count down and test each onethe scores = 93, 41, 207, 1508536954,3861,825
The naive way: count down and test each onethe scores = 3, 1, 2, 0, 3, … (8)81,38417,385,01918,487
The naive way: count down and test each onethe scores = 255, 25582321,14731

Against the naive way

The race of the first version of this project: count every number down by 1 per round, and test each one for zero with a copy.

The numbers, row by row
this pattern: the scores = 3, 1, 2, 0, 3, … (8)
384the naive way: the scores = 3, 1, 2, 0, 3, … (8)
18,487

This pattern against the naive way, on 8-bit cells, measured when this page was written. The bars show the last row: optimised steps.

ValuesOptimised stepsPlain stepsCharacters
patternnaivepatternnaivepatternnaive
the scores = 93, 41, 207, 150621,8253,891954,386663536
the scores = 3, 1, 2, 0, 3, … (8)38418,4879,60417,385,0191,1751,384

Measured in the project for 512 scores on 32-bit cells: about 5,000 optimised steps with digits of 2 bits, against 119,000 to 595,000 for the baseline, depending on how high the best score is. measured in the project

Other forms

to measure against The naive way: count down and test each one

The lowest "distance to go" wins, so each score is stored as 255 − score. Scores in cells 0…, results after them.

>>>>>>>>+[>>>+<<<<<<<<<<<[->>>>>>>>>+>+<<<<<<<<<<]>>>>>>>>>>[-<<<<<<<<<<+>>>>>>>>>>]<[>>-<<[-]]>>[<<<[->+>+<<]>>[-<<+>>]<[<-<<<<+>>>>>[-]]>>[-]]+<<<<<<<<<<[->>>>>>>>+>+<<<<<<<<<]>>>>>>>>>[-<<<<<<<<<+>>>>>>>>>]<[>>-<<[-]]>>[<<<[->+>+<<]>>[-<<+>>]<[<-<<<+>>>>[-]]>>[-]]+<<<<<<<<<[->>>>>>>+>+<<<<<<<<]>>>>>>>>[-<<<<<<<<+>>>>>>>>]<[>>-<<[-]]>>[<<<[->+>+<<]>>[-<<+>>]<[<-<<+>>>[-]]>>[-]]+<<<<<<<<[->>>>>>+>+<<<<<<<]>>>>>>>[-<<<<<<<+>>>>>>>]<[>>-<<[-]]>>[<<<[->+>+<<]>>[-<<+>>]<[<-<+>>[-]]>>[-]]<<<<<<<<<<<->->->->>>>>]<<<<<<<<[-]>[-]>[-]>[-]
Open in the playground536 characters
Run this form step by step

The form “The naive way: count down and test each one” works on 12 cells; the named ones are “to go 0”, “to go 1”, “to go 2”, “to go 3”, “result 0”, “result 1”, “result 2” and “result 3”. Press Play, drag the step slider forwards and back, or edit the scores:

The figure needs JavaScript. The program below is the result for the example values.

Where it is used

Sources

Every program on this page was run on many inputs, in plain and in optimised mode, and compared with JavaScript. The explanations are written for this page.