-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathday07.rs
More file actions
98 lines (86 loc) · 2.45 KB
/
day07.rs
File metadata and controls
98 lines (86 loc) · 2.45 KB
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
use aoc_runner_derive::{aoc, aoc_generator};
type Parsed = (Vec<u64>, u64);
#[aoc_generator(day7)]
fn parse_input(input: &str) -> Parsed {
let parsed: Vec<u64> = input.split(',').map(|s| s.parse().unwrap()).collect();
(parsed.to_owned(), *parsed.iter().max().unwrap())
}
#[aoc(day7, part1)]
fn part1(input: &Parsed) -> u64 {
let mut positions = input
.0
.iter()
.fold(vec![0; input.1 as usize + 1], |mut v, n| {
*v.get_mut(*n as usize).unwrap() += 1;
v
});
let mut base: u64 = 0;
let mut len = positions.len().to_owned();
while len > 1 {
let (left, right) = positions.split_at_mut(len / 2);
let sum_left = left.iter().sum::<u64>();
let sum_right = right.iter().sum::<u64>();
if sum_left > sum_right {
let left_last = left.get_mut(left.len() - 1).unwrap();
*left_last += sum_right;
positions.drain(len / 2..);
} else {
let right_first = right.get_mut(0).unwrap();
*right_first += sum_left;
positions.drain(..len / 2);
base += len as u64 / 2;
}
len = positions.len().to_owned();
}
input
.0
.iter()
.map(|n| match n.cmp(&base) {
std::cmp::Ordering::Less => base - *n,
std::cmp::Ordering::Greater => *n - base,
std::cmp::Ordering::Equal => 0,
})
.sum()
}
#[aoc(day7, part2)]
fn part2(input: &Parsed) -> u64 {
let max = input.1;
let costs: Vec<Vec<u64>> = input
.0
.iter()
.map(|in_pos| {
(0..=max)
.map(|i| {
if *in_pos > i {
(i..*in_pos).map(|p| *in_pos - p).sum()
} else {
(*in_pos..=i).map(|p| p - *in_pos).sum()
}
})
.collect::<Vec<u64>>()
})
.collect();
(0..=max)
.map(|p| {
costs
.iter()
.map(|c| *c.get(p as usize).unwrap())
.sum::<u64>()
})
.min()
.unwrap()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn sample1() {
let input = "16,1,2,0,4,2,7,1,2,14";
assert_eq!(part1(&parse_input(input)), 37);
}
#[test]
fn sample2() {
let input = "16,1,2,0,4,2,7,1,2,14";
assert_eq!(part2(&parse_input(input)), 168);
}
}