2017/08-09
This commit is contained in:
4
2017/08/Cargo.lock
generated
Normal file
4
2017/08/Cargo.lock
generated
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[[package]]
|
||||||
|
name = "day-08"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
6
2017/08/Cargo.toml
Normal file
6
2017/08/Cargo.toml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[package]
|
||||||
|
name = "day-08"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["logaritmisk <anders.e.olsson@gmail.com>"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
1000
2017/08/input.txt
Normal file
1000
2017/08/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
286
2017/08/src/main.rs
Normal file
286
2017/08/src/main.rs
Normal file
@@ -0,0 +1,286 @@
|
|||||||
|
use std::io::{self, Read};
|
||||||
|
use std::collections::{HashMap, VecDeque};
|
||||||
|
|
||||||
|
use ast::*;
|
||||||
|
|
||||||
|
|
||||||
|
mod ast {
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
pub enum Expr<'a> {
|
||||||
|
Equ(Value<'a>, Value<'a>, Assign<'a>), // ==
|
||||||
|
Neq(Value<'a>, Value<'a>, Assign<'a>), // !=
|
||||||
|
Lss(Value<'a>, Value<'a>, Assign<'a>), // <
|
||||||
|
Leq(Value<'a>, Value<'a>, Assign<'a>), // <=
|
||||||
|
Gtr(Value<'a>, Value<'a>, Assign<'a>), // >
|
||||||
|
Geq(Value<'a>, Value<'a>, Assign<'a>), // >=
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
pub enum Assign<'a> {
|
||||||
|
Inc(Value<'a>, Value<'a>), // +
|
||||||
|
Dec(Value<'a>, Value<'a>), // -
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
pub enum Value<'a> {
|
||||||
|
Register(&'a str),
|
||||||
|
Number(i64),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod parse {
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
|
use ast::*;
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
pub enum AssignType {
|
||||||
|
Inc,
|
||||||
|
Dec,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
pub enum ExprType {
|
||||||
|
Equ,
|
||||||
|
Neq,
|
||||||
|
Lss,
|
||||||
|
Leq,
|
||||||
|
Gtr,
|
||||||
|
Geq,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn from_str(input: &str) -> Expr {
|
||||||
|
let mut assign = None;
|
||||||
|
let mut expr = None;
|
||||||
|
|
||||||
|
let mut values = VecDeque::with_capacity(4);
|
||||||
|
|
||||||
|
for token in input.split_whitespace() {
|
||||||
|
match token {
|
||||||
|
"inc" => assign = Some(AssignType::Inc),
|
||||||
|
"dec" => assign = Some(AssignType::Dec),
|
||||||
|
|
||||||
|
"==" => expr = Some(ExprType::Equ),
|
||||||
|
"!=" => expr = Some(ExprType::Neq),
|
||||||
|
|
||||||
|
"<" => expr = Some(ExprType::Lss),
|
||||||
|
"<=" => expr = Some(ExprType::Leq),
|
||||||
|
|
||||||
|
">" => expr = Some(ExprType::Gtr),
|
||||||
|
">=" => expr = Some(ExprType::Geq),
|
||||||
|
|
||||||
|
"if" => (),
|
||||||
|
|
||||||
|
value => values.push_back(
|
||||||
|
value
|
||||||
|
.parse::<i64>()
|
||||||
|
.ok()
|
||||||
|
.map_or_else(|| Value::Register(token), Value::Number),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let a = values.pop_front().unwrap();
|
||||||
|
let b = values.pop_front().unwrap();
|
||||||
|
|
||||||
|
let assign = match assign.unwrap() {
|
||||||
|
AssignType::Inc => Assign::Inc(a, b),
|
||||||
|
AssignType::Dec => Assign::Dec(a, b),
|
||||||
|
};
|
||||||
|
|
||||||
|
let a = values.pop_front().unwrap();
|
||||||
|
let b = values.pop_front().unwrap();
|
||||||
|
|
||||||
|
match expr.unwrap() {
|
||||||
|
ExprType::Equ => Expr::Equ(a, b, assign),
|
||||||
|
ExprType::Neq => Expr::Neq(a, b, assign),
|
||||||
|
ExprType::Lss => Expr::Lss(a, b, assign),
|
||||||
|
ExprType::Leq => Expr::Leq(a, b, assign),
|
||||||
|
ExprType::Gtr => Expr::Gtr(a, b, assign),
|
||||||
|
ExprType::Geq => Expr::Geq(a, b, assign),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut input = String::new();
|
||||||
|
|
||||||
|
io::stdin()
|
||||||
|
.read_to_string(&mut input)
|
||||||
|
.expect("faild to read input");
|
||||||
|
|
||||||
|
let mut registers = HashMap::new();
|
||||||
|
let mut max_value = 0;
|
||||||
|
|
||||||
|
for instruction in input
|
||||||
|
.lines()
|
||||||
|
.filter(|line| !line.is_empty())
|
||||||
|
.map(parse::from_str)
|
||||||
|
.collect::<VecDeque<_>>()
|
||||||
|
{
|
||||||
|
let assign = match instruction {
|
||||||
|
Expr::Equ(a, b, assign) => {
|
||||||
|
let a = match a {
|
||||||
|
Value::Register(name) => *registers.entry(name).or_insert(0),
|
||||||
|
Value::Number(number) => number,
|
||||||
|
};
|
||||||
|
|
||||||
|
let b = match b {
|
||||||
|
Value::Register(name) => *registers.entry(name).or_insert(0),
|
||||||
|
Value::Number(number) => number,
|
||||||
|
};
|
||||||
|
|
||||||
|
if a == b {
|
||||||
|
Some(assign)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::Neq(a, b, assign) => {
|
||||||
|
let a = match a {
|
||||||
|
Value::Register(name) => *registers.entry(name).or_insert(0),
|
||||||
|
Value::Number(number) => number,
|
||||||
|
};
|
||||||
|
|
||||||
|
let b = match b {
|
||||||
|
Value::Register(name) => *registers.entry(name).or_insert(0),
|
||||||
|
Value::Number(number) => number,
|
||||||
|
};
|
||||||
|
|
||||||
|
if a != b {
|
||||||
|
Some(assign)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::Lss(a, b, assign) => {
|
||||||
|
let a = match a {
|
||||||
|
Value::Register(name) => *registers.entry(name).or_insert(0),
|
||||||
|
Value::Number(number) => number,
|
||||||
|
};
|
||||||
|
|
||||||
|
let b = match b {
|
||||||
|
Value::Register(name) => *registers.entry(name).or_insert(0),
|
||||||
|
Value::Number(number) => number,
|
||||||
|
};
|
||||||
|
|
||||||
|
if a < b {
|
||||||
|
Some(assign)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::Leq(a, b, assign) => {
|
||||||
|
let a = match a {
|
||||||
|
Value::Register(name) => *registers.entry(name).or_insert(0),
|
||||||
|
Value::Number(number) => number,
|
||||||
|
};
|
||||||
|
|
||||||
|
let b = match b {
|
||||||
|
Value::Register(name) => *registers.entry(name).or_insert(0),
|
||||||
|
Value::Number(number) => number,
|
||||||
|
};
|
||||||
|
|
||||||
|
if a <= b {
|
||||||
|
Some(assign)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::Gtr(a, b, assign) => {
|
||||||
|
let a = match a {
|
||||||
|
Value::Register(name) => *registers.entry(name).or_insert(0),
|
||||||
|
Value::Number(number) => number,
|
||||||
|
};
|
||||||
|
|
||||||
|
let b = match b {
|
||||||
|
Value::Register(name) => *registers.entry(name).or_insert(0),
|
||||||
|
Value::Number(number) => number,
|
||||||
|
};
|
||||||
|
|
||||||
|
if a > b {
|
||||||
|
Some(assign)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::Geq(a, b, assign) => {
|
||||||
|
let a = match a {
|
||||||
|
Value::Register(name) => *registers.entry(name).or_insert(0),
|
||||||
|
Value::Number(number) => number,
|
||||||
|
};
|
||||||
|
|
||||||
|
let b = match b {
|
||||||
|
Value::Register(name) => *registers.entry(name).or_insert(0),
|
||||||
|
Value::Number(number) => number,
|
||||||
|
};
|
||||||
|
|
||||||
|
if a >= b {
|
||||||
|
Some(assign)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(assign) = assign {
|
||||||
|
match assign {
|
||||||
|
Assign::Inc(register, value) => {
|
||||||
|
let value = match value {
|
||||||
|
Value::Register(name) => *registers.entry(name).or_insert(0),
|
||||||
|
Value::Number(number) => number,
|
||||||
|
};
|
||||||
|
|
||||||
|
match register {
|
||||||
|
Value::Register(name) => *registers.entry(name).or_insert(0) += value,
|
||||||
|
Value::Number(_) => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Assign::Dec(register, value) => {
|
||||||
|
let value = match value {
|
||||||
|
Value::Register(name) => *registers.entry(name).or_insert(0),
|
||||||
|
Value::Number(number) => number,
|
||||||
|
};
|
||||||
|
|
||||||
|
match register {
|
||||||
|
Value::Register(name) => *registers.entry(name).or_insert(0) -= value,
|
||||||
|
Value::Number(_) => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(value) = registers.values().max() {
|
||||||
|
if *value > max_value {
|
||||||
|
max_value = *value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("part_one={}", registers.values().max().unwrap());
|
||||||
|
println!("part_two={}", max_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse() {
|
||||||
|
use ast::*;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse::from_str("b inc 5 if a > 1"),
|
||||||
|
Expr::Gtr(
|
||||||
|
Value::Register("a"),
|
||||||
|
Value::Number(1),
|
||||||
|
Assign::Inc(Value::Register("b"), Value::Number(5))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
4
2017/09/Cargo.lock
generated
Normal file
4
2017/09/Cargo.lock
generated
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[[package]]
|
||||||
|
name = "day-09"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
6
2017/09/Cargo.toml
Normal file
6
2017/09/Cargo.toml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[package]
|
||||||
|
name = "day-09"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["logaritmisk <anders.e.olsson@gmail.com>"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
1
2017/09/input.txt
Normal file
1
2017/09/input.txt
Normal file
File diff suppressed because one or more lines are too long
105
2017/09/src/main.rs
Normal file
105
2017/09/src/main.rs
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
use std::io::{self, Read};
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
enum State {
|
||||||
|
Group,
|
||||||
|
Garbage,
|
||||||
|
Ignore,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn scan(input: &str) -> (usize, usize) {
|
||||||
|
let mut score = 0;
|
||||||
|
let mut garbage = 0;
|
||||||
|
|
||||||
|
let mut indendation = 0;
|
||||||
|
|
||||||
|
let mut states = Vec::new();
|
||||||
|
|
||||||
|
for ch in input.chars() {
|
||||||
|
let state = *states.last().unwrap_or(&State::Group);
|
||||||
|
|
||||||
|
match (state, ch) {
|
||||||
|
// Group
|
||||||
|
(State::Group, '{') => {
|
||||||
|
indendation += 1;
|
||||||
|
}
|
||||||
|
(State::Group, '}') => {
|
||||||
|
score += indendation;
|
||||||
|
indendation -= 1;
|
||||||
|
|
||||||
|
states.pop();
|
||||||
|
}
|
||||||
|
(State::Group, '<') => {
|
||||||
|
states.push(State::Garbage);
|
||||||
|
}
|
||||||
|
(State::Group, '!') => {
|
||||||
|
states.push(State::Ignore);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Garbage
|
||||||
|
(State::Garbage, '>') => {
|
||||||
|
states.pop();
|
||||||
|
}
|
||||||
|
(State::Garbage, '!') => {
|
||||||
|
states.push(State::Ignore);
|
||||||
|
}
|
||||||
|
(State::Garbage, _) => {
|
||||||
|
garbage += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore
|
||||||
|
(State::Ignore, _) => {
|
||||||
|
states.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(score, garbage)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut input = String::new();
|
||||||
|
|
||||||
|
io::stdin()
|
||||||
|
.read_to_string(&mut input)
|
||||||
|
.expect("faild to read input");
|
||||||
|
|
||||||
|
let (score, garbage) = scan(&input);
|
||||||
|
|
||||||
|
println!("part_one={}", score);
|
||||||
|
println!("part_two={}", garbage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_score() {
|
||||||
|
assert_eq!(scan("{}"), (1, 0));
|
||||||
|
assert_eq!(scan("{{{}}}"), (6, 0));
|
||||||
|
assert_eq!(scan("{{},{}}"), (5, 0));
|
||||||
|
assert_eq!(scan("{{{},{},{{}}}}"), (16, 0));
|
||||||
|
assert_eq!(scan("{<a>,<a>,<a>,<a>}"), (1, 4));
|
||||||
|
assert_eq!(scan("{{<ab>},{<ab>},{<ab>},{<ab>}}"), (9, 8));
|
||||||
|
assert_eq!(scan("{{<!!>},{<!!>},{<!!>},{<!!>}}"), (9, 0));
|
||||||
|
assert_eq!(scan("{{<a!>},{<a!>},{<a!>},{<ab>}}"), (3, 17));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_garbage() {
|
||||||
|
assert_eq!(scan("<>"), (0, 0));
|
||||||
|
assert_eq!(scan("<random characters>"), (0, 17));
|
||||||
|
assert_eq!(scan("<<<<>"), (0, 3));
|
||||||
|
assert_eq!(scan("<{!>}>"), (0, 2));
|
||||||
|
assert_eq!(scan("<!!>"), (0, 0));
|
||||||
|
assert_eq!(scan("<!!!>>"), (0, 0));
|
||||||
|
assert_eq!(scan(r#"<{o"i!a,<{i<a>"#), (0, 10));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user