Sério, GolfScript, CJam ou Pyth?

56

Há algum tempo, foi feita a seguinte pergunta: GolfScript, CJam ou Pyth? Baseado apenas no título, pensei que seria um desafio muito bom, mas, infelizmente, acabou sendo uma pergunta pedindo dicas. Aqui está o desafio que eu queria ler:

Quem disse que as línguas de golfe não eram usadas no mundo real? Como todos sabem, a proporção de bugs por linha de código é a mesma independentemente da linguagem de programação usada, portanto há uma clara oportunidade de reduzir os custos de depuração e manutenção com essas linguagens. Sua empresa finalmente viu a luz e decidiu usar a Golfscript, CJam e Pyth para desenvolver seus produtos.

Infelizmente, após alguns meses, seus discos rígidos estão cheios de trechos de código e você nem sabe quais estão escritos em quais idiomas (você até suspeita que alguns de seus programadores usem Perl).

Você deve escrever uma ferramenta para detectar qual de CJam, Golfscript ou Pyth é o idioma em que um programa está escrito. A situação é crítica, você pode usar qualquer idioma que desejar, mas mantenha-o curto (o armazenamento de dados é caro: quanto mais bytes usamos, mais ele custa).

Geral

  • Menor vitória no código
  • Lacunas padrão, etc.
  • Não use um intérprete online
  • Você pode escrever uma função ou um programa
  • Você pode usar eval para detectar seu próprio idioma

Entrada

  • Sua entrada é retirada do fluxo de entrada padrão ou como uma sequência
  • A entrada contém apenas caracteres imprimíveis ASCII e alimentações de linha
  • O tamanho da entrada tem até 256 bytes de comprimento

Resultado

  • A saída é impressa no fluxo de saída ou retornada como uma sequência de strings / símbolos
  • Se a entrada for sem dúvida um programa X válido , imprima ou retorne X , X ∈ {CJam, Pyth, Golfscript}

    Observação : "sem dúvida" não significa que você pode responder com um analisador burro que falha constantemente na detecção de qualquer idioma. Para Pyth , espero que os Programas Simples sejam reconhecidos (mas não codificados). O mesmo vale para CJam ( cheat sheet , exemplos ) e Golfscript ( exemplos ). Os links anteriores apontam para as especificações de cada idioma. Se você usar uma abordagem difusa / bayesiana, "sem dúvida" significa um alto nível de confiança (você pontua 99% com sua classificação, por exemplo). Veja abaixo o conjunto de testes real.

  • Se a entrada for válida em vários idiomas, cada idioma detectado deverá ser impresso / retornado. Quando impresso, deve haver um separador entre várias saídas (por exemplo, espaço, nova linha, vírgula ...).

  • A ordem na qual os idiomas são tentados não importa
  • Eu não ligo para o caso (CJam, cjam, CJAM, SPAM) [1]
  • Se nenhum dos idiomas acima for detectado, imprima " Probably Perl" . Graças a este comentário do mbomb007 , no caso acima você também pode " Seriously" gerar uma penalidade de 4 bytes (a diferença entre as duas strings).

[1] Só para esclarecer, o spam é inválido.

Exemplos

  • Entrada

    "Crime predicted: --
    Calling: 1--555-
    
    "30*{_5<{iAa*:mr}&}/
    
  • Saída (exemplo de vários valores de retorno)

    ["Golfscript", "Cjam"]
    
  • Entrada

    3
    
  • Saída (exemplo na saída padrão)

    golfscript
    cjam
    pyth
    
  • Entrada

    if {} aazd
    
  • Resultado

    Probably Perl
    

No último caso, o programa de entrada produz um erro com os três intérpretes online.

Pontuação, critério de vitória

Menor vitória no código. Adicione 4 bytes se você exibir "Seriamente". Em seguida, aplique bônus.

Testes com falha

A seguir, trechos que não devem ser reconhecidos como nenhum dos três idiomas acima.

Alinhadores (ou seja, uma entrada por linha)
$^X=~/([a-z]+)[^\/]+$/;print$1,$/
<>;map($s-=(-1)**$_/(2*$_-1),1..$_),$s=!print$s,$/for<>
((THIS IS LISP HAIKU) (TRULY THIS IS LISP HAIKU) (THIS IS LISP HAIKU))
(format t"~@(~{~R~^, ~}~).~%~:*~@(~{~:R~^, ~}~)."(loop for i to 99 collect(1+ i)))
print sum(ord(c) for c in 'Happy new year to you!')
Brainfuck
>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.
++++++++++++++++++++++++++++++++++++++++++++++++.
-----------------.
++++++++.
+++++.
--------.
+++++++++++++++.
------------------.
++++++++.
Perl
@list=( "aaaa", 
        "aaaaaaaa", 
        "aaaaaaaaaaaaaaa", 
        "aaaaaaaaaaaaaaaa", 
        "aaaaaaaaaaaaaaaaaaaaaaa", 
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");

while (@list) {
    for($i=0;$i<6;$i++){
        print length($list[$i])." ";
    }
    print "\n";
}
Peixe
#ifndef __linux
#include "x.h"
#define X/*\
a=1 set -e
+++++++++++++++++++++_+++++++++++++....Hello World!?:Q:
#endif
    echo "Hello, World!"
    int m(){}

Conjunto de teste básico

Esses são testes que devem passar. Os seguintes são linhas de uma linha para cada idioma em que o seu programa deve detectar o idioma em que está sendo escrito (não verifiquei em qual deles é poliglota).

Pyth

*2Q
FNrZTN
FNrZhTN
FNUhTN
VhTN
FNr1hQN
=N5N
K5K
K1FNr1hQ=K*KN
K1FNr1hQ=K*KNK
K1FNr1hQ=K*KN;K
DhZK*3ZRK
L?b*bytb1yQ
A(Z1)VQHA(H+HG

Golfscript

;'2706 410'~{.@\%.}do;
;''6666,-2%{2+.2/@*\/10.3??2*+}*`50<~\;
'Hello, world!'
1 2 [\]

CJam

"Hello, world"
{`"_~"}_~
"`_~"`_~
T1{_2$+}A*]`
{__'`>\'x>26*2-*-}/
Y38#
N/s:X,8-,{X>9<__{'a<},,\4%{'Z>},,*I={4=}{;}?}/

Bônus de prata: contagem de bytes * 0,6

Todos os testes anteriores devem passar, bem como os seguintes versos. Todos esses trechos são retirados das respostas reais do CodeGolf.

Pyth

VzJ:zZhZpkJ~Zhy}rJ0-G"aeoui
Vzjdm?@zd}N,dt-lzd\ Uz
jd.iSQs*RtQ,\?":0
rsXOtQmO*-GJ"aeiou"J/Q2*%Q2O"hy"4
VhQIq`N_`NN
s["$$\\varphi=1+"*Q"\cfrac1{1+"\\<\dQ"dots"*Q\}"$$
@c"weak trick fair"d-!JlfhT-M.:us_cG.u+NYtKrH7-52hK.zU52 2>J26

Golfscript

);:|;{0):0;|$:§-1%" - "§" = ""0"4$~§~-+-4>:|n|6174`=!}do"Iterations: "0"."
'-+,/'{)))))}%
4:echo(2+2);
#undef X;A!"$%&'()*+-[,.]/0123456789:<=>?@BCDEFGHIJKLMNOPQRSTUVWYZ\^_`abcghijklmopqrstvwxyz{|}~
{`),32>^.}.~
"126,32>''+".~\-'.~\-"'-
"),@`^^32>#.~".~
...[[]]{{}}&%%++++5i
  *++..0011125::::;;;?bbbbcccc{}
"This program wasn't written in "o"GolfScript"", it was built for ""CJam"oo"!"

CJam

"Q"c("ASSW"1$("aRD"(((T1
%\@_@){;_0}*__*)\15
"This program wasn't written in "o"GolfScript"", it was built for ""CJam"oo"!"
"P2"1e3K51_,1>K*$K*~]N*
li__,\mf:i2m1+:*/fb:+
ri:B__(^2/):G/,{_BBG/@-(#G@*G(B2/*+*}/]:+
{1$+S@]_1=4+1$`,-S*"2$~"}21D2$~
[S'-26*N]:Z[S'|:PS24*PN]:RR'(PS5*qi:XD=X0<-X2%2*+:Y[" ^ "_" > ""(O)"" - "__]=S8*Y[" ^ ""   "" < ""(O)"" - "__]=S5*P')NRRXD=[SPS7*'oA*S7*PN]:QR?Y[[SPS5*'oSC*'oS5*PN]:T_R[SPS7*'oS8*'oS7*PN]RRR]=QY2=TR?RRZ
li4H#+2bW%32<2b
q~:R100:H*\d:T/i){R-H*HT-/m]}6*_H)<*
"JamesBdo,"YZ+/)BA*c+Y*Y%:BS@SB)))[JW:Z____)ci+*]U*

Bônus de ouro: pontuação anterior * 0.8

Pyth

Comparar
jdm@cd)._-FQcj"
is
equal greater less
to than
"Qb
Boneco de neve
M@GCHgc"  ___

  ___
   _"bhzgc" (_*_)
 _===_
 .....
  /_\\"bhzs[g"  \ "@z4\(g"-.oO"@z2g" ,._"@z1g"-.oO"@z3\)g"  / "@z5)s[g" < /"@z4\(gc"   
 : 
] [
> <"b@z6\)g" > \\"@z5)++" ("gc"   
 : 
\" \"
___"bez\)

CJam

grande
rri:Hri:Vri:Q[q~]3/_Qa3*a+_|$W%:Pf{\a#}:AH/:B0ff*
P,,[AHAW%HBz:+_W%V\V]2/
ff{~@@f=/::|1#}0Ua4*t:R;
P0f<
V{H{BI=J=_2$=
0R{"I>! I+V<J>! J+H<"4/+4/z{~~}%:&1$*\)}%);2$-|t
}fJ}fI
[P,{_La#\1$0t1$f-}*;;]
{:TR=2/~\~V\-,>\f{\_3$=@~H\-,>{Tt}/t}~}/
:~Pf=:~
~]S*N
Boneco de neve
q:Q;SS"
 _===_,___
 ....., _
  /_\,___
 (_*_)"',/0{Q=~(=}:G~N" \ "4G'(".oO-"_2G",._ "1G@3G')" / "5GN"< / "4G'(" : ] [> <   "3/6G')"> \ "5GNS'(" : \" \"___   "3/7G')

Golfscript

Lorem Ipsum
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras imperdiet est ut sem commodo scelerisque. Sed ut ultricies enim. Nam eget lectus suscipit, gravida turpis a, volutpat tellus. Cras efficitur luctus neque, at semper massa condimentum at posuere.
Relógio digital
:*{32' _':$@'14'{?~!=}:&~32}%n*{:x' |':|\'1237'&$x'017'&|x'56'&}%n*{:x|\'134579'&$x'147'&|x'2'&}%
Feliz Aniversário
4,{"Happy Birthday "["To You""Dear GolfScript"]@2==n}%
Sequência farey
~:c[,{){.}c(*}%.c/zip{+}*]zip{~{.@\%.}do;1=},{~<},{~\10c?*\/}${'/'*}%', '*'F'c`+' = {0/1, '+\', 1/1}'
coredump
fonte
54
Do título, eu esperava que isso incluísse uma nova linguagem esotérica chamada "Sério".
mbomb007
17
@ mbomb007 Sério: uma linguagem que executa o resultado da fonte interpretada no Golfscript como Pyth, depois envia os valores separados da nova linha para uma pilha CJam e, finalmente, gera STDOUT a partir daí. Duas vezes mais fácil de usar como perl: ^)
FryAmTheEggman
3
@ mbomb007 Sinto sua decepção. Posso sugerir que você faça sua própria pergunta? "Não faz muito tempo, a seguinte pergunta foi feita ..."
coredump
31
E é isso, meus amigos, que criaram os shebangs.
Primo
6
Darei uma recompensa de 150 representantes à primeira solução qualificada para o bônus de ouro e valida as entradas com base na correspondência de padrões, em vez da minha solução simples de executar os programas pelos intérpretes.
Mego

Respostas:

2

Rubi, (135 + 4) * 0,6 * 0,8 = 66,72

Isso funciona no Windows e eu estou cansado demais para reduzi-lo executando no Unix.

(a=[%w(javaw -jar cjam),%w(python pyth),%w(rubyw golfscript)].map{|c|c[-1]if system(*c,?f,'> NUL','2>','NUL')}-[nil])==[]?'Seriously':a

Fiz essas coisas, mas não tenho certeza se elas são permitidas:

  • Renomeie cjam-[version].jarpara cjam, pyth.pypara pyth, golfscript.rbpara golfscript.
  • Leia do arquivo em fvez de obter entrada. (Adicione IO.write(?f,gets);ao início para corrigir isso e o novo comprimento é (153 + 4) * 0,6 * 0,8 = 75,36)
RShields
fonte
Infelizmente, não posso testá-lo (uma combinação do Windows e falta de tempo). Parece bom e sua pontuação é mais baixa, então estou movendo a marca de seleção.
Coredump
39

Python 2, 332 * 0,6 * 0,8 = 159,36

import os
from subprocess import*
from tempfile import*
f,n,a=NamedTemporaryFile(delete=0),open(os.devnull,'w'),''
f.write(os.read(0,256))
f.close()
for l in["CJam","java","-jar","cjam.jar"],["Pyth","./pyth.py"],["Golfscript","./golfscript.rb"]:a+=(l[0]+' ')*(call(args=l[1:]+[f.name],stdout=n,stderr=n)>0)
print a or'Probably Perl'

Tanto quanto sei, isso está dentro das regras. Requer os intérpretes Pyth, CJam e Golfscript ( pyth.py, cjam.jare golfscript.rb) no diretório atual, e Python 3, Java e Ruby instalado. Teste simples: tente executar o programa. Se ele retornar 0, estamos bem. Caso contrário, é inválido. Um arquivo temporário nomeado (por exemplo, um arquivo criado em $TMP) é criado para manter o programa, pois o CJam não possui uma opção de script. O delete=Falsesinalizador é necessário para impedir que o arquivo seja excluído quando fechado (o sistema operacional cuidará dele). O arquivo deve ser fechado antes de tentar lê-lo (embora a liberação manual do arquivo também deva funcionar, mas isso é mais simples). stdoute stderrsão redirecionados para/dev/null suprimir saída / erros (observe que isso faz funcionar apenas em sistemas * NIX).

Diversão extra: tente executar o código fornecido nos 4 idiomas para ver o que temos:

import sys
from subprocess import*
from tempfile import*
c=["Cjam","java","-jar","cjam.jar"]
p=["Pyth","./pyth.py"]
g=["Golfscript","./golfscript.rb"]
e=["Perl","perl"]
f=NamedTemporaryFile(delete=False)
s=sys.stdin.read()
f.write(s)
f.close()
n=open('/dev/null','w+')
a=''
for l in [c,p,g,e]:
    try:
        print '%s: %s'%(l[0],check_output(args=l[1:]+[f.name],stderr=n))
    except:
        continue
n.close()
Mego
fonte
11
+1 boa resposta. E é única requer 6 intérpretes para executar, bem feito ;-)
coredump
11
bash, Python 2, Python 3, Ruby, Java, CJam, Pyth, Golfscript - eu conto 8.
Mego
2
Está certo. E com o arquivo de entrada correto, ele pode até apagar seu diretório pessoal. Enfim, essa é uma abordagem válida, não me importo.
Coredump #
Só espero que você não obtenha programas com loops infinitos ou retornando valores diferentes de zero.
Paŭlo Ebermann
@Mego se um programa falhar por algum motivo (como ao abrir um arquivo que não existe - ou quando ele espera argumentos, que eu suspeito que possa ocorrer com mais frequência em programas realmente utilizados de maneira produtiva), ele deve retornar um valor diferente de zero de acordo com esse padrão de uma década. Isso não significa que não pertence a esse idioma. (Pode ser que nenhum dos casos de teste seja realmente desse tipo.) Outro caso pode estar aguardando entrada, como um catprograma ... talvez você deva pelo menos tentar redirecionar / dev / null também para a entrada?
Paŭlo Ebermann