day 3
This commit is contained in:
parent
3395b25176
commit
3d46c28bea
@ -14,7 +14,7 @@ pub fn run() {
|
||||
right.sort();
|
||||
|
||||
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 mut acc = 0;
|
||||
@ -24,7 +24,7 @@ pub fn run() {
|
||||
}
|
||||
}
|
||||
|
||||
println!("2. {}", acc);
|
||||
println!("2. {}", acc); // 23609874
|
||||
}
|
||||
|
||||
fn diff((a, b): (&i32, &i32)) -> i32 {
|
||||
|
||||
@ -8,14 +8,14 @@ pub fn run() {
|
||||
.filter_map(|mut line| is_safe(&mut line))
|
||||
.count();
|
||||
|
||||
println!("1. {}", safe); // 510
|
||||
|
||||
let safe_corrected = input
|
||||
.lines()
|
||||
.map(ExpandedSplitWhitespaceNumbers::new)
|
||||
.filter_map(|mut line| is_safe_corrected(&mut line))
|
||||
.count();
|
||||
|
||||
println!("1. {}", safe);
|
||||
println!("2. {}", safe_corrected);
|
||||
println!("2. {}", safe_corrected); // 553
|
||||
}
|
||||
|
||||
struct SplitWhitespaceNumbers<'a> {
|
||||
|
||||
149
src/day3/mod.rs
149
src/day3/mod.rs
@ -2,16 +2,66 @@ use std::fmt::Display;
|
||||
|
||||
pub fn run() {
|
||||
let input = include_str!("input");
|
||||
let mut modifier_disabled = DoModifier::disabled();
|
||||
let result = input
|
||||
.lines()
|
||||
.map(|line| parse_instr(line))
|
||||
.map(|line| parse_instr(line, &mut modifier_disabled))
|
||||
.map(|products| reduce_products(products))
|
||||
.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 first_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() {
|
||||
let next = next_state(&state, c);
|
||||
|
||||
if let ParseState::ParamOne = next {
|
||||
first_num.insert(0, c.to_digit(10).unwrap() as u64);
|
||||
if let ParseState::D = next {
|
||||
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 {
|
||||
finalize_number(&mut first_num);
|
||||
if modifier.should_mul() {
|
||||
finalize_number(&mut first_num);
|
||||
}
|
||||
} else if let ParseState::ParamTwo = next {
|
||||
second_num.insert(0, c.to_digit(10).unwrap() as u64);
|
||||
} else if let ParseState::CloseParen = next {
|
||||
finalize_number(&mut second_num);
|
||||
res.push(first_num[0] * second_num[0]);
|
||||
first_num.clear();
|
||||
second_num.clear();
|
||||
match instr {
|
||||
Some(Instr::Mul) => {
|
||||
if modifier.should_mul() {
|
||||
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 {
|
||||
@ -65,8 +134,19 @@ fn reduce_products(products: Vec<u64>) -> u64 {
|
||||
products.iter().sum()
|
||||
}
|
||||
|
||||
enum Instr {
|
||||
Do,
|
||||
Dont,
|
||||
Mul,
|
||||
}
|
||||
|
||||
enum ParseState {
|
||||
None,
|
||||
D,
|
||||
O,
|
||||
N,
|
||||
QUOTE,
|
||||
T,
|
||||
M,
|
||||
U,
|
||||
L,
|
||||
@ -79,9 +159,48 @@ enum ParseState {
|
||||
|
||||
fn next_state(state: &ParseState, c: char) -> ParseState {
|
||||
match state {
|
||||
ParseState::None => {
|
||||
ParseState::None | ParseState::CloseParen => {
|
||||
if c == '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 {
|
||||
ParseState::None
|
||||
}
|
||||
@ -110,6 +229,8 @@ fn next_state(state: &ParseState, c: char) -> ParseState {
|
||||
ParseState::OpenParen => {
|
||||
if c.is_digit(10) {
|
||||
ParseState::ParamOne
|
||||
} else if c == ')' {
|
||||
ParseState::CloseParen
|
||||
} else {
|
||||
ParseState::None
|
||||
}
|
||||
@ -139,7 +260,6 @@ fn next_state(state: &ParseState, c: char) -> ParseState {
|
||||
ParseState::None
|
||||
}
|
||||
}
|
||||
ParseState::CloseParen => ParseState::None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,6 +275,11 @@ impl Display for ParseState {
|
||||
ParseState::Comma => write!(f, ","),
|
||||
ParseState::ParamTwo => write!(f, "ParamTwo"),
|
||||
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"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user