ShareMyScreen/AdventOfCode/2022/25/FullOfHotAir
Conversion to & from offset-base-5. I can convert from and to base-5-array form using 5&#. and 5&#.^:_1, so all I need is to handle the offset. I will represent SNAFU numbers as boxed strings. I read the input.
]nums =. < onaoclines +------+-----+----+--+----+---+-----+---+-----+----+--+--+---+ |1=-0-2|12111|2=0=|21|2=01|111|20012|112|1=-1=|1-12|12|1=|122| +------+-----+----+--+----+---+-----+---+-----+----+--+--+---+
No need for a script on this one.
snatoten =. ((5&#.)@:+ _5 * >&2) @ ('012=-'&i.) @ > :. tentosna snatoten nums 1747 906 198 11 201 31 1257 32 353 107 7 3 37
To convert from SNAFU, I convert 0 1 2 _1 _2 to 0 1 2 3 4; then wherever there is a 3 or 4, I subtract 5 times the place value. This leaves two base-5 vectors, which I add and convert to decimal.
tentosna =: < @ ({&'012=-') @ (}.^:(0={.)@(((0,(- 5&*)) + 0,~]) >&2)^:_) @ (5&#.^:_1)"0 :. snatoten tentosna@snatoten snums +------+-----+----+--+----+---+-----+---+-----+----+--+--+---+ |1=-0-2|12111|2=0=|21|2=01|111|20012|112|1=-1=|1-12|12|1=|122| +------+-----+----+--+----+---+-----+---+-----+----+--+--+---+
I build up converting to SNAFU bit by bit.
- (5&#.^:_1) converts to a list of base-5 digits. I must then convert the 3s and 4s _2 and _1, and compensate by adding 1 in the next-higher place
- >&2 creates a list of the places that need to carry out a _1
- 0,~] moves those places to the next-higher place
- (- 5&*) subtracts 5 from those places containing 3 or 4
- 0, extends with a high-order 0 to match the place added for the carries
That converts to offset-base-5. If a high-order 0 was added, I remove it next.
- }.^:(0={.) discards the first atom if it is 0
Handling the carries may create another carry.
- I repeat the procedure until there are no more carries using ^:_ .
To finish up
- {&'012=-' converts the interval [_2,2] to SNAFU characters
- < boxes the result to produce an atom
Since I was careful to define snatoten and tentosna as inverses of each other, I can convert SNAFU to numeric, add the numbers, and convert back in one simple expression.
+/&.:snatoten snums +------+ |2=-1=0| +------+