So. I like Brainfuck. I find the challenge of writing code in it fun / fascinating. And a few years ago, i figured out an "easy" way of writing code with it: using it like Forth, by using the tape like a stack.
The idea was as such: treat everything on the "left" of the current position as data; treat everything on the "right" as empty space that can be used for temporary computations and to which the stack can extend. This formalism makes it easier to reason about what's happening, and therefore easier to combine simple snippets into a bigger program. For instance, the following code doubles the current value at the top of the stack, in two steps:
duplicate the current value
[->+>+<<]>>[-<<+>>]<
add the current value to the previous one
[-<+>]<
Turns out day 6 was easy! It proved to be a good opportunity to actually try writing some brainfuck directly, without the transpiler! I've tried commenting the code as much as possible to make it as readable as brainfuck code can be:
init the memory with 2 bytes counter; buffer; and 4 first bytes
{ 0 4 ' 0 0 ' A B C @D@ }
>++++>>> ,>,>,>,
while current input isn't eof
[
now: { x x 0 0 A B C @D@ }
first duplicate everything
[- >+ >+>>+>>+<<<<< <] > [- <+ >] <<
[- >>+ >>>>>>+>+>>+<<<<<<<<< <<] >> [- <<+ >>] <<<
[- >>>+ >>>>+>>>>>>+>+<<<<<<<<<<< <<<] >>> [- <<<+ >>>] <<<<
[->>>>+ >>+>>>>>>+>>>>+<<<<<<<<<<<< <<<<] >>>> [-<<<<+>>>>] >>>>>>>>>>>>
now: { x x 0 0 A B C D 0 D A D B D C C A C B B <A> }
perform all six comparisons; increase counter by one for each match
[-<->]+<[[-]>-<]> [-<<<<<<<<<<<<+>>>>>>>>>>>>] <<
[-<->]+<[[-]>-<]> [- <<<<<<<<<<+>>>>>>>>>> ] <<
[-<->]+<[[-]>-<]> [- <<<<<<<<+>>>>>>>> ] <<
[-<->]+<[[-]>-<]> [- <<<<<<+>>>>>> ] <<
[-<->]+<[[-]>-<]> [- <<<<+>>>> ] <<
[-<->]+<[[-]>-<]> [- <<+>> ] <<
now: { x x 0 0 A B C D @n@ }
if n == 0 then all bytes were different and we found it
create a copy of not n for later
[->+>+<<]>[-<+>]+>[[-]<->]<<
if n non zero we must continue
[ [-]
shift all three previous values (copy each to previous cell)
<<<<[-]
>[-<+>]
>[-<+>]
>[-<+>]
go back to counter then inc by one
<<<<<<+
check for overflow
[->+>+<<]> duplicate to both buffer cells
[-<+>]+> copy back then set to 1
[[-]<->]< set previous cell to 0 if non 0
[-<<+>>] if 1 then counter is 0: inc first cell by one
go back to cell for last byte; read input; go back to n
>>>>>,>
]
if n was zero we must break out of the loop
> [ -<[-]<[-]<[-]<[-]<[-] ] <<
if n was non zero: now: { x x 0 0 A B C @D@ }
if n was zero: now: { x x @0@ }
]
we must transform our two bytes of index into digits
increase last digit by 1 for each in lower byte
<[>>>>+
then loop back to carry values greater than 9
[- >+>+<< ] >[- <+> ]>+ >>>++++++++++
[-<<<-[->+>+<<]>>[-<<+>>]+<[[-]>-<]>[->[-]<]>]<<<[[-]<<----------<+>>>]<<<
[- >>+>+<<< ] >>[- <<+>> ]>+ >>>++++++++++
[-<<<-[->+>+<<]>>[-<<+>>]+<[[-]>-<]>[->[-]<]>]<<<[[-]<<<----------<+>>>>]<<<<
[->>>+>+<<<<]>>>[- <<<+>>> ]>+ >>>++++++++++
[-<<<-[->+>+<<]>>[-<<+>>]+<[[-]>-<]>[->[-]<]>]<<<[[-]<<<<----------<+>>>>>]<<<<<
<-]
increase digits by 2 5 6 for each in higher byte
<[>>>++>+++++>++++++
loop back to carry values greater than 9
[- >+>+<< ] >[- <+> ]>+ >>>++++++++++
[-<<<-[->+>+<<]>>[-<<+>>]+<[[-]>-<]>[->[-]<]>]<<<[[-]<<----------<+>>>]<<<
[- >>+>+<<< ] >>[- <<+>> ]>+ >>>++++++++++
[-<<<-[->+>+<<]>>[-<<+>>]+<[[-]>-<]>[->[-]<]>]<<<[[-]<<<----------<+>>>>]<<<<
[->>>+>+<<<<]>>>[- <<<+>>> ]>+ >>>++++++++++
[-<<<-[->+>+<<]>>[-<<+>>]+<[[-]>-<]>[->[-]<]>]<<<[[-]<<<<----------<+>>>>>]<<<<<
<<-]>
print the result including leading zero digits
>++++++++++++++++++++++++++++++++++++++++++++++++.
>++++++++++++++++++++++++++++++++++++++++++++++++.
>++++++++++++++++++++++++++++++++++++++++++++++++.
>++++++++++++++++++++++++++++++++++++++++++++++++.
print newline
[-]++++++++++.
I find it fun how more than half of it is just the transformation of the two counter bytes into four printable digits. ^^
