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

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\$
2
\$\begingroup\$

MathGolf, 17 16 15 bytes

9╒wôÿduckn'g╕3`

-1 byte thanks to @maxb.

Try it online.

Explanation:

Prints [1, 9] amount of duck.

9╒          # Push a list [1,2,3,4,5,6,7,8,9]
  w         # Pop and push a random integer from this list
   ô        # Loop that many times and execute the following six characters:
    ÿduck   #  Push the 4-character string "duck"
         n  #  Push a newline
   'g╕3`   '# After the loop: push 'g' and compressed "oose"
            # (join everything on the stack together and output it implicitly)
\$\endgroup\$
2
  • \$\begingroup\$ To get a random number in range [1, 9] inclusive: 9╒w. This way, you don't have to discard the stack after the loop. 15-byter: 9╒wôÿduckp'g╕3` \$\endgroup\$
    – maxb
    Jun 3, 2019 at 13:28
  • \$\begingroup\$ @maxb Ah, of course! I initially had 9w, but of course it could also result in 0, so I changed it to and combined it with , but was kinda annoyed by the integers still on the stack. But of course 9╒w is better, fixing that problem. :) \$\endgroup\$ Jun 3, 2019 at 13:47
2
\$\begingroup\$

Zsh, 25 bytes

repeat $ <<<duck
<<<goose

Try it online!

Prints duck {process ID} times. A PID is not really random, but it's indeterminate and never 0. On TIO, this tends to be in the region of 10,000.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I really like that approach to the challenge! \$\endgroup\$
    – AJFaraday
    May 28, 2021 at 10:41
  • \$\begingroup\$ 10,000? That's a lot of ducks. \$\endgroup\$
    – roblogic
    Feb 8, 2023 at 4:49
2
\$\begingroup\$

APL, 22 bytes

∇P
'DUCK'
→?3
'GOOSE'∇
\$\endgroup\$
2
\$\begingroup\$

Ly, 27 bytes

"Duck"9`1[p&:09?]p"Goose"&o

Try it online!

The code pushes a random number of "Duck\n" strings onto a stack, then pushes "Goose" and prints the whole thing.

"Duck"                      - push "Duck" onto the stack
      9`                    - push LF (9+1) onto the stack
        1                   - push 1 to start loop
         [p     ]p          - loop until top of stack is "0"
           &:               - duplicate stack
             09?            - generate random number in 0-9 range
                  "Goose"   - push "Goose" on the stack
                         &o - print the entire stack
\$\endgroup\$
1
\$\begingroup\$

J: 24 bytes

Arbitrarily limited to no more than 9 ducks:

'Goose',~>(>:?9)$<'Duck'
\$\endgroup\$
5
  • 2
    \$\begingroup\$ I've just run this through Try It Online. It doesn't seem to output anything. tio.run/##y/r/X909P784VV2nzlrDzsreUlPFRt2lNDlbR0H9/38A \$\endgroup\$
    – AJFaraday
    Mar 12, 2018 at 16:58
  • \$\begingroup\$ You need to use echo to get the output (presumably this is assumed to be run on the REPL). Try this. I don't know why it seems like it only outputs one possible number of "Duck"s, though (probably has to do with the way J evaluates ? in nouns). \$\endgroup\$
    – cole
    Mar 12, 2018 at 17:08
  • \$\begingroup\$ TIO seems to prescribe a particular format not suited to an immediate execution language like J (or their J implementation is broken). Try putting the code both in "Code" and "Input". \$\endgroup\$
    – DevonMcC
    Mar 12, 2018 at 17:14
  • \$\begingroup\$ J seeds the RNG with 16807 on startup, so the output is always deterministic, noun or not. Try it with seeding \$\endgroup\$
    – FrownyFrog
    Mar 12, 2018 at 20:41
  • \$\begingroup\$ According to Dennis at the tio site, you need to prefix the J code with "echo" to see the output. To re-seed the RNG, you could add this phrase to the right of a J phrase using random numbers: [ 9!:1]<.13#.|.}.6!:0'' \$\endgroup\$
    – DevonMcC
    Mar 12, 2018 at 21:49
1
\$\begingroup\$

Red, 38 bytes

loop random 9[print"duck"]print"goose"

Try it online!

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

Aceto with -l flag, 25 bytes

R99**i"duck\n"*£p"goose"p

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Command-line flags are counted as separate languages, now, so no need to add +1 to your byte count. \$\endgroup\$ Mar 12, 2018 at 19:09
  • \$\begingroup\$ @AdmBorkBork Wasn't aware. Thanks! \$\endgroup\$
    – drham
    Mar 12, 2018 at 19:24
1
\$\begingroup\$

Chip, 68 bytes

Uses flag -w. (Turns out we've decided to simplify how we count flags.)

!
>----z/v\ZZZZZt
>ZZZZ-xL')))xc
xx)))b`? b(((
)x-x)~a   dde
c^ed^~g

Try it online!

After printing each "DUCK\n", makes a binary choice for whether to go back to "DUCK\n", or print "GOOSE" and terminate.

So, 1/2 of all runs will see one DUCK, 1/4 will see two, 1/8 will see three, and so on.

The left blob under the Z's contains the encoding for "DUCK\n", and the right blob under the Z's contains "GOOSE". The connecting bit between the two makes the random decision, and the rest is just infrastructure.

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

Add++, 42 bytes

D,f,?:,@n
R9
y:duck
W,x:y,O,x:0,R9
x:goose

Try it online!

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

Ruby, 49 Bytes

(rand(9)+1).times do
puts "duck"
end
puts "goose"

Explanation

  1. Generate an integer between 0 and 9 and add 1 to it
  2. Each of those times print a duck
  3. End the loop and print goose
\$\endgroup\$
1
  • 1
    \$\begingroup\$ With 0.upto(rand 9){puts:duck};puts:goose you can get rid of the extra parenthesis needed due to the +1. \$\endgroup\$
    – manatwork
    Mar 13, 2018 at 13:41
1
\$\begingroup\$

RUST, 240 bytes

extern crate rand;
use rand::distributions::{IndependentSample, Range};
fn main() {
  let mut rng = rand::thread_rng();
  println!("{}", std::iter::repeat("Duck\n").take(Range::new(1, 9).ind_sample(&mut rng)).collect::<String>()+"Goose");
}

You can try it here: https://play.rust-lang.org/?version=stable&mode=release Copy and Paste Sorry I dont have shorten link due their server error!

\$\endgroup\$
3
  • \$\begingroup\$ Hi there -- I don't know RUST at all but there's definitely some unnecessary whitespace you can remove. If there's any way to make shorter variable names, that will also help. \$\endgroup\$
    – Giuseppe
    Mar 13, 2018 at 17:42
  • \$\begingroup\$ play.rust-lang.org/… 114 bytes \$\endgroup\$
    – Noskcaj
    Mar 15, 2018 at 1:48
  • 1
    \$\begingroup\$ play.rust-lang.org/… 101 bytes \$\endgroup\$
    – Noskcaj
    Mar 15, 2018 at 22:07
1
\$\begingroup\$

Ruby: 33 bytes

puts 'duck\n'*Time.new.sec+'goose'

Try it online! (Note that TIO doesn't respect newline characters like a normal console)

It might take a second, but sooner or later it'll print another number of ducks...

Okay, I just like the idea, it'd be a little shorter as:

Ruby, 30 bytes

Shortened thanks to @ovs

puts"duck\n"*-~rand(9)+'goose'

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ Ah, you've bested my Ruby version by a byte! I have had to resort to a cheat to get down to 30 (which if you apply would get you to 29). \$\endgroup\$
    – Turophile
    Mar 14, 2018 at 4:42
  • \$\begingroup\$ That's 34 bytes, not 33. \$\endgroup\$
    – Shaggy
    Mar 15, 2018 at 20:01
  • \$\begingroup\$ @Shaggy I got there with Ruby’s ‘length’ function. Perhaps it’s reading the newline character as one? \$\endgroup\$
    – AJFaraday
    Mar 15, 2018 at 22:31
  • \$\begingroup\$ Note that TIO doesn't respect newline characters like a normal console This is not a TIO issue. \n works inside double quotes, but not inside single quotes. In any case, \n can be replaced with a literal newline. Try it online! \$\endgroup\$
    – Dennis
    May 16, 2018 at 15:20
1
\$\begingroup\$

mIRC v.7.51, 40 37 bytes

Also works in most older versions, and definitely in newer versions.

//echo $str(Duck $crlf,$r(1,9)) Goose

How It Works?

$r(1,9) -> Generates a random number between 1 and 9
$crlf -> Prints the carriage return and linefeed characters (ASCII 13 and 10 respectively)
$str -> Reoeats the first argument required number of times
echo -> Prints the succeeding text in the window

-3 bytes -> Changed $rand to $r

Please note that mIRC echo does not recognize the newline character, so the text is printed in the same line in the window. However, the text contains the newline character which means that if you copy paste it anywhere, then you will see the text in multiple lines. I believe this is allowed.

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

AWK, 59 55 bytes

END{for(srand();i++<9*rand();)print"duck";print"goose"}

Try it online!

-4 bytes thanks to manatwork

\$\endgroup\$
1
  • \$\begingroup\$ No need for parenthesis around print's argument. \$\endgroup\$
    – manatwork
    Mar 13, 2018 at 12:37
1
\$\begingroup\$

Javascript - 61 bytes

document.write('duck<br>'.repeat(Math.random()*10+1)+'goose')

Live here

Second change - 57 bytes

document.write('duck<br>'.repeat(new Date()%9+1)+'goose')

Thanks @Martin

Another way is using console.log, but it is not visual for people to see the answer

52 bytes

console.log('duck\n'.repeat(new Date()%9+1)+'goose')

Try it online

46 bytes with alert

alert('duck\n'.repeat(new Date()%9+1)+'goose')

Try it online

\$\endgroup\$
6
  • \$\begingroup\$ Welcome to PPCG! You don't need to print duck so many times, so you can save a byte by reducing *10 to *9 or something like that. And I think a common way to get a shorter indeterminate number would be new Date()%9+1. \$\endgroup\$ Mar 13, 2018 at 12:27
  • \$\begingroup\$ @MartinEnder Thanks, I think about number 10 and 9 before but I forgot to try that number, and thanks for your suggestion about new Date()%9+1 that helped me saved some bytes, I will update the code \$\endgroup\$
    – Hyperfork
    Mar 13, 2018 at 12:32
  • \$\begingroup\$ The 52-byte version is completely fine. That's the usual output you'd use in a console (as opposed to a browser): tio.run/##y0osSyxOLsosKNHNy09J/f8/… \$\endgroup\$ Mar 13, 2018 at 13:00
  • \$\begingroup\$ I have added a better solution with "alert", It only 46 bytes. \$\endgroup\$
    – Hyperfork
    Mar 13, 2018 at 13:10
  • 1
    \$\begingroup\$ save another 4 bytes by using lambda: _=>*duck *.repeat(new Date()%9+1)+'goose' (literal newline after duck and ` instead of *) \$\endgroup\$
    – Brian H.
    Mar 14, 2018 at 12:27
1
\$\begingroup\$

PHP 53 45 bytes

echo str_repeat("duck\n",rand(1,99))."goose";

-8 bits thanks to @manatwork

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Wouldn't rand(1,99) do essentially the same as substr(rand(),-2)? \$\endgroup\$
    – manatwork
    Mar 13, 2018 at 12:20
  • \$\begingroup\$ @manatwork yep, didn't know that function existed, thanks \$\endgroup\$ Mar 13, 2018 at 13:10
1
\$\begingroup\$

Pyth, 17 bytes

VhOT"duck";"goose

Try it online!

Pretty simple. Loops between 1 and 11 times, printing duck, then prints goose.

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

Elixir, 57 bytes

fn->String.duplicate("duck
",:rand.uniform 2)<>"goose"end

Returns a string either one or two ducks.

Try it online!

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

Tcl, 45 characters

while {rand()<.9} puts\ duck
puts duck\ngoose

Try it online!

Tcl, 55 characters

puts [string repeat duck\n [expr int(rand()*9+1)]]goose

Sample run:

bash-4.4$ tclsh <<< 'puts [string repeat duck\n [expr int(rand()*9+1)]]goose'
duck
duck
goose

Try it online!

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

Attache, 33 bytes

Print=>Random[1,9]&"duck"'"goose"

Try it online!

Explanation

Print=> prints each element of:

Random[1,9]&"duck", which repeats "duck" a random number between 1 and 9 times, and

"goose", which is appended to the end with '.

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

SNOBOL4 (CSNOBOL4), 76 bytes

	X =TIME() * 100
S	OUTPUT ='DUCK'
	X =GT(X) X - 1	:S(S)
	OUTPUT ='GOOSE'
END

Try it online!

The TIME function counts the amount of time (in tenths of a second) elapsed since the program began, which does have a bit of randomness. Since it's so short, however, we have to scale by 100 or else the time will be nearly always zero. Then it outputs DUCK until X<0, decrementing X each iteration, before printing GOOSE.

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

Funky, 51 bytes

(p=print)"Duck"whilemath.random()>.3p"Duck"p"Goose"

Funky is surprisingly bad at Duck Duck Goose.

Try it online!

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

shell, 65 bytes

f(){ echo duck&&expr `date +%N` % 2 >/dev/null&&f||echo goose;};f

ideone

\$\endgroup\$
2
  • \$\begingroup\$ Too many 2 character list operators, when the single character ; would be enough. Also discarding expr's output would be shorter with an assignment than with redirection: f(){ echo duck;x=`expr \`date +%N\` % 2`&&f;};f;echo goose \$\endgroup\$
    – manatwork
    Mar 14, 2018 at 9:52
  • \$\begingroup\$ @manatwork Thank you for your advice. Just have fun. \$\endgroup\$
    – Divlaker
    Mar 15, 2018 at 8:53
1
\$\begingroup\$

golflua, 38 characters

M.rs(O.t())!@w"duck"!$M.r()<.1w"goose"

Sample run:

bash-4.4$ opt/eso/golflua-1.0/src/golflua -e 'M.rs(O.t())!@w"duck"!$M.r()<.1w"goose"'
duck
duck
goose
\$\endgroup\$
1
\$\begingroup\$

Perl6/Rakudo, 27 26 chars

say 「Duck
」x now%9~'Goose'

Change now%9 to 9.rand for sub-second nondeterminism at a cost of 1 char.

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

Labyrinth, 65 bytes

"  ^
1  \.701
0      .
0.117.99
0
1 "
"""v
  " 103.11:1:..5.101.@

Try it online!

\$\endgroup\$

Your Answer

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

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