Prosty tłumacz golfa


13

Wyzwanie:

Twoim zadaniem jest stworzenie prostego tłumacza dla prostego języka golfowego.


Wejście:

Dane wejściowe będą miały postać ciągu oddzielonego spacjami.

Możesz zastąpić separację przestrzeni tym, co chcesz


Wynik:

Wyprowadza wynik (liczbę lub ciąg) uzyskany po wykonaniu wszystkich operacji. Jeśli istnieje więcej niż jedno wyjście, połącz je ze sobą, aby uzyskać jeden wynik (bez separatorów). Wartość początkowa zmiennej wynosi zawsze zero. tj .: zaczyna się o0


Składnia języka:

Język ma następujące operatory:

inc  ---> add one to variable
dec  ---> remove one from variable
mult ---> multiply variable by 2
half ---> divide the variable by 2
Pri  ---> print the variable to console (or whatever your language has)
exit ---> end the program (anything after this is ignored)

Przykłady:

inc inc inc dec Pri exit                 ---> 2
dec inc mult inc inc Pri                 ---> 2
inc inc inc mult half Pri exit inc       ---> 3
inc Pri inc Pri inc Pri exit half mult   ---> 123
Pri exit                                 ---> 0
inc half Pri exit                        ---> 0.5 

Ograniczenie:

To jest golf golfowy, więc wygra najkrótszy kod w bajtach dla każdego języka.


Uwaga:

  • Dane wejściowe zawsze będą prawidłowe. (ciąg operatorów oddzielony spacją)
  • Możesz zaokrąglić w dół do najbliższej liczby całkowitej, jeśli nie chcesz miejsc dziesiętnych.

3
Czy mogę wziąć listę ciągów znaków? Czy mogę użyć innej wielkiej litery?
user202729,

Dodać przypadek wyjścia? wyjście powinno mieć znaczenie
l4m2

1
@Kaldo: Możesz rozdzielić używając nowych linii
Muhammad Salman

3
Hmm, nie nazwałbym tego języka „językiem golfa”.
Paŭlo Ebermann

1
To Deadfish z podwójnymi i połówkami zamiast kwadratowych i dłuższych nazw poleceń
Jo King

Odpowiedzi:


8

Bash , 61 bajtów

sed '1i0
s/.//2g;y"idmhe"+-*/q";/+\|-/i1
/*\|\//i2
/P/cdn'|dc

Wypróbuj online!

Konwertuje program na program dc, a następnie ocenia go jako kod dc. To pobiera dane wejściowe oddzielone znakami nowej linii. Zauważ, że dc jest oparte na stosie i używa odwrotnej notacji do polerowania.

Sygnał wejściowy jest najpierw przesyłany do sed

1i0 w pierwszym wierszu wejścia wpisz (prepend) a 0, będzie to akumulator

s/.//2g usuń wszystko oprócz pierwszego znaku w każdej linii

y"idmhe"+-*/q"transliterować idmhew +-*/qodpowiednio + - * / są średnimi arytmetycznymi polecenia i q zamykany program

/+\|-/w każdym wierszu zawierającym + lub - i1wstaw 1

/*\|\//w każdym wierszu zawierającym * lub / i2wstaw 2

/P/w każdym wierszu zawierającym P, cdnzmień go na dn, równoważny duplikatowi i wyjściu bez nowej linii w dc

Teraz jest to oceniane jako wyrażenie dc.


2
Przypuszczam, że nie jest nierozsądne oczekiwać, że sedskładnia stanie się jeszcze bardziej obca niż wcześniej uważano za możliwe, gdy gra się w golfa.
Mateen Ulhaq

6

Galaretka , 21 bajtów

ḲḢ€O%11ị⁾’‘j“IȮḤH”¤VI

Wypróbuj online!


Zauważ, że wartości ASCII pierwszych znaków ( idmhPe) modulo 11 są unikalnymi modulo 6.


Korzystanie z modulo 16:

Galaretka , 21 bajtów

ḲḢ€O%⁴ị“ḢwġḞkz’ṃØJ¤VI

Wypróbuj online!

W tym przypadku jest używany ciąg znaków, który służy do indeksowania ḤH‘’IȮ. Nie ‘’są już na granicach.


Użycie 11 bajtów do przedstawienia ciągu 6-bajtowego jest ... złe. Ale ... “”zajmuje 2 bajty, ¤zajmuje 1 bajt, same dane 6 bajtów, pozostały 2 bajty na zrobienie czegoś. Obecnie jest i j, ale ịØJlub ṃØJjest znacznie gorszy i nie działa (ponieważ Unicode).
user202729

Koncepcja ciągów jli („Ciąg jest listą liczb całkowitych ze specjalną flagą, która ma wpływ na drukowanie”) jest świetny.
user202729

5

R , 128 125 bajtów

Reduce(function(x,y)switch(y,i=x+1,d=x-1,m=x*2,h=x/2,P={cat(x);x}),substr(el(strsplit(gsub("e.*$","",scan(,""))," ")),1,1),0)

Wypróbuj online!

Należy wywołać za pomocą, source(echo=FALSE)aby zapobiec automatycznemu drukowaniu wartości zwracanej. Alternatywą byłoby owinięcie wszystkiego,invisible ale to znacznie mniej golfa (i rujnuje moją [wciąż] niezłą liczbę bajtów).


3

05AB1E , 25 bajtów

΀¬"idmhPe"S"><·;=q"S‡J.V

Wypróbuj online!

Odwzorowuje każdą funkcję języka na odpowiednią funkcję 05AB1E (używając pierwszego znaku każdej funkcji), a następnie wykonuje wynikowy ciąg jako kod 05AB1E.


2

Czerwony , 121 bajtów

func[s][v: 0 parse s[any[["i"(v: v + 1)|"d"(v: v - 1)|"m"(v: v * 2)|"h"(v: v / 2.0)|"P"(prin v)|"e"(exit)]thru" "| end]]]

Wypróbuj online!

Czytelny:

f: func [s] [
    v: 0
    parse s [
        any [
            [ "i" (v: v + 1)
            | "d" (v: v - 1)
            | "m" (v: v * 2)
            | "h" (v: v / 2.0)
            | "P" (prin v)
            | "e" (exit)]
            thru [" " | end]
        ]
    ]
] 

2

Python 2 , 131 125 122 121 118 117 115 bajtów

v=0;o=""
for x in input().split("x")[0].split():
 if"Q">x:o+=`v`
 else:v+=(1,-1,v,-v/2.)['idmh'.find(x[0])]
print o

Wypróbuj online!

-6 i -3 dzięki dzięki @Rod

-3 i -2 dzięki dzięki @etene

-1 zastępując "Pri"==xz"P"in x


można splitna "exit"i uzyskać 1st bloku, zamiast breaking oszczędność 4 bajty
Rod

1
Możesz usunąć nawiasy wokół 'idmh'i użyć findzamiast tego index, co pozwoli zaoszczędzić kilka bajtów
etene

@Rod - może pójść o krok dalej i podzielić się, exaby uratować kolejne 2
ElPedro

Można wymienić v=(v+1,v-1,v*2,v/2.)ze v+=(1,-1,v,-v/2.)to powinno działać, choć nie testowany
Rod

@Rod - zastanowił się, ale nie mógł wymyślić, jak to zrobić half. Tak prosty! Dzięki.
ElPedro

2

Python 3 , 110 91 82 bajtów

exit spowoduje zamknięcie programu z błędem.

x=0
for c in input():c=='P'==print(x,end='');x+=(1,-1,x,-x/2,c,0)['ndmhx'.find(c)]

Wypróbuj online!


Skróć nazwy zmiennych, aby zaoszczędzić 9 bajtów. i='x+=1';d='x-=1';...a następnie w swoim execpołączeniu zmień go naexec(eval(c[0]))
mypetlion

@mypetlion Dzięki, ale znalazłem lepszy sposób.
mbomb007

Myślę, że to jest poprawne: 82 bajty
Lynn

@Lynn To świetnie! Nie mogłem wymyślić dobrego sposobu na zwarcie do printoświadczenia!
mbomb007

2

JavaScript (ES6), 83 79 bajtów

Zaoszczędzono 4 bajty dzięki @ l4m2

Iteracyjnie zastępuje instrukcje albo wyjściowymi, albo pustymi ciągami.

s=>s.replace(/\S+./g,w=>m<s?'':w<{}?m:(m+={d:-1,e:w,i:1,m}[w[0]]||-m/2,''),m=0)

Wypróbuj online!

Skomentował

s =>                       // given the input string s
  s.replace(/\S+./g, w =>  // for each word w in s:
    m < s ?                //   if m is a string:
      ''                   //     ignore this instruction
    :                      //   else:
      w < {} ?             //     if w is 'Pri' ({} is coerced to '[object Object]'):
        m                  //       output the current value of m
      : (                  //     else:
          m +=             //       add to m:
            { d: -1,       //         -1 if w is 'dec'
              e: w,        //         w  if w is 'exit' (which turns m into a string)
              i: 1,        //         1  if w is 'inc'
              m            //         m  if w is 'mult'
            }[w[0]]        //       using the first character of w to decide
            || -m / 2,     //       or add -m/2 (for 'half') if the above result was falsy
        ''),               //       do not output anything
    m = 0                  //   m = unique register of our mighty CPU, initialized to 0
  )                        // end of replace()

s=>s.replace(/\S+./g,w=>k<s?'':w<{}?k:(k+={d:-1,e:w,i:1,m:k}[w[0]]||-k/2,''),k=0)
l4m2

@ l4m2 To w<{}jest czyste zło: p
Arnauld

s=>s.replace(/\S+./g,e=>m<s?'':e<{}?m:(m+={d:-1,e,i:1,m}[e[0]]||-m/2,''),m=0)też praca
l4m2

2

Węgiel drzewny , 37 35 bajtów

≔⁰ηF⎇№θx…θ⌕θxθ≡ιn≦⊕ηd≦⊖ηm≦⊗ηh≦⊘ηrIη

Wypróbuj online! Link jest do pełnej wersji kodu. Zainspirowany odpowiedzią @ RickHitchcock. Wyjaśnienie:

≔⁰η

Wyczyść zmienną.

F⎇№θx…θ⌕θxθ≡ι

Obetnij wejście, xjeśli jest, a następnie zapętl i włącz każdy znak (pozostałą część) wejścia.

n≦⊕η

ni n crements zmiennej.

d≦⊖η

d d oblicza zmienną.

m≦⊗η

m m zwielokrotnia zmienną przez dwa (tj. podwaja).

h≦⊘η

h h żyje zmienną.

rIη

rp r oznacza zmienną rzutowaną na string.


1
@RickHitchcock Przepraszamy, nie przetestowałem tego wystarczająco dokładnie. Znalazłem obejście, ale kosztowało mnie to bajt.
Neil

2

JavaScript (ES6), 77 75 bajtów

(Pożyczona ( ukradła ) @ sztuczka Arnaulda polegająca na użyciu mjako nazwy zmiennej, oszczędzając 2 bajty.)

f=([c,...s],m=0)=>c<'x'?(c=='P'?m:'')+f(s,m+({h:-m/2,d:-1,n:1,m}[c]||0)):''

Rekurencyjnie chodzi po łańcuchu, szukając odrębnych liter na instrukcję i ignorując resztę:

  • n: inc
  • d: dec
  • m: mult
  • h: połowa
  • P: Pri
  • x: wyjście

Korzysta z faktu, że undefinednie jest ani większa ani mniejsza niż niż 'x'powodując rekursji, aby zatrzymać się na końcu łańcucha lub gdy napotka 'x'na wyjściu .


1
Po usuniętym komentarzu, na który oczywiście nie mogę już odpowiedzieć, zapomniałem wkleić link do poprawionego kodu (d'oh!), Ale znalazłem nowe podejście, które jest o 2 bajty krótsze niż moja pierwotna próba.
Neil



1

JavaScript, 107 bajtów

s=>eval('x=0;x'+(s.split` `.map(v=>({i:"++",d:"--",m:"*=2",h:"/=2",P:";alert(x)",e:"//"})[v[0]]).join`;x`))


1

Lua, 207 bajtów

s=0;n=0;for a in io.read():gmatch'.'do if s==0 then s=1;n=a=='i'and n+1 or a=='d'and n-1 or a=='m'and n*2 or a=='h'and n/2 or n;if a=='P'then print(n)elseif a=="e"then break end elseif a==' 'then s=0 end end

1

Python 3 , 114 110 109 116 bajtów

W rzeczywistości wziąłbym dwa bajty mniej w Pythonie 2, ponieważ execjest to instrukcja i nie potrzebuje nawiasów ...

  • Zaoszczędź 4 dodatkowe bajty dzięki @ElPedro

  • Zapisano dodatkowy bajt, wykorzystując fakt, że findzwraca błąd po błędzie, który można następnie wykorzystać jako indeks

  • +7 bajtów, ponieważ nie zauważyłem zasady braku nowych linii :(

i=0;exec(";".join("i+=1 i-=1 i*=2 i/=2 print(i,end='') exit()".split()["idmhP".find(h[0])]for h in input().split()))

Wypróbuj online!

Mapuje pierwszy znak każdego słowa wejściowego na fragment kodu Pythona. Są one następnie łączone iexec edytowane.

Całkiem proste podejście, które prawdopodobnie można by trochę pograć w golfa. Trudność polega głównie na znalezieniu najkrótszej formy spośród wielu możliwych ...


112 Wypróbuj online! jeśli masz komendy jako ciąg rozdzielony spacjami i podziel go.
ElPedro

1
110 w nawiasach klamrowych. Spróbuj online!
ElPedro

To nie daje prawidłowego wyniku. Pytanie mówi, że musisz drukować bez separatorów, więc potrzebujesz print(i,end=''). Zobacz 4. przypadek testowy.
mbomb007

Nie zauważyłem, naprawię to. Dzięki !
eten

@Etene Komentuj, kiedy to naprawisz, a ja usunę mój komentarz.
mbomb007

1

Ruby + -na, 81 73 65 bajtów

x=0;$F.map{|w|eval %w{x+=1 x-=1 1/0 $><<x x*=2 x/=2}[w.ord%11%6]}

Wypróbuj online!

Całkiem proste. Dla pierwszej litery każdego słowa znajdź odpowiedni ciąg polecenia i evalgo. Używa podziału na liczby całkowite i exitsrzucając ZeroDivisionError.

-5 bajtów: użyj .ord%11%6zamiast wyszukiwania łańcucha. Kredyt trafia do użytkownika202729

-3 bajty: .orduwzględnia tylko pierwszy znak ciągu, więc mogę pominąć a [0].

-8 bajtów: Użyj -aflagi, aby automatycznie podzielić dane wejściowe, dzięki Kirill L.


1
Możesz zaoszczędzić jeszcze więcej bajtów, dodając -aopcję wykonania automatycznego podziału za ciebie, w ten sposób
Kirill L.

1

Emojicode , 270 bajtów

🐖🔥🍇🍮c 0🔂j🍡💣🐕🔟 🍇🍊😛j🔤inc🔤🍇🍮c➕c 1🍉🍋😛j🔤dec🔤🍇🍮c➖c 1🍉🍋😛j🔤mult🔤🍇🍮c✖️c 2🍉🍋😛j🔤half🔤🍇🍮c➗c 2🍉🍋😛j🔤Pri🔤🍇👄🔡c 10🍉🍓🍇🍎🍉🍉🍉

Wypróbuj online!

🐋🔡🍇
🐖🔥🍇
🍮c 0
🔂j🍡💣🐕🔟 🍇
🍊😛j🔤inc🔤🍇🍮c➕c 1🍉
🍋😛j🔤dec🔤🍇🍮c➖c 1🍉
🍋😛j🔤mult🔤🍇🍮c✖️c 2🍉
🍋😛j🔤half🔤🍇🍮c➗c 2🍉
🍋😛j🔤Pri🔤🍇👄🔡c 10🍉
🍓🍇🍎🍉🍉🍉🍉

🏁🍇
 🔥🔤inc inc inc dec Pri exit🔤
😀🔤🔤
 🔥🔤dec inc mult inc inc Pri🔤
😀🔤🔤
 🔥🔤inc inc inc mult half Pri exit inc🔤
😀🔤🔤
 🔥🔤inc Pri inc Pri inc Pri exit half mult🔤
😀🔤🔤
 🔥🔤Pri exit🔤
😀🔤🔤
 🔥🔤inc half Pri exit🔤
🍉

0

SNOBOL4 (CSNOBOL4) , 165 bajtów

	P =INPUT ' exit ' 
	x =0
S	P LEN(1) $ L ARB ' ' REM . P	:S($L)F(end)
i	X =X + 1	:(S)
d	X =X - 1	:(S)
P	O =O X		:(S)
m	X =X * 2	:(S)
h	X =X / 2.	:(S)
e	OUTPUT =O
END

Wypróbuj online!

Obrzydliwy.

	P =INPUT ' exit ' 				;* append ' exit ' to the input to guarantee that the program will stop
	x =0						;* initialize x to 0 else it won't print properly if the program is 'Pri'
S	P LEN(1) $ L ARB ' ' REM . P	:S($L)F(end)	;* set L to the first letter of the word and goto the appropriate label
i	X =X + 1	:(S)
d	X =X - 1	:(S)
P	O =O X		:(S)				;* append X to the output string
m	X =X * 2	:(S)
h	X =X / 2.	:(S)				;* divide by 2. to ensure floating point
e	OUTPUT =O					;* print whatever's in O, which starts off as ''
END

0

C # (.NET Core), 186 bajtów

class P{static void Main(string[]a){int v=0;foreach(var s in a){var i=s[0];if(i=='i')v++;if(i=='d')v--;if(i=='m')v*=2;if(i=='h')v/=2;if(i=='P')System.Console.Write(v);if(i=='e')break;}}}

Można golić 26bytes od tego, wykonując kilka prostych rzeczy, jak deklarowania iz v, konsultacji z tabeli ASCII, dzięki czemu można używać małych liczb, rozmieszczanie ifs, a następnie za pomocą potrójnego: class Z{static void Main(string[]a){int v=0,i;foreach(var s in a){i=s[0]%'d';if(i==1)break;if(i>9)System.Console.Write(v);else v=i<1?v-1:i<5?v/2:i<6?v+1:v*2;}}}(PS wyjaśnienie jak to działa i jak używać to (np. oczekuje, że argumenty wiersza poleceń) jest zawsze mile widziane!)
VisualMelon 28.04.2018

(Och, to zawstydzające ... Powinienem był użyć %50zamiast %'d')
VisualMelon

0

Perl 5 -a , 61 bajtów

eval'$,'.qw(++ -- ;exit ;print$,||0 *=2 /=2)[(ord)%11%6]for@F

Wypróbuj online!

Stole @ user202729's ord%11%6 sztuczki

W jaki sposób?

-a            # split the input by whitespace, store in @F
eval          # Execute the string that results from:
'$,'          # $, (the accumulator)
.             # appending:
qw(           # create an array for the following whitespace separated values:
++ --            # operators for inc & dec
;exit            # exit
;print$,||0      # Pri  (||0 ensures that 0 is output if accumulator is null
*=2 /=2)         # mult div
[(ord)%11%6] # @user202729's trick selects one of the preceding operations
for@F        # for every term input

0

Pyth, 44 bajtów

Vmx"idmhPe"hdcwd=Z@[hZtZyZcZ2ZZ)NIqN4pZIqN6B

Pakiet testowy

wyjaśnienie

Vmx"idmhPe"hdcwd=Z@[hZtZyZcZ2ZZ)NIqN4pZIqN6B   ## full program
             cwd                               ## split input on space
Vmx"idmhPe"hd                                  ## iterate through list of numbers corresponding to operators
                =Z@[hZtZyZcZ2ZZ)N              ## assign the variable Z (initialliy Zero) it's new value
                                 IqN4pZ        ## print Z if the current operator is "Pri" (4)
                                       IqN6B   ## break if the current operator is "exit" (5)

0

TI-BASIC, 112 bajtów

Wykorzystuje to niektóre założenia, które są AFAIK całkowicie do przyjęcia. Po pierwsze, wszystkie zmienne są inicjowane do zera przed wykonaniem; po drugie, wejście jest pobierane przez Ans.

Ans+" E→Str1
While 1
I+4→I
sub(Str1,I-3,1→Str2
A+(Ans="I")-(Ans="D
If inString("MH",Str2
Then
I+1→I
2AAns+A/2(1-Ans
End
If Str2="P
Disp A
If Str2="E
Stop
Ans→A
End

0

Java (OpenJDK 8) , 164 bajty

a->{int c=0;for(String g:a.split(" ")){char b=g.charAt(0);if(b==105)c++;if(b==100)c--;if(b==109)c*=2;if(b==104)c/=2;if(b==80)System.out.print(c);if(b==101)return;}}

Wypróbuj online!

Powyżej znajduje się moje rozwiązanie, które zaokrągla liczby całkowite, ale poniżej moje rozwiązanie, które obsługuje liczby dziesiętne. Nieprzyjemny sposób, w jaki java drukuje dwukrotnie, dodaje kolejne 55 bajtów do wyniku. Zostawiłem nowe wiersze, aby kod był bardziej czytelny przy drugim przesyłaniu tylko dlatego, że jest to zasadniczo to samo rozwiązanie z jednym dodatkowym poleceniem i instrukcją importu.

Java (OpenJDK 8) , 219 bajtów

a->{
double c=0;
for(String g:a.split(" ")){
char b=g.charAt(0);
if(b==105)c++;
if(b==100)c--;
if(b==109)c*=2;
if(b==104)c/=2;
if(b==80)System.out.print(new DecimalFormat("0.#").format(c));
if(b==101)return;}}

Wypróbuj online!


0

C (gcc) , 120 114 111 bajtów

-6 bajtów dzięki pułapkowi cat.

x,d;f(char*s){for(x=0;s>1;s=index(d^1?s:"",32)+1)d=*s-100,x+=d?d==5:-1,x*=d^9?d^4?1:.5:2,d+20||printf("%d",x);}

Wypróbuj online!

124 bajty

Wersja zmiennoprzecinkowa:

d;f(char*s){for(float f=0;s>1;s=strchr(s,32)+1)d=*s-80,f+=d==25,f-=d==20,f*=d^29?d^24?1:.5:2,s=d^21?s:"",d?:printf("%f",f);}

Wypróbuj online!

Nie zawracałem sobie głowy wersją, która zaokrągla w dół, ale robi wyjątek dla 0, co byłoby dozwolone, jeśli poprawnie rozumiem łańcuch komentarzy.


0

33 , 62 bajty

s'i'{1a}'d'{1m}'m'{2x}'h'{2d}'P'{o}'e'{@}It[mzsjk""ltqztItn1a]

Wypróbuj online!

Ten program przyjmuje instrukcje rozdzielone znakami nowej linii

Wyjaśnienie:

It[mzsjk""ltqztItn1a]
  [mz            n1a] | Forever
It    jk       It     | - Get the first character of the next instruction
            qz        | - Call the function declared previously
     s  ""lt  t       | - Make sure we don't lose track of the variable

Kod przed tym segmentem definiuje wszystkie funkcje.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.