-
Notifications
You must be signed in to change notification settings - Fork 0
/
day14.rs
87 lines (74 loc) · 1.89 KB
/
day14.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
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
use std::fs;
use std::collections::HashMap;
enum Instruction {
Mask(String),
Mem(i64, i64),
}
fn parse_instruction(s: &str) -> Instruction {
let xs: Vec<&str> = s.split(" = ").collect();
if xs[0] == "mask" {
Instruction::Mask(xs[1].to_owned())
} else {
let addr = xs[0][4..xs[0].len()-1].parse().unwrap();
let v = xs[1].parse().unwrap();
Instruction::Mem(addr, v)
}
}
fn part1(instructions: &Vec<Instruction>) -> i64 {
let mut mem = HashMap::new();
let mut mask = "";
for i in instructions {
match i {
Instruction::Mask(m) => { mask = m; },
Instruction::Mem(a, mut b) => {
for (i,c) in mask.chars().rev().enumerate() {
let v = 1 << i;
if c == '0' { b = b & (!v) }
if c == '1' { b = b | v }
}
mem.insert(*a, b);
},
}
}
mem.values().sum()
}
fn gen_addrs(ans: &mut Vec<i64>, addr: i64, acc: i64, mask: &Vec<char>, idx: usize) -> () {
if idx == mask.len() {
ans.push(acc);
return;
}
let new_accs = match mask[idx] {
'0' => vec![ acc * 2 + ((addr >> (35 - idx)) & 1) ],
'1' => vec![ acc * 2 + 1 ],
_ => vec![ acc * 2, acc * 2 + 1],
};
for new_acc in new_accs {
gen_addrs(ans, addr, new_acc, mask, idx+1);
}
}
fn part2(instructions: &Vec<Instruction>) -> i64 {
let mut mem = HashMap::new();
let mut mask = vec![];
for i in instructions {
match i {
Instruction::Mask(m) => { mask = m.chars().collect(); },
Instruction::Mem(a, b) => {
let mut addrs = vec![];
gen_addrs(&mut addrs, *a, 0, &mask, 0);
for addr in addrs {
mem.insert(addr, *b);
}
},
}
}
mem.values().sum()
}
fn main() {
let xs: Vec<_> =
fs::read_to_string("input/input14.txt")
.unwrap().lines()
.map(parse_instruction)
.collect();
println!("Part 1: {}", part1(&xs));
println!("Part 2: {}", part2(&xs));
}