Skip to content
This repository was archived by the owner on Jun 26, 2025. It is now read-only.

Commit 1c3a22e

Browse files
committed
Added new question: bytecode interpreter
1 parent 95ab80d commit 1c3a22e

File tree

5 files changed

+706
-0
lines changed

5 files changed

+706
-0
lines changed

competition/bytecode/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/target

competition/bytecode/Cargo.lock

Lines changed: 158 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

competition/bytecode/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "bytecode"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[dependencies]
7+
rand = "0.9.1"
8+
rand_chacha = "0.9.0"

competition/bytecode/prob.md

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
---toml
2+
[fuzz]
3+
exec = ["cargo", "run", "--release", "--", "generate"]
4+
env = {}
5+
6+
[judge]
7+
exec = ["cargo", "run", "--release", "--quiet", "--", "validate"]
8+
9+
[problem]
10+
points = 10
11+
difficulty = 1
12+
---
13+
14+
# 📜 Bytecode Interpreter
15+
16+
Congratulations! You've been hired as part of a top-secret division that
17+
specialises in decoding badly-coded machines.
18+
As your initiation, your manager has decided it's best for you to dive right into
19+
a typical day-to-day task that you'll have to carry out.
20+
21+
Next thing you know, your manager has put a massive sequence of archaic bytecode instructions
22+
on your desk, together with some sort of key that translates what each of the instructions do.
23+
24+
Initially, your manager (not knowing any better) asked you to run the code until termination
25+
and report to him what the output is.
26+
Thankfully, you remembered that the
27+
[Halting Problem](https://en.wikipedia.org/wiki/Halting_problem)
28+
is undecidable, and thus you managed to avoid an impossible task.
29+
30+
Your manager is quick on their feet though.
31+
You're now given the following task.
32+
**Given a series of bytecode instructions, if you run it for 10,000,000 steps,
33+
what will the sum of all the variables be, and what value will the output register have?**
34+
35+
Firstly, here's a brief layout of the machine.
36+
It has three components used for storing values:
37+
* A **namespace**, where variables named by a single lowercase character (a-z)
38+
can store one signed 64-bit integer and are always initialised to `0`
39+
at the start of the program,
40+
* A **stack**, where values (always signed 64-bit integers)
41+
are stored and retrieved in a first-in-last-out fashion, and
42+
* An **output register**, which functions just like a regular variable in the namespace,
43+
but is referred to in instructions by a `!` symbol, and is initialised to `1`.
44+
45+
Next, here is a list of all types of bytecode instructions it supports.
46+
* `LOAD <value>`: Puts a copy of `<value>` on the top of the **stack**.
47+
* `STORE <value>`: Stores the value at the top of the **stack**
48+
in the place indicated by `<value>`. If the **stack** is currently empty,
49+
a `0` value is placed.
50+
`<value>` in this case will *never* be an integer.
51+
* `LABEL <name>`: Does nothing, but counts as an instruction.
52+
Acts as a point in the bytecode that other instructions can jump to.
53+
* `JUMP <name>`: Jump to the line that contains a `LABEL` instruction
54+
associated with the same `<name>`.
55+
Such a `LABEL` line is guaranteed to exist such that any `JUMP` is valid,
56+
and that exactly *one* line will match, making this instruction always unambiguous.
57+
* `ADD <value> <value>`: Add the two `<value>`s and push the result on the top of the **stack**.
58+
* `SUB <value> <value>`: Subtract the second `<value>` from the first `<value>`
59+
and push the result on the top of the **stack**.
60+
* `MUL <value> <value>`: Multiply the two `<value>`s together
61+
and push the result on the top of the **stack**.
62+
* `DIVMOD <value> <value>`: Conduct a division of the first `<value>` by the second `<value>`.
63+
First push the quotient of the division onto the **stack**,
64+
then push the remainder (modulo) of the division onto the **stack**.
65+
If, however, the second `<value>` is zero, then instead of the quotient and remainder,
66+
push the original `<value>`s onto the **stack** instead.
67+
(i.e., push the first `<value>` first, then the second `<value>` next.)
68+
* `CMP <value> <value>`: Compares the first `<value>` against the second `<value>`.
69+
If the two are equal, push `0` onto the **stack**.
70+
If the first is greater than the second, push `1` onto the **stack**.
71+
If the first is less than the second, push `-1` onto the **stack**.
72+
* `BRANCHZERO <name>`: Pops off the top value of the **stack**
73+
(if empty, the value is taken as `0`). If this value is equal to `0`,
74+
jumps to the line that reads `LABEL <name>`.
75+
* `BRANCHCMP <value> <value> <ordering> <name>`:
76+
Compares the first `<value>` against the second `<value>`.
77+
If their relation is the same as given by `<ordering>`,
78+
then jump to the line that reads `LABEL <name>`.
79+
`<ordering>` is one of three values:
80+
* `EQ` matches when the first value is equal to the second value,
81+
* `GT` matches when the first value is greater than the second value,
82+
* `LS` matches when the first value is less than the second value.
83+
84+
In the above, `<value>` can be one of three different formats:
85+
* A single integer from the range `-50` to `50` inclusive,
86+
* A single character denoting the value of a variable in the **namespace**,
87+
* A `!` symbol, denoting the value of the **output register**.
88+
89+
Additionally, every `<name>` consists of three lowercase letters exactly.
90+
91+
## Example
92+
93+
Consider the following sequence of instructions.
94+
```
95+
JUMP str
96+
LABEL pqr
97+
JUMP end
98+
LABEL str
99+
LOAD 6
100+
STORE a
101+
LOAD 2
102+
STORE !
103+
ADD a !
104+
STORE b
105+
BRANCHCMP b 8 EQ pqr
106+
LABEL end
107+
```
108+
The following instructions will be executed:
109+
1. `JUMP str`: Jumps forward to the line 3 lines down.
110+
2. `LABEL str`: Does nothing. Moves to the next instruction.
111+
3. `LOAD 6`: Loads the value `6` onto the stack.
112+
4. `STORE a`: Pops `6` from the stack, stores it in the variable `a`.
113+
5. `LOAD 2`: Loads the value `2` onto the stack.
114+
6. `STORE !`: Pops `2` from the stack, stores it in the output register.
115+
7. `ADD a !`: Adds the values of the variable `a` and the output register,
116+
which is `6 + 2 = 8`. Hence, `8` is loaded onto the stack.
117+
8. `STORE b`: Pops `8` from the stack, stores it in the variable `b`.
118+
9. `BRANCHCMP b 8 EQ pqr`: Compares the variable `b` with the value `8`.
119+
Since they are equal in value, jump to the line that reads `LABEL pqr` (second from top).
120+
10. `LABEL pqr`: Does nothing. Moves to the next instruction.
121+
11. `JUMP end`: Jumps all the way to the last line (which reads `LABEL end`).
122+
12. `LABEL end`: Does nothing. Moves to the next (non-existent) instruction, thus halting.
123+
124+
At the end, the **namespace** contains the variables `a` with value `6` and `b` with value `8`.
125+
The **output register** contains the value `2`.
126+
Hence, the output in this case should be
127+
```
128+
14 2
129+
```
130+
since the sum of all variables in the namespace is 14.
131+
132+
Also note that in the above, **12** steps were executed.
133+
134+
## Input
135+
136+
Your input is the list of bytecode instructions to be executed.
137+
Each instruction will be on a new line,
138+
and the operands to each instruction are space separated.
139+
140+
## Output
141+
142+
Your output should be two space-separated integers.
143+
The first integer is the sum of all variables in the namespace,
144+
and the second integer is the value of the output register
145+
after the 10,000,000 steps have concluded (or after the program halts, whichever is earlier).

0 commit comments

Comments
 (0)