g | x | w | all
Bytes Lang Time Link
015Uiua250718T195720Znyxbird
078Swift 6250505T150743ZmacOSist
069120925T193241ZKaz
043Raku Perl 6 rakudo250415T195737Zxrs
016Japt250414T164010ZShaggy
088AWK250414T145932Zxrs
014Vyxal220502T092639Zemanresu
01605AB1E220502T014135ZMakonede
070Python 2120925T230848Zdaniero
076AHK170403T184756ZEngineer
032Seriously160114T192847Zquintopi
085PARI/GP160114T204326ZCharles
037Octave160113T151709ZStewie G
116Python120925T170527ZAdrien P
065JavaScript120925T190214ZJoe Tusk
061JavaScript120925T194334Zuser1686
143Javascript150721T145525ZSuperJed
389Java141228T154416ZPoweredB
014CJam141227T112824ZMartin E
060Mathematica120925T090624ZDavidC
031CJam141228T152433Zuser1640
018Pyth141228T114625ZJakube
042R141228T121100Zplannapu
013TIBASIC141226T011605ZTimtech
012APL140106T004813ZZaq
042Perl 6140104T095213Znull
045Mathematica131101T081242Zalephalp
059Perl131031T172123ZDom Hast
059PowerShell131029T160241ZRynant
117VBA131029T151848ZGaffi
074Perl121006T092328Zo_o
098Haskell120926T051026ZRotsor
04516bit x86 machine code under MSDOS120926T194435ZJonas En
069Lisp120925T170931Zwintermu
025Q120925T154242Zsinedcm
nan120925T231629ZKeithS
016k120925T155808Zskeevey
017J120925T105645ZGareth
061Java120926T134028ZQuasar
062Ruby 1.9120925T164615Zjs-coder
083Python120926T081158ZAlex L
nan120926T072807Zcodeporn
065Bash shell script120926T044737ZPleaseSt
055Clojure120926T015951Zmikera
072Clojure120926T014736Zmikera
123C120926T011032Zbaby-rab
026GolfScript120925T202552ZPeter Ta
097Python120925T180433Zscleaver
094C120925T161919ZJoe Iban
077PHP 77 Chars120925T165437ZTwoScoop
027GolfScript120925T122725ZIlmari K
041R120925T094203Zflodel
077Python120925T093122Zsgrieve
028K120925T082534Ztmartin

Uiua, 15 bytes

+4°⍆⊂⊸¯⊚⊟⟜-⚂₁₀9

Try it!

+4°⍆⊂⊸¯⊚⊟⟜-⚂₁₀9
               ⚂₁₀  # -> randint in [0, 9]
           ⊟⟜-   9 # r -> [r, 9-r]
         ⊚          # [p, q] -> [p 0s, q 1s]
     ⊂⊸¯            # -> [p 0s, q 1s, p -0s, q -1s]
+4°⍆                # shuffle and add 4 to each

Swift 6, 83 78 bytes

print({[3:$0,5:$0,4:18-$0*2]}(.random(in:0...9)).flatMap([_].init).shuffled())

Try it on SwiftFiddle!

TXR TXR Lisp (99 71 69 chars)

(for((x(gun(+(rand 3)3)))y)((/=(sum y)72)y)((pop x))(set y[x 0..18]))

This expression generates an infinite lazy list of random numbers from 3 to 5:

(gun (+ 3(rand 3)))  ;; gun -> "generate until null"

The expression never produces nil, so the generation continues.

The rest of the logic is a simple loop which checks whether the first 18 elements of this list add up to 72. If not, it pops an element off and tries again. The for loop contains an implicit block called nil and so (return ...) can be used to terminate the loop and return value.

Translation of Clojure (53 chars)

(find-if(opip sum(= 72))(tuples 18(gun(+(rand 3)3))))

Raku (Perl 6) (rakudo), 45 43 bytes

{my@x=(3..5).roll(18)until ([+] @x)==72;@x}

Attempt This Online!

my@x=      # declare array
(3..5)     # range 3 to 5
.roll(18)  # create 18 random holes
until      # until....
([+] @x)   # the sum of the elements
==72;      # equals 72
say @x     # print array

Japt, 16 bytes

@72nXx}f@3õ5 ö18

Test it

AWK, 88 bytes

END{for(srand();y-72;)for(y=i=0;i++<18;)y+=b[i]=int(rand()*3)+3;for(;j++<18;)print b[j]}

Attempt This Online!

Vyxal, 14 bytes

{:ṁ4≠|18ƛ3 6r℅

Try it Online!

{              # While...
 :ṁ            # The mean of the current value
   4≠          # Isn't 4
     |         # Do...
      18ƛ      # Fill an array of 18 elements with...
         3 6r℅ # one of 3, 4, and 5.

05AB1E, 16 bytes

[18Lε3LÌΩ}DO₆·Q#

Try it online!

Python 2, 70 bytes

from random import*
print sample(([3,5]*randint(0,9)+[4]*99)[:18],18)
edit:

Here's another one, similar to the solution of sgrieve:

Python 2, 73 bytes + equal probability

from random import*
a=[]
while sum(a)-72:a=sample([3,4,5]*18,18)
print a

AHK, 76 bytes

Loop{
s=
t=0
Loop,18{
Random,r,3,5
s:=r " "s
t+=r
}
If t=72
Break
}
Send,%s%

It's of the style to just loop forever until it happens to generate a list that totals 72 strokes.

Seriously, 32 bytes (noncompeting)

35k9Ju;)@nktd9-τ4nktW;lJ`\`np@WX

This language post-dates this challenge. Posted to prove the need for a shuffle command and perhaps a cons command. This uses the same solution as CJam roughly:

35k                                 Push [5,3]
   9Ju                              Push a random number n from 1 to 9
      ;)                            Save a copy of it for later use.
        @n                          Make n copies of [5,3]
          (9-τ                      Transform n -> 2*(9-n)
              4n                    Push that many 4's
                kt                  Compile all numbers into a list.
                  W         W       Until the list is empty:
                   ;lJ`\`np@        Pop a random element from it.
                             X      Discard empty list.

PARI/GP, 85 bytes

vecextract(Vec(partitions(72,[3,5],[18,18])[random(10)+1]),numtoperm(18,random(18!)))

This generates a random partition of 72 with 18 components ranging from 3 to 5. The probabilities are not uniform, from 1/10 for the all-4 vector to 1/171531360 for [3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5] and its permutations.

Octave, 37 bytes

while sum(x=2+randi(3,1,18))-72;end;x

It seems straight forward, (and I guess it is), but there are a few nifty tricks in here. It's 16 bytes shorter than the MATLAB answer, and I think it's hard to golf any further.

In Octave, you can initialize a variable inside a function call, or inside the while statement as done here. So, by doing sum(x=2+randi(3,1,18)) I manage to continuously shuffle a vector of 18 elements with values [3,4,5] until the sum is 72. Instead of checking if this equals 72, we can subtract 72, and check if that's a truthy or a falsey value. Any non-zero values are considered truthy, so it will only stop when the sum is 72. In the end, the loop stops and the vector is printed.

Python, 128 120 116 characters

import random,itertools
random.choice([g for g in itertools.product(*(range(3,6)for l in range(18))) if sum(g)==72])

import statements are still length killers (23 characters only to import 2 function in the namespace)

i hope you do not need the result in a near future, as this code first evaluates all possible solutions before chosing one at random. maybe the slowest solution to this problem.

i do claim extra kudos for equal probability of each configuration...

JavaScript, 116 99 65 bytes

for(i=0,h=[];i<18;)h[i++]=5;while(h.reduce(function(a,b){return a+b})!=72){i=Math.random()*18|0;h[i]=[3,4,4][i%3]}h;

h=[0];while(h.reduce(function(a,b){return a+b})-72)for(i=0;i<18;h[i++]=[3,4,5][Math.random()*3|0])h

while(i%18||(a=[i=s=0]),s+=a[i++]=Math.random()*3+3|0,s-72|i-18)a

JavaScript, 66 64 61 chars

Heavily inspired by TwoScoopsofPig (PHP) and Joe Tuskan (JS).

for(a=[s=0];s!=72;)for(s=i=0;i<18;s+=a[i++]=Math.random()*3+3|0);a

for(a=[s=0];s-72;)for(s=i=0;i<18;s+=a[i++]=Math.random()*3+3|0)a

for(a=s=[];s;)for(i=18,s=72;i;s-=a[--i]=Math.random()*3+3|0)a

Javascript, 148 143 bytes

t=[];d=0;while(d<18){q=t.reduce(function(a,b){return a+b},z=0);while(!z||q+z+13-d*5<0||q+z-d*3>21)z=3+3*Math.random()|0;t.push(z);d++}alert(t)

Java: 389 bytes

Run by calling the b() function.

import java.util.*;public class a{Random b=new Random();int[]b(){int[]c=new int[18];int d=0;for(int i=0;i<c.length;i++){int e=g(c.length-i,d);int f=h(c.length-i,d);c[i]=i(e,f);d=d+c[i];}
return c;}
int i(int j,int k){return b.nextInt((k-j)+1)+j;}
int g(int l,int m){int n=(l-1)*5;int o=72-m;int p=o-n;return p<3?3:p;}
int h(int q,int r){int s=(q-1)*3;int t=72-r;int u=t-s;return u>5?5:u;}}

CJam, 17 14 bytes

CJam is newer than this challenge, but this is not the shortest answer anyway, so that doesn't really matter.

Z5]Amr*I4e]mrp

Test it here.

To maintain the total of 72, each 3 must be paired with 5. So here is how it works:

Z5]            e# Push [3 5].
   Amr         e# Get a random number between 0 and 9.
      *        e# Repeat the [3 5] array that many times.
       I4e]    e# Pad the array to size 18 with 4s.
           mr  e# Shuffle the array.
             p e# Print it.

Mathematica 71 68 66 60

With 6 chars saved by Tally's suggestion.

RandomSample@RandomChoice@IntegerPartitions[72, {18}, {3, 4, 5}]

{5, 4, 3, 3, 5, 3, 5, 5, 3, 3, 4, 5, 3, 5, 4, 4, 5, 3}

All possible outcomes are possible, but they are not equally likely.


Analysis

IntegerPartitions[72, {18}, {3, 4, 5}]

produces all 10 possible partitions (combinations, not permutations) of 72 into 18 elements consisting of 3's, 4's and 5's.

partitions


RandomChoice selects one of those.

RandomSample returns a permutation of that choice.

CJam, 31

[Language was created after the question was posted]

Shamelessly long for CJam. It's basically a brute-force solution that keeps trying random configurations until it finds one that adds to 72.

L{;L{3mr3+_U+:U;a+}I*U72=:U!}g`

Pyth, 18 bytes

#Jm+3O3U18IqsJ72JB

How it works:

#                    infinite loop
       U18           generate the list [0, 1, ..., 17]
  m    U18           map every value of this list to
   +3O3              a random number between 3 and 5
 Jm+3O3U18           and assign the resulting list to J
          I          if
           qsJ72     the sum of J == 72
                J    print J
                 B   and exit the loop

R, 42 bytes

a=0;while(sum(a)-72)a=sample(3:5,18,r=T);a

sample, by default, draws evenly among the possible values (here 3 4 5). r=T stands for replace=TRUE and allows sample with replacement.

TI-BASIC, 13 bytes

3+3fPart(randIntNoRep(0,17)/3

Outputs list of 18 integers. Meets all specs and has equal probability for each case.

APL 12

4+{⍵,-⍵}?9⍴2

Note that I have the index origin set to 0, meaning arrays start at 0. You can set this with ⎕IO←0.

Perl 6 (42 bytes)

my@a=roll 18,3..5 while 72!= [+] @a;say @a

Probably too long to be acceptable, but at least the solution does exist. roll rolls the dice containing 3, 4, and 5. This generates numbers until the sum is equal to 72. I believe it can generate any course with equal probability (in theory), but considering pseudo-random number generators, it probably doesn't.

Sample output:

~ $ perl6 -e 'my@a=roll 18,3..5 while 72!= [+] @a;say @a'
3 4 3 3 4 5 4 3 4 4 3 4 5 4 5 5 4 5

Mathematica, 45 chars

NestWhile[{3, 5}~RandomInteger~18 &, {}, Tr@# != 72 &]

Perl, 59

@a=map{3+rand 3|0}1..18 while 72!=eval join'+',@a;print"@a"

Not a winner by any means and could probably be improved still...

Array sum method stolen from perlmonks.

PowerShell - 59

while(($x|measure -s).sum-ne72){$x=1..18|%{3..5|random}};$x

VBA - 117

VBA never wins at golf. :-)

Sub a()
Do Until d=72
d=0
c=""
For b=1 To 18
e=Int(3*Rnd()+3)
c=c &" " &e
d=d+e
Next
Loop
MsgBox c
End Sub

Perl, 74

{@c=map{3+int rand 3}(0)x18;$s=0;$s+=$_ for@c;redo unless$s==72}print"@c"

Alternative solution:

@q=((3,5)x($a=int rand 9),(4,4)x(9-$a));%t=map{(rand,$_)}(0..17);print"@q[@t{sort keys%t}]"

Haskell, 104 102 98 chars.

import System.Random
q l|sum l==72=print l|1>0=main
main=mapM(\_->randomRIO(3::Int,5))[1..18]>>=q

16-bit x86 machine code under MS-DOS - 45 bytes

Hexdump:

0E5F576A12595188ECE44088C3E44130D8240374F400C4AAE2EF595E80FC2475DFAC0432CD29B020CD29E2F5C3

Base64 coded binary:

Dl9XahJZUYjs5ECIw+RBMNgkA3T0AMSq4u9ZXoD8JHXfrAQyzSmwIM0p4vXD

Actual source code with some comments:

 bits 16
 org 0x100

again:
 push cs               ; Save whatever CS we get.
 pop di                ; Use CS:DI as our course buffer..
 push di               ; Save for later use in the print loop
 push 18               ; We need 18 holes for our golf course.
 pop cx                ; ch = 0, cl = 18.
 push cx               ; Save for later use.
 mov ah, ch            ; Zero out ah.
generate_course:
 in al, 0x40           ; Port 0x40 is the 8253 PIT Counter 0.
 mov bl, al            ; Save the first "random" value in bl.
 in al, 0x41           ; Port 0x41 is the 8253 PIT Counter 1.
 xor al, bl            ; Add some more pseudo randomness.
 and al, 3             ; We only need the two lower bits.
 jz generate_course    ; If zero, re-generate a value, since we need only 3, 4, 5 holes.
 add ah, al            ; Sum in ah register.
 stosb                 ; Store in the course buffer.
 loop generate_course  ; Loop for 18 holes.
 pop cx                ; cx = 18.
 pop si                ; si = course buffer.
 cmp ah, 36            ; 72 holes?
 jne again             ; No, re-generate the whole course.

print:                 ; Yup, we have a nice course.
 lodsb                 ; Load the next hole.
 add al, '2'           ; Add ASCII '2' to get '3', '4' or '5'
 int 0x29              ; Undocumented MS-DOS print function.
 mov al, ' '           ; Print a space too for better readability.
 int 0x29              ; Print the character.
 loop print            ; Print the whole course.
 ret                   ; Return to the beginning of the PSP where a INT 0x20 happen to be.

Compile with nasm 18h.asm -o 18h.com and run under MS-DOS (or Dosbox), or NTVDM from a 32-bit Windows version.

Sample output:

4 5 4 5 4 5 3 4 3 4 3 4 4 5 4 3 5 3

Lisp (78 69 chars)

(do((c()(mapcar(lambda(x)(+ 3(random 3)))(make-list 18))))((=(apply'+ c)72)c))

(do((c()(loop repeat 18 collect(+ 3(random 3)))))((=(apply'+ c)72)c))

It's rather similar to sgrieve's Python solution.

Start with c as NIL, check for a sum of 72, the do "increment function" for c generates a list of 18 numbers between 3 and 5, check for 72 again, lather, rinse, repeat.

It's refreshing to see do and loop nicely play golf together.

Q (25 characters)

Original (27)

while[72<>sum a:18?3 4 5];a

Sample output

4 4 3 3 4 5 4 3 4 5 5 3 5 5 5 4 3 3

Slightly shorter (25)

{72<>sum x}{x:18?3 4 5}/0

C# (143 non-whitespace):

()=>{
  var n=new Math.Random().Next(10);
  Enumerable.Range(1,18)
    .Select((x,i)=>i<n?3:i>=18-n?5:4)
    .OrderBy(x=>Guid.NewGuid())
    .ForEach(Console.Write);
}

k (18 17 16 chars)

Back to the original approach, credit to CS for the improvement.

(+/4-){3+18?3}/0

Other approach (17 chars), same method as the J solution, H/T to CS

4+a,-a:9?2 -18?18

Old version:

(72-+/){18?3+!3}/0

Not susceptible to stack-overflow and runs in fixed amount of space.

J, 20 18 17 characters

(?~18){4+(,-)?9#2

This works in the same way as the previous answer except that the 9 random digits are either 0 or 1 and are negated before being appended. This means there are as many -1s as there are 1s. Adding 4 gives me a list of 3s, 4s and 5s that add up to 72 every time.

Previous answer:

({~?~@#)3+(,2-])?9#3

Generates the first 9 holes randomly ?9#3, then copies and inverts them (,2-]) (turns a 3 into a 5 and a 5 into a 3) to generate the final 9. This guarantees that the total will be 72 (since every 3 will have a matching 5 the average total per hole will be 4 and 4x18=72). It then randomly shuffles the result ({~?~@#) to ensure that every combination is possible.

Java (61 chars)

while(s!=72)for(i=0,s=0;i<18;i++)s+=3+(int)(Math.random()*3);

Sample output:

5 4 3 4 5 3 4 4 3 5 4 4 4 4 3 4 4 5

Ruby 1.9 (62 chars)

a=Array.new(18){[3,4,5].sample}until(a||[]).inject(:+)==72
p a

Rails (55 chars)

In the $ rails c REPL (in any Rails folder):

a=Array.new(18){[3,4,5].sample}until(a||[]).sum==72
p a

Note: It works with Ruby 1.8 if you use shuffle[0] instead of sample.

Python 83

import random as r;x=[]
while sum(x)!=72:x=[r.randint(3,5) for i in 18*[0]]
print x

Like sgrieve's solution, but without numpy

Golfing Adrien Plisson's solution: 120->108 characters

import random as r,itertools as i
r.choice([g for g in i.product(*([3,4,5,6]for l in 18*[0]))if sum(g)==72])

MATLAB 53

x=[];
while sum(x)~=72
x=3+floor(rand(1,18)*3);
end
x

Output:

x = 4 3 4 4 4 4 5 4 4 3 4 4 3 5 3 5 4 5

Groovy

126 chars

def a=[];while(1){(new Random().nextInt(3)!=1&&a.size()<17?a<<3<<5:a<<4);if(a.size()==18)break};Collections.shuffle(a);print a

... ooooh, what a waste of chars :)

110 chars

def a=[];while(a.size()<18){(new Random().next(2)>1&&a.size()<17?a<<3<<5:a<<4)};Collections.shuffle(a);print a

Bash shell script (65 chars)

shuf -e `for x in {0..8}
do echo $((r=RANDOM%3+3)) $((8-r))
done`

(shuf comes from the GNU coreutils package. Also, thanks Gareth.)

Clojure - 55

(shuffle(mapcat #([[4 4][3 5]%](rand-int 2))(range 9)))

Quite a fun trick.... exploits the mathematical structure of the problem that there must be exactly as many 3 par holes as 5 par holes.

Clojure - 72 chars

(some #(if(=(apply +%)72)%)(partition 18(repeatedly #(+(rand-int 3)3))))

Would be much shorter if Clojure didn't have such flowery descriptive function names :-)

C (123 chars) - effort on efficiency

Pipe through wc and it will generate all 44152809 solutions within 10 seconds...

char s[19];g(d,t){int i;if(d--){for(i=51,t-=3;i<54;i++,t--)if(t>=3*d&&t<=5*d)s[d]=i,g(d,t);}else puts(s);}main(){g(18,72);}

Oh, well - didn't read the question properly - but given we're generating all solutions then picking a random one with equal probability is a scripting exercise :P

GolfScript (26 chars)

{;0{3rand.3+@@+(}18*])}do`

There are some obvious similarities with Ilmari's solution, but also some obvious differences. In particular, I'm exploiting the fact that the average par is 4.

Python, 97

Using a different method than the rejection sampling, this picks a random list of indices of random even length and alternates adding and subtracting to the elements at these indices.

from random import*;a=[4]*18;d=1
for i in sample(range(18),2*randint(0,9)):a[i]+=d;d=-d
print a

C (94 chars)

int h[18],s=0,i;
while(s!=72)for(i=s=0;i<18;s+=h[i++]=rand()%3+3);
while(i)printf("%d ",h[--i]);

The s=0 on line 1 may not be required, because what are the chances an uninitialized int will equal 72? I just don't like reading uninitialized values in straight C. Also, this probably requires seeding the rand() function.

output

3 3 3 4 5 5 3 3 4 5 5 4 3 4 5 5 5 3 

PHP - 77 Chars

<?while(array_sum($a)!=72){for($i=0;18>$i;){$a[++$i]=rand(3,5);}}print_r($a);

Much like sgrieve's solution, this builds a list of 18 holes, checks total par, and either prints it or rejects it and tries again. Oddly enough, our two solutions are the same length.

Rather annoyingly, PHP doesn't offer array functions with any brevity of name. Array_sum and print_r are killing me. Suggestions welcome.

GolfScript, 27 chars

{;18{3.rand+}*].{+}*72-}do`

Uses the same rejection sampling method as sgrieve's Python solution. Thus, every valid output actually is equally likely.

R - 41

x=0;while(sum(x)!=72)x=sample(3:5,18,T);x

# [1] 5 3 5 3 3 3 3 3 5 4 5 4 5 4 4 5 5 3

The algorithm is similar to @sgrieve's.

Python 77

Code

from numpy.random import*;l=[]
while sum(l)!=72:l=randint(3,6,18)
print l

Output

[3 4 4 5 3 3 3 5 4 4 5 4 5 3 4 4 5 4]

The import really kills this solution. It uses numpy to generate a 18 numbers between 3 and 5 and keeps generating lists until the sum of the list equals 72.

K, 28

{$[72=+/s:18?3 4 5;s;.z.s`]}