Compare commits
3 Commits
79ea3c29d0
...
0089f4337c
| Author | SHA1 | Date | |
|---|---|---|---|
| 0089f4337c | |||
| c8cef9c0ce | |||
| 420b6152fb |
1
input/day23.txt
Normal file
1
input/day23.txt
Normal file
File diff suppressed because one or more lines are too long
@@ -3,5 +3,5 @@ extern crate core;
|
|||||||
mod tasks;
|
mod tasks;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
tasks::day20::run();
|
tasks::day23::run();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -217,6 +217,7 @@ impl IntCodeComputer {
|
|||||||
op.params[0].store(&mut self.ram, *v, self.relative_base_offset);
|
op.params[0].store(&mut self.ram, *v, self.relative_base_offset);
|
||||||
self.pc += 2;
|
self.pc += 2;
|
||||||
} else {
|
} else {
|
||||||
|
self.input_storage.clear();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -282,10 +283,24 @@ impl IntCodeComputer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_input(&mut self, input: &[i128]) {
|
||||||
|
for x in input {
|
||||||
|
self.input_storage.push(*x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_input(&self) -> &[i128] {
|
||||||
|
self.input_storage.as_slice()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn clear_output(&mut self) {
|
pub fn clear_output(&mut self) {
|
||||||
self.output_storage.clear();
|
self.output_storage.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn clear_n_output(&mut self, n: usize) {
|
||||||
|
self.output_storage = Vec::from(self.output_storage.split_at(n).1);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_output(&self) -> &[i128] {
|
pub fn get_output(&self) -> &[i128] {
|
||||||
self.output_storage.as_slice()
|
self.output_storage.as_slice()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use std::collections::{HashMap, HashSet, VecDeque};
|
use std::collections::{HashMap, HashSet, VecDeque};
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
let input = std::fs::read_to_string("input/day20.txt").unwrap();
|
let input = std::fs::read_to_string("input/day20.txt").unwrap();
|
||||||
let maze = Maze::from(&input, PortalField::curried_factory);
|
let maze = Maze::from(&input, PortalField::curried_factory);
|
||||||
|
|||||||
99
src/tasks/day23.rs
Normal file
99
src/tasks/day23.rs
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
|
use crate::tasks::day05::{IntCodeComputer, load_ram, RAM};
|
||||||
|
|
||||||
|
pub fn run() {
|
||||||
|
let ram = load_ram("input/day23.txt");
|
||||||
|
part1(ram.clone());
|
||||||
|
part2(ram.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1(ram: RAM) {
|
||||||
|
let mut computers: Vec<IntCodeComputer> = (0..50).map(|address| IntCodeComputer::new(vec![address], ram.clone())).collect();
|
||||||
|
let mut buffer: VecDeque<Packet> = VecDeque::new();
|
||||||
|
loop {
|
||||||
|
for computer in &mut computers {
|
||||||
|
computer.add_input(&[-1]);
|
||||||
|
computer.run_until_input_empty();
|
||||||
|
if computer.get_output().len() >= 3 {
|
||||||
|
buffer.push_back(Packet::from(&computer.get_output()[0..3]));
|
||||||
|
computer.clear_n_output(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some(packet) = buffer.pop_front() {
|
||||||
|
if packet.destination == 255 {
|
||||||
|
println!("Part 1: Finished with first y={} to 255", packet.y);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
computers[packet.destination].add_input(packet.to_input().as_slice());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(ram: RAM) {
|
||||||
|
let mut computers: Vec<IntCodeComputer> = (0..50).map(|address| IntCodeComputer::new(vec![address], ram.clone())).collect();
|
||||||
|
let mut buffer: VecDeque<Packet> = VecDeque::new();
|
||||||
|
|
||||||
|
let mut rounds_without_packets = 0;
|
||||||
|
let mut nat_content: Option<Packet> = None;
|
||||||
|
let mut pushed_to_first: Vec<Packet> = Vec::new();
|
||||||
|
loop {
|
||||||
|
for computer in &mut computers {
|
||||||
|
if computer.get_input().is_empty() {
|
||||||
|
computer.add_input(&[-1, -1, -1]);
|
||||||
|
}
|
||||||
|
computer.run_until_input_empty();
|
||||||
|
while computer.get_output().len() >= 3 {
|
||||||
|
buffer.push_back(Packet::from(&computer.get_output()[0..3]));
|
||||||
|
computer.clear_n_output(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if buffer.is_empty() {
|
||||||
|
rounds_without_packets += 1;
|
||||||
|
}
|
||||||
|
if let Some(ref energy_packet) = nat_content {
|
||||||
|
if rounds_without_packets > 5 {
|
||||||
|
if let Some(last) = pushed_to_first.last() {
|
||||||
|
if last == energy_packet {
|
||||||
|
println!("Part 2: Got the same packet twice. Y was {}", last.y);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pushed_to_first.push(energy_packet.clone());
|
||||||
|
buffer.push_back(energy_packet.clone());
|
||||||
|
rounds_without_packets = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while let Some(packet) = buffer.pop_front() {
|
||||||
|
if packet.destination == 255 {
|
||||||
|
nat_content = Some(Packet { destination: 0, x: packet.x, y: packet.y });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
computers[packet.destination].add_input(packet.to_input().as_slice());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
|
struct Packet {
|
||||||
|
destination: usize,
|
||||||
|
x: i128,
|
||||||
|
y: i128,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Packet {
|
||||||
|
fn from(slice: &[i128]) -> Packet {
|
||||||
|
if slice.len() != 3 {
|
||||||
|
panic!("not enough for a packet")
|
||||||
|
}
|
||||||
|
Packet { destination: slice[0] as usize, x: slice[1], y: slice[2] }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_input(&self) -> Vec<i128> {
|
||||||
|
vec![self.x, self.y]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,4 +20,5 @@ pub mod day20;
|
|||||||
pub mod day21;
|
pub mod day21;
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub mod day22;
|
pub mod day22;
|
||||||
|
pub mod day23;
|
||||||
pub mod day24;
|
pub mod day24;
|
||||||
|
|||||||
Reference in New Issue
Block a user