mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Implement day 14.
This commit is contained in:
1
2018/inputs/14.txt
Normal file
1
2018/inputs/14.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
637061
|
||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user