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]]
|
[[package]]
|
||||||
name = "advent_2023"
|
name = "advent_2023"
|
||||||
version = "0.1.0"
|
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
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[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 std::{str::FromStr, path::Path, option::Option};
|
||||||
|
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
use crate::input::{AdventError, read_into_vec};
|
use crate::input::{AdventError, read_into_vec};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Number {
|
pub struct Number {
|
||||||
value: u32,
|
value: u32,
|
||||||
position: u8,
|
position: u8,
|
||||||
length: 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 {
|
impl FromStr for RowInfo {
|
||||||
type Err = AdventError;
|
type Err = AdventError;
|
||||||
|
|
||||||
@ -25,7 +65,7 @@ impl FromStr for RowInfo {
|
|||||||
struct RowInfo {
|
struct RowInfo {
|
||||||
partial_start: Option<u8>,
|
partial_start: Option<u8>,
|
||||||
partial_number: Option<String>,
|
partial_number: Option<String>,
|
||||||
pub symbol_positions: Vec<u8>,
|
pub symbols: Vec<Symbol>,
|
||||||
pub numbers: Vec<Number>,
|
pub numbers: Vec<Number>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,13 +74,13 @@ impl RowInfo {
|
|||||||
Self {
|
Self {
|
||||||
partial_start: None,
|
partial_start: None,
|
||||||
partial_number: None,
|
partial_number: None,
|
||||||
symbol_positions: Vec::<u8>::new(),
|
symbols: Vec::<Symbol>::new(),
|
||||||
numbers: Vec::<Number>::new()
|
numbers: Vec::<Number>::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_symbol(&mut self, i: usize) -> Result<(), AdventError> {
|
fn add_symbol(&mut self, b: u8, i: usize) -> Result<(), AdventError> {
|
||||||
self.symbol_positions.push(i as u8);
|
self.symbols.push(Symbol {position: i as u8, symbol: b as char});
|
||||||
if self.partial_start != None {
|
if self.partial_start != None {
|
||||||
self.finish_digit(i)?
|
self.finish_digit(i)?
|
||||||
}
|
}
|
||||||
@ -61,7 +101,7 @@ impl RowInfo {
|
|||||||
|
|
||||||
fn process(&mut self, i: usize, b: &u8) -> Result<(), AdventError> {
|
fn process(&mut self, i: usize, b: &u8) -> Result<(), AdventError> {
|
||||||
if b != &b'.' && !b.is_ascii_digit() {
|
if b != &b'.' && !b.is_ascii_digit() {
|
||||||
self.add_symbol(i)?
|
self.add_symbol(*b, i)?
|
||||||
}
|
}
|
||||||
else if b.is_ascii_digit() {
|
else if b.is_ascii_digit() {
|
||||||
if self.partial_start.is_none() {
|
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 mut vec = Vec::<(u8, u8)>::new();
|
||||||
let min_x = if number.position == 0 {
|
let min_x = if number.position == 0 {
|
||||||
0
|
0
|
||||||
@ -112,17 +152,44 @@ pub fn gen_coords(y: usize, number: &Number) -> Vec<(u8, u8)> {
|
|||||||
vec
|
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> {
|
pub fn one() -> Result<(), AdventError> {
|
||||||
let rows = read_into_vec::<RowInfo>(Path::new("resources/input3.txt"))?;
|
let rows = read_into_vec::<RowInfo>(Path::new("resources/input3.txt"))?;
|
||||||
let mut sum: u32 = 0;
|
let mut sum: u32 = 0;
|
||||||
for (i, row) in rows.iter().enumerate() {
|
for (i, row) in rows.iter().enumerate() {
|
||||||
for number in row.numbers.iter() {
|
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 coords.iter().any(|c| -> bool {
|
||||||
if c.1 as usize >= rows.len() {
|
if c.1 as usize >= rows.len() {
|
||||||
false
|
false
|
||||||
} else {
|
} 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;
|
sum += number.value;
|
||||||
@ -134,5 +201,35 @@ pub fn one() -> Result<(), AdventError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn two() -> 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(())
|
Ok(())
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user