Blue duck, red duck, gray duck
LuaLaTeX, 220 211 characters
command:
lualatex -interaction nonstopmode
Not the shortest, but the fanciest. Based on @skillmon's solution
\RequirePackage{tikzducks}\newcount\b\let~\def~\0{red}~\1{orange}~\2{yellow}~\3{green}~\4{blue}~\5{cyan}~\6{violet}~\7{gray}\loop\b\uniformdeviate8\tikz\duck[body=\csname\the\b\endcsname]; \ifnum\b<7\repeat\stop
6502 machine code (C64), 124 bytes
00 C0 AD 12 D0 85 02 A2 17 8E 18 D0 A5 02 F0 03 0A 90 02 49 1D 85 02 A8 CA 10
02 A2 2F BD 42 C0 D0 F6 88 D0 F3 86 FB E8 BD 42 C0 F0 06 20 16 E7 E8 D0 F5 AA
BD 73 C0 F0 06 20 16 E7 E8 D0 F5 A6 FB D0 C9 60 00 C7 52 45 59 00 D2 45 44 00
CF 52 41 4E 47 45 00 D9 45 4C 4C 4F 57 00 C7 52 45 45 4E 00 C2 4C 55 45 00 C9
4E 44 49 47 4F 00 D6 49 4F 4C 45 54 00 20 44 55 43 4B 0D 00
Online demo -- Usage: SYS49152
.
Explanation (commented disassembly):
00 C0 .WORD $C000 ; load address
.C:c000 AD 12 D0 LDA $D012 ; current rasterline as seed
.C:c003 85 02 STA $02 ; to "random" value
.C:c005 A2 17 LDX #$17 ; cfg for upper/lower, also use as
.C:c007 8E 18 D0 STX $D018 ; initial index into colors array
.C:c00a .loop:
.C:c00a A5 02 LDA $02 ; load current random val
.C:c00c F0 03 BEQ .doEor ; zero -> feedback
.C:c00e 0A ASL A ; shift left
.C:c00f 90 02 BCC .noEor ; bit was shifted out -> no feedback
.C:c011 .doEor:
.C:c011 49 1D EOR #$1D
.C:c013 .noEor:
.C:c013 85 02 STA $02 ; store new random val
.C:c015 A8 TAY ; use as counter for next color string
.C:c016 .findloop:
.C:c016 CA DEX ; next char pos in colors (backwards)
.C:c017 10 02 BPL .xok ; if negative ...
.C:c019 A2 2F LDX #$2F ; load length of colors - 1
.C:c01b .xok:
.C:c01b BD 42 C0 LDA .colors,X ; load character from colors
.C:c01e D0 F6 BNE .findloop ; not zero, try next character
.C:c020 88 DEY ; decrement random counter
.C:c021 D0 F3 BNE .findloop ; not zero, continue searching
.C:c023 86 FB STX $FB ; save character position
.C:c025 E8 INX ; increment to start of color
.C:c026 .outloop:
.C:c026 BD 42 C0 LDA .colors,X ; output loop for color string
.C:c029 F0 06 BEQ .duckout
.C:c02b 20 16 E7 JSR $E716
.C:c02e E8 INX
.C:c02f D0 F5 BNE .outloop
.C:c031 .duckout:
.C:c031 AA TAX ; A is now 0, use as char pos for duck
.C:c032 .duckoutloop:
.C:c032 BD 73 C0 LDA .duck,X ; output loop for duck string
.C:c035 F0 06 BEQ .outdone
.C:c037 20 16 E7 JSR $E716
.C:c03a E8 INX
.C:c03b D0 F5 BNE .duckoutloop
.C:c03d .outdone:
.C:c03d A6 FB LDX $FB ; load saved character position
.C:c03f D0 C9 BNE .loop ; not zero -> continue main loop
.C:c041 60 RTS ; zero was start of "Grey" -> done
.C:c042 .colors:
.C:c042 00 c7 52 45 .BYTE 0, "Gre"
.C:c046 59 00 d2 45 .BYTE "y", 0, "Re"
.C:c04a 44 00 cf 52 .BYTE "d", 0, "Or"
.C:c04e 41 4e 47 45 .BYTE "ange"
.C:c052 00 d9 45 4c .BYTE 0, "Yel"
.C:c056 4c 4f 57 00 .BYTE "low", 0
.C:c05a c7 52 45 45 .BYTE "Gree"
.C:c05e 4e 00 c2 4c .BYTE "n", 0, "Bl"
.C:c062 55 45 00 c9 .BYTE "ue", 0, "I"
.C:c066 4e 44 49 47 .BYTE "ndig"
.C:c06a 4f 00 d6 49 .BYTE "o", 0, "Vi"
.C:c06e 4f 4c 45 54 .BYTE "olet"
.C:c072 00 .BYTE 0
.C:c073 .duck:
.C:c073 20 44 55 43 .BYTE " duc"
.C:c077 4b 0d 00 .BYTE "k", $d, 0
Perl 5, 79 bytes
say$_=(Grey,Red,Orange,Yellow,Green,Blue,Indigo,Violet)[rand 8]." duck"until/y/
Try it online!