Advent of Code 2022 Day 25
Day 25: Full of Hot Air
https://adventofcode.com/2022/day/25
The expedition reached the last part, a trip to the north pole via hot air balloon!
It is so cold on the mountain that the fuel needs to be pre-heated. A machine that does this needs to know the total amount to process before it will work.
Today’s input is the fuel requirements for each balloon, written in a weird number format.
An example input looks like this:
1=-0-2121112=0=212=01111200121121=-1=1-12121=122
So the amount the machine (nicknamed “Bob”) has to process is the sum of all those numbers.
The numbers are in a format called SNAFU.
It’s similar to decimal. Where decimal is based on powers of 10, SNAFU is based on powers of 5.
- In decimal, starting from the right, you have a ones place, a tens place, a hundreds place, …
- In SNAFU, starting from the right, you have a ones place, a fives place, a twenty-fives place, …
The digits are similar too, with two weird ones, -
, and =
.
SNAFU | decimal |
---|---|
0 | 0 |
1 | 1 |
2 | 2 |
- | -1 |
= | -2 |
Some examples converting decimal to SNAFU:
- 10 in decimal is two fives and no ones, in SNAFU it is written 20.
- 8 in decimal iss two fives minus two ones, in SNAFU it is written 2=.
And one in the other direction:
For the SNAFU number 2=-01
2
in the 625s place=
in the 125s place-
in the 25s place0
in the 5s place1
in the 1s place
(2 * 625) + (-2 * 125) + (-1 * 25) + (0 * 5) + (1 * 1). That’s 1250 + -250 + -25 + 0 + 1. 976
Part 1
The question asks what the SNAFU number you have to supply to “Bob“‘s console is.
Helpers
A function that converts SNAFU string to a decimal number.
With a running total that starts at 0: Look at a single SNAFU digit at a time, converting it to decimal. To get the new running total: multiply the current running total by 5 and add the converted digit.
fn to_decimal(snafu: &str) -> i64 {snafu.chars().fold(0, |decimal, snafu_digit| {let decimal_digit = ['=', '-', '0', '1', '2'].into_iter().position(|c| c == snafu_digit).unwrap() as i64- 2;decimal * 5 + decimal_digit})}
A function that converts a decimal number to a SNAFU string.
Recursion!
It calculates the last SNAFU digit and adds it the the end of all the other SNAFU digits. It does this by using that base 5/power of 5 property. Keeping into account SNAFU digits start at -2.
fn to_snafu(decimal: i64) -> String {if decimal == 0 {return String::new();}let decimal_remainder = decimal % 5;let snafu_digit = ['0', '1', '2', '=', '-'][decimal_remainder as usize];let new_decimal = (decimal + 2) / 5;let mut snafu = to_snafu(new_decimal);snafu.push(snafu_digit);snafu}
Using those helpers, the final code:
- Converts all input SNAFU numbers to decimal.
- Sums all those decimal numbers.
- Converts that decimal sum back to SNAFU.
Final code
1pub fn part_1(input: &str) -> String {2 let sum = input.lines().map(to_decimal).sum();3 to_snafu(sum)4}56fn to_decimal(snafu: &str) -> i64 {7 snafu.chars().fold(0, |decimal, snafu_digit| {8 let decimal_digit = ['=', '-', '0', '1', '2']9 .into_iter()10 .position(|c| c == snafu_digit)11 .unwrap() as i6412 - 2;13 decimal * 5 + decimal_digit14 })15}1617fn to_snafu(decimal: i64) -> String {18 if decimal == 0 {19 return String::new();20 }2122 let new_decimal = (decimal + 2) / 5;23 let mut snafu = to_snafu(new_decimal);2425 let decimal_remainder = decimal % 5;26 let snafu_digit = ['0', '1', '2', '=', '-'][decimal_remainder as usize];27 snafu.push(snafu_digit);2829 snafu30}
Part 2
An Elf hands you a single star. Combined with the 49 you gathered on the expedition you make a smoothie and deliver it to the reindeer!
Series navigation for: Advent of Code 2022