2017/06-07
This commit is contained in:
4
2017/06/Cargo.lock
generated
Normal file
4
2017/06/Cargo.lock
generated
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[[package]]
|
||||||
|
name = "day-06"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
6
2017/06/Cargo.toml
Normal file
6
2017/06/Cargo.toml
Normal 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
1
2017/06/input.txt
Normal 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
101
2017/06/src/main.rs
Normal 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
4
2017/07/Cargo.lock
generated
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[[package]]
|
||||||
|
name = "day-07"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
6
2017/07/Cargo.toml
Normal file
6
2017/07/Cargo.toml
Normal 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
13
2017/07/example.txt
Normal 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
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
197
2017/07/src/main.rs
Normal 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"])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user