[2023 Day 3 (Part 1)] [Rust] Passes edge cases/tests but not real input...

Help/Question

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() + &current;
                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() + &current
                    }
                }
            }
        }
        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
Loading comments…