summaryrefslogtreecommitdiff
path: root/src/day25.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/day25.rs')
-rw-r--r--src/day25.rs73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/day25.rs b/src/day25.rs
new file mode 100644
index 0000000..2d26028
--- /dev/null
+++ b/src/day25.rs
@@ -0,0 +1,73 @@
+fn from_snafu(s: &str) -> i64 {
+ // This is the easy bit...
+ let mut i: i64 = 0;
+ let mut pow: i64 = 1;
+ for ch in s.chars().rev() {
+ match ch {
+ '2' => i += 2 * pow,
+ '1' => i += 1 * pow,
+ '0' => {}, // additive identity!
+ '-' => i += -1 * pow,
+ '=' => i += -2 * pow,
+ _ => panic!("unexpected input {}", ch)
+ }
+ pow *= 5;
+ }
+ i
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ #[test]
+ fn test_from_snafu() {
+ let cases = vec![
+ ("1=-0-2", "1747"),
+ ( "12111", "906"),
+ ( "2=0=", "198"),
+ ( "21", "11"), // works
+ ( "2=01", "201"), // 201,1 > 40,0 > 8,= > 1,1
+ ( "111", "31"), // works
+ ( "20012", "1257"), //works
+ ( "112", "32"), // works
+ ( "1=-1=", "353"), // broke
+ ( "1-12", "107"),
+ ( "12", "7"),
+ ( "1=", "3"),
+ ( "122", "37"),
+ ];
+ for (snafu, decimal) in cases {
+ let x = from_snafu(snafu);
+ assert_eq!(x.to_string().as_str(), decimal);
+ assert_eq!(to_snafu(x), snafu);
+ }
+ }
+}
+
+fn to_snafu(mut i: i64) -> String {
+ // how to do this :thinking: add two, mod 5,take away 2? // nope
+ let mut res = Vec::<char>::new();
+ while i != 0 {
+ let d = ((i + 2) % 5) - 2;
+ let ch = match d {
+ 2 => '2',
+ 1 => '1',
+ 0 => '0',
+ -1 => '-',
+ -2 => '=',
+ _ => panic!("unexpected digit {}", d)
+ };
+ res.push(ch);
+ i = (i + 2) / 5;
+ }
+ res.reverse();
+ res.into_iter().collect::<String>()
+
+}
+
+pub fn run(input: String) {
+ let s: i64 = input.lines()
+ .map(from_snafu)
+ .sum();
+ println!("Day 25: {}", to_snafu(s));
+} \ No newline at end of file