Allow subtraction to underflow

This commit is contained in:
viridian 2024-05-10 13:02:53 +02:00
parent 87d554f8e8
commit 1e2cee55a5
Signed by: viridian
GPG key ID: DCD4DF95CE23FE8C

View file

@ -1,4 +1,5 @@
use std::{ use std::{
io::Read,
ops::{Add, Sub}, ops::{Add, Sub},
process::exit, process::exit,
usize, usize,
@ -56,7 +57,7 @@ fn main() {
} }
} }
#[derive(Debug)] #[derive(Debug, Clone)]
struct Machine { struct Machine {
instruction_pointer: usize, instruction_pointer: usize,
data_pointer: usize, data_pointer: usize,
@ -64,8 +65,7 @@ struct Machine {
instructions: Vec<Instruction>, instructions: Vec<Instruction>,
} }
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Default, Clone, Copy, PartialEq)]
struct Cell { struct Cell {
value: u8, value: u8,
} }
@ -91,6 +91,7 @@ impl Machine {
fn step(&mut self) -> MachineState { fn step(&mut self) -> MachineState {
let instruction = self.instructions.get(self.instruction_pointer).unwrap(); let instruction = self.instructions.get(self.instruction_pointer).unwrap();
match instruction { match instruction {
Instruction::BINC => self.binc(), Instruction::BINC => self.binc(),
Instruction::BDEC => self.bdec(), Instruction::BDEC => self.bdec(),
@ -178,12 +179,10 @@ impl Machine {
fn inp(&mut self) { fn inp(&mut self) {
let mut input = String::new(); let mut input = String::new();
std::io::stdin().read_line(&mut input).unwrap(); std::io::stdin().take(1).read_to_string(&mut input).unwrap();
let value = input.as_bytes().first().unwrap().to_owned();
let value = *input.into_bytes().first().unwrap();
let cell = Cell { value }; let cell = Cell { value };
self.data[self.data_pointer] = cell; self.data[self.data_pointer] = cell;
} }
@ -230,25 +229,36 @@ impl Machine {
std::io::stdin().read_line(&mut input).unwrap(); std::io::stdin().read_line(&mut input).unwrap();
let repetitions: usize = input.trim().parse().unwrap(); let repetitions: usize = input.trim().parse().unwrap();
if repetitions > 10000000 {
let bar = indicatif::ProgressBar::new(repetitions as u64); let bar = indicatif::ProgressBar::new(repetitions as u64);
bar.set_style( bar.set_style(
ProgressStyle::with_template( ProgressStyle::with_template(
"{bar:40} | {human_pos}/{human_len} | {eta_precise} | {elapsed_precise}", "{bar:40} | {human_pos}/{human_len} | {eta_precise} | {elapsed_precise} | {per_sec}",
) )
.unwrap(), .unwrap(),
); );
for _ in 0..repetitions { for _ in 0..repetitions {
bar.inc(1); bar.inc(1);
match self.step() { match self.step() {
MachineState::Ok => continue, MachineState::Ok => continue,
MachineState::EOI => { MachineState::EOI => {
self.instruction_pointer -= 1; self.instruction_pointer -= 1;
break; break;
}
}
}
bar.finish();
} else {
for _ in 0..repetitions {
match self.step() {
MachineState::Ok => continue,
MachineState::EOI => {
self.instruction_pointer -= 1;
break;
}
} }
} }
} }
bar.finish();
} }
} }
@ -266,17 +276,13 @@ impl Sub for Cell {
type Output = Cell; type Output = Cell;
fn sub(self, rhs: Self) -> Self::Output { fn sub(self, rhs: Self) -> Self::Output {
if self.value == 0 { Cell {
Cell { value: 0 } value: self.value - rhs.value,
} else {
Cell {
value: self.value - rhs.value,
}
} }
} }
} }
#[allow(clippy::upper_case_acronyms)] #[allow(clippy::upper_case_acronyms)]
#[derive(PartialEq, Eq, Debug)] #[derive(PartialEq, Eq, Debug, Clone)]
enum Instruction { enum Instruction {
PINC, // > PINC, // >
PDEC, // < PDEC, // <