Submission details
Task:Tulkki
Sender:madde
Submission time:2026-10-22 14:36:40 +0300
Language:Rust (2021)
Status:COMPILE ERROR

Compiler report

error[E0658]: use of unstable library feature 'byte_slice_trim_ascii'
  --> input/code.rs:28:25
   |
28 |         let line = line.trim_ascii();
   |                         ^^^^^^^^^^
   |
   = note: see issue #94035 <https://github.com/rust-lang/rust/issues/94035> for more information

error[E0599]: no function or associated item named `from_utf8` found for type `str` in the current scope
  --> input/code.rs:60:26
   |
60 |                     str::from_utf8(line).unwrap()
   |                          ^^^^^^^^^ function or associated item not found in `str`
   |
help: you are looking for the module in `std`, not the primitive type
   |
60 |                     std::str::from_utf8(line).unwrap()
   |                     +++++

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0599, E0658.
For more information about an error, try `rustc --explain E0599`.

Code

#![allow(clippy::print_with_newline)]
use std::{
    fs::{self},
    io::Write,
};
#[derive(Debug, Clone, Copy, PartialEq)]
enum Instruction {
    Clear(u8),
    Increase(u8),
    Print(u8),
    LoopStart(u8),
    LoopClose(u8),
}

#[derive(Clone)]
struct Loop {
    loop_var: u8,
    start_point: u16,
    current_loop_var: u32,
    depth: u8,
}

fn parse<'a>(input: impl Iterator<Item = &'a [u8]>) -> (Vec<Instruction>, Vec<Loop>) {
    let mut instructions = Vec::with_capacity(1024);
    let mut loops = Vec::new();
    let mut depth = 0;
    for (line_num, line) in input.enumerate() {
        let line = line.trim_ascii();
        if line.iter().next() == Some(&b'#') {
            continue;
        }
        match line.split(|b| *b == b' ').collect::<Box<_>>().as_ref() {
            [b"CLEAR", var] => instructions.push(Instruction::Clear(var_idx(var[0]) as u8)),
            [b"INCREASE", var] => instructions.push(Instruction::Increase(var_idx(var[0]) as u8)),
            [b"PRINT", var] => instructions.push(Instruction::Print(var_idx(var[0]) as u8)),
            [b"REPEAT", var, _, _] => {
                depth += 1;
                loops.push(Loop {
                    loop_var: var_idx(var[0]) as u8,
                    start_point: instructions.len() as u16,
                    current_loop_var: 0,
                    depth,
                });
                instructions.push(Instruction::LoopStart(loops.len() as u8 - 1));
            }
            [b")"] => {
                instructions.push(Instruction::LoopClose(
                    loops
                        .iter()
                        .enumerate()
                        .rfind(|(_, l)| l.depth == depth)
                        .unwrap()
                        .0 as u8,
                ));
                depth -= 1;
            }
            _ => {
                println!(
                    "syntax error on line {line_num}: \"{}\" starting execution",
                    str::from_utf8(line).unwrap()
                );
                break;
            }
        }
    }
    (instructions, loops)
}

fn main() {
    let (instructions, loops) = if let Some(file) = std::env::args().nth(1) {
        let file = fs::read(file).expect("invalid source file");
        let input = file.split(|b| *b == b'\n');
        parse(input)
    } else {
        let file = std::io::stdin();
        parse(
            file.lines()
                .map(|l| l.expect("couldnt read stdin line").leak().as_bytes()),
        )
    };
    println!(
        "instructions executed: {}",
        (1..=1000)
            .into_iter()
            .map(|x| run(&instructions, loops.clone(), x))
            .sum::<u32>()
    )
}

fn run(instructions: &[Instruction], mut loops: Vec<Loop>, input: u32) -> u32 {
    let mut instruction_pointer = 0usize;
    let mut vars = [0u32; 26];
    vars[var_idx(b'X')] = input;
    let mut counter = 0;
    while instruction_pointer < instructions.len() {
        let instruction = instructions[instruction_pointer];
        match instruction {
            Instruction::Clear(var) => vars[var as usize] = 0,
            Instruction::Increase(var) => vars[var as usize] += 1,
            Instruction::Print(var) => {
                print!("{}\n", vars[var as usize])
            }
            Instruction::LoopStart(idx) => {
                let this_loop = &mut loops[idx as usize];
                let iterations = vars[this_loop.loop_var as usize];
                if iterations > 0 {
                    this_loop.current_loop_var = iterations;
                } else {
                    while instructions[instruction_pointer] != Instruction::LoopClose(idx) {
                        instruction_pointer += 1;
                    }
                }
            }
            Instruction::LoopClose(idx) => {
                let this_loop = &mut loops[idx as usize];
                this_loop.current_loop_var -= 1;
                if this_loop.current_loop_var > 0 {
                    instruction_pointer = this_loop.start_point as usize;
                }
            }
        }
        instruction_pointer += 1;
        counter += 1;
    }
    std::io::stdout().flush().unwrap();
    counter
}

fn var_idx(name: u8) -> usize {
    (name - b'A') as usize
}