1
0

Compare commits

..

4 Commits

Author SHA1 Message Date
9ab3453b02 cleanup 2024-12-04 07:03:13 +01:00
1f638fc7c7 day 4 part 2 2024-12-04 06:51:35 +01:00
2b7f894030 day 4 part 1 2024-12-04 06:44:17 +01:00
0e9a64e991 Prepare day 4 and template. 2024-12-03 06:55:12 +01:00
4 changed files with 153 additions and 0 deletions

116
src/day04.rs Normal file
View File

@@ -0,0 +1,116 @@
use itertools::Itertools;
use std::collections::HashMap;
use std::fs::read_to_string;
pub fn day_main() {
let input = read_to_string("input/day04.txt").unwrap();
let input = input.trim();
println!(" part1: {}", part1(input));
println!(" part2: {}", part2(input));
}
type RiddleResult = usize;
fn part1(input: &str) -> RiddleResult {
let puzzle = parse_map(input);
let mut count = 0;
let x_max = puzzle.keys().map(|k| k.0).max().unwrap();
let y_max = puzzle.keys().map(|k| k.1).max().unwrap();
for sx in 0..=x_max {
for sy in 0..=y_max {
'foo: for (a, b) in [
(1, 1),
(-1, 1),
(1, -1),
(-1, -1),
(0, 1),
(1, 0),
(0, -1),
(-1, 0),
] {
for (i, c) in "XMAS".chars().enumerate() {
let i = i as i32;
let p = (sx as i32 + i * a, sy as i32 + i * b);
if p.0 < 0 || p.1 < 0 || p.0 > x_max as i32 || p.1 > y_max as i32 {
continue 'foo;
}
if puzzle[&(p.0 as usize, p.1 as usize)] != c {
continue 'foo;
}
}
count += 1;
}
}
}
count
}
fn part2(input: &str) -> RiddleResult {
let puzzle = parse_map(input);
let mut count = 0;
let x_max = puzzle.keys().map(|k| k.0).max().unwrap();
let y_max = puzzle.keys().map(|k| k.1).max().unwrap();
for sx in 1..x_max {
for sy in 1..y_max {
let first = [
puzzle[&(sx - 1, sy - 1)],
puzzle[&(sx, sy)],
puzzle[&(sx + 1, sy + 1)],
]
.into_iter()
.join("");
let second = [
puzzle[&(sx - 1, sy + 1)],
puzzle[&(sx, sy)],
puzzle[&(sx + 1, sy - 1)],
]
.into_iter()
.join("");
if (first == "MAS" || first == "SAM") && (second == "SAM" || second == "MAS") {
count += 1;
}
}
}
count
}
fn parse_map(input: &str) -> HashMap<(usize, usize), char> {
let mut puzzle = HashMap::<(usize, usize), char>::new();
input.lines().enumerate().for_each(|(y, line)| {
line.chars().enumerate().for_each(|(x, chr)| {
puzzle.insert((x, y), chr);
})
});
puzzle
}
#[cfg(test)]
mod test {
use super::{part1, part2};
const TEST_INPUT: &str = r"MMMSXXMASM
MSAMXMSMSA
AMXSXMAAMM
MSAMASMSMX
XMASAMXAMM
XXAMMXXAMA
SMSMSASXSS
SAXAMASAAA
MAMMMXMMMM
MXMXAXMASX
";
#[test]
fn test1() {
assert_eq!(part1(TEST_INPUT), 18);
}
#[test]
fn test2() {
assert_eq!(part2(TEST_INPUT), 9);
}
}

View File

@@ -1,3 +1,4 @@
pub mod day01; pub mod day01;
pub mod day02; pub mod day02;
pub mod day03; pub mod day03;
pub mod day04;

View File

@@ -8,6 +8,7 @@ fn main() {
(1, day01::day_main as fn()), (1, day01::day_main as fn()),
(2, day02::day_main), (2, day02::day_main),
(3, day03::day_main), (3, day03::day_main),
(4, day04::day_main),
]); ]);
let day: Option<u8> = args().nth(1).and_then(|a| a.parse().ok()); let day: Option<u8> = args().nth(1).and_then(|a| a.parse().ok());
let Some(day) = day else { let Some(day) = day else {

35
src/template.rs Normal file
View File

@@ -0,0 +1,35 @@
use std::fs::read_to_string;
pub fn day_main() {
let input = read_to_string("input/dayXX.txt").unwrap();
let input = input.trim();
println!(" part1: {}", part1(input));
println!(" part2: {}", part2(input));
}
type RiddleResult = i64;
fn part1(input: &str) -> RiddleResult {
0
}
fn part2(_input: &str) -> RiddleResult {
0
}
#[cfg(test)]
mod test {
use super::{part1, part2};
const TEST_INPUT: &str = r"";
#[test]
fn test1() {
assert_eq!(part1(TEST_INPUT), 0);
}
#[test]
fn test2() {
assert_eq!(part2(TEST_INPUT), 0);
}
}