day 3
This commit is contained in:
parent
3395b25176
commit
3d46c28bea
@ -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 {
|
||||||
|
|||||||
@ -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> {
|
||||||
|
|||||||
149
src/day3/mod.rs
149
src/day3/mod.rs
@ -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"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user