-
Notifications
You must be signed in to change notification settings - Fork 0
/
lib.rs
92 lines (81 loc) · 2.17 KB
/
lib.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
88
89
90
91
92
use std::fs;
use std::collections::HashMap;
pub fn part1(input_file: &str) -> u32 {
let input = parse_input(input_file);
get_num_winning_total(&input).iter()
.map(|x|
if *x > 0 {u32::pow(2, x-1)} else {0}
)
.sum()
}
pub fn part2(input_file: &str) -> u32 {
let mut sum = 0;
let input = parse_input(input_file);
let totals = get_num_winning_total(&input);
let mut cards: HashMap<usize,u32> = HashMap::new();
for x in 0..totals.len() {
cards.entry(x).or_insert(1);
let curr = cards[&x];
for y in 1..=totals[x] {
cards.entry(x+y as usize).and_modify(|z| *z += curr).or_insert(1+curr);
}
sum += curr;
}
sum
}
fn get_num_winning_total(input: &[String]) -> Vec<u32> {
let mut out: Vec<u32> = vec![];
for line in input.iter() {
let line = line.split(":").last().unwrap();
let mut line = line.split("|");
let history = build_hashmap(
line.next()
.unwrap()
);
out.push(get_num_winning_card(history, line.next().unwrap()));
}
out
}
fn get_num_winning_card(history: HashMap<u32,bool>, input: &str) -> u32 {
let mut total = 0;
for num in input.split_whitespace() {
if history.contains_key(&num.parse::<u32>().unwrap()) {
total += 1;
}
}
total
}
fn build_hashmap(input: &str) -> HashMap<u32, bool> {
let mut history: HashMap<u32,bool> = HashMap::new();
let input = input.trim()
.split_whitespace();
for entry in input {
history.insert(
entry.trim()
.parse::<u32>()
.unwrap(),
true
);
}
history
}
fn parse_input(input_file: &str) -> Vec<String> {
let input = fs::read_to_string(input_file)
.expect("Something went wrong reading the file");
input.trim_end()
.split("\n")
.map(str::to_string)
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test1() {
assert_eq!(part1("data/test.txt"), 13);
}
#[test]
fn test2() {
assert_eq!(part2("data/test.txt"), 30);
}
}