Select Git revision
telegram_bot.py
Forked from
Uni-Film-Club / Programm-Info-Bot
Source project has a limited visibility.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
main.rs 3.21 KiB
use std::fs::File;
use std::io::{self, prelude::*, BufReader};
#[derive(Debug, Clone)]
struct Instruction {
operation: Operation,
argument: i64,
}
#[derive(Debug, Clone, PartialEq)]
enum Operation {
Increment,
Jump,
Nothing,
}
#[derive(Debug, PartialEq)]
enum Reason {
LoopDetected,
Terminated,
}
impl Instruction {
fn from_str(input: &str) -> Self {
let (op, arg) = input.split_at(4);
let operation = match op {
"acc " => Operation::Increment,
"jmp " => Operation::Jump,
"nop " => Operation::Nothing,
_ => panic!(),
};
let argument = arg.parse::<i64>().unwrap();
Instruction {
operation: operation,
argument: argument,
}
}
pub fn apply(&self, accumulator: i64, index: isize) -> (i64, isize) {
match self.operation {
Operation::Increment => (accumulator + self.argument, index.checked_add(1).unwrap()),
Operation::Jump => (accumulator, index.checked_add(self.argument as isize).unwrap()),
Operation::Nothing => (accumulator, index.checked_add(1).unwrap()),
}
}
}
fn compute(instructions: &Vec<Instruction>) -> (Reason, i64) {
let mut accumulator = 0;
let mut index: isize = 0;
let mut visited_indices = vec![];
loop {
if visited_indices.contains(&index) {
// prevent looping
return (Reason::LoopDetected, accumulator);
}
visited_indices.push(index);
if index as usize == instructions.len() {
// code run through
return (Reason::Terminated, accumulator);
}
let result = instructions[index as usize].apply(accumulator, index);
accumulator = result.0;
index = result.1;
}
}
fn main() -> io::Result<()> {
println!("Advent of Code 2020 – Day 8:");
let file = File::open("input.txt")?;
let reader = BufReader::new(file);
let instructions = reader
.lines()
.map(|l| Instruction::from_str(&l.unwrap()))
.collect::<Vec<Instruction>>();
let answer1: i64 = compute(&instructions).1;
println!("Answer Part 1: {}", answer1);
let mut answer2: i64 = 100;
for index in 0..(instructions.len()-1) {
let mut instruction = instructions[index].clone();
if instruction.operation == Operation::Increment {
// don't need to change and don't need to run
continue;
}
instruction = match instruction.operation {
Operation::Jump => Instruction {
operation: Operation::Nothing,
argument: instruction.argument,
},
Operation::Nothing => Instruction {
operation: Operation::Jump,
argument: instruction.argument,
},
_ => unimplemented!()
};
let mut mutated_instructions = instructions.clone();
mutated_instructions[index] = instruction;
let value = compute(&mutated_instructions);
if value.0 == Reason::Terminated {
// answer found
answer2 = value.1;
break;
}
}
println!("Answer Part 2: {}", answer2);
Ok(())
}