Commit 007390fc authored by Marcel Behrmann's avatar Marcel Behrmann

Merge branch 'master' of gitlab.com:EldoranDev/adventofcode

parents b9da15aa 90c35ea9
target/
\ No newline at end of file
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "day_17"
version = "0.1.0"
[package]
name = "day_17"
version = "0.1.0"
authors = ["Marcel Behrmann <[email protected]>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
1,330,331,332,109,3032,1102,1,1182,16,1101,0,1433,24,102,1,0,570,1006,570,36,1001,571,0,0,1001,570,-1,570,1001,24,1,24,1106,0,18,1008,571,0,571,1001,16,1,16,1008,16,1433,570,1006,570,14,21102,1,58,0,1105,1,786,1006,332,62,99,21101,333,0,1,21101,73,0,0,1106,0,579,1101,0,0,572,1102,0,1,573,3,574,101,1,573,573,1007,574,65,570,1005,570,151,107,67,574,570,1005,570,151,1001,574,-64,574,1002,574,-1,574,1001,572,1,572,1007,572,11,570,1006,570,165,101,1182,572,127,101,0,574,0,3,574,101,1,573,573,1008,574,10,570,1005,570,189,1008,574,44,570,1006,570,158,1105,1,81,21102,1,340,1,1106,0,177,21102,1,477,1,1105,1,177,21102,514,1,1,21101,0,176,0,1106,0,579,99,21101,184,0,0,1105,1,579,4,574,104,10,99,1007,573,22,570,1006,570,165,102,1,572,1182,21101,375,0,1,21101,0,211,0,1105,1,579,21101,1182,11,1,21102,222,1,0,1105,1,979,21101,388,0,1,21101,233,0,0,1105,1,579,21101,1182,22,1,21101,244,0,0,1105,1,979,21101,0,401,1,21102,255,1,0,1105,1,579,21101,1182,33,1,21102,1,266,0,1106,0,979,21102,1,414,1,21102,1,277,0,1106,0,579,3,575,1008,575,89,570,1008,575,121,575,1,575,570,575,3,574,1008,574,10,570,1006,570,291,104,10,21101,0,1182,1,21102,1,313,0,1105,1,622,1005,575,327,1102,1,1,575,21102,1,327,0,1105,1,786,4,438,99,0,1,1,6,77,97,105,110,58,10,33,10,69,120,112,101,99,116,101,100,32,102,117,110,99,116,105,111,110,32,110,97,109,101,32,98,117,116,32,103,111,116,58,32,0,12,70,117,110,99,116,105,111,110,32,65,58,10,12,70,117,110,99,116,105,111,110,32,66,58,10,12,70,117,110,99,116,105,111,110,32,67,58,10,23,67,111,110,116,105,110,117,111,117,115,32,118,105,100,101,111,32,102,101,101,100,63,10,0,37,10,69,120,112,101,99,116,101,100,32,82,44,32,76,44,32,111,114,32,100,105,115,116,97,110,99,101,32,98,117,116,32,103,111,116,58,32,36,10,69,120,112,101,99,116,101,100,32,99,111,109,109,97,32,111,114,32,110,101,119,108,105,110,101,32,98,117,116,32,103,111,116,58,32,43,10,68,101,102,105,110,105,116,105,111,110,115,32,109,97,121,32,98,101,32,97,116,32,109,111,115,116,32,50,48,32,99,104,97,114,97,99,116,101,114,115,33,10,94,62,118,60,0,1,0,-1,-1,0,1,0,0,0,0,0,0,1,18,14,0,109,4,2102,1,-3,587,20101,0,0,-1,22101,1,-3,-3,21102,0,1,-2,2208,-2,-1,570,1005,570,617,2201,-3,-2,609,4,0,21201,-2,1,-2,1106,0,597,109,-4,2106,0,0,109,5,1201,-4,0,630,20102,1,0,-2,22101,1,-4,-4,21101,0,0,-3,2208,-3,-2,570,1005,570,781,2201,-4,-3,652,21001,0,0,-1,1208,-1,-4,570,1005,570,709,1208,-1,-5,570,1005,570,734,1207,-1,0,570,1005,570,759,1206,-1,774,1001,578,562,684,1,0,576,576,1001,578,566,692,1,0,577,577,21101,0,702,0,1105,1,786,21201,-1,-1,-1,1106,0,676,1001,578,1,578,1008,578,4,570,1006,570,724,1001,578,-4,578,21101,0,731,0,1106,0,786,1106,0,774,1001,578,-1,578,1008,578,-1,570,1006,570,749,1001,578,4,578,21101,0,756,0,1105,1,786,1105,1,774,21202,-1,-11,1,22101,1182,1,1,21101,774,0,0,1105,1,622,21201,-3,1,-3,1106,0,640,109,-5,2105,1,0,109,7,1005,575,802,20101,0,576,-6,20101,0,577,-5,1106,0,814,21102,0,1,-1,21102,1,0,-5,21102,0,1,-6,20208,-6,576,-2,208,-5,577,570,22002,570,-2,-2,21202,-5,41,-3,22201,-6,-3,-3,22101,1433,-3,-3,2102,1,-3,843,1005,0,863,21202,-2,42,-4,22101,46,-4,-4,1206,-2,924,21102,1,1,-1,1105,1,924,1205,-2,873,21102,1,35,-4,1105,1,924,1202,-3,1,878,1008,0,1,570,1006,570,916,1001,374,1,374,1201,-3,0,895,1102,2,1,0,1202,-3,1,902,1001,438,0,438,2202,-6,-5,570,1,570,374,570,1,570,438,438,1001,578,558,922,20101,0,0,-4,1006,575,959,204,-4,22101,1,-6,-6,1208,-6,41,570,1006,570,814,104,10,22101,1,-5,-5,1208,-5,39,570,1006,570,810,104,10,1206,-1,974,99,1206,-1,974,1101,0,1,575,21101,973,0,0,1106,0,786,99,109,-7,2105,1,0,109,6,21101,0,0,-4,21102,1,0,-3,203,-2,22101,1,-3,-3,21208,-2,82,-1,1205,-1,1030,21208,-2,76,-1,1205,-1,1037,21207,-2,48,-1,1205,-1,1124,22107,57,-2,-1,1205,-1,1124,21201,-2,-48,-2,1105,1,1041,21101,0,-4,-2,1105,1,1041,21101,-5,0,-2,21201,-4,1,-4,21207,-4,11,-1,1206,-1,1138,2201,-5,-4,1059,2101,0,-2,0,203,-2,22101,1,-3,-3,21207,-2,48,-1,1205,-1,1107,22107,57,-2,-1,1205,-1,1107,21201,-2,-48,-2,2201,-5,-4,1090,20102,10,0,-1,22201,-2,-1,-2,2201,-5,-4,1103,2101,0,-2,0,1106,0,1060,21208,-2,10,-1,1205,-1,1162,21208,-2,44,-1,1206,-1,1131,1105,1,989,21102,1,439,1,1106,0,1150,21102,1,477,1,1105,1,1150,21101,514,0,1,21101,0,1149,0,1106,0,579,99,21102,1,1157,0,1105,1,579,204,-2,104,10,99,21207,-3,22,-1,1206,-1,1138,2101,0,-5,1176,2101,0,-4,0,109,-6,2105,1,0,8,7,34,1,5,1,34,1,5,1,34,1,5,1,32,11,30,1,1,1,5,1,1,1,30,1,1,1,5,7,26,1,1,1,7,1,3,1,26,1,1,1,5,11,22,1,1,1,5,1,1,1,3,1,3,1,16,7,1,9,3,1,3,1,5,1,10,1,13,1,5,1,3,1,5,1,10,1,13,1,5,1,3,1,5,1,10,1,13,1,5,1,3,1,5,1,10,1,13,1,3,7,5,1,10,1,13,1,5,1,9,1,10,1,13,7,9,12,39,12,29,1,10,1,29,1,10,1,29,1,10,1,29,1,8,7,25,1,8,1,1,1,3,1,25,1,4,7,3,1,19,7,4,1,3,1,5,1,19,1,10,1,3,1,5,1,19,1,10,1,3,1,5,1,19,1,10,1,3,1,5,1,7,7,5,1,10,1,3,1,5,1,7,1,5,1,5,1,10,11,7,1,5,1,5,1,14,1,13,1,5,1,5,1,14,7,7,1,5,1,5,1,20,1,7,1,5,1,5,1,20,1,7,1,5,7,20,1,7,1,32,1,7,1,32,1,7,1,32,9,18
\ No newline at end of file
use crate::utils;
use std::collections::VecDeque;
#[allow(dead_code)]
pub struct IntVM {
pub rom: Vec<i64>,
pub input: VecDeque<i64>,
pub output: VecDeque<i64>,
pub memory: Vec<i64>,
pub instr_ptr: usize,
pub is_halted: bool,
pub is_waiting_input: bool,
pub print_output: bool,
pub relative_offset: i64,
update_pointer: bool,
tick_length: usize,
}
impl IntVM {
#[allow(dead_code)]
pub fn reset(&mut self) {
self.memory = self.rom.clone();
self.instr_ptr = 0;
self.is_halted = false;
}
#[allow(dead_code)]
pub fn set_mem(&mut self, address: usize, value: i64) {
self.memory[address] = value;
}
pub fn get_input(&mut self, arg_count: usize) -> i64 {
let instruction = self.memory[self.instr_ptr];
let mode = (instruction / (10 as i64).pow((arg_count + 2) as u32)) % 10;
if arg_count + 2 > self.tick_length {
self.tick_length = arg_count + 2;
}
match mode {
0 => self.memory[self.memory[self.instr_ptr + 1 + arg_count] as usize],
1 => self.memory[self.instr_ptr + 1 + arg_count],
2 => self.memory[(self.relative_offset + self.memory[self.instr_ptr+1+arg_count]) as usize],
_ => self.memory[self.memory[self.instr_ptr + 1 + arg_count] as usize],
}
}
pub fn get_target(&mut self, arg_count: usize) -> usize {
if arg_count + 2 > self.tick_length {
self.tick_length = arg_count + 2;
}
let instruction = self.memory[self.instr_ptr];
let mode = (instruction / (10 as i64).pow((arg_count + 2) as u32)) % 10;
if arg_count + 2 > self.tick_length {
self.tick_length = arg_count + 2;
}
match mode {
2 => (self.relative_offset + self.memory[self.instr_ptr+1+arg_count]) as usize,
_ => self.memory[self.instr_ptr + arg_count + 1] as usize,
}
}
pub fn jump(&mut self, addr: usize) {
self.instr_ptr = addr;
self.update_pointer = false;
}
fn pre_tick(&mut self) {
self.update_pointer = true;
self.tick_length = 0;
}
fn post_tick(&mut self) {
if self.update_pointer {
self.instr_ptr = self.instr_ptr + self.tick_length;
}
}
#[allow(dead_code)]
pub fn tick(&mut self) {
if self.is_halted || self.is_waiting_input {
return;
}
self.pre_tick();
let op: i64 = self.memory[self.instr_ptr] % 100;
match op {
1 => {
let a = self.get_input(0);
let b = self.get_input(1);
let target = self.get_target(2);
self.set_mem(target, a + b);
},
2 => {
let a = self.get_input(0);
let b = self.get_input(1);
let target = self.get_target(2);
self.set_mem(target, a * b);
},
3 => {
let target = self.get_target(0);
if self.input.len() == 0 {
self.is_waiting_input = true;
return;
}
self.memory[target] = self.input.pop_front().expect("No input provieded?!");
},
4 => {
let target = self.get_input(0);
self.output.push_back(target as i64);
if self.print_output {
println!("OUT: {}", target);
}
},
5 => {
let a = self.get_input(0);
let b = self.get_input(1);
if a != 0 {
self.jump(b as usize);
}
},
6 => {
let a = self.get_input(0);
let b = self.get_input(1);
if a == 0 {
self.jump(b as usize);
}
},
7 => {
let a = self.get_input(0);
let b = self.get_input(1);
let target = self.get_target(2);
if a < b {
self.memory[target] = 1;
} else {
self.memory[target] = 0;
}
},
8 => {
let a = self.get_input(0);
let b = self.get_input(1);
let target = self.get_target(2);
if a == b {
self.memory[target] = 1;
} else {
self.memory[target] = 0;
}
},
9 => {
let a = self.get_input(0);
self.relative_offset += a;
},
99 => {
self.is_halted = true;
},
_ => {
println!("Unknown OPCode ({}, {}, {}, {}) update IntVM", op, self.memory[self.instr_ptr + 1], self.memory[self.instr_ptr + 2], self.memory[self.instr_ptr + 3]);
self.is_halted = true;
},
}
self.post_tick();
}
#[allow(dead_code)]
pub fn get_output(&mut self) -> i64 {
return self.memory[0];
}
#[allow(dead_code)]
pub fn run(&mut self) -> i64 {
self.is_waiting_input = false;
while !self.is_halted && !self.is_waiting_input {
self.tick()
};
self.get_output()
}
}
#[allow(dead_code)]
pub fn create_vm(input: &Vec<&str>) -> IntVM {
let mut vm = IntVM {
rom: utils::vec_to_int(input.clone()),
print_output: false,
instr_ptr: 0,
is_halted: false,
is_waiting_input: false,
memory: utils::vec_to_int(input.clone()),
input: VecDeque::new(),
output: VecDeque::new(),
relative_offset: 0,
update_pointer: true,
tick_length: 0,
};
for _ in 0..(1000 * 1024) {
vm.memory.push(0);
}
vm
}
\ No newline at end of file
mod utils;
mod intvm;
use std::{thread, time};
use std::fs;
use std::collections::{HashMap, VecDeque};
const INPUT_FILE: &str = "input.txt";
const SHOW_GAME: bool = true;
fn main() {
let file = &fs::read_to_string(INPUT_FILE).expect("Error reading input");
let input = get_input(file);
println!("Result part 1: {}", part_01(&input));
println!("Result part 2: {}", part_02(&input));
}
fn get_input(input: &String) -> Vec<&str> {
let codes = input.split(",");
codes.collect::<Vec<&str>>()
}
fn part_01(input: &Vec<&str>) -> i64{
let mut vm = intvm::create_vm(input);
let mut map: HashMap<(i64, i64), u8> = HashMap::new();
let mut max_x = 0;
let mut max_y = 0;
while !vm.is_halted {
vm.run();
let mut y = 0;
let mut x = 0;
while vm.output.len() > 0 {
let point = vm.output.pop_front().unwrap() as u8;
map.insert((x, y), point);
if x > max_x {
max_x = x + 1;
}
if y > max_y {
max_y = y;
}
match point {
10 => {
y += 1;
x = 0;
},
_ => {
x += 1;
}
};
}
map.insert((max_x, max_y), 10);
let intersections = get_intersections(&map, max_x, max_y);
draw_map(&map, max_x, max_y);
let mut sum = 0;
for int in intersections {
sum += int.0 * int.1;
}
return sum;
}
0
}
fn get_intersections(map: &HashMap<(i64, i64), u8>, x: i64, y: i64) -> Vec<(i64, i64)> {
let targets = vec![(0, 1), (1, 0), (0, -1), (-1, 0)];
let mut intersections: Vec<(i64, i64)> = Vec::new();
for y in 0..y {
for x in 0..x {
let p = (x, y);
let pp = *map.get(&p).or(Some(&0)).unwrap();
if pp == 35 {
let mut intersection = true;
for target in &targets {
let t = *map.get(&(p.0 + target.0, p.1 + target.1)).or(Some(&0)).unwrap();
if t != 35 {
intersection = false;
break;
}
}
if intersection {
intersections.push((x, y));
}
}
}
}
intersections
}
fn draw_map(map: &HashMap<(i64, i64), u8>, x: i64, y: i64) -> () {
if !SHOW_GAME {
return;
}
for y in 0..y {
for x in 0..x {
print!("{}", *map.get(&(x, y)).or(Some(&64)).unwrap() as char);
}
}
}
#[allow(unused_variables)]
fn part_02(input: &Vec<&str>) -> i64{
let mut vm = intvm::create_vm(input);
// Wake up robot
vm.set_mem(0, 2);
vm.run();
print_output(&mut vm);
writeln_input(&mut vm, "A,B,A,B,C,A,B,C,A,C");
vm.run();
print_output(&mut vm);
writeln_input(&mut vm, "R,6,L,6,L,10");
vm.run();
print_output(&mut vm);
writeln_input(&mut vm, "L,8,L,6,L,10,L,6");
vm.run();
print_output(&mut vm);
writeln_input(&mut vm, "R,6,L,8,L,10,R,6");
vm.run();
print_output(&mut vm);
writeln_input(&mut vm, "n");
while !vm.is_halted {
vm.run();
}
vm.output.pop_back().unwrap()
}
fn print_output(vm: &mut intvm::IntVM) {
while vm.output.len() > 0 {
print!("{}", (vm.output.pop_front().unwrap() as u8) as char);
}
}
fn writeln_input(vm: &mut intvm::IntVM, input: &str) {
for c in input.chars() {
vm.input.push_back(c as i64);
}
vm.input.push_back(10);
}
/*
input.push_str("A,B,A,B,C,A,B,C,A,C");
input.push('\n');
input.push_str("R6,L6,L10");
input.push('\n');
input.push_str("L8,L6,L10,L6");
input.push('\n');
input.push_str("R6,L8,L10,R6");
input.push('\n');
input.push('y');
input.push('\n');
*/
\ No newline at end of file
#[allow(dead_code)]
pub fn vec_to_int(input: Vec<&str>) -> Vec<i64> {
input
.into_iter()
.map(|line| { line.parse().expect("erro reading input") })
.collect()
}
#[allow(dead_code)]
pub fn vec_to_float(input: Vec<&str>) -> Vec<f64> {
input
.into_iter()
.map(|line| { line.parse().expect("erro reading input") })
.collect()
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment