summaryrefslogtreecommitdiff
path: root/08/src/part-2.rs
diff options
context:
space:
mode:
Diffstat (limited to '08/src/part-2.rs')
-rw-r--r--08/src/part-2.rs112
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);
+}