Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::io::Error;
- #[derive(PartialEq)]
- enum State {
- Active,
- Halted,
- }
- struct Computer {
- step: usize,
- data: Vec<i32>,
- state: State,
- input_buffer: Vec<i32>
- }
- impl Computer {
- fn new(input_file: &str, ids: Vec<i32>) -> Computer {
- let data = std::fs::read_to_string(input_file).unwrap()
- .trim()
- .split(",")
- .map(|s| s.to_string())
- .map(|s| s.parse::<i32>().unwrap())
- .collect::<Vec<i32>>();
- Computer {
- step: 0,
- data,
- state: State::Active,
- input_buffer: ids,
- }
- }
- fn start(&mut self) {
- println!("Started...");
- while self.state != State::Halted {
- match self.data[self.step] % 100 {
- 1 => self.opcode_1(),
- 2 => self.opcode_2(),
- 3 => self.opcode_3(),
- 4 => self.opcode_4(),
- 5 => self.opcode_5(),
- 6 => self.opcode_6(),
- 7 => self.opcode_7(),
- 8 => self.opcode_8(),
- 99 => self.opcode_99(),
- n => panic!("No such code {}", n),
- }
- }
- }
- fn opcode_1(&mut self) {
- let (mode1, mode2, mode3) = Computer::extract_modes(self.data[self.step]);
- let index1 = self.setting_index_by_mode(1, mode1);
- let index2 = self.setting_index_by_mode(2, mode2);
- let index3 = self.setting_index_by_mode(3, mode3);
- self.data[index3] = self.data[index1] + self.data[index2];
- self.step += 4;
- }
- fn opcode_2(&mut self) {
- let (mode1, mode2, mode3) = Computer::extract_modes(self.data[self.step]);
- let index1 = self.setting_index_by_mode(1, mode1);
- let index2 = self.setting_index_by_mode(2, mode2);
- let index3 = self.setting_index_by_mode(3, mode3);
- self.data[index3] = self.data[index1] * self.data[index2];
- self.step += 4;
- }
- fn opcode_3(&mut self) {
- let (mode1, _, _) = Computer::extract_modes(self.data[self.step]);
- let index1 = self.setting_index_by_mode(1, mode1);
- self.data[index1] = self.input_buffer.pop().unwrap();
- self.step += 2;
- }
- fn opcode_4(&mut self) {
- let (mode1, _, _) = Computer::extract_modes(self.data[self.step]);
- let index1 = self.setting_index_by_mode(1, mode1);
- println!("Data on position {} is {}", index1, self.data[index1]);
- self.step += 2;
- }
- fn opcode_5(&mut self) {
- let (mode1, mode2, _) = Computer::extract_modes(self.data[self.step]);
- let index1 = self.setting_index_by_mode(1, mode1);
- let index2 = self.setting_index_by_mode(2, mode2);
- if self.data[index1] != 0 {
- self.step = self.data[index2] as usize
- } else {
- self.step += 3
- };
- }
- fn opcode_6(&mut self) {
- let (mode1, mode2, _) = Computer::extract_modes(self.data[self.step]);
- let index1 = self.setting_index_by_mode(1, mode1);
- let index2 = self.setting_index_by_mode(2, mode2);
- if self.data[index1] == 0 {
- self.step = self.data[index2] as usize
- } else {
- self.step += 3
- };
- }
- fn opcode_7(&mut self) {
- let (mode1, mode2, mode3) = Computer::extract_modes(self.data[self.step]);
- let index1 = self.setting_index_by_mode(1, mode1);
- let index2 = self.setting_index_by_mode(2, mode2);
- let index3 = self.setting_index_by_mode(3, mode3);
- self.data[index3] = if self.data[index1] < self.data[index2] {
- 1
- } else {
- 0
- };
- self.step += 4;
- }
- fn opcode_8(&mut self) {
- let (mode1, mode2, mode3) = Computer::extract_modes(self.data[self.step]);
- let index1 = self.setting_index_by_mode(1, mode1);
- let index2 = self.setting_index_by_mode(2, mode2);
- let index3 = self.setting_index_by_mode(3, mode3);
- self.data[index3] = if self.data[index1] == self.data[index2] {
- 1
- } else {
- 0
- };
- self.step += 4;
- }
- fn opcode_99(&mut self) {
- self.state = State::Halted;
- }
- fn extract_modes(op_code: i32) -> (i32, i32, i32){
- (
- op_code / 100 % 10,
- op_code / 1000 % 10,
- op_code / 10000 % 10,
- )
- }
- fn setting_index_by_mode(&mut self, offset: usize, mode: i32) -> usize {
- if mode == 0 {
- self.data[self.step + offset] as usize
- } else if mode == 1 {
- self.step + offset
- } else {
- panic!("Mode does not exist");
- }
- }
- }
- fn solution1(input_file: &str) -> Result<(), Error> {
- let mut computer = Computer::new(input_file, vec![1]);
- computer.start();
- Ok(())
- }
- fn solution2(input_file: &str) -> Result<(), Error> {
- let mut computer = Computer::new(input_file, vec![5]);
- computer.start();
- Ok(())
- }
- fn main() -> Result<(), Error> {
- solution1("input.txt")?;
- solution2("input.txt")?;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement