Escreva um intérprete para *

20

A tarefa é simples. Escreva um intérprete para o idioma * .

Aqui está um link maior para o wiki.

Existem apenas três programas * válidos:

  • * Imprime "Olá, mundo"
  •  *  Imprime um número aleatório entre 0 e 2.147.483.647
  • *+* Corre para sempre.

O terceiro caso deve ser um loop infinito de acordo com as especificações nesta pergunta

Entrada:

  • A entrada pode ser obtida através de qualquer método de entrada aceitável pelas nossas regras de E / S padrão
  • Será sempre um dos programas acima

Resultado:

  • O primeiro caso deve ser impresso exatamente Hello World, com ou sem uma quebra de linha à direita.
  • Para o segundo caso, se o número inteiro máximo do seu idioma for menor que 2.147.483.647, use o número inteiro máximo do seu idioma
  • O primeiro e o segundo casos podem ser impressos em qualquer saída aceitável de acordo com nossas regras de E / S padrão.
  • O terceiro caso não deve dar saída.

Pontuação:

Como se trata de , a resposta mais curta, em bytes, vence.

TheOnlyMrCat
fonte
7
Quando você diz "entre 0e 2,147,483,647", isso é inclusivo ou exclusivo? (Por exemplo, é 0uma saída válida?)
Chas Brown
7
Alterar as especificações após postar um desafio e invalidar as soluções existentes é automático -1para mim.
Shaggy
2
Para idiomas que não possuem uma maneira integrada de gerar um número aleatório, existe uma maneira aceitável de satisfazer o requisito "imprimir um número aleatório"?
Tanner Swett em
2
Se os números inteiros da nossa língua não tiverem um valor máximo, ou mais alto, podemos usar um limite superior mais alto?
Jonathan Allan
7
@ Shaggy Não estou vendo nenhuma alteração de regra no wiki para a pergunta, apenas um espaço para um espaço sem quebra (verifique a guia de remarcação), porque o renderizador de remarcação do SE não estava renderizando, mas olhando para a revisão original , é claro que deve haver espaços normais, e o "hack" é feito apenas para problemas com o renderizador de redução de preço do SE
Ferrybig

Respostas:

20

* , 0 bytes


Como * não tem como ler a entrada, as regras padrão permitem especificar que a entrada deve ser fornecida concatenando-a no programa .

(... eu acho. Existe uma condição "pelo menos o dobro de votos positivos e negativos" que eu não tenho o representante para verificar).

Henning Makholm
fonte
4
Seu meta vinculado é realmente um padrão de site atualmente aceito (+31 -7).
Jonathan Allan
2
@A__: Parece-me que ele deve ter sido projetado especificamente para satisfazer a definição proposta por alguém de 'linguagem de programação' ("Você pode escrever um hello world!" "Você pode escrever um loop infinito!" "Você pode escrever um programa que não sempre faça a mesma coisa! ").
Henning Makholm
Eu acredito que tecnicamente Malbolge também não é uma linguagem de programação.
Bob Jansen
1
Malbolge é uma linguagem de programação para autômatos finitos, o mesmo que *, e, por exemplo, Befunge-93. Portanto, Malbolge é uma linguagem de programação formal, o mesmo que *, tecnicamente o mesmo que linguagens recursivamente enumeráveis ​​quando se trata de definição de linguagem de programação (embora as linguagens formais sejam menos poderosas).
Krzysztof Szewczyk
Voto negativo de mim, porque honestamente, essa resposta é tão chata que na verdade já é uma
brecha
8

R , 69 bytes

switch(scan(,""),"*"="Hello, World!"," * "=sample(2^31,1)-1,repeat{})

Experimente online!

switchtenta corresponder aos argumentos nomeados e, se não houver correspondência, seleciona o primeiro sem nome após o primeiro, que neste caso é o loop infinito repeat{}.

Giuseppe
fonte
6

Geléia ,  21  20 bytes

ḊOSØ%HX’¤“½,⁾ẇṭ»¹Ḃ¿?

Um link monádico que aceita uma lista de caracteres.

Experimente online!

vL’... também funciona (veja abaixo).

Quão?

ḊOSØ%HX’¤“½,⁾ẇṭ»¹Ḃ¿? - Link: list of characters   e.g.: "*"        or  " * "    or  "*+*"
Ḋ                    - dequeue                          ""             "* "         "+*"
 O                   - to ordinals                      []             [42,32]      [43,42]
  S                  - sum                              0              74           85
                   ? - if...
                  ¿  - ...if-condition: while...
                 Ḃ   -    ...while-condition: modulo 2  0              0            1
                ¹    -    ...while-true-do: identity                                85
                     -                                  0              74           (looping)
        ¤            - ...then: nilad followed by link(s) as a nilad:
   Ø%                -    literal 2^32                                 2^32
     H               -    half                                         2^31
      X              -    random integer in [1,n]                      RND[1,2^31]
       ’             -    decrement                                    RND[0,2^31)
         “½,⁾ẇṭ»     - ...else: dictionary words        "Hello World"

Alternativo

vL’... - Link: list of characters                 e.g.: "*"        or  " * "    or  "*+*"
 L     - length                                         1              3            3
v      - evaluate (left) as Jelly code with input (right)
       -                                                1^1            3^3          (3^3+3)^3
       -                                                1              27           27000
  ’    - decrement                                      0              26           26999
   ... - continue as above                              "Hello World"  RND[0,2^31)  (looping)
Jonathan Allan
fonte
5

C (gcc) , 66 63 bytes

Obrigado a attinat pelos -3 bytes.

Eu só tenho que verificar o segundo caractere: se o LSB estiver definido, é um +(portanto, o programa é " *+*") e o programa faz um loop. Depois disso, se for NUL" *" , o programa foi " " e nós exibimos Hello World; caso contrário, ele exibirá um valor aleatório ("  * ", a única outra opção restante.)

f(char*s){for(s++;*s&1;);printf(*s?"%d":"Hello World",rand());}

Experimente online!

ErikF
fonte
63 bytes
attinat 9/08
Shave a byte:f(char*s){*++s&1?f(s-1):printf(*s?"%d":"Hello World",rand());}
Roman Odaisky
Nota pedante: randnão é garantido que retorne um valor suficientemente grande; RAND_MAXe INT_MAXnão é garantido que sejam os mesmos (e não estão nos compiladores do mundo real, por exemplo, o Visual Studio RAND_MAXé 32767, enquanto INT_MAX[nos modernos sistemas derivados de x86] é o 2147483647valor especificado na pergunta do OP).
ShadowRanger
@ShadowRanger isso é completamente verdade, mas considerando que> 90% de todas as entradas CGCC baseadas em C dependem de comportamento indefinido e não especificado, não estou preocupado com isso! Eu também não estava com vontade de implementar um LCG com código de golfe hoje. :-)
ErikF 12/08
5

Python 2 , 103 93 89 87 bytes

Eu combinei minha resposta anterior com Chas das Browns resposta e tem algo alguns bytes mais curto.

O número aleatório estará entre 0 e 2 ** 31-1, inclusive.

from random import*
i=input()
while'*'<i:1
print["Hello World",randrange(2**31)][i<'!']

Experimente online!

Versões prévias:

103 bytes

from random import*
exec['print"Hello World"','while 1:1','print randint(0,2**31-1)'][cmp(input(),'*')]

93 bytes

from random import*
i=cmp(input(),'*')
while i>0:1
print["Hello World",randint(0,2**31-1)][i]
mbomb007
fonte
Salve 2 bytes substituindo randint(0,2**31-1)por randrange(2**31).
Chas Brown
while'*'<iSalvar 2
Jonathan Allan
Salve outro byte alterando randrange(2**31)para getrandbits(31)(o último retorna long, não int, mas printimprimirá o strformulário, não o reprformulário, para que o final Lnão esteja lá).
ShadowRanger
Relativamente inexperiente com o site, esclarecimentos tão rápidos: Você pode exigir que sua entrada seja citada? i=input()só funciona se as entradas forem citadas; se você simplesmente inserir sem formatação */ * /*+*, ela morreria com a SyntaxError(porque inputinclui um implícito eval); você precisaria inserir '*'/' * '/'*+*'(ou equivalente com aspas duplas). Não vi nada óbvio nas regras de E / S padrão que permitissem isso, o que poderia significar que você precisaria usar raw_input(), custando quatro bytes.
ShadowRanger
O @ShadowRanger input()pega uma string como entrada e a avalia. Eu realmente não estou adicionando à entrada, estou apenas tomando uma string como entrada, e as cordas têm aspas. Isso é bastante padrão, da mesma maneira que eu posso pegar uma matriz como, em [1,2,3]vez de uma string delimitada, que eu tenho que dividir e analisar. O objetivo do site não é restringir a entrada, é facilitar a E / S, para que possamos focar o código no desafio em questão.
mbomb007 12/08
5

Barril , -lp, -ir 30 26 25 24 20 19 bytes

!1=[_“H%c¡“| =[~.|{

-1 byte usando sinalizadores

Experimente online!

Histórico de respostas

?!1=[_“H%c¡“| =[~.|{

Experimente online!

Encurtada Hello Worldpara a sequência de dicionários

!1=[_Hello World| =[~.|{

Experimente online!

Eu nunca deixei de me surpreender com o poder do barril. Créditos ao usuário EdgyNerd por outro byte salvo.

Versões anteriores

_!0=[Hello World|\*=[~.|{

Experimente online!

Crédito ao usuário A__ pelo byte extra salvo.

Versão antiga

?!1=[_Hello World| =[__~|{

Essencialmente, pega o programa de entrada e:

  • Verifica se o comprimento da entrada é 1, imprimindo "Hello World" se true
  • Verifica se o último caractere é um espaço e imprime um número aleatório
  • Caso contrário, executa um loop infinito

Em seguida, imprima implicitamente a pilha.

?                               #Get input from the user
 !1=                            #Compare the stack's length to 1
    [_Hello World           #Push "Hello, World!" to the stack
                     | =        #See if top item is a space
                        [__~|{  #If so, generate a random number, otherwise, infinite loop.

4 bytes salvos devido ao fato de o hello world não precisar de pontuação.

Experimente online! Versão antiga

Experimente online! Nova versão

Jono 2906
fonte
Você pode cortar 4 bytes, não precisa de vírgula ou ponto de exclamação em "Hello World".
TheOnlyMrCat
1
Agora eu tenho que aprender outro idioma impopular para responder aos desafios aqui normalmente.
A
1
-1 bytes: TIO . Fico feliz por não ter perdido minha capacidade de jogar golfe em Keg.
A
@A__ Está gostando de Keg no TIO?
Jono 2906
2
24 bytes :)
EdgyNerd
3

Befunge-93 , 54 bytes

~"*"-_~1+#^_"dlroW olleH">:#,_@.%*2**:*::*88:*`0:?1#+<

Experimente online!

Anotado:

~"*"-                      _                ~1+                   #^_        "dlroW olleH">:#,_    @      .%*2**:*::*88:   *`0:             ?1#+<
Compare first      If equal, go right       Compare second       If equal,        Output          Exit    Modulo by 2^31   If less than      Add 1
character to       Otherwise, go left       character to       loop forever   "Hello World"                 and output     0, multiply     a random amount
'*'                and wrap around          -1 (EOF)                                                                         by 0            of times

A aleatoriedade não é uniforme. A cada incremento, há 50% de chance de parar de incrementar.

sete negativos
fonte
3

Japonês , 22/25 bytes

A primeira solução é para as especificações originais que tinham *<space>como segundo programa e a outra é para as especificações atualizadas que as alteraram arbitrariamente para <space>*</space>, com agradecimentos a EoI pela "correção" sugerida.

Ambos lançam um erro de estouro ao entrar no loop infinito do terceiro programa, mas, teoricamente, com memória suficiente (o que podemos assumir para os propósitos do ), funcionaria para sempre.

Å?¢?ß:2pHÉ ö:`HÁM Wld

Experimente o programa 1
Experimente o programa 2
Experimente o programa 3

Å?UÎ>S?ß:2pHÉ ö:`HÁM Wld

Experimente o programa 1
Experimente o programa 2
Experimente o programa 3

Shaggy
fonte
Eu acho que o segundo programa é "[ESPAÇO] * [ESPAÇO]", não "[ESPAÇO] *", para que seu programa não funcione
Modalidade de ignorância
@EmbodimentofIgnorance, no momento em que publiquei, o segundo programa na especificação era *<space> . Não tem tempo para atualizar agora.
Shaggy
Você pode corrigi-lo em três bytes, em UÌ>Svez de ¢no segundo ternário
Modalidade de Ignorância
@ Downvoter, tenha a cortesia de deixar um comentário.
Shaggy
2

JavaScript (ES7), 66 bytes

s=>s[1]?s<'!'?Math.random()*2**31|0:eval(`for(;;);`):'Hello World'

Experimente online! (Olá Mundo)

Experimente online! (número aleatório)

Experimente online! (Loop infinito)

Arnauld
fonte
Será que x=(z=>x())&&x()não funciona para -1byte do código de loop infinito, assumindo um navegador sem tamanho máximo pilha de chamadas?
Geza Kerecsenyi
@GezaKerecsenyi Poderíamos chamar a nós mesmos ( assim ), mas não tenho certeza se isso seria aceitável.
Arnauld
isso é justo. Gostaria de saber se existe algum navegador obscuro por aí que apenas continue (pelo menos até que a RAM se esgote)
Geza Kerecsenyi
1
@ Arnauld, teoricamente, que funcionaria para sempre, com memória infinita, o que podemos assumir como código de golfe.
Shaggy
2

Geléia , 23 21 bytes

OS¹Ḃ¿ịØ%HX’;““½,⁾ẇṭ»¤

Experimente online!

Um link monádico pegando um único argumento e retornando Hello World, um inteiro aleatório de 31 bits ou fazendo um loop infinito conforme a especificação.

Todas as opções: * * *+*

Explicação

O                     | Convert to codepoints
 S                    | Sum
  ¹Ḃ¿                 | Loop the identity function while odd 
     ị              ¤ | Index into the following as a nilad:
      Ø%              | - 2 ** 32
        H             | - Halved
         X            | - Random integer in the range 1..2**31
          ’           | - Decrease by 1 
           ;          | - Concatenated to:
            ““½,⁾ẇṭ»  |   - "", "Hello World"
Nick Kennedy
fonte
2

Python 2 , 91 89 88 bytes

from random import*
def f(p):
 while'*'<p:p
 print['Hello World',getrandbits(31)][p<'!']

Experimente online!

2 bytes graças a Jonathan Allan ; 1 byte thx para o ShadowRanger .

Chas Brown
fonte
while'*'<psalva 2
Jonathan Allan
getrandbits(31)salva um byte randrange(2**31).
ShadowRanger
Agradável! Não sabia sobre getrandbits ...
Chas Brown
1

Perl 5 -p , 43 39 bytes

$_=/ /?0|rand~0:/\+/?redo:"Hello World"

Experimente online!

Xcali
fonte
1

Ruby -n , 47 bytes

puts~/ /?rand(1<<31):~/\+/?loop{}:"Hello World"

Experimente online!

Value Ink
fonte
1

Carvão , 30 bytes

W№θ*F⁼θ*≔Hello Worldθ∨θI‽X²¦³¹

Experimente online! Link é a versão detalhada do código. Abusa do formato de entrada padrão do Charcoal, que se divide em espaços se houver apenas uma linha; portanto, a entrada do número aleatório se parece com três entradas. Explicação:

W№θ*

Repita enquanto a primeira entrada contém a *.

F⁼θ*

Se a primeira entrada for *apenas uma ...

≔Hello Worldθ

... substitua-o por Hello World, fazendo com que o loop termine. *+*não é substituído, resultando em um loop infinito.

∨θ

Se a primeira entrada não estiver vazia, emita-a.

I‽X²¦³¹

Mas se estiver vazio, emita um número inteiro aleatório no intervalo desejado.

Neil
fonte
1

Adicionar ++ , 78 bytes

z:"Hello World"
`y
xR2147483647
x:?
a:"*"
b:" * "
c:"*+*"
Ix=a,Oz
Ix=b,O
Wx=c,

Experimente online!

Explicação

z:"Hello World"	; Set z = "Hello World"
`y		; Set y as the active variable
xR2147483647	; Set y to a random number between 0 and 2147483647
x:?		; Set x to the input
a:"*"		; Set a = "*"
b:" * "		; Set b = " * "
c:"*+*"		; Set c = "*+*"
Ix=a,		; If x == a then...
	Oz	;	...output z
Ix=b,		; If x == b then...
	O	;	...output y
Wx=c,		; While x == c then...
		;	...do nothing
caird coinheringaahing
fonte
1

Braquilog , 26 23 bytes

l₃∈&hṢ∧2^₃₁-₁ṙw∨Ḥ⊇ᶠ³⁶tw

Experimente online!

Leva o programa como uma string pela variável de entrada e ignora a variável de saída. Explora fortemente a garantia de que a entrada é apenas um dos três programas válidos: qualquer entrada de comprimento três se comportará como um " * "ou "*+*"dependendo de o primeiro caractere ser um espaço ou não, e qualquer outra entrada se comportará como "*".

l₃                         The input has length 3
  ∈                        and is an element of something,
   &h                      and the input's first element
     Ṣ                     is a space
  ∈                        (if not, try some other thing it's an element of),
      ∧2^₃₁-₁              so take 2,147,483,647 and
             ṙw            print a random number between 0 and it inclusive.
               ∨           If the input's length isn't 3,
                Ḥ⊇ᶠ³⁶tw    print the 36th subsequence of "Hello, World!".
String não relacionada
fonte
Opa, "Hello World" errado - corrigindo agora
String não relacionada
1

PHP , 51 bytes

for(;'*'<$l=$argn[1];);echo$l?rand():'Hello World';

Experimente online! (Olá Mundo)

Experimente online! (Número aleatório)

Experimente online! (Loop infinito)

Toma o segundo caractere da entrada que pode ser '', '*'ou '+'. Caso '+'o valor '*'<'+'seja verdadeiro e o loop seja infinito, caso contrário, após o loop, "Hello World" ou um número aleatório é mostrado. Ele rand()gera automaticamente um número entre 0 e os getrandmax()usos definidos RAND_MAXna biblioteca C padrão e, por padrão, está 2147483647na maioria das plataformas / ambientes, incluindo o TIO.

Night2
fonte
1

05AB1E , 21 bytes

'*KgDi[ë<ižIL<Ω딟™‚ï

Experimente online. (OBSERVAÇÃO: O buildin aleatório é bastante lento com grandes listas; portanto, pode levar algum tempo até que o resultado seja fornecido.)

Explicação:

'*K           '# Remove all "*" from the (implicit) input
   g           # Get the length of what's remain (either 0, 1, or 2)
    D          # Duplicate this length
     i         # If the length is exactly 1:
      [        #  Start an infinite loop
     ë<i       # Else-if the length is 2:
        žI     #  Push builtin 2147483648
          L    #  Create a list in the range [1,2147483648]
           <   #  Decrease each by 1 to make the range [0,2147483647]
            Ω  #  Pop and push a random value from the list
               #  (after which the top of the stack is output implicitly as result)
     ë         # Else:
      ”Ÿ™‚ï    #  Push dictionary string "Hello World"
               #  (after which the top of the stack is output implicitly as result)

Veja esta dica 05AB1E meu (seção Como usar o dicionário? ) Para entender por que ”Ÿ™‚ïé "Hello World".

Kevin Cruijssen
fonte
1

Pitão , 32 bytes

It/Jw\*#;?tlJOhC*4\ÿ"Hello World

Experimente online!

Explicação (Python-ish)

I                                   # if 
  /Jw\*                             #    (J:=input()).count("*"))
 t                                  #                             - 1:
       #;                           #     try: while True: pass;except: break;
         ?                          # if (ternary)
           lJ                       #    len(J):
             O                      #     randInt(0,                    )
               C                    #                int(     , 256)
                *4\ÿ                #                    4*"ÿ"
              h                     #                                + 1
                    "Hello World    # else: (implicitly) print "Hello World"
ar4093
fonte
Isso imprime um número entre 0 e 2 ^ 32, não 0 e 2 ^ 31. Uma maneira mais curta de escrever hC*4\ÿé ^2 32, mas para que a solução esteja correta, você deve usar ^2 31. Além disso, use em zvez de Jweconomiza mais 1 byte. E sua explicação pula a linha timediatamente antes lJ.
randomdude999 27/10
Além disso, você pode detectar o comando "loop para sempre", verificando se a entrada contém algum +caractere, economiza 1 byte, porque você não precisa diminuí-lo.
randomdude999 27/10
0

APL (Dyalog Unicode) , SBCS de 39 bytes

Prefixo anônimo lambda.

{'+'∊⍵:∇⍵⋄' '∊⍵:⌊2E31×?0'Hello World'}

Experimente online!

{ "dfn"; é o argumento:

'+'∊⍵: se plus é um membro do argumento:

  ∇⍵ cauda recursão no argumento

' '∊⍵ se o espaço for um membro do argumento:

  ?0 flutuação aleatória (0–1)

  2E31× escala para (0–2³¹)

   chão

'Hello World' caso contrário, retorne a string

Adão
fonte
0

Commodore BASIC (VIC-20, C64, TheC64Mini etc) - 170 bytes tokenize BASIC

 0a%=32767:goS9:b$=leF(b$,len(b$)-1):ifb$="*"tH?"hello world
 1ifb$=" * "tH?int(rN(ti)*a%)
 2ifb$="*+*"tHfOi=.to1:i=.:nE
 3end
 9b$="":fOi=.to1:geta$:i=-(a$=cH(13)):b$=b$+a$:?a$;:nE:reT

Penso que, para fazer isso com mais precisão, terei que me aprofundar no mundo estranho da linguagem assembly 6502, mas este é um primeiro rascunho.

Primeiro, a INPUTpalavra - chave no Commodore BASIC ignora os espaços em branco; portanto, a sub-rotina em linha 9é uma maneira rápida e suja de aceitar entradas do teclado, incluindo espaços.

Segundo ponto, inteiros Commodore BASIC têm um alcance de 16-bit assinado, por isso -32.768-32.767 fonte - para que eu tenha mantido o número aleatório gerado para 0 - 32767 inclusiva

Shaun Bebbers
fonte
0

Wren ,143 135 bytes

Eu não sou um bom jogador de golfe ... O RNG gera o mesmo valor de cada vez porque é um gerador de números pseudo-aleatórios.

Fn.new{|a|
import"random"for Random
if(a=="*+*"){
while(1){}
}else System.write(a[0]==" "?Random.new(9).int((1<<31)-1):"Hello World")
}

Experimente online!

UMA
fonte
0

JavaScript, 63 bytes, sem recursividade infinita

s=>s[1]?Math.random()*2**31|eval("while(s>'!');"):'Hello World'

rede ruim, então nenhum link TIO

l4m2
fonte