Skip to content

Instantly share code, notes, and snippets.

@solson
Forked from anonymous/playground.rs
Created December 18, 2017 06:20
Show Gist options
  • Select an option

  • Save solson/70be8725d689de0e4681795dd4eaa4c0 to your computer and use it in GitHub Desktop.

Select an option

Save solson/70be8725d689de0e4681795dd4eaa4c0 to your computer and use it in GitHub Desktop.
Rust code shared from the playground
use std::collections::VecDeque;
const _INPUT_1: &str = "\
set a 1
add a 2
mul a a
mod a 5
snd a
set a 0
rcv a
jgz a -1
set a 1
jgz a -2\
";
const _INPUT_2: &str = "\
snd 1
snd 2
snd p
rcv a
rcv b
rcv c
rcv d\
";
const _INPUT: &str = "\
set i 31
set a 1
mul p 17
jgz p p
mul a 2
add i -1
jgz i -2
add a -1
set i 127
set p 680
mul p 8505
mod p a
mul p 129749
add p 12345
mod p a
set b p
mod b 10000
snd b
add i -1
jgz i -9
jgz a 3
rcv b
jgz b -1
set f 0
set i 126
rcv a
rcv b
set p a
mul p -1
add p b
jgz p 4
snd a
set a b
jgz 1 3
snd b
set f 1
add i -1
jgz i -11
snd a
jgz f -16
jgz a -19\
";
fn reg_index(reg: &str) -> usize {
(reg.as_bytes()[0] - b'a') as usize
}
fn value_of(arg: &str, regs: &mut [i64; 26]) -> i64 {
arg.parse::<i64>().unwrap_or_else(|_| {
regs[reg_index(arg)]
})
}
fn main() {
let program: Vec<&str> = _INPUT.split('\n').collect();
let mut regs = [[0i64; 26]; 2];
let mut pos = [0i64; 2];
let mut recv_queue = [VecDeque::new(), VecDeque::new()];
let mut waiting = [None::<usize>; 2];
let mut p = 0;
let mut p1_send_counter = 0;
regs[0][reg_index("p")] = 0;
regs[1][reg_index("p")] = 1;
'main: while waiting[0].is_none() || waiting[1].is_none() {
p = 1 - p;
'thread: while pos[p] >= 0 && pos[p] < program.len() as i64 {
if let Some(reg) = waiting[p] {
if let Some(value) = recv_queue[p].pop_front() {
regs[p][reg] = value;
waiting[p] = None;
pos[p] += 1;
} else {
continue 'main;
}
}
// println!("{}: {}", p, program[pos[p] as usize]);
let mut words = program[pos[p] as usize].split_whitespace();
let op = words.next().unwrap();
let arg1 = words.next().unwrap();
let arg2 = words.next();
match (op, arg1, arg2) {
("snd", arg, None) => {
if p == 1 {
p1_send_counter += 1;
}
recv_queue[1 - p].push_back(value_of(arg, &mut regs[p]));
}
("rcv", reg, None) => {
waiting[p] = Some(reg_index(reg));
continue 'thread;
}
("set", reg, Some(arg)) => {
regs[p][reg_index(reg)] = value_of(arg, &mut regs[p]);
}
("add", reg, Some(arg)) => {
regs[p][reg_index(reg)] += value_of(arg, &mut regs[p]);
}
("mul", reg, Some(arg)) => {
regs[p][reg_index(reg)] *= value_of(arg, &mut regs[p]);
}
("mod", reg, Some(arg)) => {
regs[p][reg_index(reg)] %= value_of(arg, &mut regs[p]);
}
("jgz", cond, Some(arg)) => {
if value_of(cond, &mut regs[p]) > 0 {
pos[p] += value_of(arg, &mut regs[p]);
continue 'main;
}
}
_ => unreachable!(),
}
pos[p] += 1;
continue 'main;
}
}
println!("{}", p1_send_counter);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment