Skip to content

Commit fa3c9a5

Browse files
committed
chore: had to update example on day 9 to handle channels
1 parent f99a1f2 commit fa3c9a5

File tree

10 files changed

+229
-52
lines changed

10 files changed

+229
-52
lines changed

day_09/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
extern crate day_05;
2+
3+
pub mod program;

day_09/src/main.rs

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,64 @@
1-
extern crate day_05;
2-
3-
mod program;
4-
1+
use ::day_09::program::exec;
52
use day_05::parse_input;
63

7-
use program::exec;
8-
94
fn main() {
105
let input = parse_input(include_str!("../../input/day_09"));
11-
println!("part_01, {:?}", exec(&input[0], Some(vec![1])));
12-
println!("part_02, {:?}", exec(&input[0], Some(vec![2])));
6+
println!("part_01, {:?}", exec(input[0].clone(), Some(vec![1])));
7+
println!("part_02, {:?}", exec(input[0].clone(), Some(vec![2])));
138
}
149

1510
#[cfg(test)]
1611
mod tests {
17-
use super::*;
12+
use ::day_09::program::{exec, Program};
13+
use day_05::parse_input;
14+
use std::{sync::mpsc::channel, thread::spawn};
1815

1916
const EXAMPLES_ON_PART_01: &'static str = "
2017
1102,34915192,34915192,7,4,7,99,0
2118
104,1125899906842624,99
2219
";
2320

2421
#[test]
25-
#[ignore]
2622
fn it_gets_the_examples_right_on_part_01() {
2723
let input = parse_input(&EXAMPLES_ON_PART_01);
2824

29-
assert_eq!(exec(&input[1], None), 1219070632396864);
30-
assert_eq!(exec(&input[2], None), 1125899906842624);
25+
assert_eq!(exec(input[0].clone(), None), 1219070632396864);
26+
assert_eq!(exec(input[1].clone(), None), 1125899906842624);
3127
}
3228

3329
#[test]
3430
fn quine() {
31+
let (b_sender, a_receiver) = channel();
32+
let (_, b_receiver) = channel();
33+
34+
let output_thread = spawn(move || {
35+
let mut output = vec![];
36+
loop {
37+
let new_output = match a_receiver.recv() {
38+
Ok(val) => val,
39+
_ => break,
40+
};
41+
&output.push(new_output);
42+
}
43+
output.to_owned()
44+
});
45+
3546
let input = vec![
3647
109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101, 0, 99,
3748
];
38-
let mut program = program::Program::new(&input);
39-
program.input = vec![];
40-
assert_eq!(program.run(), 99);
41-
assert_eq!(program.output, input.clone());
49+
50+
let thread_input = input.clone();
51+
let result = spawn(move || {
52+
let mut program = Program::new(&thread_input);
53+
program.new_input(b_receiver);
54+
program.new_output(b_sender);
55+
program.run()
56+
})
57+
.join()
58+
.unwrap();
59+
60+
assert_eq!(result, 99);
61+
62+
assert_eq!(output_thread.join().unwrap(), input.clone());
4263
}
4364
}

day_09/src/program.rs

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
use std::{iter::Iterator, option::Option};
1+
use std::{
2+
iter::Iterator,
3+
option::Option,
4+
sync::mpsc::{channel, Receiver, Sender},
5+
thread::spawn,
6+
};
27

38
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
49
enum Mode {
@@ -12,29 +17,34 @@ pub struct Program {
1217
pointer: usize,
1318
relative_base: usize,
1419
halted: bool,
15-
pub input: Vec<i64>,
16-
pub output: Vec<i64>,
20+
input: Receiver<i64>,
21+
output: Sender<i64>,
22+
output_value: i64,
1723
pub memory: Vec<i64>,
1824
}
1925

2026
impl Program {
2127
pub fn new(memory: &Vec<i64>) -> Program {
28+
let (output, input) = channel();
29+
2230
Program {
2331
original_memory: memory.clone(),
2432
pointer: 0,
2533
relative_base: 0,
26-
input: vec![0],
34+
input,
2735
halted: false,
2836
memory: memory.clone(),
29-
output: vec![],
37+
output,
38+
output_value: 0,
3039
}
3140
}
3241

33-
fn get_next_input(&mut self) -> Option<i64> {
34-
match self.input.iter_mut().next() {
35-
Some(input) => Some(*input),
36-
_ => None,
37-
}
42+
pub fn new_input(&mut self, receiver: Receiver<i64>) {
43+
self.input = receiver;
44+
}
45+
46+
pub fn new_output(&mut self, sender: Sender<i64>) {
47+
self.output = sender;
3848
}
3949

4050
fn get_index(&mut self, step: usize, mode: Mode) -> usize {
@@ -108,15 +118,12 @@ impl Program {
108118

109119
fn opcode_3_4(&mut self, opcode: i64, mode: Mode) -> i64 {
110120
if opcode == 3 {
111-
match self.get_next_input() {
112-
Some(input) => {
113-
*self.get_mut_memory_ref(1, mode) = input;
114-
}
115-
_ => {}
116-
}
121+
let input = self.input.recv().unwrap_or(0);
122+
*self.get_mut_memory_ref(1, mode) = input;
117123
} else {
118124
let output = self.get_memory(1, mode);
119-
self.output.push(output);
125+
self.output.send(output.to_owned()).unwrap();
126+
self.output_value = output;
120127
};
121128
2
122129
}
@@ -160,16 +167,16 @@ impl Program {
160167

161168
pub fn run(&mut self) -> i64 {
162169
self.pointer = 0;
170+
self.output_value = 0;
163171
self.halted = false;
164172
self.memory = self.original_memory.clone();
165173
self.relative_base = 0;
166-
self.output.clear();
167174

168175
while !self.halted {
169-
self.eval()
176+
self.eval();
170177
}
171178

172-
*self.output.clone().iter().last().unwrap_or(&0i64)
179+
self.output_value.to_owned()
173180
}
174181

175182
fn eval(&mut self) {
@@ -183,7 +190,6 @@ impl Program {
183190
let mode_second = self.mode(&instuction.next());
184191
let mode_third = self.mode(&instuction.next());
185192

186-
187193
if opcode == 9 && opcode_padding == 9 {
188194
self.halted = true;
189195
return;
@@ -202,13 +208,25 @@ impl Program {
202208
}
203209
}
204210

205-
pub fn exec(memory: &Vec<i64>, input: Option<Vec<i64>>) -> i64 {
206-
let input_unwrapped = match input {
207-
Some(input) => input.to_owned(),
208-
None => vec![0],
211+
pub fn exec(memory: Vec<i64>, output: Option<Vec<i64>>) -> i64 {
212+
let (program_sender, _exec_reciever) = channel();
213+
let (exec_sender, program_receiver) = channel();
214+
215+
match output {
216+
Some(vec) => {
217+
vec.into_iter().for_each(|val| {
218+
exec_sender.send(val).unwrap();
219+
});
220+
}
221+
None => {}
209222
};
210223

211-
let mut program = Program::new(memory);
212-
program.input = input_unwrapped;
213-
program.run()
224+
let handle = spawn(move || {
225+
let mut program = Program::new(&memory);
226+
program.new_input(program_receiver);
227+
program.new_output(program_sender);
228+
program.run()
229+
});
230+
231+
handle.join().unwrap()
214232
}

day_11/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ edition = "2018"
77
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
88

99
[dependencies]
10+
day_09 = { path = "../day_09" }

day_11/src/direction.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
2+
pub enum Dir {
3+
Up,
4+
Right,
5+
Down,
6+
Left,
7+
}
8+
9+
use Dir::*;
10+
11+
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
12+
pub struct Direction(pub Dir);
13+
14+
impl Direction {
15+
pub fn new() -> Direction {
16+
Direction(Up)
17+
}
18+
19+
pub fn turn(&mut self, turn: u8) {
20+
self.0 = match (self.0, turn) {
21+
(Up, 0) | (Down, 1) => Left,
22+
(Right, 0) | (Left, 1) => Up,
23+
(Down, 0) | (Up, 1) => Right,
24+
(Left, 0) | (Right, 1) => Down,
25+
_ => panic!("turn not covered"),
26+
}
27+
}
28+
}

day_11/src/intcode.rs

Lines changed: 0 additions & 2 deletions
This file was deleted.

day_11/src/lib.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
extern crate day_09;
2+
3+
pub mod direction;
4+
pub mod painting_robot;
5+
pub mod point;
6+
17
pub fn parse_input(input: &str) -> Vec<i64> {
28
input
39
.lines()
@@ -8,4 +14,4 @@ pub fn parse_input(input: &str) -> Vec<i64> {
814
.split(',')
915
.map(|part| part.parse::<i64>().unwrap())
1016
.collect::<Vec<i64>>()
11-
}
17+
}

day_11/src/main.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,26 @@
1-
use ::day_11::{parse_input};
1+
use ::day_11::{painting_robot::Robot, parse_input};
2+
use day_09::program::Program;
3+
use std::{sync::mpsc::channel, thread::spawn};
24

35
fn main() {
4-
let input = parse_input(&include_str!("../../input/day_11"));
5-
println!("{:?}", input);
6+
let (b_sender, a_receiver) = channel();
7+
let (a_sender, b_receiver) = channel();
8+
9+
let mut program = Program::new(&parse_input(&include_str!("../../input/day_11")));
10+
let mut robot = Robot::new(a_receiver, a_sender);
11+
12+
spawn(move || {
13+
program.new_input(b_receiver);
14+
program.new_output(b_sender);
15+
program.run();
16+
});
17+
18+
let part_01_output = spawn(move || robot.run()).join().unwrap();
19+
println!("part_01, {}", part_01_output);
20+
// let mut robot = Robot::new(&instructions);
21+
// println!("part_01: {:?}", robot.run());
622
}
723

824
#[cfg(test)]
925
#[allow(dead_code)]
10-
mod tests {
11-
}
26+
mod tests {}

day_11/src/painting_robot.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
use crate::direction::{Dir::*, Direction};
2+
use crate::point::Point;
3+
use std::{
4+
collections::HashSet,
5+
sync::mpsc::{Receiver, Sender},
6+
};
7+
8+
pub struct Robot {
9+
position: Point,
10+
direction: Direction,
11+
input: Receiver<i64>,
12+
output: Sender<i64>,
13+
visited: HashSet<Point>,
14+
whites: HashSet<Point>,
15+
}
16+
17+
impl Robot {
18+
pub fn new(receiver: Receiver<i64>, sender: Sender<i64>) -> Robot {
19+
let position = Point { x: 0, y: 0 };
20+
let mut visited = HashSet::new();
21+
let mut whites = HashSet::new();
22+
23+
visited.insert(position.clone());
24+
whites.insert(position.clone());
25+
26+
Robot {
27+
input: receiver,
28+
output: sender,
29+
direction: Direction::new(),
30+
position,
31+
visited,
32+
whites,
33+
}
34+
}
35+
36+
fn move_position(&mut self) {
37+
let x = self.position.x;
38+
let y = self.position.y;
39+
40+
self.position = match self.direction.0 {
41+
Up => Point { x, y: y + 1 },
42+
Right => Point { x: x + 1, y },
43+
Down => Point { x, y: y - 1 },
44+
Left => Point { x: x - 1, y },
45+
}
46+
}
47+
48+
pub fn run(&mut self) -> usize {
49+
loop {
50+
let over_white_panel = self.whites.contains(&self.position);
51+
self.output
52+
.send(if over_white_panel { 1 } else { 0 })
53+
.unwrap();
54+
55+
let next_color = match self.input.recv() {
56+
Ok(0) => 0u8,
57+
Ok(1) => 1u8,
58+
_ => break,
59+
};
60+
61+
if next_color == 0 {
62+
self.whites.remove(&self.position);
63+
} else {
64+
self.whites.insert(self.position.clone());
65+
}
66+
67+
let next_position = match self.input.recv() {
68+
Ok(0) => 0u8,
69+
Ok(1) => 1u8,
70+
_ => break,
71+
};
72+
73+
self.direction.turn(next_position);
74+
self.move_position();
75+
self.visited.insert(self.position.clone());
76+
}
77+
78+
self.visited.len()
79+
}
80+
}

day_11/src/point.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
2+
pub struct Point {
3+
pub x: i64,
4+
pub y: i64,
5+
}
6+
7+
impl Point {}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy