summaryrefslogtreecommitdiffstats
path: root/day4/src/main.rs
diff options
context:
space:
mode:
authorGravatar Tom van der Lee <tom@vanderlee.io>2024-12-05 08:44:26 +0100
committerGravatar Tom van der Lee <tom@vanderlee.io>2024-12-05 08:44:37 +0100
commit066c02d04ea46a387f7c08b3f5b7eec8fa8d783c (patch)
treea73894cb36ee8f43380266bcc61362736f4d2ef7 /day4/src/main.rs
parent120fe4c9e696ec3289736843f54657fdf2b8247d (diff)
download2024-main.tar.gz
2024-main.tar.bz2
2024-main.zip
Day4main
Diffstat (limited to 'day4/src/main.rs')
-rw-r--r--day4/src/main.rs215
1 files changed, 215 insertions, 0 deletions
diff --git a/day4/src/main.rs b/day4/src/main.rs
new file mode 100644
index 0000000..c788292
--- /dev/null
+++ b/day4/src/main.rs
@@ -0,0 +1,215 @@
1use aoc;
2use std::io::{BufRead, BufReader, Read};
3use aoc::Day;
4use regex::Regex;
5
6struct Day4 {}
7
8enum Direction {
9 Horizontal,
10 Vertical,
11 DiagonalDown,
12 DiagonalUp,
13}
14
15impl Day4 {
16 fn parse_input(&self, input: BufReader<Box<dyn Read>>) -> Vec<String> {
17 input
18 .lines()
19 .map(|l| {
20 l
21 .unwrap()
22 .trim()
23 .to_string()
24 })
25 .collect::<Vec<String>>()
26 }
27
28 fn _diagonal_half_loop(&self, input: &Vec<String>) -> Vec<String> {
29 let mut out: Vec<String> = vec![];
30 for y in 0..input.len() {
31 let mut out_row = String::new();
32
33 for (x, row) in input[0..y + 1].iter().rev().enumerate() {
34 out_row.push(row.chars().nth(x).unwrap());
35 }
36
37 out.push(out_row)
38 }
39
40 out
41 }
42
43 fn _rotate(&self, input: &Vec<String>) -> Vec<String> {
44 let mut output: Vec<String> = vec![];
45
46 for (i, _) in input[0].char_indices() {
47 let mut line_out = String::new();
48 for line in input {
49 let a = line.chars().nth(i).unwrap();
50 line_out.push(a)
51 }
52
53 output.push(line_out.chars().rev().collect::<String>());
54 }
55
56 output
57 }
58
59 fn _mirror(&self, input: &Vec<String>) -> Vec<String> {
60 input
61 .iter()
62 .map(|l| {
63 l
64 .chars()
65 .rev()
66 .collect::<String>()
67 })
68 .collect::<Vec<String>>()
69 }
70
71 fn diagonal_loop(&self, input: &Vec<String>) -> Vec<String> {
72 let mut first_half: Vec<String> = self._diagonal_half_loop(input);
73
74 let rev_input = input
75 .iter()
76 .rev()
77 .map(|row| {
78 row
79 .chars()
80 .rev()
81 .collect::<String>()
82 })
83 .collect::<Vec<String>>();
84
85
86 let mut second_half = self
87 ._diagonal_half_loop(&rev_input)
88 .iter()
89 .rev()
90 .collect::<Vec<_>>()[1..]
91 .iter()
92 .map(|row| {
93 row
94 .chars()
95 .rev()
96 .collect::<String>()
97 })
98 .collect::<Vec<String>>();
99
100
101 first_half.append(&mut second_half);
102 first_half
103 }
104
105 fn loop_over_puzzle(&self, input: &Vec<String>, direction: Direction, rev: bool) -> Vec<String> {
106 let _input = if rev {
107 self._rotate(&self._rotate(&input))
108 } else {
109 input.clone()
110 };
111
112
113 match direction {
114 Direction::Horizontal => _input,
115 Direction::Vertical => self._mirror(&self._rotate(&_input)),
116 Direction::DiagonalUp => self.diagonal_loop(&_input),
117 Direction::DiagonalDown => self.diagonal_loop(&self._rotate(&_input)),
118 }
119 }
120}
121
122impl Day for Day4 {
123 fn example_input(&self) -> &'static str {
124 r#"
125 MMMSXXMASM
126 MSAMXMSMSA
127 AMXSXMAAMM
128 MSAMASMSMX
129 XMASAMXAMM
130 XXAMMXXAMA
131 SMSMSASXSS
132 SAXAMASAAA
133 MAMMMXMMMM
134 MXMXAXMASX
135 "#.trim()
136 // r#"
137 // 123
138 // 456
139 // 789
140 // "#.trim()
141 }
142
143 fn example_result_part_1(&self) -> &'static str {
144 "18"
145 }
146
147 fn example_result_part_2(&self) -> &'static str {
148 "9"
149 }
150
151 fn part_1(&self, input: BufReader<Box<dyn Read>>) -> String {
152 let puzzle = self.parse_input(input);
153
154 let mut all_possibilities: Vec<String> = vec![];
155
156 all_possibilities.append(&mut self.loop_over_puzzle(&puzzle, Direction::Horizontal, false));
157 all_possibilities.append(&mut self.loop_over_puzzle(&puzzle, Direction::Horizontal, true));
158 all_possibilities.append(&mut self.loop_over_puzzle(&puzzle, Direction::Vertical, false));
159 all_possibilities.append(&mut self.loop_over_puzzle(&puzzle, Direction::Vertical, true));
160 all_possibilities.append(&mut self.loop_over_puzzle(&puzzle, Direction::DiagonalUp, false));
161 all_possibilities.append(&mut self.loop_over_puzzle(&puzzle, Direction::DiagonalUp, true));
162 all_possibilities.append(&mut self.loop_over_puzzle(&puzzle, Direction::DiagonalDown, false));
163 all_possibilities.append(&mut self.loop_over_puzzle(&puzzle, Direction::DiagonalDown, true));
164
165 let re = Regex::new("XMAS");
166 all_possibilities
167 .into_iter()
168 .map(|l| {
169 re
170 .clone()
171 .unwrap()
172 .find_iter(&l)
173 .count()
174 })
175 .sum::<usize>()
176 .to_string()
177 }
178
179 fn part_2(&self, input: BufReader<Box<dyn Read>>) -> String {
180 let puzzle = self.parse_input(input);
181
182 let mut all_possibilities: Vec<String> = vec![];
183
184 all_possibilities.append(&mut self.loop_over_puzzle(&puzzle, Direction::DiagonalUp, false));
185 all_possibilities.append(&mut self.loop_over_puzzle(&puzzle, Direction::DiagonalDown, false));
186
187 let re = Regex::new("MAS|SAM");
188 all_possibilities
189 .into_iter()
190 .map(|l| {
191 re
192 .clone()
193 .unwrap()
194 .find_iter(&l)
195 .map(|m| println!("{:#?}", m))
196 .count()
197 })
198 .sum::<usize>()
199 .to_string()
200 }
201}
202
203
204fn main() {
205 aoc::main(&Day4 {});
206}
207
208#[cfg(test)]
209mod tests {
210 use super::*;
211 #[test]
212 fn test_day4() {
213 aoc::test_day(&Day4 {});
214 }
215}