-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathd06.rs
More file actions
133 lines (112 loc) Β· 3.9 KB
/
d06.rs
File metadata and controls
133 lines (112 loc) Β· 3.9 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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use crate::Day;
pub struct Day06 {}
impl Day for Day06 {
fn year(&self) -> u16 {
2025
}
fn day(&self) -> u8 {
6
}
fn part_one(&self) -> String {
let input = self.read_default_input();
let lines = input.lines().rev().collect::<Vec<&str>>();
let operations = lines[0]
.split_whitespace()
.map(|char_str| {
char_str
.chars()
.next()
.expect("each operation should be a single character")
})
.map(|operation_char| match operation_char {
'*' => Operation::Mult,
'+' => Operation::Add,
_ => panic!("invalid operation character"),
})
.collect::<Vec<Operation>>();
let mut total = vec![0; operations.len()];
for (i, operation) in operations.iter().enumerate() {
match operation {
Operation::Add => total[i] = 0,
Operation::Mult => total[i] = 1,
}
}
for line in &lines[1..] {
let numbers = line
.split_whitespace()
.map(|num_str| {
num_str
.parse::<i64>()
.expect("each item on a line should be a valid i64")
})
.collect::<Vec<i64>>();
assert!(numbers.len() == total.len());
for i in 0..total.len() {
match operations[i] {
Operation::Add => total[i] += numbers[i],
Operation::Mult => total[i] *= numbers[i],
}
}
}
total.iter().sum::<i64>().to_string()
}
fn part_two(&self) -> String {
let input = self.read_default_input();
let lines = input.lines().collect::<Vec<&str>>();
let mut data: Vec<Vec<char>> = vec![vec![]; lines[0].len()];
for line in &lines {
for (i, character) in line.chars().enumerate() {
data[i].push(character);
}
}
let mut total = 0;
let mut curr_problem_total = 0;
let mut curr_operation = None;
for scan in data {
// If the last char in the vertical scan is * or +, a new problem is starting.
match scan.last().expect("scan should not be empty") {
'*' => {
curr_operation = Some(Operation::Mult);
curr_problem_total = 1;
}
'+' => {
curr_operation = Some(Operation::Add);
curr_problem_total = 0;
}
_ => (),
}
let mut digits = scan
.iter()
.filter(|c| **c != ' ' && **c != '*' && **c != '+')
.map(|c| {
c.to_digit(10)
.expect("unfiltered characters should be a valid digit")
as i64
})
.rev()
.peekable();
// The only vertical scan without any digits is the one before the start of a new
// problem, so add the total of the current problem to the aggregate total and
// move to the next vertical scan.
if digits.peek().is_none() {
total += curr_problem_total;
continue;
}
let mut number = 0i64;
for (i, digit) in digits.enumerate() {
number += digit * (10i64.pow(i as u32));
}
match curr_operation.clone().unwrap() {
Operation::Add => curr_problem_total += number,
Operation::Mult => curr_problem_total *= number,
}
}
total += curr_problem_total;
total.to_string()
}
}
#[derive(Debug, Clone)]
enum Operation {
Add,
Mult,
}