This commit is contained in:
cool-mist 2024-12-17 00:15:53 +05:30
parent 3395b25176
commit 3d46c28bea
3 changed files with 142 additions and 17 deletions

View File

@ -14,7 +14,7 @@ pub fn run() {
right.sort(); right.sort();
let res = left.iter().zip(right.iter()).map(diff).sum::<i32>(); let res = left.iter().zip(right.iter()).map(diff).sum::<i32>();
println!("1. {}", res); println!("1. {}", res); // 1646452
let left = HashSet::<i32>::from_iter(left.into_iter()); let left = HashSet::<i32>::from_iter(left.into_iter());
let mut acc = 0; let mut acc = 0;
@ -24,7 +24,7 @@ pub fn run() {
} }
} }
println!("2. {}", acc); println!("2. {}", acc); // 23609874
} }
fn diff((a, b): (&i32, &i32)) -> i32 { fn diff((a, b): (&i32, &i32)) -> i32 {

View File

@ -8,14 +8,14 @@ pub fn run() {
.filter_map(|mut line| is_safe(&mut line)) .filter_map(|mut line| is_safe(&mut line))
.count(); .count();
println!("1. {}", safe); // 510
let safe_corrected = input let safe_corrected = input
.lines() .lines()
.map(ExpandedSplitWhitespaceNumbers::new) .map(ExpandedSplitWhitespaceNumbers::new)
.filter_map(|mut line| is_safe_corrected(&mut line)) .filter_map(|mut line| is_safe_corrected(&mut line))
.count(); .count();
println!("2. {}", safe_corrected); // 553
println!("1. {}", safe);
println!("2. {}", safe_corrected);
} }
struct SplitWhitespaceNumbers<'a> { struct SplitWhitespaceNumbers<'a> {

View File

@ -2,16 +2,66 @@ use std::fmt::Display;
pub fn run() { pub fn run() {
let input = include_str!("input"); let input = include_str!("input");
let mut modifier_disabled = DoModifier::disabled();
let result = input let result = input
.lines() .lines()
.map(|line| parse_instr(line)) .map(|line| parse_instr(line, &mut modifier_disabled))
.map(|products| reduce_products(products)) .map(|products| reduce_products(products))
.sum::<u64>(); .sum::<u64>();
println!("1. {}", result); println!("1. {}", result); // 189600467
let mut modifier_default = DoModifier::default();
let result = input
.lines()
.map(|line| parse_instr(line, &mut modifier_default))
.map(|products| reduce_products(products))
.sum::<u64>();
println!("2. {}", result); // 107069718
} }
fn parse_instr(line: &str) -> Vec<u64> { struct DoModifier {
state: bool,
enabled: bool,
}
impl DoModifier {
fn disabled() -> Self {
DoModifier {
state: true,
enabled: false,
}
}
fn default() -> Self {
DoModifier {
state: true,
enabled: true,
}
}
fn should_mul(&self) -> bool {
if !self.enabled {
true
} else {
self.state
}
}
fn flip(&mut self, instr: Instr) {
if self.enabled {
self.state = match instr {
Instr::Do => true,
Instr::Dont => false,
_ => self.state,
}
}
}
}
fn parse_instr(line: &str, modifier: &mut DoModifier) -> Vec<u64> {
let mut instr = None;
let mut state = ParseState::None; let mut state = ParseState::None;
let mut first_num = Vec::new(); let mut first_num = Vec::new();
let mut second_num = Vec::new(); let mut second_num = Vec::new();
@ -19,17 +69,36 @@ fn parse_instr(line: &str) -> Vec<u64> {
for (_i, c) in line.chars().enumerate() { for (_i, c) in line.chars().enumerate() {
let next = next_state(&state, c); let next = next_state(&state, c);
if let ParseState::ParamOne = next { if let ParseState::D = next {
first_num.insert(0, c.to_digit(10).unwrap() as u64); instr = Some(Instr::Do);
} else if let ParseState::T = next {
instr = Some(Instr::Dont);
} else if let ParseState::M = next {
instr = Some(Instr::Mul);
} else if let ParseState::ParamOne = next {
if modifier.should_mul() {
first_num.insert(0, c.to_digit(10).unwrap() as u64);
}
} else if let ParseState::Comma = next { } else if let ParseState::Comma = next {
finalize_number(&mut first_num); if modifier.should_mul() {
finalize_number(&mut first_num);
}
} else if let ParseState::ParamTwo = next { } else if let ParseState::ParamTwo = next {
second_num.insert(0, c.to_digit(10).unwrap() as u64); second_num.insert(0, c.to_digit(10).unwrap() as u64);
} else if let ParseState::CloseParen = next { } else if let ParseState::CloseParen = next {
finalize_number(&mut second_num); match instr {
res.push(first_num[0] * second_num[0]); Some(Instr::Mul) => {
first_num.clear(); if modifier.should_mul() {
second_num.clear(); finalize_number(&mut second_num);
res.push(first_num[0] * second_num[0]);
}
first_num.clear();
second_num.clear();
}
Some(instr) => modifier.flip(instr),
None => {}
}
instr = None;
} }
if let ParseState::CloseParen = next { if let ParseState::CloseParen = next {
@ -65,8 +134,19 @@ fn reduce_products(products: Vec<u64>) -> u64 {
products.iter().sum() products.iter().sum()
} }
enum Instr {
Do,
Dont,
Mul,
}
enum ParseState { enum ParseState {
None, None,
D,
O,
N,
QUOTE,
T,
M, M,
U, U,
L, L,
@ -79,9 +159,48 @@ enum ParseState {
fn next_state(state: &ParseState, c: char) -> ParseState { fn next_state(state: &ParseState, c: char) -> ParseState {
match state { match state {
ParseState::None => { ParseState::None | ParseState::CloseParen => {
if c == 'm' { if c == 'm' {
ParseState::M ParseState::M
} else if c == 'd' {
ParseState::D
} else {
ParseState::None
}
}
ParseState::D => {
if c == 'o' {
ParseState::O
} else {
ParseState::None
}
}
ParseState::O => {
if c == '(' {
ParseState::OpenParen
} else if c == 'n' {
ParseState::N
} else {
ParseState::None
}
}
ParseState::N => {
if c == '\'' {
ParseState::QUOTE
} else {
ParseState::None
}
}
ParseState::QUOTE => {
if c == 't' {
ParseState::T
} else {
ParseState::None
}
}
ParseState::T => {
if c == '(' {
ParseState::OpenParen
} else { } else {
ParseState::None ParseState::None
} }
@ -110,6 +229,8 @@ fn next_state(state: &ParseState, c: char) -> ParseState {
ParseState::OpenParen => { ParseState::OpenParen => {
if c.is_digit(10) { if c.is_digit(10) {
ParseState::ParamOne ParseState::ParamOne
} else if c == ')' {
ParseState::CloseParen
} else { } else {
ParseState::None ParseState::None
} }
@ -139,7 +260,6 @@ fn next_state(state: &ParseState, c: char) -> ParseState {
ParseState::None ParseState::None
} }
} }
ParseState::CloseParen => ParseState::None,
} }
} }
@ -155,6 +275,11 @@ impl Display for ParseState {
ParseState::Comma => write!(f, ","), ParseState::Comma => write!(f, ","),
ParseState::ParamTwo => write!(f, "ParamTwo"), ParseState::ParamTwo => write!(f, "ParamTwo"),
ParseState::CloseParen => write!(f, ")"), ParseState::CloseParen => write!(f, ")"),
ParseState::D => write!(f, "D"),
ParseState::O => write!(f, "O"),
ParseState::N => write!(f, "N"),
ParseState::QUOTE => write!(f, "'"),
ParseState::T => write!(f, "T"),
} }
} }
} }