TTT: Turing Text Tape

Oct 02 2020

Wprowadzenie

Ach, INTERKAL ... Chociaż
bardzo chciałbym zachęcić wszystkich do wypróbowania online , wyjście tekstu jest po prostu bolesne.
Zgodnie z dokumentacją wykorzystuje „Turing Text Model”. Chociaż jest to ... ciekawa koncepcja, używanie jej jest równie przyjemne, jak strzelanie sobie w stopę. A co robimy z takim zadaniem? Zautomatyzuj to.

Model tekstu Turinga

Znaki znane przez INTERCAL są drukowane na okrągłej taśmie, którą można przesuwać tylko w kierunku dodatnim. Drukowanie odbywa się poprzez przekazanie poleceń ruchu głowicy taśmy w tablicy do READ OUTinstrukcji. Każdy znak ASCII jest zapisany po wewnętrznej stronie tej taśmy (na zewnątrz znajdują się znaki wejściowe, prawda). Powoduje to odwrócenie bajtów znaków na taśmie. Również głowica taśmy przesuwa się do tyłu wzdłuż listy znaków, ponieważ jej pozycjonowanie jest oparte na zewnętrznej stronie taśmy.
Głowa zaczyna się na pozycji 0.

Teraz zaczyna się magia. Będę używać wyjaśnienia Truttle1, jak osiągnąć wynik .

  1. Skonfiguruj tablicę z długością wyjściową.
  2. Wypełnij wpisy w tablicy wartościami ruchu głowicy taśmy.
    1. Znajdź binarną wartość ASCII bieżącego znaku
    2. Odwróć to i zamień liczbę z powrotem n.
    3. W nrazie potrzeby odejmij od bieżącej pozycji głowy i modulo o 256, uzyskując wartośćr
    4. r to wartość, którą musisz przechowywać w tablicy
    5. Głowa jest teraz na pozycji n.
  3. DO READ OUT tablica.

PROSZĘ ZANOTOWAĆ

  • Tablica jest wstępnie inicjalizowana za pomocą 0, pierwszy indeks to1
  • INTERCAL wykorzystuje rozszerzone 8-bitowe znaki ASCII, stąd długość taśmy 256.
  • Od 1/3 do 1/5 wszystkich linii musi zaczynać się PLEASE. Zwróć uwagę, że w takim przypadku porzucasz DOfor GIVE UPi READ OUT, ale nie dla niczego innego, jak widać w przykładach.

Wyzwanie

Biorąc pod uwagę łańcuch wejściowy, wypisz prawidłowy program INTERCAL, który drukuje ten ciąg i kończy.

Przykłady

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

Odstępy są opcjonalne. Następujące drukuje "FIZZ"

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

(Przykłady bezwstydnie skradzione z programu FizzBuzz firmy Truttle1 z filmu).

Możesz znaleźć ungolfed referencyjną implementację w Pythonie 3 tutaj

Zasady

  • Brak standardowych luk
  • To jest code-golf , najkrótszy kod wygrywa.
  • Można oczekiwać, że dane wejściowe> = 1, tylko znaki ASCII.
  • Program nie może zgłaszać żadnych błędów poza ICL774I RANDOM COMPILER BUGi ICL666I COMPILER HAS INDIGESTION. Pierwsza zdarza się losowo, druga to C-Intercal, w której brakuje pamięci i obejście tego nie jest częścią wyzwania

Odpowiedzi

8 Lynn Oct 02 2020 at 20:13

Python 3 , 157 bajtów

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

Wypróbuj online!

To drukuje \$n+3\$instrukcje, w tym \$\left\lfloor \frac{n+5}{4} \right\rfloor\$są uprzejmi. Ten stosunek ledwo mieści się w \$[1/5, 1/3]\$przedział grzecznościowy dla wszystkich \$n \geq 1\$.

-1 bajt dzięki Neilowi.

5 Arnauld Oct 02 2020 at 20:09

JavaScript (Node.js) ,  156  148 bajtów

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`

Wypróbuj online!

Wypróbuj wyjście w INTERKALU!

W jaki sposób?

Odwrócenie bitu

Używamy funkcji rekurencyjnej, aby odwrócić bity znaku 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

Uprzejmość

Zaczynając od i = 0, wstawiamy uprzejmą instrukcję za każdym razem, gdy poniższe wyrażenie jest fałszywe:

i++ && ~i & 3

Oznacza to, że wstawiamy a PLEASEjako pierwszy przetwarzany znak, a następnie co 4 znaki zaczynając od trzeciego.

Ani instrukcja wiodąca, ani dwie instrukcje końcowe nie są grzeczne. Oznaczono je odpowiednio jako Li TTw poniższej tabeli.

 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 bajty

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

-20 bajtów przez przeniesienie odpowiedzi Jelly @ UnrelatedString, więc nie zapomnij go zagłosować !!

Wyjścia z pomieszczeń w #1 DO,1 SUB#, DO READ OUTi DO GIVE UP.

Wypróbuj online lub zweryfikuj kilka innych przypadków testowych .

Wypróbuj wyjście w INTERKALU.

Wyjaśnienie:

Ç               # 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)

Zobacz moją wskazówkę 05AB1E (sekcja Jak korzystać ze słownika? ), Aby zrozumieć, dlaczego tak ‘‚µ,1<-#1€·,1—¨#1<-#ÿ€·‚Ø€Ä,1‘jest "PLEASE,1<-#1 DO,1 SUB#1<-#ÿ DO READ OUT"i ‘ÿ€·†¿€¾jest "ÿ DO GIVE UP".

4 Neil Oct 03 2020 at 02:28

Węgiel , 90 89 85 bajtów

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

Wypróbuj online! Link prowadzi do pełnej wersji kodu. Wyjaśnienie:

DO,1<-#ILθ

Wydrukuj instrukcję ustawiania długości wyjścia.

⊞υ⁰

Zacznij od głowy w pozycji 0. Wartość jest faktycznie przechowywana na predefiniowanej pustej liście, ponieważ możemy później zmodyfikować wartość listy za pomocą funkcji Pop i PushOperator, zamiast uciekać się do polecenia.

⭆θ⪫⟦...⟧ω

Zapętl znaki i wydrukuj konkatenację 5 wyrażeń dla każdego znaku. (Jest to nieco bardziej golfowe, ponieważ konkatenacja automatycznie dodaje ciąg znaków do dwóch wartości liczbowych na liście).

×PLEASE⊖﹪κ³

Bądź grzeczny co trzeci bohater. Na PLEASEkońcu znajduje się również znak grzecznościowy, tak że stosunek grzeczności wynosi ¹⁄₄, ¹⁄₅, ²⁄₆, ²⁄₇, ²⁄₈, ³⁄₉, ³⁄₁₀, ³⁄ ... po czym stosunek uprzejmości zbliża się do ¹⁄₃.

DO,1SUB#⊕κ<-#

Wydrukuj indeks 1-indeksowy na początku instrukcji, aby wypisać znak.

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

Oblicz odwróconą wartość binarną bieżącego znaku, wypisz różnicę z nagłówka i zaktualizuj nagłówek nowym odwróconym kodem binarnym, wszystko w jednym wyrażeniu. Plik binarny jest kodowany przy użyciu spacji, 0dzięki czemu można go łatwo dopełnić do 8 bitów, a użycie ciągów znaków pozwala uniknąć separatorów, które w innym przypadku byłyby konieczne.

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

Wydrukuj skompresowane instrukcje końcowe, aby wypisać łańcuch i zakończyć. Kompresja ciągów oznacza, że ​​nie muszę się martwić o optymalizację liczby PLEASEdalszych wydruków .

3 UnrelatedString Oct 03 2020 at 19:21

Python 3 , 128 bajtów

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

Wypróbuj online!

Daje podobny wynik do mojego rozwiązania Jelly, ale jest w takim samym stopniu modyfikacją rozwiązania Lynn w Pythonie.

Pierwotnie używany operator „walrus” w Pythonie 3.8 , ale okazało się, że jest krótszy, a nie o 2 bajty.

2 UnrelatedString Oct 03 2020 at 17:13

Galaretka , 62 59 bajtów

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

Wypróbuj online!

Używa tablicy o długości 1 i drukuje wielokrotnie, aby zaoszczędzić na indeksowaniu, i ustawia ją wielokrotnie, aby zaoszczędzić na logice grzeczności: wydruk elementu długości tworzy bardzo wygodną jednostkę 3.

Bez kompresji struny:

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

Wypróbuj wynik 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.