Skip to content

Commit da4b159

Browse files
committed
feat: well, that sucked. Added day 9
1 parent d8fa155 commit da4b159

File tree

8 files changed

+401
-98
lines changed

8 files changed

+401
-98
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@
1111
- [Day 6](https://github.com/ankjevel/adventofcode/tree/2019/day_06) 🌟 🌟
1212
- [Day 7](https://github.com/ankjevel/adventofcode/tree/2019/day_07) 🌟 🌟
1313
- [Day 8](https://github.com/ankjevel/adventofcode/tree/2019/day_08) 🌟 🌟
14+
- [Day 9](https://github.com/ankjevel/adventofcode/tree/2019/day_09) 🌟 🌟

day_05/src/bin/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ fn main() -> Result<()> {
66

77
println!(
88
"part_01: {:?}",
9-
exec_without_channels(input[0].clone(), None)
9+
exec_without_channels(input[0].clone(), Some(vec![1]))
1010
);
1111
println!(
1212
"part_02: {:?}",

day_05/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
pub fn parse_input(string: &str) -> Vec<Vec<i32>> {
1+
pub fn parse_input(string: &str) -> Vec<Vec<i64>> {
22
string
33
.lines()
44
.map(|string| string.trim())
55
.filter(|string| !string.is_empty())
66
.map(|string| {
77
string
88
.split(',')
9-
.map(|part| part.parse::<i32>().unwrap())
10-
.collect::<Vec<i32>>()
9+
.map(|part| part.parse::<i64>().unwrap())
10+
.collect::<Vec<i64>>()
1111
})
1212
.collect()
1313
}

day_05/src/program.rs

Lines changed: 111 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -5,58 +5,94 @@ use std::{
55
thread::{spawn, JoinHandle},
66
};
77

8+
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
9+
enum Mode {
10+
Position,
11+
Immediate,
12+
Relative,
13+
}
14+
815
pub struct Program {
9-
original_memory: Vec<i32>,
16+
original_memory: Vec<i64>,
1017
pointer: usize,
11-
input: Receiver<i32>,
18+
relative_base: usize,
19+
input: Receiver<i64>,
1220
halted: bool,
13-
output: Sender<i32>,
14-
output_value: i32,
15-
pub memory: Vec<i32>,
21+
output: Sender<i64>,
22+
output_value: i64,
23+
pub memory: Vec<i64>,
1624
}
1725

1826
impl Program {
19-
pub fn new(memory: &Vec<i32>) -> Program {
27+
pub fn new(memory: &Vec<i64>) -> Program {
2028
let (output, input) = channel();
2129

2230
Program {
2331
original_memory: memory.clone(),
2432
pointer: 0,
2533
output_value: 0,
34+
relative_base: 0,
2635
input,
2736
halted: false,
2837
memory: memory.clone(),
2938
output,
3039
}
3140
}
3241

33-
pub fn new_input(&mut self, input: Receiver<i32>) {
34-
self.input = input;
42+
pub fn new_input(&mut self, receiver: Receiver<i64>) {
43+
self.input = receiver;
3544
}
3645

37-
pub fn new_output(&mut self, output: Sender<i32>) {
38-
self.output = output;
46+
pub fn new_output(&mut self, sender: Sender<i64>) {
47+
self.output = sender;
3948
}
4049

4150
pub fn is_halted(&self) -> bool {
4251
self.halted
4352
}
4453

45-
fn get_index(&mut self, step: usize, positional: bool) -> usize {
46-
if positional {
47-
self.memory[self.pointer + step] as usize
48-
} else {
49-
self.pointer + step
54+
fn get_index(&mut self, step: usize, mode: Mode) -> usize {
55+
match mode {
56+
Mode::Position => self.memory[self.pointer + step] as usize,
57+
Mode::Immediate => self.pointer + step,
58+
Mode::Relative => self.memory[self.pointer + step] as usize,
59+
}
60+
}
61+
62+
fn ensure_memory_available(&mut self, position: &usize) {
63+
if *position >= self.memory.len() {
64+
self.memory.resize(position + 1, 0);
5065
}
5166
}
5267

53-
fn mode_1_2(&mut self, opcode: i32, positional_first: bool, positional_second: bool) -> usize {
54-
let noun_index = self.get_index(1, positional_first);
55-
let verb_index = self.get_index(2, positional_second);
56-
let out_index = self.get_index(3, true);
57-
let noun = self.memory[noun_index];
58-
let verb = self.memory[verb_index];
59-
self.memory[out_index] = if opcode == 1 {
68+
fn get_memory<'a>(&'a mut self, step: usize, mode: Mode) -> i64 {
69+
let next = match mode {
70+
Mode::Relative => {
71+
let index = &(self.pointer + step);
72+
self.ensure_memory_available(&index);
73+
self.memory[*index].to_owned() + (self.relative_base as i64)
74+
}
75+
_ => {
76+
let index = &self.get_index(step, mode);
77+
self.ensure_memory_available(&index);
78+
self.memory[*index]
79+
}
80+
};
81+
82+
next
83+
}
84+
85+
fn get_mut_memory_ref<'a>(&'a mut self, index: &'a usize) -> &'a mut i64 {
86+
self.ensure_memory_available(&index);
87+
&mut self.memory[*index]
88+
}
89+
90+
fn mode_1_2(&mut self, opcode: i64, mode_first: Mode, mode_second: Mode) -> i64 {
91+
let noun = self.get_memory(1, mode_first);
92+
let verb = self.get_memory(2, mode_second);
93+
let index = &self.get_index(3, Mode::Position);
94+
95+
*self.get_mut_memory_ref(index) = if opcode == 1 {
6096
noun + verb
6197
} else {
6298
noun * verb
@@ -65,72 +101,71 @@ impl Program {
65101
4
66102
}
67103

68-
fn mode_3_4(&mut self, opcode: i32) -> usize {
69-
let index = self.get_index(1, true);
104+
fn mode_3_4(&mut self, opcode: i64, mode: Mode) -> i64 {
70105
if opcode == 3 {
71106
let input = self.input.recv().unwrap_or(0);
72-
self.memory[index] = input.to_owned();
107+
let index = &self.get_index(1, Mode::Position);
108+
*self.get_mut_memory_ref(index) = input.to_owned();
73109
} else {
74-
let output = self.memory[index].clone();
110+
let output = self.get_memory(1, mode);
75111
self.output.send(output.to_owned()).unwrap_or(());
76112
self.output_value = output.to_owned();
77113
};
78114

79115
2
80116
}
81117

82-
fn mode_5_6(
83-
&mut self,
84-
opcode: i32,
85-
position_mode_first: bool,
86-
position_mode_second: bool,
87-
) -> usize {
88-
let first_index = self.get_index(1, position_mode_first);
89-
let second_index = self.get_index(2, position_mode_second);
90-
let param_1 = self.memory[first_index];
91-
let param_2 = self.memory[second_index];
118+
fn mode_5_6(&mut self, opcode: i64, mode_first: Mode, mode_second: Mode) -> i64 {
119+
let param_1 = self.get_memory(1, mode_first);
120+
let param_2 = self.get_memory(2, mode_second);
92121

93122
if (opcode == 5 && param_1 != 0) || (opcode == 6 && param_1 == 0) {
94-
param_2 as usize - self.pointer
123+
param_2 - self.pointer as i64
95124
} else {
96125
3
97126
}
98127
}
99128

100-
fn mode_7_8(
101-
&mut self,
102-
opcode: i32,
103-
position_mode_first: bool,
104-
position_mode_second: bool,
105-
) -> usize {
106-
let first_index = self.get_index(1, position_mode_first);
107-
let second_index = self.get_index(2, position_mode_second);
108-
let third_index = self.get_index(3, true);
129+
fn mode_7_8(&mut self, opcode: i64, mode_first: Mode, mode_second: Mode) -> i64 {
130+
let a = self.get_memory(1, mode_first);
131+
let b = self.get_memory(2, mode_second);
132+
let index = &self.get_index(3, Mode::Position);
109133

110-
let a = self.memory[first_index];
111-
let b = self.memory[second_index];
112-
113-
self.memory[third_index] = if (opcode == 7 && a < b) || (opcode == 8 && a == b) {
134+
*self.get_mut_memory_ref(index) = if (opcode == 7 && a < b) || (opcode == 8 && a == b) {
114135
1
115136
} else {
116137
0
117138
};
118139
4
119140
}
120141

121-
fn to_int(&mut self, input: &char) -> i32 {
122-
(&input.to_string()).parse::<i32>().unwrap()
142+
fn mode_9(&mut self, mode: Mode) -> i64 {
143+
let memory = self.get_memory(1, mode) as usize;
144+
let relative_base = self.relative_base + memory as usize;
145+
146+
self.relative_base = relative_base;
147+
2
148+
}
149+
150+
fn to_int(&mut self, input: &char) -> i64 {
151+
(&input.to_string()).parse::<i64>().unwrap()
123152
}
124153

125-
fn position_mode(&mut self, input: &Option<char>) -> bool {
126-
input.unwrap_or('0') == '0'
154+
fn mode(&mut self, input: &Option<char>) -> Mode {
155+
match input.unwrap_or('0') {
156+
'0' => Mode::Position,
157+
'1' => Mode::Immediate,
158+
'2' => Mode::Relative,
159+
_ => Mode::Position,
160+
}
127161
}
128162

129-
pub fn run(&mut self) -> i32 {
163+
pub fn run(&mut self) -> i64 {
130164
self.pointer = 0;
131165
self.output_value = 0;
132166
self.halted = false;
133167
self.memory = self.original_memory.clone();
168+
self.relative_base = 0;
134169

135170
while !self.halted {
136171
self.eval()
@@ -151,48 +186,48 @@ impl Program {
151186
let mut instuction = string.chars().rev();
152187
let opcode = self.to_int(&instuction.next().unwrap());
153188
instuction.next();
154-
let positional_first = self.position_mode(&instuction.next());
155-
let positional_second = self.position_mode(&instuction.next());
156-
157-
self.pointer += match opcode {
158-
1 | 2 => self.mode_1_2(opcode, positional_first, positional_second),
159-
3 | 4 => self.mode_3_4(opcode),
160-
5 | 6 => self.mode_5_6(opcode, positional_first, positional_second),
161-
7 | 8 => self.mode_7_8(opcode, positional_first, positional_second),
162-
9 => {
163-
self.halted = true;
164-
0
165-
}
189+
let mode_first = self.mode(&instuction.next());
190+
let mode_second = self.mode(&instuction.next());
191+
192+
let next = match opcode {
193+
1 | 2 => self.mode_1_2(opcode, mode_first, mode_second),
194+
3 | 4 => self.mode_3_4(opcode, mode_first),
195+
5 | 6 => self.mode_5_6(opcode, mode_first, mode_second),
196+
7 | 8 => self.mode_7_8(opcode, mode_first, mode_second),
197+
9 => self.mode_9(mode_first),
166198
_ => panic!("[{}], opcode: {}", self.pointer, opcode),
167199
};
200+
201+
self.pointer = ((self.pointer as i64) + next) as usize;
168202
}
169203
}
170204

171-
pub fn exec(memory: Vec<i32>, input: Receiver<i32>, output: Sender<i32>) -> JoinHandle<i32> {
205+
pub fn exec(memory: Vec<i64>, receiver: Receiver<i64>, sender: Sender<i64>) -> JoinHandle<i64> {
172206
spawn(move || {
173207
let mut program = Program::new(&memory);
174-
program.new_input(input);
175-
program.new_output(output);
208+
program.new_input(receiver);
209+
program.new_output(sender);
176210
program.run()
177211
})
178212
}
179213

180-
pub fn exec_without_channels(memory: Vec<i32>, input: Option<Vec<i32>>) -> i32 {
181-
let (c_out, c_in) = channel();
214+
pub fn exec_without_channels(memory: Vec<i64>, input: Option<Vec<i64>>) -> i64 {
215+
let (sender, receiver) = channel();
182216
match input {
183217
Some(input) => {
184218
for seq in input.clone() {
185-
c_out.send(seq).unwrap();
219+
sender.send(seq).unwrap();
186220
}
187221
}
188222
None => {
189-
c_out.send(0).unwrap();
223+
sender.send(0).unwrap();
190224
}
191225
};
226+
192227
spawn(move || {
193228
let mut program = Program::new(&memory);
194-
program.new_input(c_in);
195-
program.new_output(c_out);
229+
program.new_input(receiver);
230+
program.new_output(sender);
196231
program.run()
197232
})
198233
.join()

day_07/src/main.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use day_05::{
88
use permute::permute;
99
use std::{iter::Iterator, sync::mpsc::channel};
1010

11-
fn part_01(sequence: &Vec<i32>, memory: &Vec<i32>) -> i32 {
11+
fn part_01(sequence: &Vec<i64>, memory: &Vec<i64>) -> i64 {
1212
let mut input = vec![0];
1313
for signal in sequence {
1414
input.insert(0, signal.to_owned());
@@ -20,28 +20,28 @@ fn part_01(sequence: &Vec<i32>, memory: &Vec<i32>) -> i32 {
2020
input[0]
2121
}
2222

23-
fn part_02(sequence: &Vec<i32>, memory: &Vec<i32>) -> i32 {
23+
fn part_02(sequence: &Vec<i64>, memory: &Vec<i64>) -> i64 {
2424
let mut seq = sequence.to_owned();
2525
let mut iter = seq.iter_mut();
2626

27-
let (e_out, a_in) = channel();
28-
let (a_out, b_in) = channel();
29-
let (b_out, c_in) = channel();
30-
let (c_out, d_in) = channel();
31-
let (d_out, e_in) = channel();
27+
let (e_sender, a_receiver) = channel();
28+
let (a_sender, b_receiver) = channel();
29+
let (b_sender, c_receiver) = channel();
30+
let (c_sender, d_receiver) = channel();
31+
let (d_sender, e_receiver) = channel();
3232

33-
e_out.send(*iter.next().unwrap()).unwrap();
34-
a_out.send(*iter.next().unwrap()).unwrap();
35-
b_out.send(*iter.next().unwrap()).unwrap();
36-
c_out.send(*iter.next().unwrap()).unwrap();
37-
d_out.send(*iter.next().unwrap()).unwrap();
38-
e_out.send(0).unwrap();
33+
e_sender.send(*iter.next().unwrap()).unwrap();
34+
a_sender.send(*iter.next().unwrap()).unwrap();
35+
b_sender.send(*iter.next().unwrap()).unwrap();
36+
c_sender.send(*iter.next().unwrap()).unwrap();
37+
d_sender.send(*iter.next().unwrap()).unwrap();
38+
e_sender.send(0).unwrap();
3939

40-
exec(memory.clone(), a_in, a_out);
41-
exec(memory.clone(), b_in, b_out);
42-
exec(memory.clone(), c_in, c_out);
43-
exec(memory.clone(), d_in, d_out);
44-
exec(memory.clone(), e_in, e_out).join().unwrap()
40+
exec(memory.clone(), a_receiver, a_sender);
41+
exec(memory.clone(), b_receiver, b_sender);
42+
exec(memory.clone(), c_receiver, c_sender);
43+
exec(memory.clone(), d_receiver, d_sender);
44+
exec(memory.clone(), e_receiver, e_sender).join().unwrap()
4545
}
4646

4747
fn main() {

day_09/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "day_09"
3+
version = "0.1.0"
4+
authors = ["Dennis Pettersson <mail@dennispettersson.se>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
day_05 = { path = "../day_05" }

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