TTT: Turing Text Tape

Oct 02 2020

Introdução

Ah, INTERCAL ...
Por mais que eu queira encorajar todos a Experimentar Online , a produção de texto é simplesmente dolorosa.
De acordo com a documentação, ele usa o "Modelo de Texto de Turing". Embora seja um conceito ... interessante , usá-lo é tão divertido quanto atirar no próprio pé. E o que fazemos com uma tarefa como essa? Automatize.

O modelo de texto de Turing

Os caracteres que INTERCAL conhece são impressos em uma fita circular que só pode ser movida na direção positiva. A impressão é feita passando os comandos de movimento da cabeça da fita em uma matriz para a READ OUTinstrução. Cada caractere ASCII é escrito no interior da fita (o exterior contém os caracteres para a entrada, dãã). Isso resulta em bytes dos caracteres na fita ao contrário. Além disso, a cabeça da fita se move para trás ao longo da lista de caracteres, porque seu posicionamento é baseado na parte externa da fita.
O cabeçote começa na posição 0.

Agora a mágica começa. Eu vou estar usando a explicação de Truttle1 sobre como conseguir a saída .

  1. Configure uma matriz com o comprimento de saída.
  2. Preencha as entradas na matriz com os valores de movimento da cabeça da fita.
    1. Encontre o valor ASCII do caractere atual em binário
    2. Inverta-o e converta de volta um número n.
    3. Subtraia nda posição atual da cabeça e do módulo em 256, se necessário, resultando em um valorr
    4. r é o valor que você precisa armazenar na matriz
    5. A cabeça está agora na posição n.
  3. DO READ OUT a matriz.

OBSERVE

  • Array é pré-inicializado com 0, o primeiro índice é1
  • INTERCAL usa caracteres ASCII de 8 bits estendidos, portanto, o comprimento da fita de 256.
  • Entre 1/3 e 1/5 de todas as linhas devem começar PLEASE. Observe que, nesse caso, você ignora o DOfor GIVE UPe READ OUT, mas não para qualquer outra coisa, como visto nos exemplos.

Desafio

Dada uma string de entrada, produza um programa INTERCAL válido que imprime essa string e termina.

Exemplos

Imprime "BUZZ"

DO ,1 <- #4
DO ,1 SUB #1 <- #190
DO ,1 SUB #2 <- #152
PLEASE DO ,1 SUB #3 <- #336
DO READ OUT ,1
PLEASE GIVE UP

O espaço em branco é opcional. O seguinte imprime "FIZZ"

DO,1<-#4DO,1SUB#1<-#158DO,1SUB#2<-#208DO,1SUB#3<-#312PLEASEREADOUT,1PLEASEGIVEUP

(Exemplos descaradamente roubados do programa FizzBuzz de Truttle1 do vídeo.)

Você pode encontrar uma implementação de referência não dada em python 3 aqui

Regras

  • Sem lacunas padrão
  • Este é o código de golfe , o menor código vence.
  • Você pode esperar entrada> = 1, caracteres ASCII apenas.
  • O programa não pode lançar quaisquer erros além de ICL774I RANDOM COMPILER BUGe ICL666I COMPILER HAS INDIGESTION. O primeiro acontece ao acaso, o segundo é o C-Intercal ficando sem memória e contornando isso não faz parte do desafio

Respostas

8 Lynn Oct 02 2020 at 20:13

Python 3 , 157 bytes

t=i=0
p=o='PLEASE'
for c in input():i+=1;k=int(f'{ord(c):08b}'[::-1],2);o+=i%4//3*p+f'DO,1SUB#{i}<-#{t-k&255}';t=k
print(f'DO,1<-#{i}{o}DOREADOUT,1DOGIVEUP')

Experimente online!

Isso imprime \$n+3\$instruções, das quais \$\left\lfloor \frac{n+5}{4} \right\rfloor\$são educados. Essa proporção mal se encaixa no \$[1/5, 1/3]\$intervalo de educação para todos \$n \geq 1\$.

-1 byte graças a Neil.

5 Arnauld Oct 02 2020 at 20:09

JavaScript (Node.js) ,  156  148 bytes

s=>`DO,1<-#${Buffer(s).map(c=>o+=`${i++&&~i&3?'':'PLEASE'}DO,1SUB#${i}<-#`+(p-(g=k=>p=k--&&c>>k&1|g(k)*2)(8)&255),i=p=o=""),i+o}DOREADOUT,1DOGIVEUP`

Experimente online!

Experimente a saída em INTERCAL!

Quão?

Inversão de bits

Usamos uma função recursiva para reverter os bits do caractere c .

( g = k =>       // k = bit position counter 
  k-- &&         // decrement k; if it was not 0:
    c >> k & 1   //   bring the k-th bit of c at position 0 and isolate it
    | g(k)       //   bitwise OR with a recursive call,
      * 2        //   whose result is doubled
)(8)             // initial call with k = 8

Polidez

Começando com i = 0, inserimos uma declaração educada sempre que a seguinte expressão for falsa:

i++ && ~i & 3

Isso significa que inserimos um PLEASEpara o primeiro caractere processado e, em seguida, a cada 4 caracteres começando com o terceiro.

Nem a instrução inicial nem as duas instruções posteriores são educadas. Eles são marcados como Le TTrespectivamente na tabela a seguir.

 length | output structure   | politeness ratio
--------+--------------------+------------------
    1   | LPTT               |   1/ 4 = 0.250
    2   | LP-TT              |   1/ 5 = 0.200 <-- lower bound
    3   | LP-PTT             |   2/ 6 ≈ 0.333 <-- upper bound
    4   | LP-P-TT            |   2/ 7 ≈ 0.286
    5   | LP-P--TT           |   2/ 8 = 0.250
    6   | LP-P---TT          |   2/ 9 ≈ 0.222
    7   | LP-P---PTT         |   3/10 = 0.300
    8   | LP-P---P-TT        |   3/11 ≈ 0.273
    9   | LP-P---P--TT       |   3/12 = 0.250
   10   | LP-P---P---TT      |   3/13 ≈ 0.231
   11   | LP-P---P---PTT     |   4/14 ≈ 0.286
   12   | LP-P---P---P-TT    |   4/15 ≈ 0.267
   13   | LP-P---P---P--TT   |   4/16 = 0.250
   14   | LP-P---P---P---TT  |   4/17 ≈ 0.235
   15   | LP-P---P---P---PTT |   5/18 ≈ 0.278
   ..   | ...                |   1/5 < r < 1/3
5 KevinCruijssen Oct 02 2020 at 21:43

05AB1E , 77 74 54 bytes

Ç₁+₁šb퀨C¥(₁%€‘‚µ,1<-#1€·,1—¨#1<-#ÿ€·‚Ø€Ä,1‘J‘ÿ€·†¿€¾

-20 bytes portando a resposta Jelly de @UnrelatedString , então certifique-se de votar nele !!

Saídas com espaços no #1 DO,1 SUB#, DO READ OUTe DO GIVE UP.

Experimente online ou verifique mais alguns casos de teste .

Experimente a saída em INTERCAL.

Explicação:

Ç               # Convert the (implicit) input-string to a list of codepoint integers
 ₁+             # Add 256 to each value
   ₁š           # Prepend 256 at the front of the list
     b          # Convert each value to a binary string
      í         # Reverse each
       ۬       # Remove the last digit of each
         C      # Convert each from binary back to a base-10 integer
          ¥     # Take the forward differences (deltas) of this list
           (    # Negate each difference
            ₁%  # Take modulo-256 on each
€               # Map over each integer:
 ‘‚µ,1<-#1€·,1—¨#1<-#ÿ€·‚Ø€Ä,1‘
                #  Push dictionary string "PLEASE,1<-#1 DO,1 SUB#1<-#ÿ DO READ OUT",
                #  where the `ÿ` is automatically filled with the integer
   J            # Join this list of strings together
    ‘ÿ€·†¿€¾    # Push string "ÿ DO GIVE UP", where the `y` is filled with the string
                # (after which the result is output implicitly)

Veja esta minha dica 05AB1E (seção Como usar o dicionário? ) Para entender por que ‘‚µ,1<-#1€·,1—¨#1<-#ÿ€·‚Ø€Ä,1‘é "PLEASE,1<-#1 DO,1 SUB#1<-#ÿ DO READ OUT"e ‘ÿ€·†¿€¾é "ÿ DO GIVE UP".

4 Neil Oct 03 2020 at 02:28

Carvão , 90 89 85 bytes

DO,1<-#ILθ⊞υ⁰⭆θ⪫⟦×PLEASE⊖﹪κ³DO,1SUB#⊕κ<-#﹪⁻⊟υΣ⊞Oυ⍘⮌◧⍘℅ι !⁸ !²⁵⁶⟧ω”Z1∨?AE₂-πK↷Y:γüD0←✂

Experimente online! O link é para a versão detalhada do código. Explicação:

DO,1<-#ILθ

Imprima a instrução para definir o comprimento da saída.

⊞υ⁰

Comece com o cabeçote na posição 0. O valor é realmente armazenado na lista vazia predefinida, pois podemos modificar o valor da lista posteriormente usando as funções Pop e PushOperator em vez de ter que recorrer a um comando.

⭆θ⪫⟦...⟧ω

Faça um loop sobre os caracteres e imprima a concatenação de 5 expressões para cada caractere. (Isso é um pouco mais golfo, pois a concatenação sequencia automaticamente os dois valores numéricos na lista).

×PLEASE⊖﹪κ³

Seja educado a cada três caracteres. Há também um PLEASEno final, de modo que a proporção de polidez é ¹⁄₄, ¹⁄₅, ²⁄₆, ²⁄₇, ²⁄₈, ³⁄₉, ³⁄₁₀, ³⁄₁₁ ... depois do qual a taxa de polidez tende a ¹⁄₃.

DO,1SUB#⊕κ<-#

Imprima o índice indexado 1 no início da instrução para produzir o caractere.

﹪⁻⊟υΣ⊞Oυ⍘⮌◧⍘℅ι !⁸ !²⁵⁶

Calcule o binário reverso do caractere atual, produza a diferença da cabeça e atualize a cabeça com o novo binário reverso, tudo em uma expressão. O binário é codificado usando espaço para, de 0modo que pode ser facilmente preenchido para 8 bits, além do uso de strings evita separadores que seriam necessários de outra forma.

”Z1∨?AE₂-πK↷Y:γüD0←✂

Imprima as instruções finais compactadas para produzir a string e sair. A compactação da string significa que não preciso me preocupar em otimizar o número de vezes que produzo PLEASEmais.

3 UnrelatedString Oct 03 2020 at 19:21

Python 3 , 128 bytes

t=0
for c in input():n=int(f'{ord(c):08b}'[::-1],2);print(f'PLEASE,1<-#1DO,1SUB#1<-#{t-n&255}DOREADOUT,1');t=n
print('DOGIVEUP')

Experimente online!

Produz uma saída semelhante à minha solução Jelly, mas é uma modificação da solução Python de Lynn.

Usava originalmente o operador "walrus" do Python 3.8 , mas acabou sendo mais curto, sem 2 bytes.

2 UnrelatedString Oct 03 2020 at 17:13

Jelly , 62 59 bytes

OŻ+⁹BUṖ€Ḅ_Ɲ%⁹“!![ẓ,ȮFẈẋ⁹⁾V!ĖÐĊnß6ṛ»;;“Œ°þ[ṪȦṄ»Ʋ€;“©⁴Œ½OлŒu

Experimente online!

Usa um comprimento de array de 1 e imprime repetidamente para economizar na indexação e define o comprimento para um repetidamente para economizar na lógica de polidez: length-element-print forma uma unidade muito conveniente de 3.

Sem compressão de string:

OŻ+⁹BUṖ€Ḅ_Ɲ%⁹“please,1<-#1do,1sub#1<-#”;;“doreadout,1”Ʋ€;“dogiveup”Œu

Experimente um resultado online!

O                                      Codepoints of input.
 Ż                                     Prepend zero,
  +⁹                                   add 256 to each,
    B                                  convert each to binary.
     U                                 Reverse each,
      Ṗ€                               remove last element from each,
        Ḅ                              convert from binary.                                
         _Ɲ                            Subtract all adjacent pairs,
           %⁹                          and modulo 256.
                         Ʋ€            Map:
                  ;                    prepend to the number
             “...»                     "please,1<-#1do,1sub#1<-#",
                   ;                   append to that
                    “...»              "doreadout,1".
                           ;“...»      Append "dogiveup" to the whole result
                                 Œu    and uppercase.