65
\$\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\$
14
  • 11
    \$\begingroup\$ Could you define indeterminate? Could it mean either zero or one? \$\endgroup\$
    – recursive
    Mar 12, 2018 at 15:51
  • 1
    \$\begingroup\$ Please define how randomly this should be generated. Uniform in range or with exponential decline? \$\endgroup\$
    – hyper-neutrino
    Mar 12, 2018 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, 2018 at 15:52
  • 3
    \$\begingroup\$ Speaking as a Minnesotan, what if mine prints "duck, duck, gray duck" instead? :) \$\endgroup\$
    – Mike Hill
    Mar 14, 2018 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, 2018 at 23:13

125 Answers 125

1
\$\begingroup\$

PHP 55 53 Bytes (Thanks manatwork)

for($i=0;$i<time();$i++)echo 'duck<br>';echo 'goose';

Legibly

for($i=0;$i<time();$i++){
    echo 'duck<br>';
}
echo 'goose';

Now, I haven't tested this, because I don't want to melt my old computer, but it will output one duck for every second since January 1, 1970, 0000 hours. (Then a goose)

\$\endgroup\$
1
  • \$\begingroup\$ Checked the documentation of mktime()? The Notes contains a good golfing hint: mktime() without parameter is equivalent with time(). \$\endgroup\$
    – manatwork
    Mar 14, 2018 at 8:40
1
\$\begingroup\$

PHP, 40 bytes

<?=str_pad(goose,5+5*date(m),"duck
",0);

prints one duck for every month (3 in March, 4 in April etc.)

Run with -n (no config file) or try it online.

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

APL+WIN, 24 bytes

⊃((?⎕),1)/'duck' 'goose'

Prompts for an integer which can be between 1 and system maximum and will then select a number from 1 to that integer at random for the number of ducks. If no input is desired then the max integer can be hard coded for a few more bytes.

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

Lua, 50 46 bytes

Giving a new language a try.

d="duck\n"print(d:rep(os.time()%9|1).."goose")

Try it online

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

C (gcc), 48 bytes

Too many ducks for one goose!

main(){while(rand())puts("duck");puts("goose");}

Try it online!

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

WinDBG, 39 bytes

.foreach(_ {#}){.echo duck};.echo goose

How it works:

.foreach(_                              $$ Loop..., using an unused variable _
           {#})                         $$ ...through each space separated "word" of the next disassembly text
               {.echo duck};            $$ Print duck on each iteration
                            .echo goose $$ Print goose at the end

The dissambly text will be formatted something like this. The examples on MSDN don't have the first line, so maybe that only shows if you have symbols for the code that you're currently debugging. But definitely the assembly_details part can contain spaces (or be empty) which will cause a different number of ducks to print.

dll!Function [source @ line]:
address binary_code      assembly_mnemonic     assembly_details

With the above example, it would print (in parenthesis is the value of _, not actually printed)

duck (dll!Function)
duck ([source)
duck (@)
duck (line]:)
duck (address)
duck (binary_code)
duck (assembly_mnemonic)
duck (assembly_details)
goose
\$\endgroup\$
1
\$\begingroup\$

Twig, 45 bytes

Twig is a templating language written in PHP.

This uses the random() function up to 9.
Then, it will loop all elements in the range of 1 - random(9).

This causes a bug: random(<n>) returns values up to the <n> value (including 0).
However, twig allows to make a range of 1 - 0, creating an array with 2 elements.

This ensures that there is always, at least, 1 duck.

{%for _ in 1..random(9)%}duck
{%endfor%}goose

You can try it on https://twigfiddle.com/w0m6p6

\$\endgroup\$
2
  • \$\begingroup\$ I guess it´s a feature, not a bug. 0..random(9) and random(9)..0 should also work. \$\endgroup\$
    – Titus
    Mar 15, 2018 at 13:04
  • \$\begingroup\$ Well, it could cause a bug. And yes, those work as well. \$\endgroup\$ Mar 15, 2018 at 13:30
1
\$\begingroup\$

jamal, 47 characters

{@format time=ss}{#for i/0..{#time}/duck
}goose

(No proper random, no subdivision of seconds, so the most random thing is the second.)

Sample run:

bash-4.4$ jamal.pl duck.jam
duck
duck
goose
\$\endgroup\$
1
\$\begingroup\$

Labyrinth, 58 bytes

" v03.1:1:1:..5.01.@
" ^
1;v
.  100.11
0 7     7
1.101.99.

Try it online!

Shorter than the previous Labyrinth solution. This is the first Labyrinth program I have written with moving code!

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

Visual Basic For Applications, 37 bytes

do:?"duck":loop while rnd>.1:?"goose"
\$\endgroup\$
1
\$\begingroup\$

Kotlin, 45 bytes

"duck\n".repeat((1..9).shuffled()[0])+"goose"

Try it online!

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

Kotlin 71 65 bytes

for(i in 1..(1..9).shuffled()[0])println("duck");println("goose")

Thanks Makotosan for the tip on how to replace the random to shave a few bytes.

\$\endgroup\$
1
  • \$\begingroup\$ You can save a byte by using 9 instead of 10. Also, you can shave off a few more by changing your random function to this: (1..9).shuffled()[0] So that your for loop looks like : for(i in 1..(1..9).shuffled()[0]) This will only work as long as you use small values. If you get into the millions, it will take up a lot of CPU and memory. \$\endgroup\$
    – Makotosan
    Mar 21, 2018 at 21:58
1
\$\begingroup\$

Java (OpenJDK 8), 106 bytes

a->{int r = new Random().nextInt(9);while(r>0){System.out.println("duck");r--;}System.out.print("goose");}

Try it online!

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

Python 2, 84 82 bytes

from random import*
a="Duck"
print a
while randint(0,9)%2:print a
print"Goose"

EDIT: changed random number function

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

Julia, 46 40 bytes

d="duck\n";print(d^rand(UInt)*d*"goose")

Upon invocation, this will print out between 1 and 2^64 instances of "duck " on the screen before printing "goose". If your computer uses a 64-bit processor like most people do, this will almost certainly blow whatever process memory allowance there is and cause an OOM error which Julia catches and returns to you gracefully.

If you want to test it, put "UInt8" instead of "UInt" to pare it down to between 1 and 256 ducks before a goose.

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

C#, 97 Bytes

a=>{var r=new Random();var s="";do{s+="Duck\n";}while(r.Next(9)>0);s+="Goose";Console.Write(s);};
\$\endgroup\$
1
\$\begingroup\$

Swift 3/4, 94 74 73 bytes

import Foundation;for _ in -1..<time(nil)%9{print("duck")};print("goose")

Try it online!

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

Gol><>, 21 bytes

"esooG"fSxXFa"kcuD"|H

Try it online!

How it works

"esooG"fSxXFa"kcuD"|H

"esooG"                Push "Goose" in reverse order
       f               Push 15
        Sx             Push a random number in [0,1)
          X            Exponentiation
           F  ...  |   Pop n and repeat the content n times
            a"kcuD"    Push "Duck\n" in reverse order
                    H  Print the content of the stack as chars
                       from top to bottom, then halt

The result of fSxX is in the range [1,15), but F takes the ceiling of the popped value as the repeat count, so the actual result has [2,15] ducks. (1 duck is theoretically possible, but the chance is about 2**-52.)

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

Python 3, 43 40 36 bytes

EDIT: Saved 3 bytes thanks to l4m2

EDIT: Saved 4 bytes by removing useless end= from print function.

print('Duck\n'*max(id(0),1),'Goose')

Python's id function produces an indeterminate value between runs of the program. So we call id on 0. id is not guaranteed to be >=1, so use max to ensure the value is at least 1.

\$\endgroup\$
9
  • \$\begingroup\$ This doesn't work. \$\endgroup\$ Mar 12, 2018 at 17:18
  • \$\begingroup\$ Is hash guaranteed to be non-zero? The output is required to have at least one duck. \$\endgroup\$
    – recursive
    Mar 12, 2018 at 17:18
  • \$\begingroup\$ @recursive Good point. Edited. \$\endgroup\$
    – mypetlion
    Mar 12, 2018 at 17:20
  • \$\begingroup\$ @EriktheOutgolfer How so? \$\endgroup\$
    – mypetlion
    Mar 12, 2018 at 17:21
  • 1
    \$\begingroup\$ archivum.info/[email protected]/2005-02/00414/… \$\endgroup\$
    – l4m2
    Mar 12, 2018 at 18:11
1
\$\begingroup\$

Taxi, 567 bytes

Go to Heisenberg's: w 1 r, 3 r, 1 l.Pickup a passenger going to The Underground.Go to The Underground: s 1 r 1 l.[a]Switch to plan "b" if no one is waiting.Pickup a passenger going to The Underground."duck\n" is waiting at Writer's Depot.Go to Zoom Zoom: n 3 l 2 r.Go to Writer's Depot: w.Pickup a passenger going to Post Office.Go to Post Office: n 1 r 2 r 1 l.Go to The Underground: n 1 r 1 l.Switch to plan "a".[b]"duck\ngoose\n" is waiting at Writer's Depot.Go to Writer's Depot: n 3 l 2 l.Pickup a passenger going to Post Office.Go to Post Office: n 1 r 2 r 1 l.

Prints a very large number of ducks, almost always enough to overflow the output buffer on TIO, and then prints a goose, then terminates with an error. Note: "duck\ngoose\n" can't be shortened to just "goose\n", because Heisenberg's could return exactly zero (although the chance is miniscule).

Try it online!

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

Python 3, 50 bytes

exec("print('duck');"*abs(id({})))
print("goose")

Could be shortened by 1 byte using

id(1)

But than there will be no random on the same environment.

Explanation

id() -- returns unique id of python object, usually adress in memory, because we getting ID of freshly created hash it will different every run.

\$\endgroup\$
1
  • \$\begingroup\$ This usually errors as the program runs out memory trying to store an extremely large string \$\endgroup\$
    – Jo King
    Aug 2, 2018 at 7:41
1
\$\begingroup\$

x86-64 Machine Code (Linux), 40 bytes

0000000000000000 <goose>:
   0:   67 6f
   2:   6f
   3:   73 65
   5:   0a

0000000000000006 <duck>:
   6:   64 75 63
   9:   6b
   a:   0a

Disassembly of section .text:

0000000000000000 <_start>:
   0:   b0 01                   mov    $0x1,%al
   2:   40 b7 01                mov    $0x1,%dil
   5:   be 00 00 00 00          mov    $0x0,%esi
   a:   b2 06                   mov    $0x6,%dl
   c:   0f 05                   syscall
   e:   0f c7 f1                rdrand %ecx
  11:   67 e3 ec                jecxz  0 <_start>
  14:   b0 01                   mov    $0x1,%al
  16:   be 00 00 00 00          mov    $0x0,%esi
  1b:   0f 05                   syscall

The first 12 bytes are used to store the strings "goose\n" and "duck\n". Technically when duck is printed, it prints 6 bytes (while "duck\n" is 5 bytes), but chances are that the byte after where duck is located in the binary will be an invisible character.

The blocks that preceded the syscall are just setting up the sys_write system call. Normally in x86-64 this looks like (in Intel syntax rather than AT&T):

b8 01 00 00 00                   mov    $0x1,%eax ; syscall number for sys_write
bf 01 00 00 00                   mov    $0x1,%edi ; fd number for STDOUT
48 be 00 00 00 00 00 00 00 00    movabs $0x0,%rsi ; pointer to where the "duck\n" string is located (nasm syntax)   
ba 06 00 00 00                   mov    $0x6,%edx ; number of bytes to write
0f 05                            syscall

However we can use the lower bits addressing of the registers to produce shorter x86 opcodes.

For the second syscall, only rax gets clobbered (since it holds the return value for sys_write), so we have to reset it.

The randomness comes from using the rdrand instruction, which sets a hardware random number into ecx. The next instruction then jumps back to _start if ecx is 0. This means that "duck" will only be printed again with a chance of 1/(2^32). However small this chance is, it technically is possible and non-deterministic.

The more interesting way to print out a series of "duck" strings before "goose" is to replace the rdrand and jecxz instructions with:

66 0f c7 f3             rdrand %bx
66 85 db                test   %bx,%bx
75 e9                   jne    0 <_start>

Unfortunately this takes 2 more bytes, but the effect is that the result of rdrand is stored into bx, which is a 16 bit register. Additionally, each time this is run, the chance the code jumps back to start and prints "duck" again is (2^16 - 1)/(2^16). This means that after about 50000 loops there's over a 50% chance of bx being 0 in at least one of the loops. (The exact amount is 45426 loops). For a 90% chance of bx being 0 in at least one of the loops, just over 150000 loops need to occur.

Finally, with normal program behavior, this program should call sys_exit with this code:

0000000000000020 <_exit>:
  20:   b8 3c 00 00 00          mov    $0x3c,%eax
  25:   31 ff                   xor    %edi,%edi
  27:   0f 05                   syscall

But since we can just leave this out and the program will exit with a segmentation fault, this is fine. The challenge has already been completed by this point.

For better inline comments, check out the original nasm source code in my repo.

\$\endgroup\$
1
  • \$\begingroup\$ Suggest xor %esi, %esi instead of mov $0x0, %esi \$\endgroup\$
    – ceilingcat
    Sep 30, 2019 at 18:20
1
\$\begingroup\$

APL (Dyalog Unicode), 40 bytes

{⎕←'Duck'}⍣{1=?9}2⋄⎕←'Goose'

Sure there's already a shorter Dyalog solution, but it doesn't have the potential to print Duck an infinite amount of times :P

Also the 2 does absolutely nothing lol

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ You say the 2 does nothing, but removing it gives you “goose” every time. If must do something? \$\endgroup\$
    – AJFaraday
    Jan 13, 2019 at 14:30
  • 1
    \$\begingroup\$ @AJFaraday well ok it does do something. it forces the niladic dfn on the left to get called otherwise it won't be. \$\endgroup\$
    – akhmorn
    Jan 13, 2019 at 15:02
1
\$\begingroup\$

Japt -R, 15 bytes

`Ýõãµ&o `qÍtMq

Run it online

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

TI-BASIC (TI-84), 20 bytes

While not(rand:Disp "DUCK:End:Disp "GOOSE

Prints DUCK on a new line until rand returns 1, where it will then print GOOSE.
This program will take a significant amount of time to complete due to the specifications of rand.
If randjust so happens to have 196164532 as its seed, then the program won't print any DUCKs. This can be fixed by adding 4 bytes:

0:While not(Ans:Disp "DUCK:rand:End:Disp "GOOSE

Note: TI-BASIC is a tokenized language. Character count does not equal byte count.

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

Java 8, 139 bytes

OP wanted a full program, so here you go

interface I{static<T>void p(T t){System.out.println(t);}static void main(String[]a){for(p("duck");Math.random()>.1;p("duck"));p("goose");}}

Try it online!

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

Trigger, 52 bytes

ABddduuuccckkk


AAB	 	 	 	 	 	 	 	Bgggooo ooossseee

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ I think you missed a line when copy-pasting. \$\endgroup\$ Jun 4, 2019 at 12:56
  • \$\begingroup\$ @negativeseven I did not copy-paste. Also, there is no line missing\ \$\endgroup\$
    – MilkyWay90
    Jun 4, 2019 at 20:51
  • \$\begingroup\$ Ah, TIO just wrapped the line but the UI here didn't. My bad. \$\endgroup\$ Jun 5, 2019 at 7:44
1
\$\begingroup\$

GolfScript, 25 bytes

1 9rand+{"duck"n}*"goose"

Explanation

1 9rand+        # pick a random integer in [1, 10]
{"duck"n}       # push 'duck\n'
*               # repeat the previous code block the random number of times
"goose"         # push 'goose'
\$\endgroup\$
1
\$\begingroup\$

Roblox Studio - 71 bytes

@BenjaminUrquhart Better find more games to answer in

Looks like I found another game (a reasonably popular one too)!

print('duck')
while math.random(9)>1 do print('duck')end
print('goose')

Apparently 0 is a truthy value in Roblox/Lua so I had to use >1.
You can seed this with math.randomseed(tick()). enter image description here

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

Runic Enchantments, 22 bytes

"duck"akqf'RA*"goose"@

Try it online!

Explanation

"duck"akq                Push the string "duck" with a newline on the end
         'RA             Random number 0-15
            *            Duplicate the string so that there are n copies python
                             style (bug? 0 still leaves one copy; I'm ok with this)
             "goose"     Concatenate "goose" onto the end
                    @    Print and terminate
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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