Compare commits
2 Commits
0089f4337c
...
0f9d48314e
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f9d48314e | |||
| 14fc032ffc |
1
input/day25.txt
Normal file
1
input/day25.txt
Normal file
File diff suppressed because one or more lines are too long
@@ -3,5 +3,5 @@ extern crate core;
|
||||
mod tasks;
|
||||
|
||||
fn main() {
|
||||
tasks::day23::run();
|
||||
tasks::day16::run();
|
||||
}
|
||||
|
||||
@@ -1,16 +1,30 @@
|
||||
use itertools::Itertools;
|
||||
use num_integer::Integer;
|
||||
use std::collections::HashMap;
|
||||
use std::iter;
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
const BASE_PATTERN: [i32; 4] = [0, 1, 0, -1];
|
||||
const INPUT: &str = "59750530221324194853012320069589312027523989854830232144164799228029162830477472078089790749906142587998642764059439173975199276254972017316624772614925079238407309384923979338502430726930592959991878698412537971672558832588540600963437409230550897544434635267172603132396722812334366528344715912756154006039512272491073906389218927420387151599044435060075148142946789007756800733869891008058075303490106699737554949348715600795187032293436328810969288892220127730287766004467730818489269295982526297430971411865028098708555709525646237713045259603175397623654950719275982134690893685598734136409536436003548128411943963263336042840301380655801969822";
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn run() {
|
||||
let input = to_digits(INPUT);
|
||||
task1(input.clone());
|
||||
task2(to_digits("02935109699940807407585447034323"));
|
||||
task2(input.clone());
|
||||
}
|
||||
|
||||
fn task1(input: Vec<V>) -> String {
|
||||
let mut s = S { input, cache: HashMap::new() };
|
||||
s.prep();
|
||||
let result = format!("{:.*}", 8, (0..8).map(|position| {
|
||||
let r = s.get(position, 100);
|
||||
r
|
||||
}).join(""));
|
||||
println!("Task 1: {result}");
|
||||
result
|
||||
}
|
||||
|
||||
fn to_digits(input: &str) -> Vec<i32> {
|
||||
input
|
||||
.chars()
|
||||
@@ -18,71 +32,88 @@ fn to_digits(input: &str) -> Vec<i32> {
|
||||
.collect_vec()
|
||||
}
|
||||
|
||||
fn task1(input: Vec<i32>) -> String {
|
||||
let p = [0, 1, 0, -1];
|
||||
let result = (0..100).fold(input, |old, _| {
|
||||
(1..=old.len())
|
||||
.map(|position| {
|
||||
let pattern = p
|
||||
.iter()
|
||||
.map(|x| std::iter::repeat(*x).take(position))
|
||||
.flatten();
|
||||
let val: i32 = old
|
||||
.iter()
|
||||
.zip(std::iter::repeat(pattern).flatten().skip(1))
|
||||
.map(|(value, multiplier)| value * multiplier)
|
||||
.sum();
|
||||
val.abs() % 10
|
||||
})
|
||||
.collect_vec()
|
||||
});
|
||||
let result = format!("{:.*}", 8, result.iter().join(""));
|
||||
println!("Task 1: {result}");
|
||||
fn task2(input: Vec<i32>) -> String {
|
||||
let big_input = iter::repeat(input.clone().into_iter())
|
||||
.take(10_000)
|
||||
.flatten()
|
||||
.collect_vec();
|
||||
|
||||
let mut s = S { input: big_input, cache: HashMap::new() };
|
||||
let result_position = format!("{}", input.split_at(7).0.iter().join("")).parse::<usize>().unwrap();
|
||||
s.prep_after(result_position);
|
||||
let result = format!("{:.*}", 8, (0..8).map(|position| {
|
||||
let r = s.get(position + result_position, 100);
|
||||
r
|
||||
}).join(""));
|
||||
|
||||
println!("Task 2: {result}");
|
||||
result
|
||||
}
|
||||
|
||||
fn task2(input: Vec<i32>) -> String {
|
||||
let l = input.len() * 10_000;
|
||||
let big_input = iter::repeat(input.clone().into_iter())
|
||||
.flatten()
|
||||
.take(l)
|
||||
.collect_vec();
|
||||
let p = [0, 1, 0, -1];
|
||||
let result = (0..100).fold(big_input, |old, _| {
|
||||
(1..=old.len())
|
||||
.map(|position| {
|
||||
let pattern = p.iter().map(|x| iter::repeat(*x).take(position)).flatten();
|
||||
let iter = iter::repeat(pattern).flatten().skip(1);
|
||||
let repeats_after = (4 * position).lcm(&input.len());
|
||||
if repeats_after > l {
|
||||
l
|
||||
} else {
|
||||
repeats_after
|
||||
};
|
||||
let part: i32 = iter::repeat(input.iter())
|
||||
.flatten()
|
||||
.zip(iter.clone())
|
||||
.take(repeats_after)
|
||||
.map(|(value, multiplier)| value * multiplier)
|
||||
.sum();
|
||||
let part_fits = l / repeats_after;
|
||||
let most_parts = part * part_fits as i32;
|
||||
type V = i32;
|
||||
|
||||
let number_rest = l / repeats_after;
|
||||
let part_rest: i32 = iter
|
||||
.zip(iter::repeat(input.iter()).flatten())
|
||||
.take(number_rest)
|
||||
.map(|(value, multiplier)| value * multiplier)
|
||||
.sum();
|
||||
struct S {
|
||||
input: Vec<V>,
|
||||
cache: HashMap<(usize, usize), V>,
|
||||
}
|
||||
|
||||
(part_rest + most_parts) % 10
|
||||
})
|
||||
.collect_vec()
|
||||
});
|
||||
let offset = input[0..7].iter().join("").parse::<usize>().unwrap();
|
||||
let message = result[offset..offset + 8].iter().join("");
|
||||
println!("Task 2: {}", message);
|
||||
message
|
||||
impl S {
|
||||
fn pattern(&self, position: usize, size: usize) -> Vec<i32> {
|
||||
let pattern = BASE_PATTERN.iter().map(|x| iter::repeat(*x).take(position)).flatten();
|
||||
let iter = iter::repeat(pattern).flatten().skip(1).take(size);
|
||||
iter.collect()
|
||||
}
|
||||
|
||||
fn get(&mut self, index: usize, phase: usize) -> V {
|
||||
if phase == 0 {
|
||||
return self.input[index];
|
||||
}
|
||||
|
||||
if self.cache.contains_key(&(phase, index)) {
|
||||
return self.cache[&(phase, index)];
|
||||
}
|
||||
|
||||
if index == self.input.len() - 1 {
|
||||
let v = self.get(index, phase - 1);
|
||||
self.cache.insert((phase, index), v);
|
||||
return v;
|
||||
}
|
||||
|
||||
if index > (self.input.len() / 2 + 1) {
|
||||
let v = self.get(index + 1, phase) + self.get(index, phase - 1);
|
||||
let v = v.abs() % 10;
|
||||
self.cache.insert((phase, index), v);
|
||||
return v;
|
||||
}
|
||||
|
||||
let pattern = self.pattern(index + 1, self.input.len());
|
||||
let val: i32 = pattern
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, p)| if *p == 0 { 0 } else { *p * self.get(i, phase - 1) })
|
||||
.sum();
|
||||
let result = val.abs() % 10;
|
||||
self.cache.insert((phase, index), result);
|
||||
result
|
||||
}
|
||||
|
||||
fn prep(&mut self) {
|
||||
for phase in 1..=100 {
|
||||
for i in 1..self.input.len() / 2 {
|
||||
self.get(self.input.len() - i, phase);
|
||||
}
|
||||
}
|
||||
println!("preparation done")
|
||||
}
|
||||
|
||||
fn prep_after(&mut self, start: usize) {
|
||||
for phase in 1..=100 {
|
||||
for i in (start..self.input.len()).rev() {
|
||||
self.get(i, phase);
|
||||
}
|
||||
}
|
||||
println!("preparation done")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -104,13 +135,30 @@ mod test {
|
||||
"52432133"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_1_solution() {
|
||||
assert_eq!(task1(to_digits(INPUT)), "84487724");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_2() {
|
||||
fn test_part_2_solution() {
|
||||
assert_eq!(task2(to_digits(INPUT)), "84692524");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trivial() {
|
||||
let mut s = S { input: to_digits("12345678"), cache: HashMap::new() };
|
||||
s.prep();
|
||||
let result = format!("{:.*}", 8, (0..8).map(|position| {
|
||||
let r = s.get(position, 1);
|
||||
r
|
||||
}).join(""));
|
||||
assert_eq!(result, "48226158");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_2_examples() {
|
||||
assert_eq!(
|
||||
task2(to_digits("02935109699940807407585447034323")),
|
||||
"78725270"
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::collections::VecDeque;
|
||||
|
||||
use crate::tasks::day05::{IntCodeComputer, load_ram, RAM};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn run() {
|
||||
let ram = load_ram("input/day23.txt");
|
||||
part1(ram.clone());
|
||||
|
||||
44
src/tasks/day25.rs
Normal file
44
src/tasks/day25.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
use std::io;
|
||||
|
||||
use crate::tasks::day05::{IntCodeComputer, load_ram};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn run() {
|
||||
let ram = load_ram("input/day25.txt");
|
||||
let mut computer = IntCodeComputer::new(vec![], ram);
|
||||
|
||||
loop {
|
||||
let done = computer.run_until_input_empty();
|
||||
println!("{}", to_ascii(computer.get_output()));
|
||||
computer.clear_output();
|
||||
|
||||
if done {
|
||||
println!("Game Over");
|
||||
return;
|
||||
}
|
||||
|
||||
let input = read_line();
|
||||
computer.set_input(&input);
|
||||
}
|
||||
|
||||
// needed items:
|
||||
// fixed point
|
||||
// polygon
|
||||
// candy cane
|
||||
// shell
|
||||
|
||||
// result: 136839232
|
||||
}
|
||||
|
||||
fn to_ascii(output: &[i128]) -> String {
|
||||
output.iter().map(|i| (*i as u8) as char).collect()
|
||||
}
|
||||
|
||||
fn read_line() -> Vec<i128> {
|
||||
let mut buffer = String::new();
|
||||
io::stdin().read_line(&mut buffer).unwrap();
|
||||
if !buffer.is_ascii() {
|
||||
panic!("'{}' is not ascii input", buffer);
|
||||
}
|
||||
buffer.chars().map(|c| c as i128).collect()
|
||||
}
|
||||
@@ -22,3 +22,4 @@ pub mod day21;
|
||||
pub mod day22;
|
||||
pub mod day23;
|
||||
pub mod day24;
|
||||
pub mod day25;
|
||||
|
||||
Reference in New Issue
Block a user