Implement day 14.

This commit is contained in:
2018-12-14 11:37:30 +01:00
parent faf3ad90d9
commit 98da0a9857
3 changed files with 106 additions and 5 deletions

1
2018/inputs/14.txt Normal file
View File

@@ -0,0 +1 @@
637061

View File

@@ -1,6 +1,8 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::hash::Hash; use std::hash::Hash;
use std::io; use std::io;
use std::io::Read;
use std::str::FromStr;
/// Apply Erathostenes's sieve to the supplied array /// Apply Erathostenes's sieve to the supplied array
/// ///
@@ -50,6 +52,19 @@ pub fn trim_back(input: &mut Vec<u8>) {
} }
} }
/// Read the entire input as one value.
///
/// This function loads the input into a string and then attempts to parse it.
pub fn read_single_input<T>(input: &mut Read) -> T
where T: FromStr,
<T as FromStr>::Err: std::fmt::Debug
{
let mut buf = String::new();
input.read_to_string(&mut buf).unwrap();
buf.trim().parse().unwrap()
}
/// An interface to count elements in particular categories. /// An interface to count elements in particular categories.
pub trait GroupingCount { pub trait GroupingCount {

View File

@@ -1,6 +1,68 @@
use std::io::Read; use std::io::Read;
use common::Solution; use common::Solution;
use common::read_single_input;
fn skill_after(n: usize) -> u64 {
let mut state = vec![3u8, 7];
let mut elves = [0, 1];
while state.len() < n + 10 {
let result: u8 = elves.iter().map(|x| state[*x]).sum();
if result >= 10 {
state.push(result / 10);
}
state.push(result % 10);
for elf in elves.iter_mut() {
*elf = (*elf + state[*elf] as usize + 1) % state.len();
}
}
let mut skill = 0;
for d in state.into_iter().skip(n).take(10) {
skill *= 10;
skill += d as u64;
}
skill
}
fn update_current(mut current: usize, by: usize, base: usize) -> usize {
current *= 10;
current %= base;
current += by;
current
}
fn find_first(n: usize, len: usize) -> usize {
println!("{} {}", n, len);
let mut state = vec![3u8, 7];
let mut elves = [0, 1];
let mut current = 37;
let mod_base = 10usize.pow(len as u32);
loop {
let result: u8 = elves.iter().map(|x| state[*x]).sum();
if result >= 10 {
current = update_current(current, result as usize / 10, mod_base);
if current == n {
return state.len() - 5;
}
state.push(result / 10);
}
current = update_current(current, result as usize % 10, mod_base);
if current == n {
return state.len() - 5 + 1;
}
state.push(result % 10);
for elf in elves.iter_mut() {
*elf = (*elf + state[*elf] as usize + 1) % state.len();
}
}
}
#[derive(Default)] #[derive(Default)]
pub struct Day14 {} pub struct Day14 {}
@@ -12,14 +74,37 @@ impl Day14 {
} }
impl Solution for Day14 { impl Solution for Day14 {
fn part1(&mut self, _input: &mut Read) -> String { fn part1(&mut self, input: &mut Read) -> String {
unimplemented!() let input = read_single_input(input);
format!("{:010}", skill_after(input))
} }
fn part2(&mut self, _input: &mut Read) -> String { fn part2(&mut self, input: &mut Read) -> String {
unimplemented!() let mut buf = String::new();
input.read_to_string(&mut buf).unwrap();
let input = buf.trim().parse().unwrap();
format!("{}", find_first(input, buf.trim().len()))
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests {} mod tests {
use super::*;
#[test]
fn test_skill_after() {
assert_eq!(5158916779, skill_after(9));
assert_eq!(124515891, skill_after(5));
assert_eq!(9251071085, skill_after(18));
assert_eq!(5941429882, skill_after(2018));
}
#[test]
fn test_find_first() {
assert_eq!(9, find_first(51589, 5));
assert_eq!(5, find_first(1245, 5));
assert_eq!(18, find_first(92510, 5));
assert_eq!(2018, find_first(59414, 5));
}
}