Files

179 lines
6.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: 5a23c84252665b21eecc8038
title: Subleq
challengeType: 5
forumTopicId: 302328
dashedName: subleq
---
# --description--
[Subleq](https://rosettacode.org/wiki/eso:Subleq) — приклад a [One-Instruction Set Computer (OISC) (Комп'ютер із набором однієї інструкції)](https://en.wikipedia.org/wiki/One_instruction_set_computer).
Назва пішла від перших літер інструкції: **SU**btract і **B**ranch if **L**ess than or **EQ**ual to zero (відняти й перейти, якщо результат менший або рівний нулю).
Ваше завдання — створити дешифрувальник, який змоделює принцип дії такої машини.
Пам'ять машини складається з масиву цілих чисел зі знаком. Підійде будь-який допустимий розмір слова, але пам'ять повинна підтримувати від'ємні та додатні числа.
Виконання починається з лічильника команд, спрямованого на перше слово, яке є адресою 0. Це відбувається наступним чином:
<ol>
<li>Нехай А, В та С будуть значеннями, що зберігаються в трьох послідовних словах у пам'яті, починаючи з лічильника команд.</li>
<li>Розширте лічильник команд, розташувавши курсор у адресному рядку після компонента, що містить значення C.</li>
<li>Якщо A = -1, тоді символ зчитується зі стандартного вводу та його кодова точка, що зберігається в адресі, зазначеному у B. C не використовується.</li>
<li>Якщо B — -1, тоді число, що міститься в адресі, вказаній А, інтерпретується як кодова точка та відповідний символ виходу. C знову не використовується.</li>
<li>В іншому випадку і A, і B розглядаються як адреси комірок пам'яті. Число, що знаходиться в адресі, що вказана A, віднімається від числа в адресі, вказаній B (а результат зберігається назад в адрес B). Якщо результат дорівнює нулю або від'ємний, значення C стає новим лічильником команд.</li>
<li>Якщо лічильник команд стає від'ємним — виконання припиняється.</li>
</ol>
Інші негативні адреси, окрім -1, можна вважати еквівалентом -1 або згенерувати помилку — робіть так, як вважаєте за потрібне.
Ваше рішення повинно показати, чи надаєте Ви дозвіл програмі виконати дану операцію в комп'ютері незалежно від вхідного потоку самої програми.
Ця програма має бути в сирому "машинному коді" subleq — десяткові числа, розділені пробілом з символьним ім'ям чи інші розширення рівня асемблера, які завантажаться у пам'ять, починаючи з адреси 0. Покажіть вивід свого рішення, коли запустите цю програму "Hello, world!". (Зверніть увагу, що цей приклад припускає використання ASCII або його надмножину, таку як будь-який сет символів чи Unicode. Ви можете перекласти його на іншу кодову систему, якщо ваше виконання засноване на середовищі, не сумісному з ASCIL.)
<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>
Що відповідає чомусь схожому на це у гіпотетичній мові асемблера:
<pre>start:
zero, message, -1
message, -1, -1
neg1, start+1, -1
neg1, start+3, -1
zero, zero, start
zero: 0
neg1: -1
message: "Hello, world!\n\0"
</pre>
# --instructions--
Напишіть функцію, що використовує набір цілих чисел як параметр. Це відображає елементи пам'яті. Функція повинна інтерпретувати послідовність та виводити вихідний рядок. Для цього завдання припустимо, що стандартного вводу немає.
# --hints--
`Subleq` має бути функцією.
```js
assert(typeof Subleq == 'function');
```
`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])` має виводити рядок.
```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'
);
```
`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!"`.
```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!'
);
```
# --seed--
## --seed-contents--
```js
function Subleq(mem) {
}
```
# --solutions--
```js
function Subleq(mem) {
var out = '';
var instructionPointer = 0;
do {
var a = mem[instructionPointer];
var b = mem[instructionPointer + 1];
if (a === -1) {
} else if (b === -1) {
out += String.fromCharCode(mem[a]);
} else {
mem[b] -= mem[a];
if (mem[b] < 1) {
instructionPointer = mem[instructionPointer + 2];
continue;
}
}
instructionPointer += 3;
} while (instructionPointer >= 0);
return out;
}
```