Skip to content

Commit

Permalink
day 4
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesPatrickGill committed Dec 4, 2024
1 parent 1e75b2f commit 256c62d
Show file tree
Hide file tree
Showing 3 changed files with 250 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
| [Day 1](./src/bin/01.rs) | `40.7µs` | `58.2µs` |
| [Day 2](./src/bin/02.rs) | `117.1µs` | `205.3µs` |
| [Day 3](./src/bin/03.rs) | `115.1µs` | `148.7µs` |
| [Day 4](./src/bin/04.rs) | `81.9µs` | `51.3µs` |

**Total: 0.69ms**
**Total: 0.82ms**
<!--- benchmarking table --->
10 changes: 10 additions & 0 deletions data/examples/04.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
MMMSXXMASM
MSAMXMSMSA
AMXSXMAAMM
MSAMASMSMX
XMASAMXAMM
XXAMMXXAMA
SMSMSASXSS
SAXAMASAAA
MAMMMXMMMM
MXMXAXMASX
238 changes: 238 additions & 0 deletions src/bin/04.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
use itertools::Itertools;

advent_of_code::solution!(4);

const XMAS: [char; 4] = ['X', 'M', 'A', 'S'];
const MAS: [char; 3] = ['M', 'A', 'S'];
const SAM: [char; 3] = ['S', 'A', 'M'];

pub fn part_one(input: &str) -> Option<u32> {
let matrix = input
.lines()
.map(|line| line.chars().collect_vec())
.collect_vec();

let y_range = matrix.len();
let x_range = matrix[0].len();

let mut found = 0;
for y in 0..y_range {
for x in 0..x_range {
if check_north(&matrix, x, y) {
found += 1;
};

if check_northeast(&matrix, x, y) {
found += 1;
};

if check_east(&matrix, x, y) {
found += 1;
};

if check_southeast(&matrix, x, y) {
found += 1;
};

if check_south(&matrix, x, y) {
found += 1;
};

if check_southwest(&matrix, x, y) {
found += 1;
};

if check_west(&matrix, x, y) {
found += 1;
};

if check_northwest(&matrix, x, y) {
found += 1;
};
}
}
Some(found)
}

pub fn part_two(input: &str) -> Option<u32> {
let matrix = input
.lines()
.map(|line| line.chars().collect_vec())
.collect_vec();

let y_range = matrix.len();
let x_range = matrix[0].len();

let mut found = 0;
for y in 0..y_range {
for x in 0..x_range {
if check_x_mas(&matrix, x, y) {
found += 1;
};
}
}
Some(found)
}

fn check_north(matrix: &[Vec<char>], x: usize, y: usize) -> bool {
if y < 3 {
return false;
}
for (idx, test_char) in XMAS.iter().enumerate() {
if let Some(to_test_col) = matrix.get(y - idx) {
if &to_test_col[x] != test_char {
return false;
}
} else {
return false;
}
}
true
}

fn check_northeast(matrix: &[Vec<char>], x: usize, y: usize) -> bool {
if y < 3 {
return false;
}
for (idx, test_char) in XMAS.iter().enumerate() {
if let Some(to_test_col) = matrix.get(y - idx) {
if let Some(to_test) = to_test_col.get(x + idx) {
if to_test != test_char {
return false;
}
} else {
return false;
}
} else {
return false;
}
}
true
}

fn check_east(matrix: &[Vec<char>], x: usize, y: usize) -> bool {
for (idx, test_char) in XMAS.iter().enumerate() {
if let Some(to_test) = matrix[y].get(x + idx) {
if to_test != test_char {
return false;
}
} else {
return false;
}
}
true
}

fn check_southeast(matrix: &[Vec<char>], x: usize, y: usize) -> bool {
for (idx, test_char) in XMAS.iter().enumerate() {
if let Some(to_test_col) = matrix.get(y + idx) {
if let Some(to_test) = to_test_col.get(x + idx) {
if to_test != test_char {
return false;
}
} else {
return false;
}
} else {
return false;
}
}
true
}

fn check_south(matrix: &[Vec<char>], x: usize, y: usize) -> bool {
for (idx, test_char) in XMAS.iter().enumerate() {
if let Some(to_test_col) = matrix.get(y + idx) {
if &to_test_col[x] != test_char {
return false;
}
} else {
return false;
}
}
true
}

fn check_southwest(matrix: &[Vec<char>], x: usize, y: usize) -> bool {
if x < 3 {
return false;
}
for (idx, test_char) in XMAS.iter().enumerate() {
if let Some(to_test_col) = matrix.get(y + idx) {
if let Some(to_test) = to_test_col.get(x - idx) {
if to_test != test_char {
return false;
}
} else {
return false;
}
} else {
return false;
}
}
true
}

fn check_west(matrix: &[Vec<char>], x: usize, y: usize) -> bool {
if x < 3 {
return false;
}
for (idx, test_char) in XMAS.iter().enumerate() {
if let Some(to_test) = matrix[y].get(x - idx) {
if to_test != test_char {
return false;
}
} else {
return false;
}
}
true
}

fn check_northwest(matrix: &[Vec<char>], x: usize, y: usize) -> bool {
if x < 3 || y < 3 {
return false;
}
for (idx, test_char) in XMAS.iter().enumerate() {
if let Some(to_test_col) = matrix.get(y - idx) {
if let Some(to_test) = to_test_col.get(x - idx) {
if to_test != test_char {
return false;
}
} else {
return false;
}
} else {
return false;
}
}
true
}

fn check_x_mas(matrix: &[Vec<char>], x: usize, y: usize) -> bool {
if x < 1 || y < 1 || y > matrix.len() - 2 || x > matrix[0].len() - 2 {
return false;
}

let word1 = [matrix[y - 1][x - 1], matrix[y][x], matrix[y + 1][x + 1]];
let word2 = [matrix[y + 1][x - 1], matrix[y][x], matrix[y - 1][x + 1]];

(word1 == SAM || word1 == MAS) && (word2 == MAS || word2 == SAM)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_part_one() {
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, None);
}

#[test]
fn test_part_two() {
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, None);
}
}

0 comments on commit 256c62d

Please sign in to comment.