1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
mod bitfield;
use std::io::{BufRead};
use crate::bitfield::{Bitfield, parse_input};
/*
* This is a terrible, brute-force solution of day 8. I spent way too
* long on a better solution that I never got working, so here's the
* brute-force.
*
*/
// 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);
}
|