-
Notifications
You must be signed in to change notification settings - Fork 0
/
day14.rs
105 lines (96 loc) · 2.86 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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// vi: set shiftwidth=4 tabstop=4 expandtab:
use common::input::check_answer;
use common::input::get_answers;
use common::input::get_first_line_from_file;
use std::time::Instant;
const INPUT_FILEPATH: &str = "../resources/year2018_day14_input.txt";
const ANSWERS_FILEPATH: &str = "../resources/year2018_day14_answer.txt";
type Int = usize;
fn slice_to_int(vec: &[Int]) -> Int {
let mut res = 0;
for n in vec {
res = 10 * res + n;
}
res
}
fn part1(nb_recipe: &str) -> Int {
let nb_recipe = nb_recipe.parse().unwrap();
let mut scores = Vec::from([3, 7]);
let mut e1 = 0;
let mut e2 = 1;
let nb_recipe_required = nb_recipe + 10;
while scores.len() < nb_recipe_required {
let old_s1 = scores[e1];
let old_s2 = scores[e2];
let s = old_s1 + old_s2;
let s1 = s / 10;
let s2 = s % 10;
if s1 > 0 {
scores.push(s1);
}
scores.push(s2);
let l = scores.len();
e1 = (e1 + old_s1 + 1) % l;
e2 = (e2 + old_s2 + 1) % l;
}
slice_to_int(&scores[nb_recipe..nb_recipe + 10])
}
fn part2(expected_score: &str) -> Int {
let mut scores = Vec::from([3, 7]);
let mut e1 = 0;
let mut e2 = 1;
let expected_vec: Vec<Int> = expected_score
.chars()
.map(|c| c.to_digit(10).unwrap() as usize)
.collect();
let expected_len = expected_vec.len();
loop {
let old_s1 = scores[e1];
let old_s2 = scores[e2];
let s = old_s1 + old_s2;
let s1 = s / 10;
let s2 = s % 10;
if s1 > 0 {
scores.push(s1);
if scores.len() >= expected_len && scores[scores.len() - expected_len..] == expected_vec
{
return scores.len() - expected_len;
}
}
scores.push(s2);
if scores.len() >= expected_len && scores[scores.len() - expected_len..] == expected_vec {
return scores.len() - expected_len;
}
let l = scores.len();
e1 = (e1 + old_s1 + 1) % l;
e2 = (e2 + old_s2 + 1) % l;
}
}
fn main() {
let before = Instant::now();
let data = &get_first_line_from_file(INPUT_FILEPATH);
let (ans, ans2) = get_answers(ANSWERS_FILEPATH);
let solved = true;
let res = part1(data);
check_answer(&res.to_string(), ans, solved);
let res2 = part2(data);
check_answer(&res2.to_string(), ans2, solved);
println!("Elapsed time: {:.2?}", before.elapsed());
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() {
assert_eq!(part1("5"), 124_515_891);
assert_eq!(part1("18"), 9_251_071_085);
assert_eq!(part1("2018"), 5_941_429_882);
}
#[test]
fn test_part2() {
assert_eq!(part2("51589"), 9);
assert_eq!(part2("01245"), 5);
assert_eq!(part2("92510"), 18);
assert_eq!(part2("59414"), 2018);
}
}