ShareMyScreen/AdventOfCode/2022/25/FullOfHotAir

From J Wiki
Jump to navigation Jump to search

The Problem <<

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|
+------+