s" lib.fs" included ...
This file is valid Forth source code, but also a Markdown file thanks to Forth allowing to define new syntax. Anything outside fenced code blocks will be skipped by the Forth compiler/interpreter. This allows code to be written in the literate programming style.
Full solution without the annotations.
s" lib.fs" included
s" 1.txt" load-data data
: depth< dup cell - @ over @ < ;
: collect swap depth< if 1 else 0 then rot + ;
: solve ['] collect data cell + 0 reduce ;
solve .
bye
We are given an ordered set of numbers, and asked to count the number of times when the two successive elements are ordered such that the next one is greater than the previous.
First, load the data into an array in memory with zero as a terminator.
s" 1.txt" load-data data
load-data
is defined in lib.fs
, where I keep a collection of
useful words that are not directly related to the problem, and generic
enough to be used across most problems. Some of these words are
reduce
, for-each
and load-data
.
The next Markdown code block will also be skipped to prevent it from being compiled in.
load-data
is defined is like this in lib.fs
:
: load-data ( addr u "<spaces>ccc<space>" -- ) create included ;
It creates a dictionary entry for a name, and includes the data file into Forth compiler/interpreter.
Note that data files are formatted as valid Forth code to simplify the parsing process. They will typically compile in data blocks into dictionary.
Next, define depth<
that will take the address of an element in the
array, and compare it to the previous element. It keeps the address,
and leaves an extra boolean flag in the stack indicating the result of
the comparison.
: depth< ( addr -- addr f ) dup cell - @ over @ < ;
Next, define collect
that will take an element address and the
accumulator, and add 1 to the accumulator if depth<
is true.
: collect ( addr acc -- addr acc ) swap depth< if 1 else 0 then rot + ;
Finally, define solve
which will reduce
the array from left to
right starting from the second element.
It starts from the second element because depth<
always compares
with the previous element.
: solve ['] collect data cell + 0 reduce ;
Print the solution and exit:
solve . bye