# Write an interpreter for *

The task is simple. Write an interpreter for the language *.

Here's a bigger link to the wiki.

There are only three valid * programs:

• * Prints "Hello World"
•  *  Prints a random number between 0 and 2,147,483,647
• *+* Runs forever.

The third case must be an infinite loop according to the specifications in this question

## Input:

• The input can be taken via any acceptable input method by our standard I/O rules
• It will always be one of the above programs

## Output:

• The first case should print exactly Hello World, with or without a trailing line break.
• For the second case, if your language's integer maximum is smaller than 2,147,483,647, use your language's integer maximum
• The first and second cases can print to any acceptable output by our standard I/O rules.
• The third case should not give any output.

## Scoring:

As this is , the shortest answer, in bytes, wins.

• When you say 'between 0 and 2,147,483,647', is that inclusive or exclusive? (E.g., is 0 a valid output?) – Chas Brown Aug 9 at 21:46
• @Chas the linked wiki has interpreters in Java & JS which include 0. – Jonathan Allan Aug 9 at 22:48
• Changing the spec after posting a challenge and invalidating existing solutions is an automatic -1 from me. – Shaggy Aug 10 at 7:00
• If our language's integers have no, or a higher, maximum may we use a higher upper bound? – Jonathan Allan Aug 10 at 23:43
• @Shaggy I'm not seeing any rule changes in the wiki for the question, only a space to a non-breaking space (check the markdown tab), because the SE markdown renderer wasn't rendering it, but looking at the original revisision, it's clear it should be normal spaces, and the "hack' is only done for SE markdown renderer issues – Ferrybig Aug 11 at 20:49

## *, 0 bytes




Since * has no way of reading input, the default rules allow specifying that the input must be given by concatenating it onto the program.

(... I think. There's an "at least twice as many upvotes as downvotes" condition that I don't have the rep to verify).

• Your linked meta is indeed a currently accepted site standard (+31 -7). – Jonathan Allan Aug 10 at 19:32
• @A__: It looks to me like it must have been designed specifically to satisfy someone's proposed definition of 'programming language' ("You can write hello world!" "You can write an infinite loop!" "You can write a program that doesn't always do the same thing!"). – Henning Makholm Aug 11 at 3:44
• @HenningMakholm This does not fullfill our concensus of programming languages, thus it is invalid. In order to post in * here, you should present a prime-checking program to us first in order to fullfill our definition. – A _ Aug 11 at 4:20
• I believe that technically Malbolge is not a programming language either then. – Bob Jansen Aug 11 at 10:16
• Malbolge is programming language for finite automata, the same as *, and, for example, Befunge-93. Therefore Malbolge is formal programming language, the same as *, technically the same as recursively enumerable languages when it comes to programming language definition (albeit formal languages are less powerful). – Krzysztof Szewczyk Aug 11 at 17:05

# R, 69 bytes

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


Try it online!

switch tries to match the named arguments and if there's no match, selects the first unnamed one after the first, which in this case is the infinite loop repeat{}.

# Keg, 302625 24 bytes

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


Try it online!

I never ceased to be amazed at the power of Keg. Credits to user EdgyNerd for another byte saved.

## Prior Versions

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


Try it online!

Credit to user A__ for the extra byte saved.

## Old version

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


Essentially, takes the input program and:

• Checks to see if the input length is 1, printing "Hello World" if true
• Checks to see if the last character is a space, and prints a random number
• Otherwise runs an infinite loop

Then implicitly print the stack.

?                               #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 saved due to the fact that hello world doesnt need punctuation.

Try it online! Old version

Try it online! New version

• You can cut off 4 bytes, you don't need the comma or exclamation mark in "Hello World". – TheOnlyMrCat Aug 10 at 2:14
• Now I have to learn another unpopular language in order to answer challenges here normally. – A _ Aug 10 at 6:26
• -1 bytes: TIO. I am glad that I did not lose my ability to golf in Keg. – A _ Aug 10 at 6:36
• @A__ Enjoying Keg being on TIO? – Jono 2906 Aug 10 at 6:48
• 24 bytes :) – EdgyNerd Aug 10 at 8:49

# Jelly,  21  20 bytes

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


A monadic Link accepting a list of characters.

Try it online!

vL’... also works (see below).

### How?

Ḋ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"


Alternative

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)


# Python 2, 1039389 87 bytes

I combined my earlier answer with Chas Browns's answer and got something a few bytes shorter.

The random number will be between 0 and 2**31-1 inclusive.

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


Try it online!

### Previous versions:

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]

• Save 2 bytes by replacing randint(0,2**31-1) with randrange(2**31). – Chas Brown Aug 9 at 21:53
• while'*'<i saves 2 – Jonathan Allan Aug 10 at 0:12
• Save another byte by changing randrange(2**31) to getrandbits(31) (the latter returns long, not int, but print will print the str form, not the repr form, so the trailing L won't be there). – ShadowRanger Aug 12 at 14:18
• Relatively inexperienced with site, so quick clarification: Are you allowed to require your input to be quoted? i=input() only works if the inputs are quoted, if you just input plain */ * /*+*, it would die with a SyntaxError (because input includes an implicit eval); you'd need to input '*'/' * '/'*+*' (or equivalent with double-quotes instead). I didn't see anything obvious on the standard I/O rules that would allow this, which might mean you'd need to use raw_input(), costing four bytes. – ShadowRanger Aug 12 at 14:27
• @ShadowRanger input() takes a string as input and evaluates it. I'm not really adding to the input, I'm merely taking a string as input, and strings have quotes. This is pretty standard, in the same way that I can take an array like [1,2,3] instead of as a delimited string that I then have to split and parse. The goal of the site is not to make input strict, it's to make I/O easy so we can focus code on the challenge at hand. – mbomb007 Aug 12 at 15:49

# C (gcc), 66 63 bytes

Thanks to attinat for the -3 bytes.

I only have to check the second character: if the LSB is set, it's a + (thus the program is "*+*") and the program loops. After that, if it's a NUL, the program was "*" and we display Hello World; otherwise, it displays a random value (" * ", the only other option left.)

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


Try it online!

• 63 bytes – attinat Aug 9 at 22:21
• Shave a byte: f(char*s){*++s&1?f(s-1):printf(*s?"%d":"Hello World",rand());} – Roman Odaisky Aug 10 at 22:24
• Pedantic note: rand is not guaranteed to return a sufficiently large value; RAND_MAX and INT_MAX are not guaranteed to be the same (and are not on real world compilers, e.g. Visual Studio's RAND_MAX is 32767, while INT_MAX is [on modern x86 derived systems] the 2147483647 value specified in the OP's question). – ShadowRanger Aug 12 at 14:45
• @ShadowRanger that is completely true, but considering that >90% of all C-based CGCC entries rely on undefined and unspecified behaviour I'm not worried about that! I also didn't feel like implementing a code-golfed LCG today. :-) – ErikF Aug 12 at 16:53

# Japt, 22/25 bytes

The first solution is for the original spec which had *<space> as the second programme and the other is for the updated spec which arbitrarily changed it to <space>*</space>, with thanks to EoI for the suggested "fix".

Both throw an overflow error upon entering the infinite loop of the third programme but, theoretically, with enough memory (which we may assume for the purposes of ), would run forever.

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

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

• I think the second program is "[SPACE]*[SPACE]", not "[SPACE]*", so your program doesn't work – Embodiment of Ignorance Aug 10 at 6:51
• @EmbodimentofIgnorance, at the time I posted, the second programme in the spec was *<space>. Don't have time to update now. – Shaggy Aug 10 at 6:58
• You can fix it in three bytes with UÌ>S instead of ¢ on the second ternary – Embodiment of Ignorance Aug 10 at 7:08
• @Downvoter, please have the courtesy to leave a comment. – Shaggy Aug 12 at 9:17

# JavaScript (ES7), 66 bytes

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


Try it online! (Hello World)

Try it online! (random number)

Try it online! (infinite loop)

• Would x=(z=>x())&&x() not work for -1byte from the infinite loop code, assuming a browser with no max call stack size? – Geza Kerecsenyi Aug 10 at 15:52
• @GezaKerecsenyi We could just call ourself (like this) but I'm not sure that would be acceptable. – Arnauld Aug 10 at 15:55
• that's fair. I wonder if there is some obscure browser out there that just keeps going (at least, until RAM runs out) – Geza Kerecsenyi Aug 10 at 15:57
• @Arnauld, theoretically, that would run forever given infinite memory, which we may assume for code golf. – Shaggy Aug 10 at 20:47

# Jelly, 23 21 bytes

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


Try it online!

A monadic link taking a single argument and returning Hello World, a random 31 bit integer or looping infinitely as per the spec.

All options: *  *  *+*

## Explanation

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"


# Befunge-93, 54 bytes

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


Try it online!

Annotated:

~"*"-                      _                ~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


The randomness is not uniform. At each increment there is a 50% chance to stop incrementing.

# Python 2, 9189 88 bytes

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


Try it online!

2 bytes thanks to Jonathan Allan; 1 byte thx to ShadowRanger.

• while'*'<p saves 2 – Jonathan Allan Aug 9 at 22:25
• getrandbits(31) saves a byte over randrange(2**31). – ShadowRanger Aug 12 at 14:21
• Nice! Didn't know about getrandbits... – Chas Brown Aug 12 at 18:48

$_=/ /?0|rand~0:/\+/?redo:"Hello World"  Try it online! # C# (Visual C# Interactive Compiler), 71 bytes s=>{for(;s=="*+*";);return"*"==s?"Hello World":new Random().Next()+"";}  Try it online! # Ruby-n, 47 bytes puts~/ /?rand(1<<31):~/\+/?loop{}:"Hello World"  Try it online! # Wolfram Language (Mathematica), 65 bytes #/.{"*"->"Hello World"," * "->RandomInteger[2^31-1],_:>0~Do~∞}&  Try it online! # Java (JDK), 83 bytes s->{for(s=s.intern();s=="*+*";);return"*"==s?"Hello World":(-1>>>1)*Math.random();}  Try it online! # Brachylog, 26 23 bytes l₃∈&hṢ∧2^₃₁-₁ṙw∨Ḥ⊇ᶠ³⁶tw  Try it online! Takes the program as a string through the input variable, and ignores the output variable. Heavily exploits the guarantee that the input is only ever one of the three valid programs: any length-three input will behave like either " * " or "*+*" depending on whether or not the first character is a space, and any other input will behave like "*". 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!".  • Oops, wrong "Hello World"--fixing now – Unrelated String Aug 9 at 21:41 # PHP, 51 bytes for(;'*'<$l=$argn[1];);echo$l?rand():'Hello World';


Try it online! (Hello World)

Try it online! (Random Number)

Try it online! (Infinite Loop)

Takes second character of input which can be '', '*' or '+'. In case of '+' the '*'<'+' will be true and the loop will be infinite, else, after the loop, "Hello World" or a random number is shown. The rand() automatically outputs a number between 0 and getrandmax() which uses defined RAND_MAX in standard C library and by default is 2147483647 on most platforms/environments, including TIO.

# 05AB1E, 21 bytes

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


Try it online. (NOTE: The random buildin is pretty slow with big lists, so it might take awhile before the result is given.)

Explanation:

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


See this 05AB1E tip of mine (section How to use the dictionary?) to understand why ”Ÿ™‚ï is "Hello World".

# PowerShell, 60, 56 bytes

switch($args){*{'Hello World'}' * '{random}*+*{for(){}}}  Pretty dumb version, the only golfing technique here is omitting Get- in Get-Random. UPD. Stripped down to 56 bytes by removing quotes, thanks to veskah! # Charcoal, 30 bytes Ｗ№θ*Ｆ⁼θ*≔Hello Worldθ∨θＩ‽Ｘ²¦³¹  Try it online! Link is to verbose version of code. Abuses Charcoal's default input format which splits on spaces if there is only one line, thus the random number input actually looks like three inputs. Explanation: Ｗ№θ*  Repeat while the first input contains a *. Ｆ⁼θ*  If the first input is a * only... ≔Hello Worldθ  ... then replace it with Hello World, thus causing the loop to terminate. *+* doesn't get replaced, resulting in an infinite loop. ∨θ  If the first input is not empty then output it. Ｉ‽Ｘ²¦³¹  But if it is empty then output a random integer in the desired range. # Add++, 78 bytes z:"Hello World" y xR2147483647 x:? a:"*" b:" * " c:"*+*" Ix=a,Oz Ix=b,O Wx=c,  Try it online! ## Explanation 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  # APL (Dyalog Unicode), 39 bytesSBCS Anonymous prefix lambda. {'+'∊⍵:∇⍵⋄' '∊⍵:⌊2E31×?0⋄'Hello World'}  Try it online! { "dfn"; ⍵ is the argument: '+'∊⍵: if plus is a member of the argument: ∇⍵ tail recurse on argument ' '∊⍵ if space is a member of the argument: ?0 random float (0–1) 2E31× scale to (0–2³¹) ⌊ floor 'Hello World' else return the string # Pyth, 32 bytes It/Jw\*#;?tlJOhC*4\ÿ"Hello World  Try it online! ## Explanation (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"  # Commodore BASIC (VIC-20, C64, TheC64Mini etc) - 170 tokenize BASIC bytes  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


I think to do this more accurately, I'll have to delve into the weird world of 6502 assembly language, but this is a first draft.

First point, the INPUT keyword in Commodore BASIC ignores white spaces, so the sub-routine at line 9 is a quick-and-dirty way to accept keyboard entries including spaces.

Second point, Commodore BASIC integers have a range of 16-bit signed, so -32768 to +32767 source - so I've kept the random number generated to 0 - 32767 inclusive