diff options
Diffstat (limited to '08/src/part-2.rs')
-rw-r--r-- | 08/src/part-2.rs | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/08/src/part-2.rs b/08/src/part-2.rs new file mode 100644 index 0000000..a11e7b9 --- /dev/null +++ b/08/src/part-2.rs @@ -0,0 +1,112 @@ +mod bitfield; + +use std::io::{BufRead}; + +use crate::bitfield::{Bitfield, parse_input}; + +// This is embarassingly inefficient, and full of completely needless +// allocations. I just wanna get day 8 done! +fn perms(x: Vec<usize>) -> Vec<Vec<usize>> { + if x.len() == 1 { vec![x] } + else { + let mut ret: Vec<Vec<usize>> = Vec::new(); + for perm in perms(x[1..].to_vec()) { + for i in 0..x.len() { + let mut tmp: Vec<usize> = Vec::with_capacity(perm.len() + 1); + tmp.extend(& perm[0..i]); + tmp.push(x[0]); + tmp.extend(& perm[i..]); + ret.push(tmp); + } + } + ret + } +} + +const DIGIT_0: Bitfield = Bitfield { data: (1 << 0) | (1 << 1) | (1 << 2) | (0 << 3) | (1 << 4) | (1 << 5) | (1 << 6) }; +const DIGIT_1: Bitfield = Bitfield { data: (0 << 0) | (0 << 1) | (1 << 2) | (0 << 3) | (0 << 4) | (1 << 5) | (0 << 6) }; +const DIGIT_2: Bitfield = Bitfield { data: (1 << 0) | (0 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (0 << 5) | (1 << 6) }; +const DIGIT_3: Bitfield = Bitfield { data: (1 << 0) | (0 << 1) | (1 << 2) | (1 << 3) | (0 << 4) | (1 << 5) | (1 << 6) }; +const DIGIT_4: Bitfield = Bitfield { data: (0 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (0 << 4) | (1 << 5) | (0 << 6) }; +const DIGIT_5: Bitfield = Bitfield { data: (1 << 0) | (1 << 1) | (0 << 2) | (1 << 3) | (0 << 4) | (1 << 5) | (1 << 6) }; +const DIGIT_6: Bitfield = Bitfield { data: (1 << 0) | (1 << 1) | (0 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) }; +const DIGIT_7: Bitfield = Bitfield { data: (1 << 0) | (0 << 1) | (1 << 2) | (0 << 3) | (0 << 4) | (1 << 5) | (0 << 6) }; +const DIGIT_8: Bitfield = Bitfield { data: (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) }; +const DIGIT_9: Bitfield = Bitfield { data: (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (0 << 4) | (1 << 5) | (1 << 6) }; + +fn decode(x: Bitfield) -> Option<usize> { + match x { + DIGIT_0 => Some(0), + DIGIT_1 => Some(1), + DIGIT_2 => Some(2), + DIGIT_3 => Some(3), + DIGIT_4 => Some(4), + DIGIT_5 => Some(5), + DIGIT_6 => Some(6), + DIGIT_7 => Some(7), + DIGIT_8 => Some(8), + DIGIT_9 => Some(9), + _ => None + } +} + + +pub fn main() { + let mut stdin = std::io::stdin(); + let mut handle = stdin.lock(); + + /* + println!("{}", DIGIT_0 == Bitfield::try_from("abcefg").unwrap()); + println!("{}", DIGIT_1 == Bitfield::try_from("cf").unwrap()); + println!("{}", DIGIT_2 == Bitfield::try_from("acdeg").unwrap()); + println!("{}", DIGIT_3 == Bitfield::try_from("acdfg").unwrap()); + println!("{}", DIGIT_4 == Bitfield::try_from("bcdf").unwrap()); + println!("{}", DIGIT_5 == Bitfield::try_from("abdfg").unwrap()); + println!("{}", DIGIT_6 == Bitfield::try_from("abdefg").unwrap()); + println!("{}", DIGIT_7 == Bitfield::try_from("acf").unwrap()); + println!("{}", DIGIT_8 == Bitfield::try_from("abcdefg").unwrap()); + println!("{}", DIGIT_9 == Bitfield::try_from("abcdfg").unwrap()); + return; + */ + + let mut sum: usize = 0; + + for line in handle.lines() { + let l = line.unwrap(); + let (all, output) = parse_input(& l); + let mut decoded_output: [usize; 4] = [0; 4]; + + for perm in perms(vec![0,1,2,3,4,5,6]) { + let mut all_digits = [Bitfield::new(); 10]; + for a in 0..10 { + all_digits[a] = all[a].permute((& perm).into_iter()); + } + let mut seen_digits: Vec<bool> = std::iter::repeat(false).take(10).collect(); + for a in 0..10 { + if let Some(digit) = decode(all_digits[a]) { + seen_digits[digit] = true; + } + } + /* + print!("Decoded: "); + for a in 0..10 { + if seen_digits[a] { print!("{} ", a); } + } + */ + if (& seen_digits).into_iter().all(|&d| d) { + println!("OK!"); + for a in 0..4 { + let descrambled = output[a].permute((& perm).into_iter()); + decoded_output[a] = decode(descrambled).unwrap(); + } + break; + } + } + + let line_answer = decoded_output[3]*1 + decoded_output[2]*10 + decoded_output[1]*100 + decoded_output[0]*1000; + println!("Answer: {}", line_answer); + sum += line_answer; + } + + println!("Sum: {}", sum); +} |