2017/06-07

This commit is contained in:
2017-12-07 11:08:39 +01:00
parent 6fc08571bf
commit 413c80b41b
9 changed files with 1624 additions and 0 deletions

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

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

6
2017/06/Cargo.toml Normal file
View File

@@ -0,0 +1,6 @@
[package]
name = "day-06"
version = "0.1.0"
authors = ["logaritmisk <anders.e.olsson@gmail.com>"]
[dependencies]

1
2017/06/input.txt Normal file
View File

@@ -0,0 +1 @@
4 10 4 1 8 4 9 14 5 1 14 15 0 15 3 5

101
2017/06/src/main.rs Normal file
View File

@@ -0,0 +1,101 @@
use std::io::{self, Read};
use std::collections::HashSet;
fn parse(input: &str) -> Vec<u16> {
input.split_whitespace().flat_map(str::parse).collect()
}
fn cycle(input: &mut [u16]) {
let (index, blocks) = input
.iter()
.enumerate()
.fold((0, 0), |acc, (index, blocks)| {
if *blocks > acc.1 {
(index, *blocks)
} else {
acc
}
});
input[index] = 0;
let len = input.len();
for i in 0..blocks as usize {
input[(index + i + 1) % len] += 1;
}
}
fn infinit_loop(mut memory: Vec<u16>) -> (Vec<u16>, usize) {
let mut states = HashSet::new();
states.insert(memory.clone());
let mut i = 0;
loop {
i += 1;
cycle(&mut memory);
if states.contains(&memory) {
break;
}
states.insert(memory.clone());
}
(memory, i)
}
fn main() {
let mut input = String::new();
io::stdin()
.read_to_string(&mut input)
.expect("faild to read input");
for entry in input.lines().filter(|line| !line.is_empty()).map(parse) {
let (state, cycle) = infinit_loop(entry);
println!("part_one={}", cycle);
let (_, cycle) = infinit_loop(state);
println!("part_two={}", cycle);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse() {
assert_eq!(parse("0 2 7 0"), vec![0, 2, 7, 0]);
}
#[test]
fn test_cycle() {
let mut data = vec![0, 2, 7, 0];
cycle(&mut data);
assert_eq!(data, vec![2, 4, 1, 2]);
}
#[test]
fn test_infinit_loop() {
let data = vec![0, 2, 7, 0];
let (state, cycle) = infinit_loop(data);
assert_eq!(cycle, 5);
let (_, cycle) = infinit_loop(state);
assert_eq!(cycle, 4);
}
}

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

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

6
2017/07/Cargo.toml Normal file
View File

@@ -0,0 +1,6 @@
[package]
name = "day-07"
version = "0.1.0"
authors = ["logaritmisk <anders.e.olsson@gmail.com>"]
[dependencies]

13
2017/07/example.txt Normal file
View File

@@ -0,0 +1,13 @@
pbga (66)
xhth (57)
ebii (61)
havc (66)
ktlj (57)
fwft (72) -> ktlj, cntj, xhth
qoyq (66)
padx (45) -> pbga, havc, qoyq
tknk (41) -> ugml, padx, fwft
jptl (61)
ugml (68) -> gyxo, ebii, jptl
gyxo (61)
cntj (57)

1292
2017/07/input.txt Normal file

File diff suppressed because it is too large Load Diff

197
2017/07/src/main.rs Normal file
View File

@@ -0,0 +1,197 @@
use std::io::{self, Read};
mod parser {
pub type Program<'a> = (&'a str, i64, Vec<&'a str>);
#[derive(Clone, Copy)]
enum State {
Name,
PreWeight,
Weight(usize),
PreAbove,
Above(usize),
}
pub fn from_str(input: &str) -> Program {
let mut name = None;
let mut weight = None;
let mut above = Vec::new();
let mut state = State::Name;
for (i, c) in input.chars().enumerate() {
match (state, c) {
(State::Name, ' ') => {
name = Some(&input[0..i]);
state = State::PreWeight;
}
(State::PreWeight, '(') => {
state = State::Weight(i + 1);
}
(State::Weight(start), ')') => {
weight = input[start..i].parse::<i64>().ok();
state = State::PreAbove;
}
(State::PreAbove, 'a'...'z') => {
state = State::Above(i);
}
(State::Above(start), ',') => {
above.push(&input[start..i]);
state = State::PreAbove;
}
_ => (),
}
}
if let State::Above(start) = state {
above.push(&input[start..input.len()]);
}
(name.unwrap(), weight.unwrap(), above)
}
}
mod tree {
use std::collections::{HashMap, VecDeque};
use parser::Program;
pub type Tree<'a> = HashMap<&'a str, Info<'a>>;
#[derive(Debug)]
pub struct Info<'a> {
weight: i64,
above: Tree<'a>,
}
pub fn build(programs: Vec<Program>) -> Tree {
let mut tree = Tree::new();
let mut temp = VecDeque::new();
for (name, weight, above) in programs {
if above.is_empty() {
tree.insert(
name,
Info {
weight: weight,
above: Tree::new(),
},
);
} else {
temp.push_back((name, weight, above));
}
}
while let Some((name, weight, above)) = temp.pop_front() {
if above
.iter()
.any(|name_above| !tree.contains_key(name_above))
{
temp.push_back((name, weight, above));
continue;
}
let info = Info {
weight: weight,
above: above
.into_iter()
.map(|name_above| (name_above, tree.remove(name_above).unwrap()))
.collect::<Tree>(),
};
tree.insert(name, info);
}
tree
}
pub fn stacker(name: &str, root: &Info, level: usize) -> i64 {
if root.above.is_empty() {
root.weight
} else {
let mut total = 0;
let mut map = HashMap::new();
for (name, stack) in &root.above {
let weight = stacker(name, stack, level + 1);
total += weight;
map.entry(weight).or_insert_with(Vec::new).push(name);
}
if map.len() > 1 {
let (wrong, correct) =
map.iter()
.fold((0, 0), |(wrong, correct), (weight, programs)| {
if programs.len() == 1 {
(*weight, correct)
} else {
(wrong, *weight)
}
});
let mut weight = root.above[map[&wrong][0]].weight;
weight += correct - wrong;
println!("{}: {} weight should be {}", level, name, weight);
}
root.weight + total
}
}
}
fn main() {
let mut input = String::new();
io::stdin()
.read_to_string(&mut input)
.expect("failed to read input");
let programs = input
.lines()
.filter(|line| !line.is_empty())
.map(parser::from_str)
.collect::<Vec<_>>();
let tree = tree::build(programs);
let root = tree.keys().nth(0).unwrap();
println!("part_one={:?}", root);
println!("part_two:");
tree::stacker(root, &tree[root], 0);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse() {
assert_eq!(parser::from_str("pbga (66)"), ("pbga", 66, vec![]));
assert_eq!(
parser::from_str("fwft (72) -> ktlj, cntj, xhth"),
("fwft", 72, vec!["ktlj", "cntj", "xhth"])
);
}
}