2017/08-09

This commit is contained in:
2017-12-09 11:53:47 +01:00
parent 413c80b41b
commit 02718ba05f
8 changed files with 1412 additions and 0 deletions

4
2017/08/Cargo.lock generated Normal file
View File

@@ -0,0 +1,4 @@
[[package]]
name = "day-08"
version = "0.1.0"

6
2017/08/Cargo.toml Normal file
View 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

File diff suppressed because it is too large Load Diff

286
2017/08/src/main.rs Normal file
View 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
View File

@@ -0,0 +1,4 @@
[[package]]
name = "day-09"
version = "0.1.0"

6
2017/09/Cargo.toml Normal file
View 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

File diff suppressed because one or more lines are too long

105
2017/09/src/main.rs Normal file
View 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));
}
}