O GolfScript Meta Par Hole

8

Parece que o GolfScript ganha tudo isso. Então você não pode vencê-los, junte-se a eles.

Escreva um intérprete de golfe independente

Estou usando a definição de auto-contido para significar um único programa: - Portanto, não é necessário passar algum dinheiro para algum programa externo para fazer o trabalho por você.

Casos de teste:

Strings e blocos são representados como listas de códigos ASCII. Os tipos não são verificados com esses testes, mas devem estar corretos de qualquer maneira.

test("[50] [60]+", [[50, 60]]);
test("{a} {b}+", [[97, 32, 98]]);
test("'a' 'b'+", [[97, 98]]);

test("' ' 0+", [[32, 48]]);
test("' ' [50]+", [[32, 50]]);

test("{a} 0+", [[97, 32, 48]]);
test("{a} [50]+", [[97, 32, 53, 48]]);

test("5 ~", [-6]);
test('"1 2+"~', [3]);
test('{1 2+}~', [3]);
test('[1 2 3]~', [1, 2, 3]);

test('1`', [[49]]);
test("[1 [2] 'asdf']`", [[91, 49, 32, 91, 50, 93, 32, 34, 97, 115, 100, 102, 34, 93]]);
test('"1"`', [[34, 49, 34]]);
test("{1}`", [[123, 49, 125]]);

test("0!", [1]);
test("[]!", [1]);
test("{}!", [1]);
test("''!", [1]);

test("5!", [0]);
test("[[]]!", [0]);
test("{{}}!", [0]);
test("'asdf'!", [0]);

test("1 2 3 4 @", [1, 3, 4, 2]);

test("1 # 2", [1]);

test("1 2 3 4 5 1 $", [1, 2, 3, 4, 5, 4]);
test("'asdf' $", [[97, 100, 102, 115]]);
test("[5 4 3 1 2]{-1*}$", [[5, 4, 3, 2, 1]]);

test("5 7 +", [12]);
test("'a'{b}+", [[97, 32, 98]]);
test("[1 2 3][4 5]+", [[1, 2, 3, 4, 5]]);

test("1 2-3+", [1, -1]);
test("1 2 -3+", [1, -1]);
test("1 2- 3+", [2]);
test("[5 2 5 4 1 1][1 2]-", [[5, 5, 4]]);

test("2 4*", [8]);
test("2 {2*} 5*", [64]);
test("[1 2 3]2*", [[1, 2, 3, 1, 2, 3]]);
test("3'asdf'*", [[97,115,100,102,97,115,100,102,97,115,100,102]]);

test("[1 2 3]' '*", [[49, 32, 50, 32, 51]]);
test("[1 2 3][4]*", [[1,4,2,4,3]]);
test("'asdf'' '*", [[97,32,115,32,100,32,102]]);
test("[1 [2] [3 [4 [5]]]]' '*", [[49, 32, 2, 32, 3, 4, 5]]);
test("[1 [2] [3 [4 [5]]]][6 7]*", [[1, 6, 7, 2, 6, 7, 3, [4, [5]]]]);

test("[1 2 3 4]{+}*", [10]);
test("'asdf'{+}*", [414]);

test("7 3 /", [2]);
test("[1 2 3 4 2 3 5][2 3]/", [[[1], [4], [5]]]);
test("[1 2 3 4 5] 2/", [[[1, 2], [3, 4], [5]]]);

test("0 1 {10<} { .@+ } /", [8, [1, 1, 2, 3, 5, 8]]);
test("[1 2 3]{1+}/", [2, 3, 4]);

test("7 3 %", [1]);

test("'assdfs' 's'%", [[[97], [100, 102]]]);
test("'assdfs' 's'/", [[[97], [], [100, 102], []]]);

test("[1 2 3 4 5] 2%", [[1, 3, 5]]);
test("[1 2 3 4 5] -1%", [[5, 4, 3, 2, 1]]);
test("[1 2 3] {1+}%", [[2, 3, 4]]);

test("5 3 |", [7]);
test("[5 5 1] [1 3] |", [[5, 1, 3]]);

test("5 3 &", [1]);
test("[1 1 2 2][1 3]&", [[1]]);

test("5 3 ^", [6]);
test("[1 1 2 2][1 3]^", [[2, 3]]);

test("1 2 [\\]", [[2, 1]]);

test("1 2 3 \\", [1, 3, 2]);
test("1 2 3; ", [1, 2]);

test("3 4 <", [1]);
test('"asdf" "asdg" <', [1]);
test("[1 2 3] 2 <", [[1, 2]]);
test("{asdf} -1 <", [[97, 115, 100]]);

test("3 4 >", [0]);
test('"asdf" "asdg" >', [0]);
test("[1 2 3] 2 >", [[3]]);
test("{asdf} -1 >", [[102]]);

test("3 4 =", [0]);
test('"asdf" "asdg" =', [0]);
test("[1 2 3] 2 =", [3]);
test("{asdf} -1 =", [102]);

test("3,", [[0,1,2]]);
test("10,,", [10]);
test("10,{3%},", [[1, 2, 4, 5, 7, 8]]);

test("1 2 .", [1,2,2]);

test("2 8?", [256]);
test(" 5 [4 3 5 1] ?", [2]);
test(" 6 [4 3 5 1] ?", [-1]);

test("[1 2 3 4 5 6] {.* 20>} ?", [5]);

test("5(", [4]);
test("[1 2 3](", [[2, 3], 1]);

test("5)", [6]);
test("[1 2 3])", [[1, 2], 3]);

test("5 {1 0/} or", [5]);
test("5 {1 1+} and", [2]);
test("0 [3] xor", [[3]]);
test("2 [3] xor", [0]);

test("5{1-..}do", [4, 3, 2, 1, 0, 0]);
test("5{.}{1-.}while", [4, 3, 2, 1, 0, 0]);
test("5{.}{1-.}until", [5]);

test("1 2 3 if", [2]);
test("0 2 {1.} if", [1, 1]);

test("[[1 2 3][4 5 6][7 8 9]]zip", [[[1, 4, 7], [2, 5, 8], [3, 6, 9]]]);

test("[1 1 0] 2 base", [6]);
test("6 2 base", [[1, 1, 0]]);
Adam Speight
fonte
4
Aviso para quem tenta isso: é uma tarefa muito grande se você não estiver usando um idioma intimamente relacionado ao Ruby.
Peter Taylor
@ PeterTaylor Onde você diria que a melhor documentação é para alguém que está tentando esta tarefa? É o site golfscript.com, ou seria melhor apenas procurar na própria fonte golfscript.rb?
Gareth
2
Você ganha pontos extras por escrevê-lo no Golfscript?
Sr. Lister
3
Você sabe, para uma tarefa tão complexa, o solicitante de perguntas realmente deve postar um bom conjunto de casos de teste ...
Peter Taylor
4
Temos que apoiar a avaliação de strings de rubi, como "The time is #{Time.now}"? Que tal números de precisão arbitrários?
copie

Respostas:

9

Ruby, 5490 bytes

Bem, eu posso jogar golfe no interpretador GolfScript de 8283 bytes até 5490 ...

$m=[];class G;def g;$k<<self;end;def v;@v;end
'+-|&^'.each_byte{|i|eval'def%c(r);if r.class!=self.class
a,b=u(r);a%c b;else;f(@v%c r.v);end;end'%([i]*3)}
def==(r);@v==r.v;end;def eql?(r);@v==r.v;end;def hash
@v.hash;end;def<=>(r);@v<=>r.v;end;end;class H<G;def
initialize(i);@v=case i;when true then 1;when false then 0
else;i;end;end;def f(a);H.new(a);end
def t;J.new(@v.to_s);end;def to_int#for pack
@v;end;def s;t;end;def N;0;end;def u(b);[if b.class==I
I.new([self]);elsif b.class==J;t;else#K
t.to_s.w;end,b];end;def~;H.new(~@v);end;def R;H.new(@v==0)
end;'*/%<>'.each_byte{|i|eval'def%c(r);H.new(@v%c r.v)
end'%[i,i]};def E(r);H.new(@v==r.v);end;def q(b)
H.new(@v**b.v);end;def B(a);if I===a;r=0;a.v.each{|i|r*=@v
r+=i.v};H.new(r);else;i=a.v.abs;r=[];while i!=0;r.unshift
H.new(i%@v);i/=@v;end;I.new(r);end;end;def n;H.new(@v-1);end;def
p;H.new(@v+1);end;end;class I<G;def initialize(a);@v=a;end;def
f(a);I.new(a);end;def t;@v.inject(J.new("")){|s,i|s+i.t};end
def F#maybe name to_a ?
I.new(@v.inject([]){|s,i|s+case i;when J then i.v;when H then[i]
when I then i.F.v;when K then i.v;end});end;def s
J.new('[')+I.new(@v.map{|i|i.s})*J.new(' ')+J.new(']');end;def
g;$k<<self;end;def N;1;end;def u(b);if b.class==H
b.u(self).reverse;elsif b.class==J;[J.new(self),b];else
[(self*J.new(' ')).to_s.w,b];end;end;def n;[f(@v[1..-1]),@v[0]]
end;def p;[f(@v[0..-2]),@v[-1]];end;def*(b);if b.class==H
f(@v*b.v);else;return b*self if self.class==J&&b.class==I;return
self/H.new(1)*b if self.class==J;return;b.f([])[email protected]<1
[email protected];r,x=r.u(b)if r.class!=b.class#for size 1
@v[1..-1].each{|i|r=r+b+i};r;end;end;def/(b);if b.class==H
r=[];a=b.v<0 [email protected]: @v;i=-b=b.v.abs
r<<f(a[i,b])while(i+=b)<a.size;I.new(r);else;r=[];i=b.f([])
j=0;while j<@v.size;if@v[j,b.v.size]==b.v;r<<i;i=b.f([])
j+=b.v.size;else;i.v<<@v[j];j+=1;end;end;r<<i;I.new(r);end;end
def%(b);if b.class==H;b=b.v
f((0..(@v.size-1)/b.abs).inject([]){|s,i|s<<@v[b<0 ?i*b-1:i*b]})
else;self/b-I.new([I.new([])]);end;end;def R;H.new(@v.empty?)
end;def q(b);H.new(@v.index(b)||-1);end;def E(b);b.class==H ?
@v[b.v] : H.new(@v==b.v);end;def<(b);b.class==H ? f(@v[0..b.v]):
H.new(@v<b.v);end;def>(b);b.class==H ?
f(@v[[b.v,[email protected]].max..-1]) : H.new(@v>b.v);end;def sort
f(@v.sort);end;def T;r=[];@v.size.times{|x|@v[x].v.size.times{|y|
(r[y]||=@v[0].f([])).v<<@v[x].v[y]}};I.new(r);end;def~;v;end;end
class J<I;def initialize(a);@v=case a;when String then
a.unpack('C*').map{|i|H.new(i)};when Array then a;when I then
a.F.v;end;end;def f(a);J.new(a);end;def t;self;end;def s
f(to_s.inspect);end;def to_s;@v.pack('C*');end;def N;2;end
def u(b);b.class==K ? [to_s.w,b]:b.u(t).reverse;end;def q(b)
if b.class==J;H.new(to_s.index(b.to_s)||-1);elsif b.class==I
b.q(t);else;H.new(@v.index(b)||-1);end;end;def~;to_s.w.g;nil;end
end;class K<I;def initialize(a,b=nil);@v=J.new(b).v
@n=eval("lambda{#{a}}");end;def g;@n.call;end;def f(b)
J.new(b).to_s.w;end;def N;3;end;def t;J.new("{"+J.new(@v).to_s+"}")
end;def s;t;end;def u(b);b.u(self).reverse;end;def+(b);if
b.class!=self.class;a,b=u(b);a+b;else
J.new(@v+J.new(" ").v+b.v).to_s.w;end;end;def*(b);if b.class==H
b.v.times{g};else;z b.v.first;(b.v[1..-1]||[]).each{|i|$k<<i;g}
end;nil;end;def/(b);if b.class==I||b.class==J;b.v.each{|i|z i;g}
nil;else#unfold
r=[];loop{$k<<$k.last;g;break if y.R.v!=0;r<<$k.last;b.g}
y;I.new(r);end;end;def%(b);r=[];b.v.each{|i|m=$k.size
$k<<i;g;r.concat($k.slice!(m..$k.size))};r=I.new(r)
J==b.class ? J.new(r):r;end;def~;g;nil;end
def sort;a=y;a.f(a.v.sort_by{|i|z i;g;y});end
def C(a);a.f(a.v.C{|i|z i;g;y.R.v==0});end
def q(b);b.v.find{|i|z i;g;y.R.v==0};end;end
class NilClass;def g;end;end
class Array;def^(r);self-r|r-self;end;include Comparable;end
e=gets(nil)||'';Q=$stdin;$_=Q.isatty ? '':Q.read;$k=[J.new($_)]
$l={};def x(name,v=nil);eval"#{s="$_#{$l[name]||=$l.size}"}||=v"
s;end;$j=0
class String;def W;K.new(self);end;def X;('a=y;'+self).W;end
def Y;('b=y;a=y;'+self).W;end;def Z;('c=y;b=y;a=y;'+self).W;end
def o;('b=y;a=y;a,b=b,a if a.N<b.N;'+self).W;end;def
w(a=scan(/[a-zA-Z_][a-zA-Z0-9_]*|'(?:\\.|[^'])*'?|"(?:\\.|[^"])*"?|-?[0-9]+|#[^\n\r]*|./m))
b=a.dup;c="";while t=a.slice!(0);c<<case t
when"{"then"$k<<"+x("{#{$j+=1}",w(a));when"}"then break
when":"then x(a.slice!(0))+"=$k.last"
when/^["']/ then x(t,J.new(eval(t)))+".g"
when/^-?[0-9]+/ then x(t,H.new(t.to_i))+".g"
else;x(t)+".g";end+"\n";end
d=b[0,b.size-a.size-(t=="}"?1:0)]*"";K.new(c,d);end;end
def y;($m.size-1).downto(0){|i|break if$m[i]<$k.size;$m[i]-=1}
$k.pop;end;def z a;$k.push(*a)if a;end
x'[','$m<<$k.size'.W;x']','z I.new($k.slice!(($m.pop||0)..-1))'.W
x'~','z~a'.X;x'`','z a.s'.X;x';',''.X;x'.','$k<<a<<a'.X
x'\\','$k<<b<<a'.Y;x'@','$k<<b<<c<<a'.Z;x'+','z a+b'.Y
x'-','z a-b'.Y;x'|','z a|b'.Y;x'&','z a&b'.Y;x'^','z a^b'.Y
x'*','z a*b'.o;x'/','z a/b'.o;x'%','z a%b'.o;x'=','z a.E(b)'.o
x'<','z a<b'.o;x'>','z a>b'.o;x'!','z a.R'.X
x'?','z a.q(b)'.o;x'$','z(a.class==H ? $k[~a.v]:a.sort)'.X
x',','z case a;when H then I.new([*0...a.v].map{|i|H.new(i)})
when K then a.C(y);when I then H.new(a.v.size);end'.X
x')','z a.p'.X;x'(','z a.n'.X
x'rand','z H.new(rand([1,a.v].max))'.X;x'abs','z H.new(a.v.abs)'.X
x'print','print a.t'.X;x'if',"#{x'!'}.g;(y.v==0?a:b).g".Y
x'do',"loop{a.g;#{x'!'}.g;break if y.v!=0}".X
x'while',"loop{a.g;#{x'!'}.g;break if y.v!=0;b.g}".Y
x'until',"loop{a.g;#{x'!'}.g;break if y.v==0;b.g}".Y
x'zip','z a.T'.X;x'base','z b.B(a)'.Y
'"\n":n;{print n print}:puts;{`puts}:p;{1$if}:and;{1$\if}:or;{\!!{!}*}:xor;'.w.g
e.w.g;z I.new($k);'puts'.w.g
multidão
fonte
10

Javascript, 2227 bytes

@ Peter Taylor: Desafio aceito!

_ = 'S = b9b? B ^ 3? "{" +) + "}": \' "\ '+) + \'" \ ': "[" + B6SB "") + "]": "" " + b}; $ = b ||! b99b: [b] b6 $ B "" L; M = b9 $ (bb + ""}; A = b? (gb.charCodeAt (0) A (b1)) v = g, v = 3, g, v}; C = b9 (k = b6Ck = b, kb}; a = g, s, O, r = Wj, uX, d, c, i, yPb = (b? $ (bb + ""). match (/ \ '(. | [^ \']) * \ '| "(. | [^"]) * "| -? \\ d + | \\ 043 [^ \\ n ] * | [a-z _] \\ w * | ./imgFi=y=0; z = b [i ++];) "{" Yz?! y ++ Zk = iy? "}" Yz! - yZe = A (bk, i-1B "")) e = 4 \ '"\' YzQ? A (eval (z.replace (" \\ n "," n ")))" \ '"YzQ? A ( z1, -1) .replace (/ (| \ ') / g, "$ 1")) ":" Yz? r [b [i ++]] = (d = s [s-1]) ^ 4? S ( dd: r [z]? r [z] z + "." - 0,1? eval (z) eval ("// ~ t; t98? ts = st ~ t \\ 140A (S (G))) // [ O.uns] JEt, u @ `vEuX, v%` I! U) t% u! TPt3? [32]: [] Xu + tV-5! ~ Tc) RcL # qt / `I! U) Matemática. float / u)! tPv = 0; j% tY0ZvRvv,vvcdvLu ^ 4Pp = 1 ITPFd; \ '. \' u;) ds [s-1] tGdL # {D; HL // * 7I! t) q * t! uPFd; u -;) T? td = dCUd = 8; T || dL8 ^ 4P! U8Zu6M) 6A) d = dC (j? T: [] cd = 8; GdL # {q.) HL // zipt; Fv = c; v -;)! D [v] Zd [v] d [v] c [v] 7IT) HG) Zcu # t9tuMath.pow (uX) $ t; u = 0; t9 (T? (u = t, G) t) .sort (uZaua, bubb-a} C (s ~ t) Q) = `t! 9ut) Q: 0 | $ (u) Y $ U> N $ U | 0: t0Xu> t | 0V) K ()]: [t + 1] (K.)]: [t-1] & 5v; ~ tc) vc & t | 5dvt | t ^ 5v; k, ut! ~ tc) ^! ~ kc) vc ^ tif`v =? u : t; v ^ 4? A (S (v) v! +! randMath.random () * G) | 0) ". split (" // "+ z) [1] L, \ '{1 $ se }: e {1 $ if}: ou {!! {!} *}: xor {.. 0sZOQ = sFfoGs (HctIif (Js.splice (O.)) Kt; s = st9 [tXL)} N`q9t9 $ (u) P) {Q [0] RdT8> 3U (t) V8 // Função (b, X, tY == Z (`; qu '; para (Y = 0; $ =' q`ZYXWVUTRQPNLKJIHGFEDB98765 # '[ Y ++];) com (_. Split ($)) _ = junção (pop ()); eval (_)d [v] Zd [v] d [v] c [v] 7IT) HG) Zcu # t9tuMath.pow (uX) $ t; u = 0; t9 (T? (u = t, G) t). class (uZaua, bubb-a} C (s ~ t) Q) = `t! 9ut) Q: 0 | $ (u) Y $ U> N $ U | 0: t0Xu> t | 0V) K ()] : [t + 1] (K.)]: [t-1] & lt; 5cv; vc & t | 5dvt | t ^ 5v; k, ut! ~ tc) ^! ~ kc) vc ^ tif`v =? u: t; v ^ 4? A (S (v) v! +! randMath.random () * G) | 0) ". split (" // "+ z) [1] L, \ '{1 $ if}: e {1 $ if}: ou {!! {!} *}: xor {.. 0sZOQ = sFfoGs (HctIif (Js.splice (O.)) Kt; s = st9 [tXL)} N`q9t9 $ (u) P) {Q [0] RdT8> 3U (t) V8 // Função (b, X, tY == Z (`; qu '; para (Y = 0; $ =' q`ZYXWVUTRQPNLKJIHGFEDB98765 # # [Y ++];) com (_. Split ($)) _ = junção (pop ()); eval (_)d [v] Zd [v] d [v] c [v] 7IT) HG) Zcu # t9tuMath.pow (uX) $ t; u = 0; t9 (T? (u = t, G) t). class (uZaua, bubb-a} C (s ~ t) Q) = `t! 9ut) Q: 0 | $ (u) Y $ U> N $ U | 0: t0Xu> t | 0V) K ()] : [t + 1] (K.)]: [t-1] & lt; 5cv; vc & t | 5dvt | t ^ 5v; k, ut! ~ tc) ^! ~ kc) vc ^ tif`v =? u: t; v ^ 4? A (S (v) v! +! randMath.random () * G) | 0) ". split (" // "+ z) [1] L, \ '{1 $ if}: e {1 $ if}: ou {!! {!} *}: xor {.. 0sZOQ = sFfoGs (HctIif (Js.splice (O.)) Kt; s = st9 [tXL)} N`q9t9 $ (u) P) {Q [0] RdT8> 3U (t) V8 // Função (b, X, tY == Z (`; qu '; para (Y = 0; $ =' q`ZYXWVUTRQPNLKJIHGFEDB98765 # # [Y ++];) com (_. Split ($)) _ = junção (pop ()); eval (_)0sZOQ = sFfoGs (HctIif (Js.splice (O.)) Kt; s = st9 [tXL)} N`q9t9 $ (u) P) {Q [0] RdT8> 3U (t) V8 // Função (b, X, tY == Z (`; qu '; para (Y = 0; $ =' q`ZYXWVUTRQPNLKJIHGFEDB98765 # '[Y ++];) com (_. Split ($)) _ = join (pop ()); eval (_)0sZOQ = sFfoGs (HctIif (Js.splice (O.)) Kt; s = st9 [tXL)} N`q9t9 $ (u) P) {Q [0] RdT8> 3U (t) V8 // Função (b, X, tY == Z (`; qu '; para (Y = 0; $ =' q`ZYXWVUTRQPNLKJIHGFEDB98765 # '[Y ++];) com (_. Split ($)) _ = join (pop ()); eval (_)

Nota: Contém alguns caracteres de controle, mas nada fora do ASCII. Aqui está um link direto para o arquivo: gs.js . O código fornece uma função aque pega o código Golfscript como um único parâmetro e retorna a pilha resultante como uma matriz, com cadeias e blocos representados como ASCII.

Diferenças do intérprete oficial:

  • Os números têm apenas 53 bits de precisão
  • Nenhuma saída exata e nenhuma direta print(seria fácil adicionar)
  • As strings entre aspas duplas são analisadas usando a avaliação do Javascript, que pode funcionar diferente da do Ruby. Também não há acesso às funções Ruby via strings
  • Comportamento indefinido (tentei o meu melhor)

Também fiz vários casos de teste e configurei um pequeno formulário para executar o código Golfscript: http://copy.sh/golfscript/

aqui estão alguns exemplos:

Esta é minha biblioteca Golfscript padrão, sugestões são bem-vindas:

{1$if}:and
{1$\\if}:or
{\!!{!}*}:xor
{..0<2**-}:abs
{\{!}+\while}:until
{0$}:.
"\n":n
{\.[]*{0{2$*\(@+1$}do@;\;}{[{.@.@\\%@@.@\/.}do;;]-1%}if}:base
];
cópia de
fonte
;[1 2]{+}*parece repetir para sempre em vez de avaliar quase instantaneamente 3. Tudo o resto que tentei até agora funcionou. Fará mais alguns testes mais tarde.
Peter Taylor
;[1 2]{+}*funciona para mim (também todos os casos de teste são aprovados), mas esse bug pode aparecer devido ao estado global. Estou pesquisando ...
copie
E um pequeno problema de que os números não são tratados como variáveis: 11:10 10 * não aparece 121como deveria. Também parece lidar com a pilha vazia de maneira inconsistente: ;5 p 4 * pnão deve funcionar, mas dá 20.
Howard
As variáveis ​​numéricas @ Howard devem funcionar agora. A outra coisa não é executada conforme o esperado, porque pnão está definida
copie