56
\$\begingroup\$

Remember the kids game, 'Duck, Duck, Goose'? No? Me neither.

The challenge

  • Print the word 'duck' on individual lines an indeterminate amount of times.
  • Print the word 'goose'.
  • Your program ends.

The rules

  • Attempt to play the game in the fewest bytes.
  • There must be at least one duck.
  • There must be exactly one goose, at the end of the list.
  • There must be exactly one bird on each line. No empty lines.
  • The case of the outputted strings is irrelevant.
  • White-space within a line is fine.
  • Your program must finish.
  • Your program must not consistently produce the same number of ducks.

Have fun!


Please note: This question is not a duplicate of Shortest code to produce non-deterministic output

Reasons include:

  • The association to a childrens' game
  • The defined start and end requirements of the result string. There is no specified output in the other challenge.
  • Answers For the other, non-duplicate challenge are in a single-digit number of bytes. The average for this one is around 30, or there about.
  • By the amount of overlap between this challenge and that one, any code-golf question including the 'random' tag is a duplicate. Should we delete them all?
  • The code answers for this challenge would match the other challenge (in a ridiculously bloated way), but the answers to that challenge would not match this one.
\$\endgroup\$
  • 10
    \$\begingroup\$ Could you define indeterminate? Could it mean either zero or one? \$\endgroup\$ – recursive Mar 12 '18 at 15:51
  • 1
    \$\begingroup\$ Please define how randomly this should be generated. Uniform in range or with exponential decline? \$\endgroup\$ – HyperNeutrino Mar 12 '18 at 15:52
  • \$\begingroup\$ @recursive Nope, but let's go with a working definition... The program does not consistently present the same number of ducks. \$\endgroup\$ – AJFaraday Mar 12 '18 at 15:52
  • 2
    \$\begingroup\$ Speaking as a Minnesotan, what if mine prints "duck, duck, gray duck" instead? :) \$\endgroup\$ – Mike Hill Mar 14 '18 at 19:13
  • 1
    \$\begingroup\$ @jpmc26 I’m sure there are others. You’d have had to play it with others, for a start. \$\endgroup\$ – AJFaraday Mar 15 '18 at 23:13

111 Answers 111

4
\$\begingroup\$

Javascript 79 69 62 60 bytes

-10 bits thanks to @Herman Lauenstein

-7 bits thanks to @binarymax

-2 bits thanks to @Shaggy

_=>{for(_=0;_++<=new Date%9;)(l=console.log)`Duck`;l`goose`}

a=_=>{for(_=0;_++<=new Date%9;)(l=console.log)`Duck`;l`goose`}
a()

\$\endgroup\$
  • 1
    \$\begingroup\$ 69 bytes: _=>{for(_=0;_<Math.random()*9;_++)(l=console.log)('Duck');l('goose')} \$\endgroup\$ – Herman L Mar 12 '18 at 20:36
  • 1
    \$\begingroup\$ Won't this give you no ducks if random returns zero? \$\endgroup\$ – Shaggy Mar 13 '18 at 8:00
  • 1
    \$\begingroup\$ 63 Bytes: _=>{for(_=0;_<=new Date%10;_++)(l=console.log)`Duck`;l`goose`} \$\endgroup\$ – binarymax Mar 13 '18 at 15:38
  • 1
    \$\begingroup\$ @binarymax, you can save 2 more bytes on that with _++<=new Date%9 and a few more by using alert instead of console.log. \$\endgroup\$ – Shaggy Mar 14 '18 at 17:13
  • 1
    \$\begingroup\$ One byte shorter: for(_=9;_-->new Date%9;). Another four bytes less: for(_=new Date;_--;) (no idea if that works, though) \$\endgroup\$ – Titus Mar 14 '18 at 17:27
4
\$\begingroup\$

Minecraft Functions (18w11a, 1.13 snapshots), 402 382 bytes

duck duck goose in minecraft

Uses three functions in the minecraft namespace

a:

scoreboard objectives add r custom:play_one_minute
scoreboard objectives add t dummy
scoreboard objectives add x dummy
scoreboard players set @s t 9
scoreboard players operation @s x = @s r
scoreboard players operation @s x %= @s t
function b

b:

execute if score @s x = @s t run say Goose
execute unless score @s x = @s t run function c

c:

say Duck
scoreboard players add @s x 1
function b

Datapack with the functions

-20 bytes by removing unnecessary namespaces

Explanation

Function a creates three scoreboard objectives (variables). Objectives with the criteria dummy are like conventional variables, however, r has the criteria custom:play_one_minute. This means it will increase each in game minute. By using modulus it becomes a pseudorandom number between 0 and 9. The t objective is used because there is no way to do math with literal values, so we need a "constant" objective.

The function b is the main loop, calling the c function until the counter objective x is equal to 9 at which point it prints "Goose".

The c function prints "Duck", increments the counter objective and then calls the b function again

\$\endgroup\$
3
\$\begingroup\$

R, 45 bytes

while({cat("duck
");rt(1,1)>0})0;cat('goose')

Try it online!

Outgolfed by @user2390246

Prints a single duck, then with probability 1/2, prints another duck and repeats, or prints goose and terminates.

This could also be without the >0 part, since the Student's t-distribution might eventually return a 0 but that is highly improbable, so I prefer this.

\$\endgroup\$
  • \$\begingroup\$ 35 bytes \$\endgroup\$ – user2390246 Mar 12 '18 at 16:38
  • 1
    \$\begingroup\$ @user2390246 I think that's sufficiently different from mine as to warrant its own answer, especially since every answer is bound to be a variant of "generate a random number of ducks one goose"; yours is a quite distinct approach. \$\endgroup\$ – Giuseppe Mar 12 '18 at 16:42
  • 2
    \$\begingroup\$ Fair enough, thanks for your sportsmanship! Added as a separate answer \$\endgroup\$ – user2390246 Mar 12 '18 at 16:50
3
\$\begingroup\$

Python 3, 52 bytes

prints 1 to 256 ducks.

import os
print("duck\n"*-~os.urandom(1)[0]+"goose")

Try it online!

\$\endgroup\$
3
\$\begingroup\$

DOS .BAT, 54 Bytes

@for /l %%d in (0,9,%random%)do @echo duck
@echo goose

43 Bytes

[main.bat]
  @0&echo goose
[0.bat]
  @echo duck&%random% 2>nul
\$\endgroup\$
  • \$\begingroup\$ Change the 1 to a 0 in case %random% returns 0? \$\endgroup\$ – Neil Mar 12 '18 at 17:31
  • \$\begingroup\$ @Neil Done               \$\endgroup\$ – l4m2 Mar 12 '18 at 17:36
3
\$\begingroup\$

Dirty, 20 bytes

Warning: May produce up to 2^63 "duck"s

#.⇖('duck'‼)'goose'‼

Try it online!

Explained:

#.⇖       generate a range up to a random number, put into left stack
('duck'‼) while left stack isn't empty, print "duck" and a newline
'goose'‼  print "goose" and a newline
\$\endgroup\$
3
\$\begingroup\$

SmileBASIC, 31 25 bytes

?"duck
EXEC!RND(9)?"goose

Has a 1/9 chance of ending after each iteration.

Explanation:

PRINT "duck"
EXEC !RND(9)
PRINT "goose"

SmileBasic has 4 "slots" that you can run code in. Normally programs run in slot 0, but you can load things like libraries into the others. EXEC <slot> is used to run code in a different slot.

RND(9) generates a random number from 0 to 8. If this is 0, !RND(9) is 1, otherwise it's 0.

EXEC 0 will run the current slot from the beginning (creating a loop), but EXEC 1 runs slot 1 (which is empty)

After running slot 1, execution returns to slot 0, and the program prints "goose" and ends.

\$\endgroup\$
3
\$\begingroup\$

Vim + date, 33 29 bytes

:r!date +1\%SO␊D@"duck␛ogoose

Prints 100 to 159 ducks

Explanation

:r!date +1\%SO␊        Get the current date in seconds, prepend it with and postpend an O
D@"aduck␛             Take the current line, cut it and use as code to insert duck the
                       specified amount of times
ogoose                 insert goose
\$\endgroup\$
3
\$\begingroup\$

PHP, 35 bytes

duck
<?=time()%2?'duck
':''?>
goose

Or rand() if you prefer.

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I think this breaks the rule "There must be exactly one bird on each line. No empty lines." \$\endgroup\$ – Goose Mar 13 '18 at 18:50
  • \$\begingroup\$ @Goose: There is a leading duck in the first line before the code. \$\endgroup\$ – Titus Mar 14 '18 at 15:54
  • \$\begingroup\$ Save one byte with -n and date(s) instead of time()%2. \$\endgroup\$ – Titus Mar 14 '18 at 15:57
  • \$\begingroup\$ @Tinus there's nothing in this code to makes new lines. Everything is on the same line. Every duck and goose must be on it's own line. \$\endgroup\$ – Goose Mar 14 '18 at 17:27
  • 1
    \$\begingroup\$ @Goose works for me \$\endgroup\$ – Οurous Mar 14 '18 at 21:42
3
\$\begingroup\$

Julia 0.6, 33 bytes

print("duck\n"^rand(1:9),"goose")

This will print duck up to 9 times before goose!

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Welcome to PPCG! \$\endgroup\$ – Martin Ender Mar 13 '18 at 10:08
  • \$\begingroup\$ Welcome to PPCG! You can include a link to Try it online! (aka TIO) for your answer; TIO has a lot of interpreters and can automatically format your answer for you :) \$\endgroup\$ – Giuseppe Mar 13 '18 at 13:45
3
\$\begingroup\$

F#, 74 bytes

let c=System.Random().Next()
for i=0 to c do
 printfn"duck"
printfn"goose"

Try it online! - but note that the sample is limited to at most 20 ducks.

Setting i=0 means that if c is 0, then at least one "duck" will still be printed.

\$\endgroup\$
  • \$\begingroup\$ Why using variable c and not just for i=0 to System.Random().Next()do printfn"duck" directly? \$\endgroup\$ – manatwork Mar 13 '18 at 15:15
  • \$\begingroup\$ It would interfere with the randomness of it. Instead of i terminating at a random value, the larger i gets the more chance it has of being greater than a new random value. \$\endgroup\$ – Ciaran_McCarthy Mar 13 '18 at 15:35
3
\$\begingroup\$

T-SQL, 44 bytes

a:PRINT'duck'IF RAND()<.5GOTO a PRINT'goose'

Different method than Alex' excellent answer.

\$\endgroup\$
3
\$\begingroup\$

Pure Bash, 41 37 bytes

printf %s\\n ${RANDOM//[0-9]/duck } goose

This uses the same trick as in Sophia Lechner's answer to obtain a random number in the range 0-32767 with $RANDOM but does not require sed or any other external utilities to be installed to transform it into the desired result.

The Bash parameter expansion ${variable//pattern/replacement} obtains the value of variable with any match on pattern replaced by replacement. The shell then expands and tokenizes the arguments to printf, which applies the format string to each resulting argument.

I'm not a good golfer. Digital Trauma's answer has a much more lenient pattern which gets me down to 37 bytes.

printf %s\\n ${RANDOM//?/duck } goose

Try it online!

\$\endgroup\$
3
\$\begingroup\$

PHP, 36 bytes:

<?do{?>duck
<?}while(date(s))?>goose

Run with -n (no config file)

\$\endgroup\$
3
\$\begingroup\$

Japt, 18 17 16 bytes

Prints 1 or 2 ducks

`goo `i`Ýõ
`pM€

Try it online!

Saved 1 byte thanks to Shaggy & 1 byte thanks to Oliver

Explanation

`goo `     // compressed string "goose"
      i    // prepend string
       `Ýõ // compressed string "duck\n"
`          // ...
 p         // repeat n times
  M¬       // random int 0 or 1
    Ä      // add 1
\$\endgroup\$
  • \$\begingroup\$ 17 bytes \$\endgroup\$ – Shaggy Mar 13 '18 at 7:53
  • \$\begingroup\$ 16 bytes \$\endgroup\$ – Oliver Mar 14 '18 at 18:01
  • \$\begingroup\$ You can use p2â ö to randomly return 1 or 2. Unfortunately the shortcut for p2 wouldn't be useful here so it would still be 17 bytes. \$\endgroup\$ – Oliver Mar 14 '18 at 18:09
  • \$\begingroup\$ Thanks @Oliver! I didn't catch that in the shortcuts. \$\endgroup\$ – powelles Mar 14 '18 at 20:44
3
\$\begingroup\$

Forth, 91 BYTES

: DUCKDUCKGOOSE BEGIN 0 100 RANDOM 0 = IF ." GOOSE " LEAVE ELSE ." DUCK " THEN CR UNTIL ;

**OUTPUT: **

DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
DUCK 
GOOSE  ok....
\$\endgroup\$
  • \$\begingroup\$ Technically you need to add include random.fs also you can make it 67 bytes by using a do loop \$\endgroup\$ – reffu Aug 3 '18 at 15:42
2
\$\begingroup\$

Python 2, 54 bytes

Turns out thecoder16 ninja'd this Python 2 version...

from random import*
print"duck\n"*randint(1,9)+"goose"

Prints 1-9 ducks then a goose.

Try it online!


Originally...

Python 3,  61  56 bytes

from random import*
print("duck\n"*randint(1,9)+"goose")

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ You can reach 54 bytes if you switch to py2 \$\endgroup\$ – Rod Mar 12 '18 at 16:45
  • \$\begingroup\$ I think I may have just posted that, sorry \$\endgroup\$ – Quintec Mar 12 '18 at 16:48
  • \$\begingroup\$ @thecoder16 Oh you ninja'd me? :D \$\endgroup\$ – Jonathan Allan Mar 12 '18 at 16:49
  • \$\begingroup\$ It’s down there somewhere, about 3 minutes ago, though it’s not properly formatted because I don’t know how :( Should I delete or what? \$\endgroup\$ – Quintec Mar 12 '18 at 16:51
  • \$\begingroup\$ @thecoder16 No, that's fine, I've hit the same solution as others within short time frames before - I only delete if I am much later and it's just a result of not reading other answers! (I've also linked to your post too) \$\endgroup\$ – Jonathan Allan Mar 12 '18 at 16:52
2
\$\begingroup\$

Python 2, 65 bytes

from random import*
while random():print"duck"
print"duck\ngoose"

Try it online!

-6 bytes thanks to Rod

theoretically finishes. practically will probably never finish but eventually random.random() will spit out a 0

\$\endgroup\$
  • \$\begingroup\$ I've not seen it finishing after a few tries... Theoretically it will is a fun one, tho ;) \$\endgroup\$ – AJFaraday Mar 12 '18 at 15:55
  • 2
    \$\begingroup\$ 65 bytes \$\endgroup\$ – Rod Mar 12 '18 at 15:58
  • 2
    \$\begingroup\$ I'm not totally certain this is valid, isn't it possible that for some seed the PRNG will actually never generate a zero? It's not a particularly big deal, since you can correct it easily, but I think this would technically need a proof. \$\endgroup\$ – FryAmTheEggman Mar 12 '18 at 17:26
  • \$\begingroup\$ @FryAmTheEggman I think in this case "Never say never" is mathematically accurate. \$\endgroup\$ – Berry M. Mar 12 '18 at 18:41
2
\$\begingroup\$

I don't have the rep to comment on the other PowerShell answer, so I have to post it separately:

PowerShell, 36 bytes

,'duck'*(random -mi 1 -ma 9);'goose'

Try it online!

My answer is longer, because the maximum flag is required. Omitting it often leads to an OutOfMemoryException: Array dimensions exceeded supported range. In this case the program does not output anything besides the error.

\$\endgroup\$
2
\$\begingroup\$

Java 8, 83 82 72 68 51 47 bytes

v->(Math.random()<.5?"duck\n":"")+"duck\ngoose"

Returns either one or two "duck" before "goose".

-1 byte thanks to @l4m2.
-4 bytes thanks to @someone.

Explanation:

Try it online.

v->                   // Method with empty unused parameter and String return-type
  (Math.random()<.5?  //  If the random boolean is true:
    "duck\n"          //   Return a "duck" + new-line
   :                  //  Else:
    "")               //   Return nothing
   +"duck\ngoose";    //  Appended with a "duck", new-line and "goose"
\$\endgroup\$
  • 1
    \$\begingroup\$ d+=.1 => d*=2 \$\endgroup\$ – l4m2 Mar 13 '18 at 10:00
  • \$\begingroup\$ I made several searches before posting my answer, but I couldn't find this one, for some reason. I deleted it after seeing this one. Anyways, I'm not sure this fulfills the challenge as the challenge specifies "print", not "output". Edit... 2 pages, that's why I didn't see it... \$\endgroup\$ – Olivier Grégoire Mar 13 '18 at 11:00
  • \$\begingroup\$ "Anyways, I'm not sure this fulfills the challenge as the challenge specifies "print", not "output"." Well, it also specifies program instead of function. I personally interpret 'print' as 'print or return' in almost all cases, except for explicitly STDOUT is mentioned. But maybe that's just me.. \$\endgroup\$ – Kevin Cruijssen Mar 13 '18 at 11:55
  • \$\begingroup\$ I'm not familiar with Java, but this seems to work for 47 bytes. According to the docs, Math.random() returns values such that 0 <= x < 1, so Math.random()>0 should work too, but that seems hard to test and very unlikely to actually happen. \$\endgroup\$ – someone Mar 13 '18 at 13:20
  • \$\begingroup\$ @someone The changes of an actual 0.000... are indeed astronomical small. But your 47-byte version is indeed a nice golf, so thanks! :) \$\endgroup\$ – Kevin Cruijssen Mar 13 '18 at 13:44
2
\$\begingroup\$

My name has never been more relevant.

PHP, 40 bytes

<?=str_repeat("duck\n",date("h"))?>goose

Only trick used is date("h") to generate a random number that will never be 0.

\$\endgroup\$
  • \$\begingroup\$ Presumably you could just as easily use millisecond? \$\endgroup\$ – AJFaraday Mar 13 '18 at 19:26
  • \$\begingroup\$ Probably a lot of options depending on how wide a range of random numbers you want, but I think they'd all be the same byte count. \$\endgroup\$ – Goose Mar 13 '18 at 20:19
  • \$\begingroup\$ @Goose using mktime() saves one byte \$\endgroup\$ – Ben Mar 14 '18 at 1:58
  • \$\begingroup\$ @Ben true, but it tries to allocate 7605159771 bytes and I can't run that on my machine so I'm not sure if it's appropriate to include. \$\endgroup\$ – Goose Mar 14 '18 at 12:55
  • 1
    \$\begingroup\$ default values (no config; flag -n) disable notices and allow <?=str_repeat("duck\n",date(h))?>goose or <?=str_repeat("duck\n",date(h)),goose;, saving two bytes; a literal newline saves another byte. \$\endgroup\$ – Titus Mar 15 '18 at 21:43
2
\$\begingroup\$

PowerShell, 57 bytes

$r=Random @(1..9)
for($x=0;$x -lt $r;$x++){"Duck"}"Goose"

While $x is less than the value of $r, write "duck", else write "goose".

First code golf I've done. Had fun with the challenge, and am looking forward to getting better!

\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome to PPCG! \$\endgroup\$ – Shaggy Mar 15 '18 at 0:50
2
\$\begingroup\$

CJam, 17 bytes

es"duck
"*"goose"

Prints around 10^12 ducks. es is the builtin for Unix timestamp.

For two more bytes, a version with more reasonable output:

9mr)"duck
"*"goose"
\$\endgroup\$
2
\$\begingroup\$

Excel, 33 bytes

=REPT("duck
",9*RAND()+1)&"goose"

Prints duck between 1 and 10 times, followed by goose.

\$\endgroup\$
2
\$\begingroup\$

T-SQL, 43 bytes

PRINT REPLICATE('duck
',RAND()*5+1)+'goose'
\$\endgroup\$
2
\$\begingroup\$

Assembly (nasm, x64, Linux), 79 55 bytes

global main

main:
  rdrand ecx
  jnc main
.ducks:
  mov al, 1      ; Move the syscall id into ral. Doing it using a single byte is shorter
  mov edi, eax   ; Copy the value over, which takes exactly 2 bytes.
  xor esi, esi   ; \
  or rsi, duckD  ; Move a pointer to duckD into rsi. This is shorter than the equivalent move.
  mov dl, 5      ; Move the size of the string into rdl.
  push rcx       ; Preserve rcx for use by the loop instruction
  syscall        ; Call the syscall. in this case, syscall write to file descriptor 1, aka stdout.
  pop rcx        ; Restore rcx
  loop .ducks    ; Decrement rcx and jmp back to .ducks if rcx isn't 0
  mov al, 1
  mov edi, eax
  xor esi, esi
  or rsi, gooseD
  mov dl, 6
  syscall
  ret
duckD: db 'duck', 10, 0
gooseD: db 'goose', 10, 0

Try it online!

A simple explanation of syscall write is sitting here. Mostly for me, because I forget it exists sometimes.

WARNING: May print up to 2^32 ducks

\$\endgroup\$
2
\$\begingroup\$

Ahead, 30 bytes

There is a 25% chance after each duck that the loop will be broken and goose will be printed. This is because the X cell, which chooses a random cardinal direction. Every direction except right will skip over the lower segment due to how the ~ are placed.

>"kcud"WNojrXv
^~@W"goose"~<>~

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Python 2, 48 43 33 bytes

print"duck\n"*(id(0)%9+1)+"goose"

Try it online!

Takes no input. Prints a max of 9 'duck's.

Explanation:

               # Call the id() function on the integer 0.
               # This is a different, usually very large integer every time the program is executed.
               # % 9 will return 0-8, so this will return 1-9.
               id(0)%9+1
# print 1-9 'duck's, each ending in a new line, then finally 'goose'
print"duck\n"*(.........)+"goose"
\$\endgroup\$
2
\$\begingroup\$

Ink, 24 22 bytes

-(h)
duck
{~goose|->h}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

C (gcc), 66 65 53 50 bytes

main(){for(;puts("duck")&time(0););puts("goose");}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I can print one or two ducks in 46 bytes if you're interested... \$\endgroup\$ – Neil Mar 12 '18 at 16:15
  • 1
    \$\begingroup\$ @Neil Post your answer \$\endgroup\$ – cleblanc Mar 12 '18 at 16:21
  • 2
    \$\begingroup\$ main(){puts("duck\nduck\ngoose"+time(0)%2*5);} \$\endgroup\$ – Neil Mar 12 '18 at 16:33
  • \$\begingroup\$ I think as puts returns 5 all the time (for this case), so for(;time(0)&puts("duck");) may work (although in a different way) \$\endgroup\$ – user202729 Mar 12 '18 at 16:37
  • \$\begingroup\$ If you use puts("duck")&time(0) u should say the environment. Some puts() return 0 \$\endgroup\$ – l4m2 Mar 12 '18 at 17:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.