[2023 Day 3 (Part 1)] [Rust] Passes edge cases/tests but not real input...
Yet another one of these posts. Didn't want to repeat it but yeah, I've gone through every edge case I can find (there was a thread with loads), and the small test input, all give the correct value. But not the full input.
The code is a complete mess (even for me this is bad) but this day has taken too much out of me to write something proper.
Code:
#[macro_use]
extern crate lazy_static;
use std::fs::File;
use std::io::{prelude::*, BufReader, self};
use std::collections::HashMap;
use regex::Regex;
#[derive(Debug, Clone)]
struct Board {
data: Vec<Vec<char>>,
height: usize,
width: usize,
}
lazy_static! {
static ref LOOKUP: HashMap<String, (i32, i32)> = {
let mut l = HashMap::new();
l.insert("up".to_string(), (1i32, 0i32));
l.insert("up_ri".to_string(), (1i32, 1i32));
l.insert("ri".to_string(), (0i32, 1i32));
l.insert("bo_ri".to_string(), (-1i32, 1i32));
l.insert("bo".to_string(), (-1i32, 0i32));
l.insert("bo_le".to_string(), (-1i32, -1i32));
l.insert("le".to_string(), (0i32, -1i32));
l.insert("up_le".to_string(), (1i32, -1i32));
l
};
}
fn parser(path: &str) -> Board {
let file = match File::open(path) {
Ok(value) => value,
Err(e) => panic!("Error: {}", e),
};
let reader = BufReader::new(file);
let mut lines: Vec<Vec<char>> = reader.lines()
.map(|line| line.expect("Line error")
.chars()
.collect())
.collect();
for l in &mut lines {
l.insert(0, '.');
l.push('.')
}
lines.insert(0, vec!['.'; lines[0].len()]);
lines.push(vec!['.'; lines[0].len()]);
let board = Board {
data: lines.clone(),
height: lines.len(),
width: lines[0].len()
};
board
}
fn part_1(board: Board) -> i32 {
let re = Regex::new(r"\d").unwrap();
let mut part_indexes = vec![];
(1..board.height).for_each(|y| {
(1..board.width).for_each(|x| {
if re.is_match(&board.data[y][x].to_string()) {
for (i, j) in LOOKUP.values() {
match (i.to_owned(), j.to_owned()) {
(-1, 0) => {
//if y > 0 {
if board.data[y-1][x] != '.' &&
!re.is_match(&board.data[y-1][x].to_string()) {
part_indexes.push((y, x))
}
//}
},
(-1, 1) => {
//if y > 0 && x < board.width - 1 {
if board.data[y-1][x+1] != '.' &&
!re.is_match(&board.data[y-1][x+1].to_string()) {
part_indexes.push((y, x))
}
//}
},
(0, 1) => {
//if x < board.width - 1 {
if board.data[y][x+1] != '.' &&
!re.is_match(&board.data[y][x+1].to_string()) {
part_indexes.push((y, x))
}
//}
},
(1, 1) => {
//if y < board.height - 1 && x < board.width - 1 {
if board.data[y+1][x+1] != '.' &&
!re.is_match(&board.data[y+1][x+1].to_string()) {
part_indexes.push((y, x))
}
//}
},
(1, 0) => {
//if y < board.height - 1 {
if board.data[y+1][x] != '.' &&
!re.is_match(&board.data[y+1][x].to_string()) {
part_indexes.push((y, x))
}
//}
},
(1, -1) => {
//if y < board.height - 1 && x > 0{
if board.data[y+1][x-1] != '.' &&
!re.is_match(&board.data[y+1][x-1].to_string()) {
part_indexes.push((y, x))
}
//}
},
(0, -1) => {
//if x > 0{
if board.data[y][x-1] != '.' &&
!re.is_match(&board.data[y][x-1].to_string()) {
part_indexes.push((y, x))
}
//}
},
(-1, -1) => {
//if y > 0 && x > 0{
if board.data[y-1][x-1] != '.' &&
!re.is_match(&board.data[y-1][x-1].to_string()) {
part_indexes.push((y, x))
}
//}
},
_ => println!("Not in LOOKUP {:?}", (i, j))
}
}
}
})
});
let mut trimmed_indexes = vec![];
(0..part_indexes.len()).for_each(|p| {
if p == 0 {
trimmed_indexes.push(part_indexes[0])
} else if part_indexes[p].1 - 1 != part_indexes[p-1].1 &&
part_indexes[p] != part_indexes[p-1] {
trimmed_indexes.push(part_indexes[p])
}
});
let mut values = vec![];
for val in trimmed_indexes {
let mut current = board.data[val.0][val.1].to_string();
if val.1 > 0 {
if re.is_match(&board.data[val.0][val.1-1].to_string()) {
current = board.data[val.0][val.1-1].to_string() + ¤t;
if val.1 > 1 {
if re.is_match(&board.data[val.0][val.1-2].to_string()) &&
!re.is_match(&board.data[val.0][val.1+1].to_string()) {
current = board.data[val.0][val.1-2].to_string() + ¤t
}
}
}
}
if val.1 < board.width - 1 {
if re.is_match(&board.data[val.0][val.1+1].to_string()) {
current = current + &board.data[val.0][val.1+1].to_string();
if val.1 < board.width - 2 {
if re.is_match(&board.data[val.0][val.1+2].to_string()) &&
!re.is_match(&board.data[val.0][val.1+1].to_string()) {
current = current + &board.data[val.0][val.1+2].to_string()
}
}
}
}
values.push(current)
}
let mut total = 0;
for v in values {
total += v.parse::<i32>().unwrap();
}
total
}
fn main() -> io::Result<()> {
let board = parser("./input");
println!("Part 1: {}", part_1(board));
Ok(())
}
Posted Dec 6, 2023, 8:44 PM UTC
35