day10 finished

This commit is contained in:
Ruediger Ludwig 2023-02-05 16:12:44 +01:00
parent f630ef6874
commit 54fd03233a
6 changed files with 464 additions and 2 deletions

146
data/day10/example01.txt Normal file
View file

@ -0,0 +1,146 @@
addx 15
addx -11
addx 6
addx -3
addx 5
addx -1
addx -8
addx 13
addx 4
noop
addx -1
addx 5
addx -1
addx 5
addx -1
addx 5
addx -1
addx 5
addx -1
addx -35
addx 1
addx 24
addx -19
addx 1
addx 16
addx -11
noop
noop
addx 21
addx -15
noop
noop
addx -3
addx 9
addx 1
addx -3
addx 8
addx 1
addx 5
noop
noop
noop
noop
noop
addx -36
noop
addx 1
addx 7
noop
noop
noop
addx 2
addx 6
noop
noop
noop
noop
noop
addx 1
noop
noop
addx 7
addx 1
noop
addx -13
addx 13
addx 7
noop
addx 1
addx -33
noop
noop
noop
addx 2
noop
noop
noop
addx 8
noop
addx -1
addx 2
addx 1
noop
addx 17
addx -9
addx 1
addx 1
addx -3
addx 11
noop
noop
addx 1
noop
addx 1
noop
noop
addx -13
addx -19
addx 1
addx 3
addx 26
addx -30
addx 12
addx -1
addx 3
addx 1
noop
noop
noop
addx -9
addx 18
addx 1
addx 2
noop
noop
addx 9
noop
noop
noop
addx -1
addx 2
addx -37
addx 1
addx 3
noop
addx 15
addx -21
addx 22
addx -6
addx 1
noop
addx 2
addx 1
noop
addx -10
noop
noop
addx 20
addx 1
addx 2
addx 2
addx -6
addx -11
noop
noop
noop

View file

@ -0,0 +1,6 @@
## ## ## ## ## ## ## ## ## ##
### ### ### ### ### ### ###
#### #### #### #### ####
##### ##### ##### #####
###### ###### ###### ####
####### ####### #######

143
data/day10/input.txt Normal file
View file

@ -0,0 +1,143 @@
noop
addx 26
addx -21
addx 2
addx 3
noop
noop
addx 23
addx -17
addx -1
noop
noop
addx 7
noop
addx 3
addx 1
noop
noop
addx 2
noop
addx 7
noop
addx -12
addx 13
addx -38
addx 5
addx 34
addx -2
addx -29
addx 2
addx 5
addx 2
addx 3
addx -2
addx -1
addx 8
addx 2
addx 6
addx -26
addx 23
addx -26
addx 33
addx 2
addx -37
addx -1
addx 1
noop
noop
noop
addx 5
addx 5
addx 3
addx -2
addx 2
addx 5
addx 5
noop
noop
addx -2
addx 4
noop
noop
noop
addx 3
noop
noop
addx 7
addx -1
addx -35
addx -1
addx 5
addx 3
noop
addx 4
noop
noop
noop
noop
noop
addx 5
addx 1
noop
noop
noop
addx -7
addx 12
addx 2
addx 7
noop
addx -2
noop
noop
addx 7
addx 2
addx -39
noop
noop
addx 5
addx 2
addx -4
addx 25
addx -18
addx 7
noop
addx -2
addx 5
addx 2
addx 6
addx -5
addx 2
addx -22
addx 29
addx -21
addx -7
addx 31
addx 2
noop
addx -36
addx 1
addx 5
noop
addx 1
addx 4
addx 5
noop
noop
noop
addx 3
noop
addx -13
addx 15
noop
addx 5
noop
addx 1
noop
addx 3
addx 2
addx 4
addx 3
noop
addx -3
noop

165
src/days/day10/mod.rs Normal file
View file

@ -0,0 +1,165 @@
use super::template::{DayTrait, ResultType};
use std::{num::ParseIntError, slice::Iter};
use thiserror::Error;
const DAY_NUMBER: usize = 10;
pub struct Day;
impl DayTrait for Day {
fn get_day_number(&self) -> usize {
DAY_NUMBER
}
fn part1(&self, lines: &[String]) -> anyhow::Result<ResultType> {
let instructions = lines
.iter()
.map(|line| Instruction::parse(line))
.collect::<Result<Vec<_>, _>>()?;
let result = CpuCycles::signal_strength(&instructions, &[20, 60, 100, 140, 180, 220]);
Ok(ResultType::Integer(result as i64))
}
fn part2(&self, lines: &[String]) -> anyhow::Result<ResultType> {
let instructions = lines
.iter()
.map(|line| Instruction::parse(line))
.collect::<Result<Vec<_>, _>>()?;
let result = CpuCycles::draw(&instructions);
Ok(ResultType::Lines(result))
}
}
#[derive(Debug, Error)]
enum CpuError {
#[error("unknown instruction: {0}")]
UnknownInstruction(String),
#[error("could not parse Number")]
InvalidInteger(#[from] ParseIntError),
}
enum Instruction {
Add(i32),
Noop,
}
impl Instruction {
pub fn parse(line: &str) -> Result<Self, CpuError> {
if line == "noop" {
Ok(Instruction::Noop)
} else if line.starts_with("addx") {
let value = line[5..].parse()?;
Ok(Instruction::Add(value))
} else {
Err(CpuError::UnknownInstruction(line.to_owned()))
}
}
}
struct CpuCycles<'a> {
register: i32,
instructions: Iter<'a, Instruction>,
current: Option<i32>,
}
impl<'a> CpuCycles<'a> {
pub fn create(instructions: &'a [Instruction]) -> Self {
Self {
instructions: instructions.iter(),
register: 1,
current: None,
}
}
pub fn signal_strength(instructions: &'a [Instruction], to_collect: &[usize]) -> i32 {
CpuCycles::create(instructions)
.enumerate()
.filter_map(|(cycle, register)| {
if to_collect.contains(&(cycle + 1)) {
Some(register * (cycle + 1) as i32)
} else {
None
}
})
.sum()
}
pub fn draw(instructions: &'a [Instruction]) -> Vec<String> {
let mut result = Vec::new();
let mut line = "".to_owned();
for (cycle, sprite) in CpuCycles::create(instructions).enumerate() {
let cycle = (cycle % 40) as i32;
if (sprite - cycle).abs() <= 1 {
line.push('#');
} else {
line.push(' ');
}
if cycle == 39 {
result.push(line.to_owned());
line = "".to_owned();
}
}
result
}
}
impl<'a> Iterator for CpuCycles<'a> {
type Item = i32;
fn next(&mut self) -> Option<Self::Item> {
if let Some(value) = self.current {
let start_register = self.register;
self.register += value;
self.current = None;
Some(start_register)
} else if let Some(instruction) = self.instructions.next() {
match instruction {
Instruction::Add(value) => self.current = Some(*value),
Instruction::Noop => {}
}
Some(self.register)
} else {
None
}
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::common::file::read_lines;
use anyhow::Result;
#[test]
fn test_simple() -> Result<()> {
let instructions = vec![Instruction::Noop, Instruction::Add(3), Instruction::Add(-5)];
let expected = vec![1, 1, 1, 4, 4];
let result = CpuCycles::create(&instructions).collect::<Vec<_>>();
assert_eq!(result, expected);
Ok(())
}
#[test]
fn test_part1() -> Result<()> {
let day = Day {};
let lines = read_lines(day.get_day_number(), "example01.txt")?;
let expected = ResultType::Integer(13140);
let result = day.part1(&lines)?;
assert_eq!(result, expected);
Ok(())
}
#[test]
fn test_part2() -> Result<()> {
let day = Day {};
let lines = read_lines(day.get_day_number(), "example01.txt")?;
let expected = ResultType::Lines(read_lines(day.get_day_number(), "expected01.txt")?);
let result = day.part2(&lines)?;
assert_eq!(result, expected);
Ok(())
}
}

View file

@ -7,6 +7,7 @@ mod day06;
mod day07;
mod day08;
mod day09;
mod day10;
mod template;
pub use template::DayTrait;
@ -16,7 +17,7 @@ pub mod day_provider {
use super::*;
use thiserror::Error;
const MAX_DAY: usize = 9;
const MAX_DAY: usize = 10;
pub fn get_day(day_num: usize) -> Result<Box<dyn DayTrait>, ProviderError> {
match day_num {
@ -29,6 +30,7 @@ pub mod day_provider {
7 => Ok(Box::new(day07::Day)),
8 => Ok(Box::new(day08::Day)),
9 => Ok(Box::new(day09::Day)),
10 => Ok(Box::new(day10::Day)),
_ => Err(ProviderError::InvalidNumber(day_num)),
}
}

View file

@ -40,7 +40,7 @@ fn output(day: usize, part: usize, result: ResultType, time: Duration) {
time.as_secs_f32()
);
for line in &value[1..] {
println!(" part : {line}");
println!(" {line}");
}
}
ResultType::Nothing => {}