diff options
| author | Reiner Herrmann <reiner@reiner-h.de> | 2022-12-26 22:55:33 +0100 |
|---|---|---|
| committer | Reiner Herrmann <reiner@reiner-h.de> | 2022-12-26 22:55:33 +0100 |
| commit | 62e9513b6f5800c3fb722b65e3804ed4551b514e (patch) | |
| tree | 37597b36fb4a4950c67186ff0055ee90a9ba91c7 /src/bin/day25.rs | |
| parent | 203fcaaa3d2579c862112ca36a05187a55838406 (diff) | |
day25
Diffstat (limited to 'src/bin/day25.rs')
| -rw-r--r-- | src/bin/day25.rs | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/src/bin/day25.rs b/src/bin/day25.rs new file mode 100644 index 0000000..4350d7d --- /dev/null +++ b/src/bin/day25.rs @@ -0,0 +1,111 @@ +static DAY: u8 = 25; + +fn main() { + let input = advent::read_lines(DAY); + println!("{DAY}a: {}", console_number(&input)); +} + +fn snafu_to_number(input: &str) -> i64 { + let mut number = 0; + for c in input.chars() { + number *= 5; + number += match c { + '0' => 0, + '1' => 1, + '2' => 2, + '-' => -1, + '=' => -2, + _ => unimplemented!(), + }; + } + number +} + +fn number_to_snafu(input: i64) -> String { + let mut number = input; + + let mut digits = Vec::new(); + while number > 0 { + digits.push(number % 5); + number /= 5; + } + digits.push(0); + + for i in 0 .. digits.len() - 1 { + if digits[i] == 3 { + digits[i+1] += 1; + digits[i] = -2; + } else if digits[i] == 4 { + digits[i+1] += 1; + digits[i] = -1; + } else if digits[i] == 5 { + digits[i+1] += 1; + digits[i] = 0; + } + } + + let mut snafu = String::new(); + for digit in digits.iter().rev().skip_while(|&x| *x == 0) { + match digit { + -1 => snafu.push('-'), + -2 => snafu.push('='), + 0 => snafu.push('0'), + 1 => snafu.push('1'), + 2 => snafu.push('2'), + _ => unimplemented!(), + } + } + snafu +} + +fn console_number(input: &[String]) -> String { + let number = input.iter() + .map(|x| snafu_to_number(x)) + .sum(); + number_to_snafu(number) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test() { + let input = [ + "1=-0-2", + "12111", + "2=0=", + "21", + "2=01", + "111", + "20012", + "112", + "1=-1=", + "1-12", + "12", + "1=", + "122", + ].iter().map(|&x| String::from(x)).collect::<Vec<_>>(); + + assert_eq!(console_number(&input), "2=-1=0"); + } + + #[test] + fn test_number_to_snafu() { + assert_eq!(number_to_snafu(1), "1"); + assert_eq!(number_to_snafu(2), "2"); + assert_eq!(number_to_snafu(3), "1="); + assert_eq!(number_to_snafu(4), "1-"); + assert_eq!(number_to_snafu(5), "10"); + assert_eq!(number_to_snafu(6), "11"); + assert_eq!(number_to_snafu(7), "12"); + assert_eq!(number_to_snafu(8), "2="); + assert_eq!(number_to_snafu(9), "2-"); + assert_eq!(number_to_snafu(10), "20"); + assert_eq!(number_to_snafu(15), "1=0"); + assert_eq!(number_to_snafu(20), "1-0"); + assert_eq!(number_to_snafu(2022), "1=11-2"); + assert_eq!(number_to_snafu(12345), "1-0---0"); + assert_eq!(number_to_snafu(314159265), "1121-1110-1=0"); + } +} |
