Completed day 14
This commit is contained in:
parent
3872264523
commit
e85f9131be
1
inputs/14.txt
Normal file
1
inputs/14.txt
Normal file
@ -0,0 +1 @@
|
||||
236021
|
@ -1,5 +1,3 @@
|
||||
extern crate regex;
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::error::Error;
|
||||
use std::fs;
|
||||
|
249
src/day14.rs
Normal file
249
src/day14.rs
Normal file
@ -0,0 +1,249 @@
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::fs;
|
||||
use std::result;
|
||||
|
||||
type Result<T> = result::Result<T, Box<Error>>;
|
||||
|
||||
const INPUT: &str = "inputs/14.txt";
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct Recipes {
|
||||
scores: Vec<u8>,
|
||||
elf1_index: usize,
|
||||
elf2_index: usize,
|
||||
}
|
||||
|
||||
impl fmt::Display for Recipes {
|
||||
#[allow(clippy::write_with_newline)]
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for (index, score) in self.scores.iter().enumerate() {
|
||||
if index == self.elf1_index {
|
||||
write!(f, "({})", score)?;
|
||||
} else if index == self.elf2_index {
|
||||
write!(f, "[{}]", score)?;
|
||||
} else {
|
||||
write!(f, " {} ", score)?;
|
||||
}
|
||||
}
|
||||
write!(f, "\n")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Recipes {
|
||||
fn new() -> Recipes {
|
||||
Recipes {
|
||||
scores: vec![3, 7],
|
||||
elf1_index: 0,
|
||||
elf2_index: 1,
|
||||
}
|
||||
}
|
||||
|
||||
fn new_recipes(&mut self) {
|
||||
let elf1_score = self.scores[self.elf1_index];
|
||||
let elf2_score = self.scores[self.elf2_index];
|
||||
let sum = elf1_score + elf2_score;
|
||||
fn push_digits(n: u8, digits: &mut Vec<u8>) {
|
||||
if n >= 10 {
|
||||
push_digits(n / 10, digits);
|
||||
}
|
||||
digits.push(n % 10);
|
||||
}
|
||||
push_digits(sum, &mut self.scores);
|
||||
}
|
||||
|
||||
fn pick_recipes(&mut self) {
|
||||
let elf1_score = self.scores[self.elf1_index];
|
||||
let elf2_score = self.scores[self.elf2_index];
|
||||
self.elf1_index = (self.elf1_index + (1 + elf1_score as usize)) % self.scores.len();
|
||||
self.elf2_index = (self.elf2_index + (1 + elf2_score as usize)) % self.scores.len();
|
||||
}
|
||||
|
||||
fn scores_after_n_recipes(&mut self, n: usize, num_scores: usize) -> String {
|
||||
while self.scores.len() < n + num_scores {
|
||||
self.new_recipes();
|
||||
self.pick_recipes();
|
||||
}
|
||||
self.scores[n..n + num_scores].iter().map(|score| format!("{}", score)).collect()
|
||||
}
|
||||
|
||||
fn find_index_of_sequence(&mut self, seq: &[u8]) -> usize {
|
||||
let seq_len = seq.len();
|
||||
loop {
|
||||
let scores_len = self.scores.len();
|
||||
self.new_recipes();
|
||||
self.pick_recipes();
|
||||
let new_scores_len = self.scores.len();
|
||||
let diff = new_scores_len - scores_len;
|
||||
if scores_len >= seq_len {
|
||||
for i in 0..diff {
|
||||
let seq_index = scores_len + i - seq_len;
|
||||
if &self.scores[seq_index..(seq_index + seq_len)] == seq {
|
||||
return seq_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn digit_seq(n: &str) -> Vec<u8> {
|
||||
let mut digits: Vec<u8> = vec![];
|
||||
for digit in n.chars() {
|
||||
digits.push(digit.to_digit(10).unwrap() as u8);
|
||||
}
|
||||
digits
|
||||
}
|
||||
|
||||
fn read_input_file(filename: &str) -> Result<usize> {
|
||||
let input = fs::read_to_string(filename)?;
|
||||
Ok(input.trim().parse()?)
|
||||
}
|
||||
|
||||
pub fn solve_part1() -> Result<String> {
|
||||
let input = read_input_file(INPUT)?;
|
||||
let mut recipes = Recipes::new();
|
||||
Ok(recipes.scores_after_n_recipes(input, 10))
|
||||
}
|
||||
|
||||
pub fn solve_part2() -> Result<usize> {
|
||||
let input = fs::read_to_string(INPUT)?;
|
||||
let mut recipes = Recipes::new();
|
||||
let seq = digit_seq(&input.trim());
|
||||
Ok(recipes.find_index_of_sequence(&seq[..]))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn creates_new_recipes_struct() {
|
||||
let recipes = Recipes::new();
|
||||
assert_eq!(recipes.scores, vec![3, 7]);
|
||||
assert_eq!(recipes.elf1_index, 0);
|
||||
assert_eq!(recipes.elf2_index, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn adds_new_recipes() {
|
||||
let mut recipes = Recipes::new();
|
||||
recipes.new_recipes();
|
||||
assert_eq!(recipes.scores, vec![3, 7, 1, 0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn picks_new_recipes() {
|
||||
let mut recipes = Recipes::new();
|
||||
recipes.new_recipes();
|
||||
recipes.pick_recipes();
|
||||
assert_eq!(recipes.elf1_index, 0);
|
||||
assert_eq!(recipes.elf2_index, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn iterates_15_times() {
|
||||
let mut recipes = Recipes::new();
|
||||
for _ in 0..15 {
|
||||
recipes.new_recipes();
|
||||
recipes.pick_recipes();
|
||||
}
|
||||
assert_eq!(
|
||||
format!("{}", recipes),
|
||||
" 3 7 1 0 [1] 0 1 2 (4) 5 1 5 8 9 1 6 7 7 9 2 \n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scores_after_5_recipes() {
|
||||
let mut recipes = Recipes::new();
|
||||
assert_eq!(
|
||||
recipes.scores_after_n_recipes(5, 10),
|
||||
"0124515891",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scores_after_9_recipes() {
|
||||
let mut recipes = Recipes::new();
|
||||
assert_eq!(
|
||||
recipes.scores_after_n_recipes(9, 10),
|
||||
"5158916779",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scores_after_18_recipes() {
|
||||
let mut recipes = Recipes::new();
|
||||
assert_eq!(
|
||||
recipes.scores_after_n_recipes(18, 10),
|
||||
"9251071085",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scores_after_2018_recipes() {
|
||||
let mut recipes = Recipes::new();
|
||||
assert_eq!(
|
||||
recipes.scores_after_n_recipes(2018, 10),
|
||||
"5941429882",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn finds_index_of_sequence_1() {
|
||||
let mut recipes = Recipes::new();
|
||||
let seq = vec![5, 1, 5, 8, 9];
|
||||
assert_eq!(
|
||||
recipes.find_index_of_sequence(&seq[..]),
|
||||
9,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn finds_index_of_sequence_2() {
|
||||
let mut recipes = Recipes::new();
|
||||
let seq = vec![0, 1, 2, 4, 5];
|
||||
assert_eq!(
|
||||
recipes.find_index_of_sequence(&seq[..]),
|
||||
5,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn finds_index_of_sequence_3() {
|
||||
let mut recipes = Recipes::new();
|
||||
let seq = vec![9, 2, 5, 1, 0];
|
||||
assert_eq!(
|
||||
recipes.find_index_of_sequence(&seq[..]),
|
||||
18,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn finds_index_of_sequence_4() {
|
||||
let mut recipes = Recipes::new();
|
||||
let seq = vec![5, 9, 4, 1, 4];
|
||||
assert_eq!(
|
||||
recipes.find_index_of_sequence(&seq[..]),
|
||||
2018,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gets_digit_seq_1() {
|
||||
assert_eq!(
|
||||
digit_seq("51589"),
|
||||
vec![5, 1, 5, 8, 9],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gets_digit_seq_2() {
|
||||
assert_eq!(
|
||||
digit_seq("01245"),
|
||||
vec![0, 1, 2, 4, 5],
|
||||
);
|
||||
}
|
||||
}
|
14
src/main.rs
14
src/main.rs
@ -16,6 +16,7 @@ mod day10;
|
||||
mod day11;
|
||||
mod day12;
|
||||
mod day13;
|
||||
mod day14;
|
||||
|
||||
fn main() {
|
||||
// println!("Day 1:");
|
||||
@ -57,9 +58,12 @@ fn main() {
|
||||
// println!("Day 12:");
|
||||
// println!("{}", day12::solve_part1().unwrap());
|
||||
// println!("{}", day12::solve_part2().unwrap());
|
||||
println!("Day 13");
|
||||
let part1 = day13::solve_part1().unwrap();
|
||||
println!("{},{}", part1.x, part1.y);
|
||||
let part2 = day13::solve_part2().unwrap();
|
||||
println!("{},{}", part2.x, part2.y);
|
||||
// println!("Day 13");
|
||||
// let part1 = day13::solve_part1().unwrap();
|
||||
// println!("{},{}", part1.x, part1.y);
|
||||
// println!("{},{}", part2.x, part2.y);
|
||||
// let part2 = day13::solve_part2().unwrap();
|
||||
println!("Day 14");
|
||||
println!("{}", day14::solve_part1().unwrap());
|
||||
println!("{}", day14::solve_part2().unwrap());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user