diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..65fb382 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,161 @@ +use std::{vec, fs}; + +#[derive(Copy, Clone, Debug)] +struct Coord(u32, u32, u32); + +fn main() { + let mut numbers: Vec<u32> = vec![]; + let mut array: Vec<Vec<char>> = vec![]; + + let f = fs::read_to_string("input").unwrap(); + + // Convert file to array + for line in f.lines() { + let xline: Vec<char> = line.chars().collect(); + array.push(xline); + } + // No longer mutable + let array = array; + + // Make an array the same size for the purpose of number coord tracking and matching + // initialize it with -1 for nothing there + let mut numarray: Vec<Vec<i32>> = vec![vec![-1; array[0].len()]; array.len()]; + + + + // Find Numbers + let mut num = false; + let mut numcoords = Coord(0, 0, 0); + + let mut yidx = 0; + for y in array.clone() { + let mut xidx = 0; + + for x in y { + match x.to_string().parse::<u32>() { + Ok(_) => { + // if num is not set, start recording the number + if !num { + numcoords = Coord(yidx, xidx, 0); + num = true; + } + }, + Err(_) => { + // if we were making a number + if num { + num = false; + // handle number being at the end of the line + // and xidx wraps back to 0 + if xidx == 0 { + numcoords = Coord(numcoords.0, numcoords.1, (array[0].len() -1) as u32); + } else { + numcoords = Coord(numcoords.0, numcoords.1, xidx - 1); + } + numbers.push(range_to_number(numcoords, &array)); + + // Set numarray coords to the numidx + let numidx = numbers.len() - 1; + + for i in numcoords.1..=numcoords.2 { + numarray[numcoords.0 as usize][i as usize] = numidx as i32; + } + } + }, + } + + xidx += 1; + } + + yidx += 1; + } + + + // Search for all symbols that are not numbers or '.' and search around them in numarray for anything not -1 + const AROUND: [(i8, i8); 8] = [ + (0, 1), + (1, 1), + (1, 0), + (-1, 0), + (-1, -1), + (0, -1), + (1, -1), + (-1, 1), + ]; + let mut outvec = vec![]; + + let mut yidx = 0; + for y in array { + let mut xidx = 0; + for c in y { + let ctest = match c.to_string().parse::<u32>() { + Ok(_) => true, + Err(_) => false, + }; + + // if ctest is a number or '.', then continue + if ctest || c == '.' { + xidx += 1; + continue + } + + // Character is a symbol + for pos in AROUND { + let i = match numarray.get(u32_calc(yidx, pos.0)) { + Some(n) => { + match n.get(u32_calc(xidx, pos.1)) { + Some(n) => n, + None => &-1, + } + }, + None => continue + }; + + if i > &-1 { + outvec.push(*i) + } + + } + + xidx += 1; + } + + yidx += 1; + } + + // Get only a single of each number and add them all up + outvec.sort(); + outvec.dedup_by_key(|i| {*i}); + let outvec: Vec<u32> = outvec.iter().map(|i| { + match numbers.get(*i as usize) { + Some(n) => *n, + None => 0, + } + }).collect(); + + // Add It Up + let mut final_num = 0; + for x in outvec { + final_num += x; + } + + println!("{}", final_num); +} + +fn u32_calc(x: u32, y: i8) -> usize { + // nothing should matter if x is greater than 0 + if x < 1 && y == -1 { + 0 + } else { + (x as i64 + y as i64) as usize + } +} + +fn range_to_number(coords: Coord, array: &Vec<Vec<char>>) -> u32 { + let mut outstring = "".to_string(); + + for i in coords.1..=coords.2 { + outstring.push(*array.get(coords.0 as usize).unwrap().get(i as usize).unwrap()) + } + + outstring.parse().unwrap() +}
\ No newline at end of file |