-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsolver.rs
56 lines (51 loc) · 1.48 KB
/
solver.rs
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
use aoc::{Reader, answer};
fn main() {
answer::timer(solution);
}
fn solution() {
let row = Reader::default()
.chars::<char>()
.into_iter()
.map(|ch| ch == '.')
.collect::<Vec<_>>();
answer::part1(2013, total_safe(&row, 40));
answer::part2(20006289, total_safe(&row, 400_000));
}
fn total_safe(row: &[bool], rounds: usize) -> usize {
let mut safe = 0;
let mut row = row.to_vec();
for _ in 0..rounds {
safe += row.iter().filter(|&&v| v).count();
row = next_row(&row);
}
safe
}
fn next_row(row: &[bool]) -> Vec<bool> {
let mut result = Vec::default();
for i in 0..row.len() {
let element = get_element(
*row.get(i - 1).unwrap_or(&true),
*row.get(i + 1).unwrap_or(&true),
);
result.push(element);
}
result
}
fn get_element(left: bool, right: bool) -> bool {
/*
* Raw conditions for a TRAP can be summed up as an or of:
* 1) L & C & ~R
* 2) ~L & C & R
* 3) L & ~C & ~R
* 4) ~L & ~C & R
*
* Doing some simple grouping we learn that the center value plays no role:
* (L & C & ~R) | (L & ~C & ~R) -> L & (C | ~C) & ~R -> L & ~R
* (~L & C & R) | (~L & ~C & R) -> ~L & (C | ~C) & R -> ~L & R
*
* Further simplifies to an exclusive or, i.e. not equal (one true one false)
* (L & ~R) | (~L & R) -> L ^ R
* This makes the condition for SAFE the opposite, i.e. L == R
*/
left == right
}