2018-12-30 13:35:56 +00:00
---
id: 5a23c84252665b21eecc8038
title: Subleq
challengeType: 5
2019-08-05 16:17:33 +00:00
forumTopicId: 302328
2021-01-13 02:31:00 +00:00
dashedName: subleq
2018-12-30 13:35:56 +00:00
---
2020-11-27 18:02:05 +00:00
# --description--
[Subleq ](https://rosettacode.org/wiki/eso:Subleq ) is an example of a [One-Instruction Set Computer (OISC) ](https://en.wikipedia.org/wiki/One_instruction_set_computer ).
It is named after its only instruction, which is **SU**btract and **B**ranch if **L**ess than or **EQ**ual
2020-03-30 16:23:18 +00:00
2018-12-30 13:35:56 +00:00
to zero.
2020-11-27 18:02:05 +00:00
2018-12-30 13:35:56 +00:00
Your task is to create an interpreter which emulates such a machine.
2020-11-27 18:02:05 +00:00
2018-12-30 13:35:56 +00:00
The machine's memory consists of an array of signed integers. Any reasonable word size is fine, but the memory must be
2020-11-27 18:02:05 +00:00
2018-12-30 13:35:56 +00:00
able to hold negative as well as positive numbers.
2020-11-27 18:02:05 +00:00
2018-12-30 13:35:56 +00:00
Execution begins with the instruction pointer aimed at the first word, which is address 0. It proceeds as follows:
2020-11-27 18:02:05 +00:00
2018-12-30 13:35:56 +00:00
< ol >
< li > Let A, B, and C be the value stored in the three consecutive words in memory starting at the instruction pointer.< / li >
< li > Advance the instruction pointer 3 words to point at the address after the one containing C.< / li >
< li > If A is -1, then a character is read from standard input and its code point stored in the address given by B. C
is unused.< / li >
< li > If B is -1, then the number contained in the address given by A is interpreted as a code point and the
corresponding character output. C is again unused.< / li >
< li > Otherwise, both A and B are treated as the addresses of memory locations. The number contained in the address
given by A is subtracted from the number at the address given by B (and the result stored back in address B). If
the result is zero or negative, the value C becomes the new instruction pointer.< / li >
< li > If the instruction pointer becomes negative, execution halts.< / li >
< / ol >
2020-11-27 18:02:05 +00:00
2018-12-30 13:35:56 +00:00
Other negative addresses besides -1 may be treated as equivalent to -1, or generate an error, as you see fit.
2020-11-27 18:02:05 +00:00
2018-12-30 13:35:56 +00:00
Your solution should accept a program to execute on the machine, separately from the input fed to the program itself.
2020-11-27 18:02:05 +00:00
2018-12-30 13:35:56 +00:00
This program should be in raw subleq "machine code" - whitespace-separated decimal numbers, with no symbolic names or
2020-11-27 18:02:05 +00:00
2018-12-30 13:35:56 +00:00
other assembly-level extensions, to be loaded into memory starting at address 0. Show the output of your solution when
2020-11-27 18:02:05 +00:00
2018-12-30 13:35:56 +00:00
fed this "Hello, world!" program. (Note that the example assumes ASCII or a superset of it, such as any of the Latin-N
2020-11-27 18:02:05 +00:00
2018-12-30 13:35:56 +00:00
character sets or Unicode. You may translate it into another character set if your implementation is on a
2020-11-27 18:02:05 +00:00
2018-12-30 13:35:56 +00:00
non-ASCiI-compatible environment.)
2020-11-27 18:02:05 +00:00
2018-12-30 13:35:56 +00:00
< pre > 15 17 -1 17 -1 -1 16 1 -1 16 3 -1 15 15 0 0 -1 72 101 108 108 111 44 32 119 111 114 108 100 33 10 0< / pre >
2020-11-27 18:02:05 +00:00
2018-12-30 13:35:56 +00:00
Which corresponds to something like this in a hypothetical assembler language:
2020-11-27 18:02:05 +00:00
< pre > start:
2018-12-30 13:35:56 +00:00
zero, message, -1
message, -1, -1
neg1, start+1, -1
neg1, start+3, -1
zero, zero, start
zero: 0
neg1: -1
2019-03-10 10:14:48 +00:00
message: "Hello, world!\n\0"
< / pre >
2018-12-30 13:35:56 +00:00
2020-11-27 18:02:05 +00:00
# --instructions--
2020-03-30 16:23:18 +00:00
2019-03-10 10:14:48 +00:00
Write a function that takes an array of integers as a parameter. This represents the memory elements. The function
2020-11-27 18:02:05 +00:00
2019-03-10 10:14:48 +00:00
should interpret the sequence and return the output string. For this task, assume that there is no standard input.
2018-12-30 13:35:56 +00:00
2020-11-27 18:02:05 +00:00
# --hints--
`Subleq` should be a function.
```js
assert(typeof Subleq == 'function');
```
2020-03-30 16:23:18 +00:00
2020-11-27 18:02:05 +00:00
`Subleq([15, 17, -1, 17, -1, -1, 16, 1, -1, 16, 3, -1, 15, 15, 0, 0, -1, 72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33, 0])` should return a string.
2018-12-30 13:35:56 +00:00
2020-11-27 18:02:05 +00:00
```js
assert(
typeof Subleq([
15,
17,
-1,
17,
-1,
-1,
16,
1,
-1,
16,
3,
-1,
15,
15,
0,
0,
-1,
72,
101,
108,
108,
111,
44,
32,
119,
111,
114,
108,
100,
33,
0
]) == 'string'
);
2018-12-30 13:35:56 +00:00
```
2020-11-27 18:02:05 +00:00
`Subleq([15, 17, -1, 17, -1, -1, 16, 1, -1, 16, 3, -1, 15, 15, 0, 0, -1, 72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33, 0])` should return `"Hello, world!"` .
```js
assert.equal(
Subleq([
15,
17,
-1,
17,
-1,
-1,
16,
1,
-1,
16,
3,
-1,
15,
15,
0,
0,
-1,
72,
101,
108,
108,
111,
44,
32,
119,
111,
114,
108,
100,
33,
0
]),
'Hello, world!'
);
```
2018-12-30 13:35:56 +00:00
2020-11-27 18:02:05 +00:00
# --seed--
2020-03-30 16:23:18 +00:00
2020-11-27 18:02:05 +00:00
## --seed-contents--
2018-12-30 13:35:56 +00:00
```js
2019-03-10 10:14:48 +00:00
function Subleq(mem) {
2020-09-15 16:57:40 +00:00
2018-12-30 13:35:56 +00:00
}
```
2020-11-27 18:02:05 +00:00
# --solutions--
2018-12-30 13:35:56 +00:00
```js
2019-03-10 10:14:48 +00:00
function Subleq(mem) {
2020-03-30 16:23:18 +00:00
var out = '';
2018-12-30 13:35:56 +00:00
var instructionPointer = 0;
do {
var a = mem[instructionPointer];
var b = mem[instructionPointer + 1];
2020-03-30 16:23:18 +00:00
if (a === -1) {
} else if (b === -1) {
2018-12-30 13:35:56 +00:00
out += String.fromCharCode(mem[a]);
} else {
mem[b] -= mem[a];
if (mem[b] < 1 ) {
instructionPointer = mem[instructionPointer + 2];
continue;
}
}
instructionPointer += 3;
2020-03-30 16:23:18 +00:00
} while (instructionPointer >= 0);
2018-12-30 13:35:56 +00:00
return out;
}
```