freeCodeCamp/curriculum/challenges/portuguese/10-coding-interview-prep/rosetta-code/subleq.md

4.9 KiB

id title challengeType forumTopicId dashedName
5a23c84252665b21eecc8038 Subleq 5 302328 subleq

--description--

O Subleq é um exemplo de um One-Instruction Set Computer (OISC).

Seu nome vem de sua única instrução, que é SUbtract and Branch if Less than or EQual (subtraia e ramifique se for menor ou igual) a zero.

Sua tarefa é criar um interpretador que emule esse tipo de máquina.

A memória da máquina consiste em um array de números inteiros com sinal. Qualquer tamanho razoável de palavra é bom, mas a memória deve ser capaz de manter números negativos e positivos.

A execução começa com o ponteiro de instrução mirando a primeira palavra, que é o endereço 0. Ela prossegue da seguinte forma:

  1. Permita que A, B e C sejam valores armazenado nas três palavras consecutivas na memória, começando no ponteiro de instrução.
  2. Avance o ponteiro de instrução 3 palavras para apontar para o endereço após o que contém C.
  3. Se A é -1, então um caractere é lido a partir da entrada padrão e seu ponto de código armazenado no endereço fornecido por B. C não é usado.
  4. Se B é -1, então o número contido no endereço dado por A é interpretado como um ponto de código e a saída de caractere correspondente. C, mais uma vez, não é utilizado.
  5. Caso contrário, tanto A quanto B são tratados como endereços de locais de memória. O número contido no endereço fornecido por A é subtraído do número do endereço fornecido por B (e o resultado é armazenado de volta no endereço B). Se o resultado for zero ou negativo, o valor C se torna o novo ponteiro da instrução.
  6. Se o ponteiro da instrução se tornar negativo, a execução para.

Outros endereços negativos além de -1 podem ser tratados como equivalentes a -1 ou gerar um erro, como você achar adequado.

A solução deve aceitar um programa que será executado na máquina, separadamente da entrada alimentado no programa em si.

Este programa deve estar em "código de máquina" subleq puro - números decimais separados por espaços em branco, sem nomes simbólicos ou outras extensões de nível de assembly, a serem carregadas na memória começando no endereço 0. Mostre o resultado de sua solução quando receber o programa "Olá, mundo!". (Observe que o exemplo assume ASCII ou um superconjunto dele, como qualquer um dos conjuntos de caracteres Latin-N ou Unicode. Você pode traduzi-lo para outro conjunto de caracteres se a implementação estiver em um ambiente não compatível com ASCII.)

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

O que corresponde a algo assim em uma linguagem hipotética de assembler:

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"

--instructions--

Escreva uma função que receba um array de números inteiros como parâmetro. Ele representa os elementos da memória. A função deve interpretar a sequência e retornar a string de saída. Para esta tarefa, considere que não há uma entrada padrão.

--hints--

Subleq deve ser uma função.

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]) deve retornar uma string.

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]) deve retornar "Hello, world!".

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--

function Subleq(mem) {

}

--solutions--

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;
}