Finished Day 3-2
This commit is contained in:
		
							parent
							
								
									d5e580ad83
								
							
						
					
					
						commit
						891852d716
					
				
							
								
								
									
										18
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										18
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -5,3 +5,21 @@ version = 3
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "advent_2023"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "itertools",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "either"
 | 
			
		||||
version = "1.9.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "itertools"
 | 
			
		||||
version = "0.7.11"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "either",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@ -6,3 +6,4 @@ edition = "2021"
 | 
			
		||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
itertools = "0.7.4"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										115
									
								
								src/three/mod.rs
									
									
									
									
									
								
							
							
						
						
									
										115
									
								
								src/three/mod.rs
									
									
									
									
									
								
							@ -1,14 +1,54 @@
 | 
			
		||||
use std::{str::FromStr, path::Path, option::Option};
 | 
			
		||||
 | 
			
		||||
use itertools::Itertools;
 | 
			
		||||
 | 
			
		||||
use crate::input::{AdventError, read_into_vec};
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 | 
			
		||||
pub struct Number {
 | 
			
		||||
    value: u32,
 | 
			
		||||
    position: u8,
 | 
			
		||||
    length: u8
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub struct Symbol {
 | 
			
		||||
    position: u8,
 | 
			
		||||
    symbol: char,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl From<u8> for Symbol {
 | 
			
		||||
    fn from(value: u8) -> Self {
 | 
			
		||||
        Symbol{position: value, symbol: ' '}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl PartialEq for Symbol {
 | 
			
		||||
    fn eq(&self, other: &Self) -> bool {
 | 
			
		||||
        self.position == other.position
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl PartialOrd for Symbol {
 | 
			
		||||
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
 | 
			
		||||
        match self.position.partial_cmp(&other.position) {
 | 
			
		||||
            Some(core::cmp::Ordering::Equal) => {}
 | 
			
		||||
            ord => return ord,
 | 
			
		||||
        }
 | 
			
		||||
        self.symbol.partial_cmp(&other.symbol)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Eq for Symbol {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Ord for Symbol {
 | 
			
		||||
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
 | 
			
		||||
        self.position.cmp(&other.position)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl FromStr for RowInfo {
 | 
			
		||||
    type Err = AdventError;
 | 
			
		||||
 | 
			
		||||
@ -25,7 +65,7 @@ impl FromStr for RowInfo {
 | 
			
		||||
struct RowInfo {
 | 
			
		||||
    partial_start: Option<u8>,
 | 
			
		||||
    partial_number: Option<String>,
 | 
			
		||||
    pub symbol_positions: Vec<u8>,
 | 
			
		||||
    pub symbols: Vec<Symbol>,
 | 
			
		||||
    pub numbers: Vec<Number>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -34,13 +74,13 @@ impl RowInfo {
 | 
			
		||||
        Self {
 | 
			
		||||
            partial_start: None,
 | 
			
		||||
            partial_number: None,
 | 
			
		||||
            symbol_positions: Vec::<u8>::new(),
 | 
			
		||||
            symbols: Vec::<Symbol>::new(),
 | 
			
		||||
            numbers: Vec::<Number>::new()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn add_symbol(&mut self, i: usize) -> Result<(), AdventError> {
 | 
			
		||||
        self.symbol_positions.push(i as u8);
 | 
			
		||||
    fn add_symbol(&mut self, b: u8, i: usize) -> Result<(), AdventError> {
 | 
			
		||||
        self.symbols.push(Symbol {position: i as u8, symbol: b as char});
 | 
			
		||||
        if self.partial_start != None {
 | 
			
		||||
            self.finish_digit(i)?
 | 
			
		||||
        }
 | 
			
		||||
@ -61,7 +101,7 @@ impl RowInfo {
 | 
			
		||||
 | 
			
		||||
    fn process(&mut self, i: usize, b: &u8) -> Result<(), AdventError> {
 | 
			
		||||
        if b != &b'.' && !b.is_ascii_digit() {
 | 
			
		||||
            self.add_symbol(i)?
 | 
			
		||||
            self.add_symbol(*b, i)?
 | 
			
		||||
        }
 | 
			
		||||
        else if b.is_ascii_digit() {
 | 
			
		||||
            if self.partial_start.is_none() {
 | 
			
		||||
@ -92,7 +132,7 @@ impl Default for RowInfo {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn gen_coords(y: usize, number: &Number) -> Vec<(u8, u8)> {
 | 
			
		||||
pub fn gen_coords_number(y: usize, number: &Number) -> Vec<(u8, u8)> {
 | 
			
		||||
    let mut vec = Vec::<(u8, u8)>::new();
 | 
			
		||||
    let min_x = if number.position == 0 {
 | 
			
		||||
        0
 | 
			
		||||
@ -112,17 +152,44 @@ pub fn gen_coords(y: usize, number: &Number) -> Vec<(u8, u8)> {
 | 
			
		||||
    vec
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn gen_coords_symbol(y: usize, symbol: &Symbol) -> Vec<(u8,u8)> {
 | 
			
		||||
    let mut vec = Vec::<(u8, u8)>::new();
 | 
			
		||||
    let min_x = if symbol.position == 0 {
 | 
			
		||||
        0
 | 
			
		||||
    } else {
 | 
			
		||||
        symbol.position - 1
 | 
			
		||||
    };
 | 
			
		||||
    let max_x = symbol.position + 1 + 1;
 | 
			
		||||
    for x in min_x..max_x {
 | 
			
		||||
        if y != 0 {
 | 
			
		||||
            vec.push((x, y as u8 - 1));
 | 
			
		||||
        }
 | 
			
		||||
        if x < symbol.position || x > symbol.position {
 | 
			
		||||
            vec.push((x, y as u8));
 | 
			
		||||
        }
 | 
			
		||||
        vec.push((x, y as u8 + 1));
 | 
			
		||||
    }
 | 
			
		||||
    vec
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn filter_gears(rows: &mut Vec<RowInfo>) -> &mut Vec<RowInfo> {
 | 
			
		||||
    for row in rows.iter_mut() {
 | 
			
		||||
        row.symbols = row.symbols.clone().into_iter().filter(|x| { x.symbol == '*' }).collect::<Vec<Symbol>>()
 | 
			
		||||
    }
 | 
			
		||||
    rows
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn one() -> Result<(), AdventError> {
 | 
			
		||||
    let rows = read_into_vec::<RowInfo>(Path::new("resources/input3.txt"))?;
 | 
			
		||||
    let mut sum: u32 = 0;
 | 
			
		||||
    for (i, row) in rows.iter().enumerate() {
 | 
			
		||||
        for number in row.numbers.iter() {
 | 
			
		||||
            let coords = gen_coords(i, number);
 | 
			
		||||
            let coords = gen_coords_number(i, number);
 | 
			
		||||
            if coords.iter().any(|c| -> bool {
 | 
			
		||||
                if c.1 as usize >= rows.len() {
 | 
			
		||||
                    false
 | 
			
		||||
                } else {
 | 
			
		||||
                    rows[c.1 as usize].symbol_positions.binary_search(&c.0).is_ok()
 | 
			
		||||
                    rows[c.1 as usize].symbols.binary_search(&c.0.into()).is_ok()
 | 
			
		||||
                }
 | 
			
		||||
            }) {
 | 
			
		||||
                sum += number.value;
 | 
			
		||||
@ -134,5 +201,35 @@ pub fn one() -> Result<(), AdventError> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn two() -> Result<(), AdventError> {
 | 
			
		||||
    let mut rows = read_into_vec::<RowInfo>(Path::new("resources/input3.txt"))?;
 | 
			
		||||
    rows = filter_gears(&mut rows).clone();
 | 
			
		||||
    let mut sum: u32 = 0;
 | 
			
		||||
    for (i, row) in rows.iter().enumerate() {
 | 
			
		||||
        for symbol in row.symbols.iter() {
 | 
			
		||||
            let coords = gen_coords_symbol(i, symbol);
 | 
			
		||||
            let numbers = coords.iter().map(|(x, y)| {
 | 
			
		||||
                if *y as usize >= rows.len() {
 | 
			
		||||
                    None
 | 
			
		||||
                } else {
 | 
			
		||||
                    let relevant_numbers = rows[*y as usize].numbers.clone().into_iter().filter(|number| {*x >= number.position && *x < number.position + number.length}).collect::<Vec<Number>>();
 | 
			
		||||
                    if relevant_numbers.len() == 1 {
 | 
			
		||||
                        Some(relevant_numbers[0].clone())
 | 
			
		||||
                    } else {
 | 
			
		||||
                        None
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .filter(|x| {x.is_some()})
 | 
			
		||||
            .map(|x| {x.unwrap()})
 | 
			
		||||
            .unique()
 | 
			
		||||
            .collect::<Vec<Number>>();
 | 
			
		||||
 | 
			
		||||
            if numbers.len() == 2 {
 | 
			
		||||
                sum += numbers[0].value * numbers[1].value;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    println!("{}", sum);
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user