text:
Blue duck, red duck, gray duck
So, last week I posted a challenge to play Duck, Duck, Goose. This lead to a number of Minnesotans commenting about their regional 'Gray duck' variation.
So here's the rules:
Using this list of colours:
Red
Orange
Yellow
Green
Blue
Indigo
Violet
Gray

Write a program to follow these rules:

Select one of these colours, and prepend it to the word 'duck' and print the result to a new line.
If the colour was not 'Gray', repeat step 1.
If the colour was 'Gray', end your program.

Rules which must be followed:

The program should not consistently print the same number of lines.
It can begin on 'Gray duck', but should not do consistently.
There should be exactly one duck on each line and no empty lines are output.
There should be at least one space between a colour and a duck.
White space before and after the significant output does not matter.
The case of the output doesn't matter.
Colours can be repeated.
The output doesn't have to contain every colour every time, but it must be possible that your code will output every colour.
No colours outside the above array can be included.
Either grey or gray are acceptable in your answer.
Colours should not consistently be in the same order.
Aim for the shortest program. Smallest number of bytes wins.

Example output:
Green duck
Orange duck
Yellow duck
Indigo duck
Yellow duck
Gray duck

Thanks to @Mike Hill for first alerting me to this variation.

Any rules on the distribution on outcomes? Because I could generate valid outputs by picking from non-grey colours a random number of times, followed by printing Grey once (so I wouldn't have to pick from all of them and check whether I've picked Grey).

@MartinEnder That's fine. "Colours should not consistently be in the same order." matters, but there's nothing to stop you picking grey separately at the end.

Is the alternative spelling "gray" allowed?

@12Me21 Curious, tho. Is there a technical reason for that? Or just an aesthetic one?

Mostly just aesthetic, though it might affect golfing languages with built in string compression.

I believe "gray" should be allowed, even encouraged, because that's how Minnesotans are more likely to spell it. ;)

@DLosc I almost feel like I should change the question now...

In my not-so-humble opinion, you are missing one extremely important duck color.  Blue is close, but not precise enough.

@cobaltduck We've got blue, we've got green. You can just mix up a batch ;)

Thunno 2, 41 bytes
(’Red ṆỴ »Ẹ Ɓ# Ñɦ ƲỤ ṡʂ Ɓ~’OɼD‘ _*‘+£`Ɓ~Q

Attempt This Online!
Explanation
(                     # While loop
 ’...’                # (condition)  Push compressed string of colours
      O               #              Split it on spaces
       ɼ              #              Pick a random item from this list
        D             #              Duplicate the item
         ‘ _*‘+       #              Append compressed string " duck"
               £      #              Pop and print with a newline
                `Ɓ~   #              Push compressed string "Grey"
                   Q  #              Check for inequality
                      # (body)  Do nothing

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

Good heavens! This is just the best thing! You've made my day, Alex.

@AJFaraday indeed amazing idea to use tikzducks there :)

+1 and my apologies for choosing such a long package name!

@sam, you get my absolution

Hello mr. person who I definitely don't know from other technical communities like TeX.sx. Since this answer covers some birds in the family Anatidae, I feel compelled to provide a token of approval by upvoting it. :)

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

I'm sorry, your demo doesn't seem to output any duck-related content.

@AJFaraday please notice the "usage" part ... the command to run it is sys 49152.

Okay, that made my day :)

haha good :D just in case anyone cares, you have to type the sys command because it's a plain machine code program, and the normal run on the C64 only runs BASIC programs. Of course it's simple to link a "BASIC header", I don't do it here to save bytes ;)

That was awesome.  It's been a while since I've written c64 assembly.

@lsd: same here! my very first program was 6502 assembly on a C64,because I just got it and a friend gave me the 6502 book with a task "write a game!" to jumsptart me into writing something! (great way! it was a great motivator to not just read, but actually write something). wrote a 192 bytes (iirc) "Snake" program (with a, imo, clever double index pointing to the head & to the tail of the snake's position)... first try: it zoomed past the bottom edge, 'eating' into the rest of the ram, growing on any "@", as I forgot to set up the walls ^^

Perl 5, 79 bytes
say$_=(Grey,Red,Orange,Yellow,Green,Blue,Indigo,Violet)[rand 8]." duck"until/y/

Try it online!

Taxi, 1995 bytes
Go to Heisenberg's:w 1 r 3 r 1 l.[a]Pickup a passenger going to Divide and Conquer.8 is waiting at Starchild Numerology.8 is waiting at Starchild Numerology.Go to Starchild Numerology:n 1 l 3 l 1 l 3 l.Pickup a passenger going to Divide and Conquer.Pickup a passenger going to Multiplication Station.Go to Divide and Conquer:w 1 r 3 r 1 r 2 r 1 r.Pickup a passenger going to Cyclone.Go to Cyclone:e 1 l 1 l 2 l.Pickup a passenger going to What's The Difference.Pickup a passenger going to Trunkers.Go to Zoom Zoom:n.Go to Trunkers:w 3 l.Pickup a passenger going to What's The Difference.Go to What's The Difference:w 2 r 1 l.Pickup a passenger going to Multiplication Station.1 is waiting at Starchild Numerology.Go to Starchild Numerology:e 1 r 1 l 3 l.Pickup a passenger going to Addition Alley.Go to Multiplication Station:w 1 r 2 r 1 r 4 l.Pickup a passenger going to Addition Alley.Go to Addition Alley:n 2 l 1 r 3 l 1 l.Pickup a passenger going to The Underground.'Red duck\n' is waiting at Writer's Depot.'Orange duck\n' is waiting at Writer's Depot.'Yellow duck\n' is waiting at Writer's Depot.'Green duck\n' is waiting at Writer's Depot.'Blue duck\n' is waiting at Writer's Depot.'Indigo duck\n' is waiting at Writer's Depot.'Violet duck\n' is waiting at Writer's Depot.'Grey duck' is waiting at Writer's Depot.Go to Writer's Depot:n 1 l 1 l.[b]Pickup a passenger going to Narrow Path Park.Go to Narrow Path Park:n 3 r 1 l 1 r.Go to The Underground:e 1 r.Switch to plan "c" if no one is waiting.Pickup a passenger going to The Underground.Go to Writer's Depot:s 2 r 1 l 2 l.Switch to plan "b".[c]Go to Narrow Path Park:n 4 l.Pickup a passenger going to Post Office.Go to Post Office:e 1 r 4 r 1 l.Go to Writer's Depot:s 1 r 1 l 2 l.Switch to plan "a" if no one is waiting.[d]Pickup a passenger going to Sunny Skies Park.Go to Sunny Skies Park:n 2 r.Go to Writer's Depot:n 1 l.Switch to plan "e" if no one is waiting.Switch to plan "d".[e]Go to Heisenberg's:n 3 r 3 r.Switch to plan "a".

Try it online!
I think it's worth noting that 47% of this code is just picking a random integer from 1 to 8.
Also, Taxi is so verbose that it is way shorter to hard code the duck\n after each color rather than concatenating it later.
Here's the un-golfed version:
Go to Heisenberg's: west 1st right 3rd right 1st left.

[Pick up a random INT 1-8 going to The Underground]
[a]
Pickup a passenger going to Divide and Conquer.
8 is waiting at Starchild Numerology.
8 is waiting at Starchild Numerology.
Go to Starchild Numerology: north 1st left 3rd left 1st left 3rd left.
Pickup a passenger going to Divide and Conquer.
Pickup a passenger going to Multiplication Station.
Go to Divide and Conquer: west 1st right 3rd right 1st right 2nd right 1st right.
Pickup a passenger going to Cyclone.
Go to Cyclone: east 1st left 1st left 2nd left.
Pickup a passenger going to What's The Difference.
Pickup a passenger going to Trunkers.
Go to Zoom Zoom: north.
Go to Trunkers: west 3rd left.
Pickup a passenger going to What's The Difference.
Go to What's The Difference: west 2nd right 1st left.
Pickup a passenger going to Multiplication Station.
1 is waiting at Starchild Numerology.
Go to Starchild Numerology: east 1st right 1st left 3rd left.
Pickup a passenger going to Addition Alley.
Go to Multiplication Station: west 1st right 2nd right 1st right 4th left.
Pickup a passenger going to Addition Alley.
Go to Addition Alley: north 2nd left 1st right 3rd left 1st left.
Pickup a passenger going to The Underground.

[Use the random INT to select a color]
'Red duck\n' is waiting at Writer's Depot.
'Orange duck\n' is waiting at Writer's Depot.
'Yellow duck\n' is waiting at Writer's Depot.
'Green duck\n' is waiting at Writer's Depot.
'Blue duck\n' is waiting at Writer's Depot.
'Indigo duck\n' is waiting at Writer's Depot.
'Violet duck\n' is waiting at Writer's Depot.
'Grey duck' is waiting at Writer's Depot.
Go to Writer's Depot: north 1st left 1st left.
[b]
Pickup a passenger going to Narrow Path Park.
Go to Narrow Path Park: north 3rd right 1st left 1st right.
Go to The Underground: east 1st right.
Switch to plan "c" if no one is waiting.
Pickup a passenger going to The Underground.
Go to Writer's Depot: south 2nd right 1st left 2nd left.
Switch to plan "b".

[Output the selected color]
[c]
Go to Narrow Path Park: north 4th left.
Pickup a passenger going to Post Office.
Go to Post Office: east 1st right 4th right 1st left.

[If the color was grey, exit by error]
Go to Writer's Depot: south 1st right 1st left 2nd left.
Switch to plan "a" if no one is waiting.

[Get rid of the rest of the colors]
[You could throw them off a bridge but you won't get paid]
[d]
Pickup a passenger going to Sunny Skies Park.
Go to Sunny Skies Park: north 2nd right.
Go to Writer's Depot: north 1st left.
Switch to plan "e" if no one is waiting.
Switch to plan "d".

[Start over from the beginning]
[e]
Go to Heisenberg's: north 3rd right 3rd right.
Switch to plan "a".

That was fun to read.

Golly, that's esoteric! I can't begin to understand how it works. Lots of fun, tho :)

This seems related to Fetlang

Java (OpenJDK 9), 133 bytes
v->{for(int x=9;x>0;)System.out.println("Grey,Red,Orange,Yellow,Green,Blue,Indigo,Violet".split(",")[x+=Math.random()*8-x]+" duck");}

Try it online!
Explanations
v->{                              // Void-accepting void lambda function
  for(int x=9;x>0;)               //  Loop until x is zero
    System.out.println(           //   Print...
        "Grey,Red,Orange,         //       colors, "Grey" first
         Yellow,Green,Blue,       //          more colors
         Indigo,Violet"           //          more colors
        .split(",")               //       as an array
          [x+=Math.random()*8-x]  //       pick one randomly, use implicit double to int cast with "x+=<double>-x" trick
        +" duck");                //      Oh, and append " duck" to the color.
}

Ruby, 93 91 90 89 87 86 85 bytes
Thanks to Dom Hastings for saving 2 bytes, Kirill L. 1 byte and Asone Tuhid 1 byte!
puts %w(Red Orange Yellow Green Blue Indigo Violet Grey)[$.=rand(8)]+" duck"while$.<7

Try it online!

You can remove () around the code and if you use $. instead of s to store the index, you can avoid creating s altogether (since $. is pre-initialised to the line number!) You'll need to move Grey to the end of the list and check for $.<7 instead though. Hope that helps!

@DomHastings Thanks! I was looking for a way to get rid of s=1 and $. was perfect!

I think you can also remove space after while, Ruby doesn't  seem to complain about that.

@KirillL. That's right, thanks! I previously had while s... and the space was needed. Didn't see this opportunity after changing s to $..

Color+" duck" saves 1 byte

@AsoneTuhid Cool, thanks! :)

@GolfWolf, you can also use p instead of puts, saves another 3 bytes :)

@Kapenaar I don't know if it is acceptable to output every line in quotes.

Operation Flashpoint scripting language, 133 bytes
f={s="";v=s;while{v!="grey"}do{v=["Red","Orange","Yellow","Green","Blue","Indigo","Violet","Grey"]select random 7;s=s+v+" duck\n"};s}

Call with:
hint call f

Example output:

At first I somehow misread the challenge as if the goal was to just output a varying amount of lines, not necessarily ending at the "Grey duck" -line. Following that incorrect interpretation produced a slightly more interesting piece of code:
f={s="";c=[1];c set[random 9,0];{s=s+(["Red","Orange","Yellow","Green","Blue","Indigo","Violet","Grey"]select random 7)+" duck\n"}count c;s}

pdfTeX, 231 220 219 209 207 bytes
\newcount\b\let~\def~\0{Red}~\1{Orange}~\2{Yellow}~\3{Green}~\4{Blue}~\5{Indigo}~\6{Violet}~\7{Gray}~\9{ }\newlinechar`z\loop\b\pdfuniformdeviate8\message{z\csname\the\b\endcsname\9duck}\ifnum\b<7\repeat\bye

LuaTeX, 216 206 204 bytes
\newcount\b\let~\def~\0{Red}~\1{Orange}~\2{Yellow}~\3{Green}~\4{Blue}~\5{Indigo}~\6{Violet}~\7{Gray}~\9{ }\newlinechar`z\loop\b\uniformdeviate8\message{z\csname\the\b\endcsname\9duck}\ifnum\b<7\repeat\bye

05AB1E, 42 40 bytes
Saved 2 bytes thanks to Erik the Outgolfer
[“ëßigo°¯†¾›ÈŠÛˆ¨‡—°Íolet“#7ÝΩ©è'Ðœðý,®#

Try it online!

I've noticed a lot of these unreadable golfing languages. Is there a compiler from some more human-readable form?

@AJFaraday: Not that I'm aware of. The only golfing language I know which has one of those is Charcoal.

You can compress your string further, ind is ëß!

@EriktheOutgolfer: Thanks! I checked all the way down to indi, but I assumed ind wasn't a word. Serves me right :P

@Emigna I actually had another 41-byte version, but then looked at yours and realized there was a miscompression there :P [“†¾›ÈŠÛˆ¨‡—ëßigo°Íolet°¯“#ΩD’ Ðœ’«,'°¯Q#

Gs2 has one also. But that language is not used so much these days.

Which ANSI code page have you used to write this program? Because written on Unicode, with multi-byte code points, it takes more than 40 bytes.

@Simón: The 05AB1E code page

Brachylog, 68 bytes
"Grey","
Red
Orange
Yellow
Green
Blue
Indigo
Violet"ṇṛS," duck"ẉS¬?↰

Try it online!

Ruby, 84 81 bytes
Thanks to Dom Hastings for -3 bytes.

puts$_=%w[Red Orange Yellow Green Blue Indigo Violet Grey].sample+" duck"until/y/

Try it online!

If you store in $_, you can just have until/y/ at the end for -3!

Bash + GNU utilities, 72
shuf -e {Red,Orange,Yellow,Green,Blue,Indigo,Violet,Grey}\ Duck|sed /y/q

Try it online.

PHP, 89 bytes
do echo[Grey,Red,Orange,Yellow,Green,Blue,Indigo,Violet][$i=rand()%8]," Duck
";while($i);

Run with -nr or try it online.

><>, 107 bytes
x<>" duck"a>
x<^"deR"
x<^"egnarO"
x<^"wolleY"
x<^"neerG"
x<^"eulB"
x<^"ogidnI"
x<^"teloiV"
x"Grey duck"r>o|

Try it online!

JavaScript, 104 bytes
f=_=>`grey,red,orange,yellow,green,blue,indigo,violet`.split`,`[n=Math.random()*8|0]+` duck
${n?f():``}`

Try it online

FWIW, I had this variant, but I'm stuck at 104 bytes as well.

Shame we can't use new Date for the RNG here.

Python 3, 130, 128, 127, 126, 125 bytes
from random import*
d,c=1,'Grey Red Orange Yellow Green Blue Indigo Violet'.split()
while d!=c[0]:d=choice(c);print(d,'duck')

-1 by @ElPedro!
-1 by me
-1 by @Bubbler!
Try it online!

Can you move Grey to the front and have d!=c[0] to save a byte?

print(d,'duck') to save a byte. The default delimiter is a space.

Python 2, 138 133 120 117 116 bytes
import os
while id:id=ord(os.urandom(1))%8;print"Grey Red Orange Yellow Green Blue Indigo Violet".split()[id],'duck'

Try it online!
Much better with some ideas from @EriktheOutgolfer. Thanks!
-3 more with thanks to @ovs
-1 with thanks to @Rod for a cool new trick learned :-)

Octave, 114 112 bytes
do disp([strsplit('Red Orange Yellow Green Blue Indigo Violet'){i=randi(7)},' duck'])until i>6
disp('Grey duck')

Try it online!
There are a bunch of different options that are all between 112 and 118 bytes... Some initialize an index in the start and decrements it by a random number for each loop, and waits until it's 0. Others use printf instead of disp to avoid some brackets and so on.

Little question: Is there a symbol in octave that does the same as & in Excel, because I think it is possible to shorten the code even further then.

Unfortunately, no... Strings must be concatenated inside square brackets (or using functions such as cat and horzcat. Thanks though :)

PHP, 133 125 111 108 97 92 bytes
<?for(;$b=[Red,Orange,Yellow,Green,Blue,Indigo,Violet][rand(0,7)];)echo"$b duck
"?>Grey duck

Try it online!
-8 bytes thanks to @Olivier Grégoire
-3 bytes thanks to @manatwork
-11 bytes thanks to @Dom Hastings

In the color string and the test, change Grey to X, since it's not used. You'll gain 6 bytes.

@OlivierGrégoire Oh true. Thanks for that :)

Reverse the for's condition to need no parenthesis: x!=$b=$a[array_rand($a)]. BTW, ?> terminates a statement, no need for ; in front of it.

@manatwork Ohh, nice! I'll update my answer now!

You can save a few more bytes by not including x at all and using $b=$a.. as the condition and using rand(0,7) instead of array_rand. You can remove the newline between ?> and Grey duck too. Also your TIO link still had full tags, you can add -d short_open_tag=on to flags to get that working! :)

Thanks @DomHastings! I've updated my answer. Using rand instead of array_rand was a neat trick I hadn't thought of! I also didn't know about -d short_open_tag=on for tio :)

bash, 96 bytes
a=(Grey Red Orange Yellow Green Blue Indigo Violet);for((i=1;i;));{ echo ${a[i=RANDOM%8]} duck;}

Thanks to @DigitalTrauma.

Lots of opportunities to golf this - check out the bash golfing tips

@DigitalTrauma I was in hurry, but I wanted a pure Bash solution w/no GNU coreutils. I could shrink it from 112 to 105 bytes.

Yep, I like the pure-bash answers too.  Here's another 10 bytes off

I stripped >0, however, I left ${#a} instead of 8.

Why do you need to keep ${#a} instead of 8?  This is code-golf - there is no need to give your code generalisability to be modified for a different number of colours.  All you need to do is meet the spec in the smallest number of bytes.

Clever, I like the use of a loop that exits when the index variable (which is not being used as an actual index lol) hits 1

Retina, 69 68 bytes
Thanks to Leo for saving 1 byte.
.^/y/{K`Red¶Orange¶Yellow¶Green¶Blue¶Indigo¶Violet¶Grey
" duck¶">?G`

Try it online!
Explanation
./y/^{K`Red¶Orange¶Yellow¶Green¶Blue¶Indigo¶Violet¶Grey

. suppresses implicit output at the end of the program (otherwise, we'd get two grey ducks). /y/^{ wraps the entire program in a loop which continues as long as the working string doesn't contain a y. The rest of that line sets the working string to a linefeed-separated list of all the colours.
" duck¶">G?`

We grep a random line from the working string (and therefore a random colour). And we print the result with a trailing  duck and a linefeed.

Java (JDK 10), 287 bytes
Random r=new Random();int i;String c;do{i=r.nextInt(8);switch(i){case 0:c="Red";break;case 1:c="Orange";break;case 2:c="Yellow";break;case 3:c="Green";break;case 4:c="Blue";break;case 5:c="Indigo";break;case 6:c="Violet";break;default:c="Gray";}System.out.println(c+" duck");}while(i!=7)

Try it online!
My very first codegolf! Obviously not competitive, just happy to have learned enough Java (currently in CS200) to be able to participate.

AWK, 114 bytes
{srand();for(split("Red9Orange9Yellow9Green9Blue9Indigo9Violet9Grey",A,9);r<8;print A[r]" duck")r=int(8*rand()+1)}

Try it online!
Explanation
{srand();                  # Seed rand to obtain different sequence each run
for(
     split("Red9Orange9Yellow9Green9Blue9Indigo9Violet9Grey",
            A,9);          # Split on 9 to avoid using '"'s
     r<8;
     print A[r]" duck")    # Print the colored ducks
     r=int(8*rand()+1)     # AWK uses 1-indexing not 0-indexing when splitting strings into arrays
}

Note that this requires "some" input. The input can be empty. To avoid the need for input prepend the first line with BEGIN

PowerShell, 94 bytes
for(;$r-ne'Grey'){$r=-split"Red
Orange
Yellow
Green
Blue
Indigo
Violet
Grey"|Random;"$r Duck"}

Try it online!
Loops until $r is equal to Grey. Inside the loop, -splits the literal string on newlines, chooses a Random one thereof, then prints out the color plus Duck (technically, it's left on the pipeline and pipeline cleanup on the next loop iteration causes a Write-Output to happen). Note that it's theoretically possible for Grey to never be chosen, and the loop to continue infinitely, but this almost never (in the probability sense) will happen.

R, 101 bytes
cat(paste(c(sample(scan(,""),rexp(1),T),"gray"),"duck\n"))
Red
Orange
Yellow
Green
Blue
Indigo
Violet

Try it online!
Heavily inspired by @user2390246's answer to the related challenge. We need two sources of randomness: Changing the order of the colors and sampling the non-gray duck colors. The sample will take a random sample of random size given by an exponential distribution with rate parameter 1, truncated to an integer. Using an exponential distrubtion unfortunately means that there is a probability of exp(-8) or around 0.0003354  that the sample will be at least 8, so we have to sample with replace=T.

you can replace then \n with an actual newline for 1

also you can save quite a bit using colors()[c(26,254,498,552,640,652)] in place of the scan(..) etc.  should come down to about 83

@MickyT ......... I don't use R's graphics enough to remember about all the nice graphics builtins like colors()! Those are some nice golfs, which I think you should post as your own answer, since this is the less elegant way of getting the colors.

ok then, I'll post it up with a couple of little changes

MATL, 68 64 bytes
`'DYCIXMSQ(qm#Q$4{#is,Gh1(=lAjUSId;&'F2Y232hZaYb8YrX)' duck'h7Mq

Try it online!
Explanation
`                         % Do...while
  'DYCI···Id;&'           %   Push this string (to be decompressed by base conversion)
  F                       %   Push false
  2Y2                     %   Push string 'abc...xyz'
  32                      %   Push 32 (ASCII for space)
  h                       %   Concatenate horizontally. Gives 'abc...xyz '
  Za                      %   Base-convert from alphabet of all printable ASCII
                          %   characters except single quote (represented by input
                          %   false) to alphabet 'abc...xyz '. Produces the string
                          %   'grey red ··· violet'
  Yb                      %   Split on space. Gives a cell array of strings
  8Yr                     %   Random integer from 1 to 8, say k
  X)                      %   Get the content of the k-th cell
  ' duck'                 %   Push this string
  h                       %   Concatenate horizontally
  7M                      %   Push k again
  q                       %   Subtract 1
                          % Implicit end. Run a new iteration if top of the stack
                          % is non-zero
                          % Implicit display

Python 2, 98 bytes
Look ma no imports!
v=0
while 1:x=id(v)%97%8;print"GVIYORGBrinererleodladeuyliln ee egog n  towe"[x::8],"duck";v=1/x,v

(Prints extra spaces between the colours and duck as allowed in the question)
Try it online!
A pretty poor pseudo-random number generator seeded with the object id of 0 (but it seems to fit the spec) which repeatedly yields an integer, x, in [0,7] which is used to slice a list of characters from that index in steps of 8 to get the colour name which is printed along with duck as a tuple, forcing a space in-between. When x becomes zero Grey is printed and the evaluation of the next input to the modulo based random number generator errors attempting to divide by zero (v=1/x,v tries to make a new tuple with the first element 1/x = 1/0)

Same way is 100 in Python 3 with
v=0
while 1:x=id(v)%17%8;print("GVIYORGBrinererleodladeuyliln ee egog n  towe"[x::8],"duck");v=1/x,v

Japt, 54 53 52 bytes
Could probably be shorter but my tool for finding the optimal permutation of the string to compress is crapping out on this, for some reason.
_èSiy}a@P±` Ýõ
`i`gÎ9h½uehéHÃÎÁeâ¸©ºÄgohgyËB`qh ö

Test it
1 byte saved thanks to Oliver

52 bytes

Thanks, @Oliver. Did you brute force that?

Your tool only works with six items, so I excluded red and grey (shortest length), ran it through your tool, then added red and grey to the final list.

APL (Dyalog Unicode), 86 bytes
{×⍵:∇r⊣⎕←'Grey' 'Red' 'Orange' 'Yellow' 'Green' 'Blue' 'Indigo' 'Violet'[r←?8]'duck'}1

Try it online!
Assumes ⎕IO←0.

Kotlin, 122 bytes
while({x:Any->println("$x duck");x!="Grey"}("Red,Orange,Yellow,Green,Blue,Indigo,Violet,Grey".split(",").shuffled()[0])){}

Try it online!

Might be helpful to someone out there, to get a random integer value in Kotlin, You can use the following:
(0..7).shuffled()[0]
Shorter than:
(Math.random()*8).toInt()

T-SQL, 195 185 184 bytes
DECLARE @ VARCHAR(9)=''WHILE @<>'Grey'BEGIN SELECT @=c FROM(VALUES('Red'),('Orange'),('Yellow'),('Green'),('Blue'),('Indigo'),('Violet'),('Grey'))v(c)ORDER BY NEWID()PRINT @+' Duck'END

Nice variation. You can remove the space before BEGIN.

MS-SQL, 158 bytes
DECLARE @ VARCHAR(6)a:SELECT @=value FROM STRING_SPLIT('Red,Orange,Yellow,Green,Blue,Indigo,Violet,Grey',',')ORDER BY NEWID()PRINT @+' duck'IF @<>'Grey'GOTO a

Based largely on Razvan's excellent answer, but using the STRING_SPLIT function that is specific to MS-SQL 2016 and later. Also uses a GOTO instead of a WHILE loop.
Formatted:
DECLARE @ VARCHAR(6)
a:
    SELECT @=value FROM
        STRING_SPLIT('Red,Orange,Yellow,Green,Blue,Indigo,Violet,Grey',',')
        ORDER BY NEWID()
    PRINT @+' duck'
IF @<>'Grey'GOTO a

x86_64 machine code, 120 bytes.
I got inspired by the 6502 machine code and implemented the same in x86_64 machine code.
0x603000: 0x47    0x72    0x61    0x79    0x20    0x00    0x00    0x00
0x603008: 0x52    0x65    0x64    0x20    0x00    0x00    0x00    0x00
0x603010: 0x4f    0x72    0x61    0x6e    0x67    0x65    0x20    0x00
0x603018: 0x59    0x65    0x6c    0x6c    0x6f    0x77    0x20    0x00
0x603020: 0x47    0x72    0x65    0x65    0x6e    0x20    0x00    0x00
0x603028: 0x42    0x6c    0x75    0x65    0x20    0x00    0x00    0x00
0x603030: 0x49    0x6e    0x64    0x69    0x67    0x6f    0x20    0x00
0x603038: 0x56    0x69    0x6f    0x6c    0x65    0x74    0x20    0x00
0x603040: 0x64    0x75    0x63    0x6b    0x0a    0x00    0x0f    0x31
0x603048: 0xc1    0xe8    0x03    0x33    0xdb    0x83    0xc3    0x07
0x603050: 0x23    0xd8    0x8b    0xfb    0xc1    0xe7    0x03    0x48
0x603058: 0x81    0xc7    0x00    0x30    0x60    0x00    0xe8    0x73
0x603060: 0xd5    0xdf    0xff    0x48    0xc7    0xc7    0x40    0x30
0x603068: 0x60    0x00    0xe8    0x67    0xd5    0xdf    0xff    0x85
0x603070: 0xdb    0x0f    0x85    0xcf    0xff    0xff    0xff    0xc3

Or the disassembly:
   0x603046:  rdtsc
   0x603048:  shr    eax,0x3
   0x60304b:  xor    ebx,ebx
   0x60304d:  add    ebx,0x7
   0x603050:  and    ebx,eax
   0x603052:  mov    edi,ebx
   0x603054:  shl    edi,0x3
   0x603057:  add    rdi,0x603000
   0x60305e:  call   0x4005d6 <printf>
   0x603063:  mov    rdi,0x603040
   0x60306a:  call   0x4005d6 <printf>
   0x60306f:  test   ebx,ebx
   0x603071:  jne    0x603046
   0x603077:  ret

The first 70 bytes is a string table that looks like:
Gray\0\0\0\0
Red\0\0\0\0\0
Yellow\0\0
...
 duck\0

There is certainly room for optimizations and it might not be the shortest implementation in terms of bytes but it probably competes for least amount of bytes executed :)

Vyxal, 49 bytes
λ`⟇∴ ɾ⟩ °√ ×ŀ ⟇↵ ¯Ǔ⋏ġ Vio⟇» ←√`⌈℅:` ¦ø`+,‛←√≠[x|¤

Try it Online!

C (gcc), 104 bytes
f(n){for(;printf("%.6s duck\n","Gray\0 OrangeYellowIndigoVioletGreen\0Blue\0 Red"+(n=time(0)%7)*6),n;);}

Try it online!

TI-BASIC, 80 bytes
Repeat not(I
int(8rand→I
Disp sub("GRAY  RED   ORANGEYELLOWGREEN BLUE  INDIGOVIOLET",6I+1,6)+" DUCK
End

F#, 171 bytes
let r=System.Random()
let mutable i=r.Next(8)
while i<>7 do
 printfn"%s duck"["Red";"Orange";"Yellow";"Green";"Blue";"Indigo";"Violet"].[i]
 i<-r.Next(8)
printf"Grey duck"

Try it online!
That flipping "mutable" keyword! I thought that F#'s lack of a do/while loop (it only has while/do) would hurt me, but on retrospect it worked out, since "Grey duck" is always printed without a line separator (printfn versus printf), so there's no trailing empty line.

Visual Basic for Applications, 110 102 bytes
Edit: saved eight more bytes by using split() instead of array()
while rnd>.3:?split("Red,Orange,Yellow,Green,Blue,Indigo,Violet",",")(rnd*6)+" duck":wend:?"Gray duck"

Type in the immediate window.

Red, 96 91  bytes
until[n: random 8 print[pick[Red Orange Yellow Green Blue Indigo Violet Grey]n"duck"]n = 8]

Try it online!

APL+WIN, 106 bytes
⊃('red' 'orange' 'yellow' 'green' 'blue' 'indigo' 'violet' 'grey')[(↑(m=8)/⍳⍴m)↑m←1+8|n←1E3?1E3],¨⊂' duck'

Generates a vector of random integers between 1 and 8 and takes the series up to and including the first occurance of an 8 as indices into the colour vector and then concatenates the duck.

C (gcc), 138 133 123 122 bytes
Saved a byte thanks to @ceilingcat
*c[]={"Grey","Red","Orange","Yellow","Green","Blue","Violet"};main(i){for(;printf("%s duck\n",c[i=time(sleep(1))%6])*i;);}

Try it online!

PHP, 166, 148, 142 98 Bytes
Down to 98 bytes thanks to Shaggy and Titus.
I tried a recursive solution.
function f(){echo[grey,red,orange,yellow,green,blue,indigo,violet][$n=rand()&7]." duck
 ";$n&&f();}

Explanation
function f(){
  echo[grey,red,orange,yellow,green,blue,indigo,violet][$n=rand()&7]
  //a line break goes here, thats why it skips a line after duck
  //saves one byte over \n
        ." duck
         ";
  $n&&f();
}

For real it does not need much, the function will stop when $n == false or as php asumes $n == 0 as a false then it leaves the method.
Try it online
Don't really know how to "golf code", but i found this forum really, really fascinating.

the php tag was missing :D

Welcome to PPCG! I think I see a few potential savings but I'll let those more proficient in PHP steer you better. @AJFaraday, you're missing the first line.

@Shaggy I didn't, if you take a look at the edit history, it initially didn't have the php tag.

Replace ' Duck'.PHP_EOL with " Duck\n" to save a few bytes, for starters.

Do i need to set something else on tio.run?, if i do that the output is "Violet Duck\nGreen Duck\nRed Duck\nGray Duck\n"

mmm the if else is unnecesary, as on php 0 is intepreted as false.

Note the double, rather than single, quotes ;) Got it down to 103 bytes.

I would never ever woulda found this $n&&f();

101 bytes

99 using the header

Drop <?php at all and invoke it with cat prog.php | php -r

rand()&7 saves one more byte.

SOGL V0.12, 40 39 38 bytes
]"sω2a⁄Ξ┌┼0⁾    a║EΣ?GΘƨ+}‘θJ;7ψ:≥w⁽OX@oo

Try it Here!

Pyth, 72 bytes(SBCS)
K" Duck"#=kOc." y9Fª¹Ú¹«·.Û»õx¾jL[`ýõ?;ß¼<|9ü"\ +kKIqk"Gray"B

Try it online!
Python 3 translation:
import random
K=" Duck"
while True:
    k=random.choice("Red Orange Yellow Green Blue Indigo Violet Gray".split())
    print(k+K)
    if k=="Gray":
        break

65 bytes: Try it here

T-SQL, 211 178 bytes
SELECT c+' Duck'FROM(SELECT TOP(CAST(RAND()*9AS INT))c FROM(VALUES('Red'),('Orange'),('Yellow'),('Green'),('Blue'),('Indigo'),('Violet'))v(c)ORDER BY NEWID()UNION SELECT'Grey'c)q

SQLFiddle

Nice work, I couldn't figure out how to make TOP vary like that. You can save 2 bytes by removing the spaces after ' Duck' and after RAND()*9.

Also, looks like its sorting the other colors by name, you could keep the randomness (and save bytes) by removing the outer sort entirely, and simply changing the order of your UNION: ...FROM(SELECT TOP...ORDER BY NEWID()UNION SELECT'Grey'c)q

@BradC: Good advices, thanks! Although UNION without ORDER BY does not guarantee ordering, it's probable that the order will be correct, because for few rows it's unlikely to get a parallel execution plan.

Yep, seems unlikely in this small dataset. This answer suggests that a UNION ALL is more likely to not change the order, but doesn't link to any sources.

Swift, 161 143 bytes
import Foundation;var x=9;while x>0{x=time(nil)%7;print(["Grey","Red","Orange","Yellow","Green","Blue","Indigo","Violet"][x]+" duck");sleep(1)}

Thanks to @cleblanc, whom I got the idea of the shorter code from.
Explanation
import Foundation                   //we need Foundation for time

var x = 9

while x > 0 {
    x = time(nil)%7
    print(["Grey",
           "Red",
           "Orange",
           "Yellow",
           "Green",
           "Blue",
           "Indigo",
           "Violet"][x] + " duck") //subscripting color array, appending "duck"
            sleep(1)
}

Try it online!

Python 3, 127 bytes
from random import *;x=''
while'Grey'!=x:x=choice('Red,Orange,Yellow,Green,Blue,Indigo,Violet,Grey'.split(','));print(x,'duck')

Try it online!

FYI a very standard Python tip is to use from module import* and then just thing rather than module.thing here it will save 1 byte -- exceptions are when module is length four of less (e.g. import os;os.wait(1)) or there are multiple imports being made, when choices between modules should be made and as may come into play.

You could swap x!='Grey to 'Grey'!=x to save one (the space). You could use no arguments for split() to save 3 (splits on spaces). You could use the allowance of any casing of output to go from 'Grey'!=x to something like 'a'<x to save four more... All in all my tips will save you 9 bytes Try It Online! - it doesn't get you under other Python answers but good things for future golfing IMO anyway :)

Perl 6/Rakudo 78 bytes
say $_=<Grey Red Orange Yellow Green Blue Indigo Violet>.roll~" duck"until /y/

Stealing directly from Dom Hastings' Perl 5 answer
Perl 6 wins slightly with .roll

Bash + Coreutils, 100 Bytes
B=`shuf -en1 Red Orange Yellow Green Blue Indigo Violet Gray`;echo $B duck;[[ $B = Gray ]]||bash $0

Welcome to the site! I think you have a little bit of unneeded whitespace in this answer. But I'm not an expert in Bash. Does [[$B=Gray]]||bash $0 at the end work?

SmileBASIC, 134 116 bytes
DIM C$[8]C=RND(8)COPY C$,@L@L?C$[C];" duck
EXEC!C
DATA"Gray","Red","Orange","Yellow","Green","Blue","Indigo","Violet

Python 3, 124 bytes
import random
b=1
while b>0:b=random.randint(0,7);print('Gray Red Orange Yellow Green Blue Indigo Violet'.split()[b],'duck')

Try it online!
I almost always accompany my posts with explanations, but this one seems simple enough that I feel confident going without one...

ink, 78 87 bytes
-(e){RANDOM(0,1):{~Red|Orange|Yellow|Green|Blue|Indigo|Violet} duck|Gray duck->END}
->e

Try it online!
Explanation
-(e){RANDOM(0,1):{~Red|Orange|Yellow|Green|Blue|Indigo|Violet} duck|Gray duck->END}  // With a 50% chance of each, either pick a colour that hasn't been picked already (unless all others have also been picked) and print it followed by "duck", or print "Gray duck" and terminate.
->e   // if we haven't terminated we get here and go back to the line above

+9 bytes: Apparently shuffles in ink will not repeat an option until all options have been visited. This means the previous version of my program was not valid, since it would always encounter "gray" before it could encounter any other colour for the second time, and thus broke the "Colours can be repeated" rule. The new answer will print each non-gray colour once until all have been printed, then shuffle again and restart - except every time it's about to pick a colour there's a 50% chance it instead prints gray and terminates.


text:
Add Rainbow Pairs
The rules are as follows:

Take in a string of integers separated by spaces. Add the first and last numbers, the second and second-last numbers, and so on.
The program must output the numbers separated by newlines.
The program must handle negative numbers, but may not handle decimals.
If an odd amount of integers are inputted, just print the lone integer at the end.
This is code golf, fewest bytes wins.

Here are some test cases:
> input
output
more output
etc.
-------------------
> 2 2
4

> 1 2 3 4 5 6
7
7
7

> 3 4 2 6
9
6

> 1 2 3 4 5
6
6
3

> -5 3 -8 2
-3
-5

"The program must deal with invalid input". I'd strongly suggest rethinking that requirement; input validation doesn't go down too well here. I'd also suggest loosening the I/O formats. Need we handle negative numbers?

Welcome to PPCG! I have a few questions, but this seems like it can be a good challenge. In the future, I would consider using The Sandbox to get some feedback. :)

Like Shaggy, I would reconsider having to handle invalid input, especially since we have a consensus to allow programs to error on invalid input.

I think the 4th test case should output 6 6 3.

Along with the requirement that invalid input must be dealt with there are a number of other restrictions here that I would remove.  Input as a space separated string is unnecessarily complicated allowing answers to take input as a list of integers would be much nicer.  Otherwise answers become almost entirely a parser.

Is the input a string or a list?

May we also take as input a list of integers and return a list of integers?

"May not handle decimals"?  So what if there is a decimal in the input?

I would upvote but the I/O requirement on strings and newlines is just fluff detracting from the actual challenge.

Do we have to handle 0?

What exactly does "may not handle decimals" mean - must programs error if such input is encountered or is casting to an integer acceptable? (I am firmly in the "relax I/O requirements camp)

... I had started commenting on answers that appear to break the ruling about handling decimals, but have given up since almost all answers may not comply.

Stax, 9 8 bytes
Thanks to Weijun Zhou for -1 bytes
It actually conforms with the required output format!
Φ┴⌐Öâ9|Ö

Run and debug it
Here's the ungolfed ascii representation of the program.
L   Concatenate all inputs into list
2M  Create two equal-ish size batches, with the bigger piece first
Er  Push the two parts to the stack, and reverse the second one
LM  Put two parts back together as 2-row matrix, then transpose
m|+ For each zipped pair, print the sum on a separate line

Run this one

8 bytes.

@WeijunZhou: Much appreciated.

Perl 5 -a, 23 bytes
#!/usr/bin/perl -a
say$'*s//a/+pop@F for@F

Try it online!
Perl is unusual in that it is valid to change an array while you are looping over it. So you can have $_ walking from front to back while using pop to effectively walk from back to front while removing array elements which will stop the loop when they meet in the middle:
say$_+pop@F for@F

This however fails for an odd number of elements because in the middle both $_ and pop@F are that middle element so you get twice the value.
So instead I use another odd fact of perl loops: the loop variable is not a copy of the corresponding array position but is an alias for it. If you change $_ then you change the corresponding array element. In this case I want to both get the value of $_ and change it to 0 so that the pop@F returns zero when processing the middle element. The shortest way (without needing ()) to do that is s//a/ which changes e.g. 6 to a6 which evaluates to 0 in a numeric context. The part after the substitution is preserved in $' which will be 6 in the example. And since s/// returns the number of substitutions (1 in this case) the expression s//a/*$' will both set $_ to zero and return the original value.
This however would require a space after say. So finally I use yet another perl oddity, the fact that the expression stack also uses aliases of the values and variables you are processing. Therefore $'*s//a/ also works. When $' is put on the expression stack it is not set yet but when next s//a/ is executed it changes to the old value of $_ in place just before the multiplication is done. This is also the reason why the simpler seeming
say$_+($_=0)+pop@F for@F

does not work. The first $_ gets changed to 0 just before the first addition. You would need to force a copy with something like
say "$_"+($_=0)+pop@F for@F

to make that work

@msh210 added an explanation

Great explanation.

Python 3, 57 bytes, relaxed I/O
def f(a):
 try:x,*a,y=a;return[x+y]+f(a)
 except:return a

Try it online!
First time to see try..except in golfing.
print version, 57 bytes
def f(a):
 try:x,*a,y=a;print(x+y);f(a)
 except:print(*a)

Try it online!
printing instead of returning gives the same length.
Python 3, 73 bytes, strict I/O
a=*map(int,input().split()),
while len(a)>1:x,*a,y=a;print(x+y)
print(*a)

Try it online!
This prints an extra newline at the end if the number of elements is even.

JavaScript ES6, 100 97 bytes
_=>{for(_=_.split(' ').map(Number);0<_.length;)console.log(1<_.length?_.shift()+_.pop():_.pop())}

https://jsbin.com/nufanenehu/edit?js,console
First golfing answer ever. Be gentle.

Welcome to the site! A fair few people here use JavaScript so I'm sure you'll get some golfs in a while. Be sure to read these tips as well!

A simple thing you can do to save bytes is to drop the f=. Unnamed functions are fine as long as you don't need the function name for a recursive call or something like that.

Welcome! There are a few golfing tricks you can use here: 1) x<_.length is essentially the same as x in _, so using 0 in _ and 1 in _? can save you a few bytes. 2) you can use this trick to do _=_.split` `.map(Number), saving 2 bytes. 3) ~~x converts the value of x to an integer, or 0 if this fails; combine this with the fact that _.pop() on an empty array returns undefined, and you can turn the entire final expression into console.log(_.shift()+~~_.pop()).

05AB1E, 7 bytes
#2ä`R+»

Try it online!
Explanation
#          # split input on spaces
 2ä        # divide into 2 parts
   `       # split separately to stack
    R      # reverse the second one
     +     # add the lists of numbers
      »    # join on newlines

@JonathanAllan: "must handle negative" + "may not handle decimals" sounds to me like it means "does not have to handle decimals" rather that "must not handle decimals", but we'll see what the OP has to say.

You could well be correct with your interpretation as it is not a separate bullet point.

JavaScript (Node.js), 77 58 bytes
a=>g(a.split` `)
g=a=>+a.shift()+~~a.pop()+`
`+(a+a&&g(a))

Try it online!
Thanks to @Neil for chopping off 17 bytes at once. Also, I found that ~~ works instead of |0, which removes a pair of parens.
Original submission, 77 bytes
a=>g(a.split` `.map(x=>+x))
g=a=>a.shift()+(a.pop()|0)+`
`+(a.length?g(a):'')

Try it online!
Input as a space-delimited string, output as a newline-delimited string. First converts the input string into an array, then passes to a recursive function that generates the output string.

You don't need to map, just use +a.shift(), also you can use a+a&&g(a) instead of a.length?g(a):'', saving 17 bytes in total if I counted correctly.

Brainfuck, 61 bytes
>>+[>,]<[<]>->[[-<<+>>]>[>]<[[<]<<+>>>[>]<-]<[<]>]<<<[<]>[.>]

Try it online!
This program takes a null-terminated list of base-256 ASCII numbers as input :)
Commented Version
Read input chars until \0
>>+[>,]<
Clear initial 1
[<]>->
[
  Copy two to the left
  [-<<+>>]>
  Head to right side
  [>]<
  Subtract from right side add to left side repeat
  [[<]<< +>>> [>]< - ]
  Start at next spot
  <[<]>
]
Print it all out
<<<
[<]
>[.>]

Satisfying I/O requirements, 81 bytes
>>+[>,>,[-]<]<[<]>->[[-<<+>>]>[>]<[[<]<<+>>>[>]<-]<[<]>]<<<[<]>[.[-]++++++++++.>]

In this version the input characters must be separated and the output is split by newlines.

Jelly, 7 bytes
œs2U2¦S

Try it online!
Takes a list of integers, such as [1, 2, 3, 4, 5]. Outputs as an array, such as [6, 6, 3].
11 bytes to conform to the strict input specifications.

R, 68 66 bytes
cat(c((n=scan())[y<-1:(x=sum(n|1)/2)],rep(0,x!=x%/%1))+rev(n[-y]))

Try it online!
Takes input from stdin as in the examples, and prints the output on stdout. Since using scan() is typically shorter than defining a function and taking an array as input, this is the shortest way to take input.
Reads in data, takes the first half (rounded down) of the list, and appends a zero (if necessary), then adds it to the reverse of the second half of the list.

J, 28 bytes
>.@-:@#({.|:@,:@+/@,:|.@}.)]

ungolfed
>.@-:@# ({. |:@,:@+/@,: |.@}.) ]

Try it online!
My J is rusty and surely this could be improved -- suggestions encouraged.  Almost all the complexity arises from the odd length case and the newline requirement.  I had 22 bytes before I noticed the newline requirement:
>.@-:@# ({. +/@,: |.@}.) ]

Python 2, 46 bytes
f=lambda x:x[1:]and[x[0]+x[-1]]+f(x[1:-1])or x

Try it online!
x[1:] is just a shorter way to write len(x)>1

Python 3, 70 bytes
lambda a:[a[i]+a[~i]for i in range(len(a)//2)]+len(a)%2*[a[len(a)//2]]

Try it online!
+32 bytes for strict input:
Python 3, 102 bytes
a=[*map(int,input().split())]
l=len(a)
for q in[a[i]+a[~i]for i in range(l//2)]+l%2*[a[l//2]]:print(q)

Try it online!

Ruby + -p, 52 bytes (spec compliant)
a=$_.split.map(&:to_i);loop{puts a.shift+(a.pop||0)}

Try it online!
A full program, taking a string of space-separated integers and printing the results separated by newlines.
Normally the -p flag forces you to reassign the $_ variable, as it will be implicitly printed at the end of the program. However this code terminates with an NoMethodError when it calls + on nil (the result of shifting the head off an empty array), before that implicit print can happen.
Ruby, 33 bytes (relaxed IO)
->a{puts a.shift+(a.pop||0);redo}

Try it online!
This lambda skips the integer parsing code, and it is able to save 2 bytes by replacing loop{} with redo since it is already inside of a repeatable block. This also terminates with NoMethodError.

Perl 6 -n,  58  42 bytes
.&{$_,{S:s/(\S+) (.*?) (\S+)?$ {say $0+($2//0)}/$1/}...''}

Try it
.say for .=words[^*/2]Z+ |.[$_-1...$_/2],0

Try it

If the input/output restrictions are relaxed 40 bytes
*.[^*/2,{$_-1...$_/2}].&roundrobin».sum

Test it

You don't need to include command line flags to the byte count, as per this meta consensus. You can just specify the flags used as a part of the language, such as "Perl 6 -n, 58 bytes".

You can use the Z+ operator for 41 bytes: (.=words[^*/2]Z+ |.[$_-1...$_/2],0)>>.say

@nwellnhof ».say can cause the results to be printed in any order so .say for .=words[^*/2]Z+ |.[$_-1...$_/2],0 would be more correct. (At one point the implementation would intentionally run them out of order)

@nwellnhof Note that ».sum is fine as even though they can be calculated in any order, they are put back into the right order in the result.

Right. Z+ also doesn't guarantee that the left operand is evaluated before the right operand, so you'd actually need .=words;.say for .[^*/2]Z+ |.[$_-1...$_/2],0. But relying on implementation quirks is OK according to meta, so it's mostly a matter of taste.

@nwellnhof Actually &infix:«+» does guarantee that the left operand is evaluated first.

@BradGilbertb2gills Is this also true for zip operators? Where is this documented?

Java (OpenJDK 9), 76 bytes
a->{for(int i=0,l=a.length;i<l--;)System.out.println(i<l?a[i++]+a[l]:a[i]);}

Try it online!
With strict input
Java (JDK 10), 115 bytes
s->{var a=s.split(" ");for(int i=0,l=a.length;i<l--;)System.out.println(i<l?new Long(a[i++])+new Long(a[l]):a[i]);}

Try it online!
Credits

-10 bytes on strict input thanks to Kevin Cruijssen

Nice trick with i<l--. I'll delete my longer answer. Although, you currently are ignoring the rule "Take in a string of integers separated by spaces.".. It would be 119 bytes with that rule (probably more golfable).

@KevinCruijssen Oops, I didn't see your post... Sorry. Thanks for the reminder on the strict input and for the following nice golfs!

JavaScript (Node.js), 56 bytes
f=x=>([a,m='',b]=x.split(/ (.*) | /),b?a- -b+`
`+f(m):a)

Try it online!
Split the string by all the middle numbers and capture them all as a group, add the ends (coercing strings to numbers via a- -b, which is shorter than any alternatives I know of), and concatenate the result with a line break and f(all captured middle numbers) where available.

Haskell, 93 80 bytes
Saved 13 bytes thanks to Laikoni!
f s|x<-read<$>words s=mapM print$zipWith(+)(take(div(1+length x)2)x)$reverse$0:x

Try it online!

div(1+length x)2 instead of (1+length x)`div`2 saves two bytes.

You can get rid of the splitAt with zipWith(+)(take(div(1+length x)2)x)$reverse$0:x.

@Laikoni Thanks! Edited.

Haskell, 78 72 70 67 bytes
mapM print.f.map read.words
f(x:r@(_:_))=(x+last r):f(init r)
f e=e

Try it online!
Edits:

-6 bytes by using mapM print instead of unlines.map show from GolfWolf's Haskell answer.
-2 bytes by removing +0 which I though was necessary for type inference but wasn't. Thanks to GolfWolf for pointing out.
-3 bytes by adding r@(_:_) to make the f[x]=f[x] pattern superfluous. Thanks again to GolfWolf.

Very nice solution! I think the +0 can be safely removed.

Here's an even shorter one.

x+last r doesn't need parentheses around it.

Clojure, 124 bytes
#(loop[l(map bigint(.split %" "))](println(+(first l)(or(last(rest l))0)))(if(>(count l)2)(recur(concat(butlast(rest l))))))

Try it online!
Ungolfed:
#(loop [l (map bigint (.split % " "))]
   (println (+ (first l) (or (last (rest l)) 0)))
   (if (> (count l) 2)
     (recur (concat (butlast (rest l))))))

An anonymous function that takes the input string and splits it. loop is rerun with every iteration with the "middle" items of the changing list if there are enough items left. Combining butlast and rest creates the "middle" list.
Interesting is the part where the sum is printed. Simply adding (first l) and (last l) only works for an even number of items. When an uneven number of items is passed, first and last will hit the same item. Using rest will remove the first item, in this case the only one, and return an empty list. Using last will return nil which is converted into zero by the or function.

Python 2, 111 107 103 bytes
i=map(int,input().split())
for y in[i[x]+i[-(x+1)]for x in range(len(i)/2)]+[i[x+1]]*(len(i)%2):print y

Try it online!
Takes input in "strict" format (space separated string of numbers) and outputs a trailing newline if the count is even. Works because in Python 2, list comprehensions leak the last value of the variable x so it can be used later to identify the middle number.
Python 2, 79 75 69 bytes
lambda i:[i[x]+i[-(x+1)]for x in range(len(i)/2)]+[i[x+1]]*(len(i)%2)

Try it online!
Shorter version with input and output as lists. Adds an empty string to the output for even numbers.

Python 3, 108 bytes
i=[*map(int,input().split())]
l=len(i)
for a,b in zip(i,i[:int(l/2-.5):-1]):print(a+b)
if l&1:print(i[l//2])

Try it online!
Non competitive, just thought it would be nice to share this zip approach :)
Too bad slicing and reversing in python is a bit finicky

Java (OpenJDK 8), 163 bytes
a->{String[] b=a.split(" ");int c=b.length;a="";for(int d=0;d<c/2;d++){a+=(Integer.parseInt(b[d])+Integer.parseInt(b[c-1-d]))+"\n";}if(c%2>0){a+=b[c/2];}return a;}

Try it online!
Well It’s sure not going to win me the bounty, but all in all I’m pretty happy with my work here.
Explanation:
a->{String[] b=a.split(" ");    //Create String array to get rid of the pesky spaces
int c=b.length;
a="";    //Since we now only need the array, we can reuse the original string to save a few bytes
for(int d=0;d<c/2;d++){    //Loop half(even) or half-1(odd) of the array length
  a+=(Integer.parseInt(b[d])+
   Integer.parseInt(b[c-1-d]))+    //Add the ‘rainbow pairs’ to the output string
  "\n";}    //Add a newline to each sum and end the loop
if(c%2>0){a+=b[c/2];}    //If the number of input numbers is odd, print the middle digit
return a;}    //the Output string is the Input string

Save 28 bytes by using a few tricks and switching to Java 10: a->{var b=a.split(" ");int c=b.length;a="";for(int d=0;d<c/2;d++)a+=new Long(b[d])+new Long(b[c-1-d])+"\n";return a+(c%2>0?b[c/2]:"");}

Red, 105 bytes
func[s][b: to-block s
l: length? b
repeat n l / 2[print b/(n) + b/(l - n + 1)]if odd? l[print b/(n + 1)]]

Try it online!
Red, 91 bytes (Relaxed IO - a list ot integers)
func[b][l: length? b
repeat n l / 2[print b/(n) + b/(l - n + 1)]if odd? l[print b/(n + 1)]]

Try it online!

FORTH 76 Bytes
: A BEGIN DEPTH 1 - ROLL + CR . DEPTH 2 <= UNTIL DEPTH 1 = IF CR . THEN ;

Output:
1 2 3 4 5 a
6
6
3  ok

2 2 A
4  ok

-5 3 -8 2 A
-3
-5 ok

Python 2, 112 bytes
def f(s):
 s=[int(i)for i in s.split(' ')];s.insert(len(s)//2,0)
 for i in range(len(s)//2):print s[i]+s[-i-1]

Perl 6/Rakudo 45 bytes
Perl6 -ne
{say .shift+(.pop||0) while $_}(.words.Array)

Super simple, shifts and pops, Perl makes the empty list (with odd count) easy with .pop||0.

Python 3, 136 bytes
def f(x):
 x,o=[int(i) for i in x.split()],[];y=len(x)
 for i in range(int(y/2)):o+=[x[i]+x[-i-1]]
 if y%2!=0:o+=[x[int(y/2)]]
 return o

Try it online!

Ruby, 67 bytes
This can probably be improved, but I'm not sure how...
def x(a);puts a.shift.to_i+a.pop.to_i;return if a.length==0;x a;end

Try it online!

C, 128 bytes
This version is more in keeping with the terms of the challenge, but has a hard-coded maximum of 9 numbers that it can accept.
i[9],j,k;f(char*s){for(s=strtok(s," ");j++,s;i[j]=atoi(s),s=strtok(0," "));while(--j>=++k)printf("%d\n",i[j]+(j==k?0:i[k]));}

Try it online!
I let C do the tokenizing for me, which allows me to send each string directly to atoi(). Afterwards, I just add the mirror indexes until the start>end.
As I couldn't get a array length and strtok() destroys the original string, making backtracking difficult, and I didn't want to have to realloc() to resize arrays, I hard-coded an array with a maximum of 9 values.
C, 107 bytes (uses argv)
i,j,*k;f(char**s){k=(int*)s;while(s[++i])k[i]=atoi(s[i]);while(++j<=--i)printf("%d\n",k[i]+(i==j?0:k[j]));}

Try it online!
This version makes use of the fact that argv already has been tokenized; as a bonus, it doesn't have a hard-coded limit on the number of numbers! It does, however, assume that sizeof(int)==sizeof(char*), which is truly evil and non-portable.

PHP, 107 bytes
New to this, so please forgive my lack of correct formatting.
for($i=0,$a=explode(" ",$argv[1]),$c=count($a);$i<$c/2;$i++)echo$i==$c-$i-1?$a[$i]:$a[$i]+$a[$c-$i-1]."\n";

Try it online!

Welcome to PPCG! It looks like you've hardcoded the input into your solution. That's not generally valid (among other reasons because it means that your byte count depends on the specific input you chose). Answers either need to be full programs or callable functions. You can have a look at this list for valid I/O methods. (I don't know which option is the shortest in PHP.

OK thanks, Ill see what the best input mechanism is and update accordingly!

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

sort: votes