use std::{
fs::File,
io::{BufRead, BufReader},
path::Path,
};
pub fn solve(input: &Path) -> anyhow::Result<()> {
println!("part one: {}", part_one(input)?);
println!("part two: {}", part_two(input)?);
Ok(())
}
fn part_one(input: &Path) -> anyhow::Result<i32> {
let reader = BufReader::new(File::open(input)?);
let mut input: Vec<Vec<char>> = vec![];
for line in reader.lines() {
input.push(line?.chars().collect());
}
let xmas = "XMAS".as_bytes();
let samx = "SAMX".as_bytes();
let mut answer: i32 = 0;
for line in &input {
answer += String::from_iter(line)
.as_bytes()
.windows(4)
.filter(|&w| w == xmas || w == samx)
.count() as i32;
}
for y in 0..input[0].len() {
let mut col = vec![];
for c in &input {
col.push(c[y]);
}
answer += String::from_iter(col)
.as_bytes()
.windows(4)
.filter(|&w| w == xmas || w == samx)
.count() as i32;
}
let len = input.len();
for i in 0..len * 2 {
let mut diag = vec![];
for y in 0..i + 1 {
let x = i - y;
if x < len && y < len {
//print!("{} ", input[x][y]);
diag.push(input[x][y]);
}
}
answer += String::from_iter(diag)
.as_bytes()
.windows(4)
.filter(|&w| w == xmas || w == samx)
.count() as i32;
//println!();
}
let len = input.len();
input.reverse();
for i in 0..len * 2 {
let mut diag = vec![];
for y in 0..i + 1 {
let x = i - y;
if x < len && y < len {
//print!("{} ", input[x][y]);
diag.push(input[x][y]);
}
}
answer += String::from_iter(diag)
.as_bytes()
.windows(4)
.filter(|&w| w == xmas || w == samx)
.count() as i32;
//println!();
}
Ok(answer)
}
fn part_two(input: &Path) -> anyhow::Result<i32> {
let reader = BufReader::new(File::open(input)?);
let mut input: Vec<Vec<char>> = vec![];
for line in reader.lines() {
input.push(line?.chars().collect());
}
let mut fucking_windows = vec![];
let row_windows = input.windows(3).collect::<Vec<_>>();
for row_window in row_windows {
let col_windows_one = row_window[0].windows(3).collect::<Vec<_>>();
let col_windows_two = row_window[1].windows(3).collect::<Vec<_>>();
let col_windows_three = row_window[2].windows(3).collect::<Vec<_>>();
for i in 0..col_windows_one.len() {
let window = vec![col_windows_one[i], col_windows_two[i], col_windows_three[i]];
fucking_windows.push(window);
}
}
let mas = "MAS".as_bytes();
let sam = "SAM".as_bytes();
let mut answer: i32 = 0;
for mut window in fucking_windows {
let mut found_diag = false;
let mut found_diag_rev = false;
let len = window.len();
for i in 0..len * 2 {
let mut diag = vec![];
for y in 0..i + 1 {
let x = i - y;
if x < len && y < len {
diag.push(window[x][y]);
}
}
if String::from_iter(diag)
.as_bytes()
.windows(3)
.filter(|&w| w == mas || w == sam)
.count()
> 0
{
found_diag = true;
}
}
let len = window.len();
window.reverse();
for i in 0..len * 2 {
let mut diag = vec![];
for y in 0..i + 1 {
let x = i - y;
if x < len && y < len {
diag.push(window[x][y]);
}
}
if String::from_iter(diag)
.as_bytes()
.windows(3)
.filter(|&w| w == mas || w == sam)
.count()
> 0
{
found_diag_rev = true;
}
}
if found_diag && found_diag_rev {
answer += 1;
}
}
Ok(answer)
}