45
\$\begingroup\$

Skittles are colored candy where there are 5 distinct flavors; grape, green apple, lemon, orange, and strawberry represented by (p)urple, (g)reen, (y)ellow, (o)range, and (r)ed respectively. I used to eat skittles by sorting all the different colors, then eating them in sequence. After getting a few weird looks in the office, I now pretend to eat them like a normal person. Your task is to emulate this:

Your code (full program or function) will receive an array of skittles (10x10) as input (in any reasonable format). This array will represent a pile of unsorted skittles. Your task is to "eat" them from your least favorite to favorite color. My preferred order is grape, green apple, lemon, orange, strawberry, but you are free to choose any order so long as it is consistently enforced (please list your preference in your submission so I can judge you for it). After eating each piece of candy your code will output (in the same format you take input) the remaining pile with the eaten piece replaced by a space. You will repeat until only your favorite remains. You may choose any skittle to eat (may be random or deterministic). Trailing spaces must be kept.

For example, your output sequence could look like this (using 5x5 for brevity and showing spaces as .)

start   1     2     3     4     5        n 
.org. .org. .org. .org. .or.. .or..    ..r..
prgrg .rgrg .rgrg .rgrg .rgrg .r.rg    .r.r.
gggpr gggpr ggg.r ggg.r ggg.r ggg.r    ....r
oyyor oyyor oyyor oyyor oyyor oyyor    ....r
.r.p. .r.p. .r.p. .r... .r... .r...    .r...

This is , so shortest code in bytes wins

TL;DR Rules:

  • Submission may be full program or function
  • Input may be taken in any reasonable format (string, list, matrix, etc) by any reasonable method (STDIN, function arguments, etc.). However there must be some delineation between rows
  • Output must be produced in the same format as input by any reasonable method (STDOUT, function return, ect.). Intermediate output may or may not be delimited
  • First output shall be the first input
  • Trailing spaces must be preserved
  • Any color order may be used (list in your answer)
  • Any skittle of the current color may be eaten
  • Last output shall be only your favorite color and spaces
  • If possible, include a link to an online compiler to test your submission
\$\endgroup\$
12
  • 4
    \$\begingroup\$ @MukulKumar, correct, you want them to be better as you go along \$\endgroup\$
    – wnnmaw
    Commented Dec 6, 2016 at 15:15
  • 2
    \$\begingroup\$ Can we accept the skittles as a single 100-skittle string, no line breaks or anything? \$\endgroup\$ Commented Dec 6, 2016 at 15:29
  • 1
    \$\begingroup\$ Do intermediate outputs need to be separated by anything? \$\endgroup\$
    – Poke
    Commented Dec 6, 2016 at 15:54
  • 5
    \$\begingroup\$ Related codegolf.stackexchange.com/questions/40913/… \$\endgroup\$ Commented Dec 6, 2016 at 17:06
  • 8
    \$\begingroup\$ I considered entering this challenge, and then read "please list your preference in your submission so I can judge you for it". I think that people are already too judgemental of my preferences! \$\endgroup\$ Commented Dec 7, 2016 at 9:36

18 Answers 18

15
\$\begingroup\$

Jelly, 16 14  13 bytes

Ṅ⁶ỤṪ$¦µQL>3µ¿

TryItOnline!

Most to least favourite, as for anyone serious about their O.C.D., is alphabetical!

Takes input and outputs as text (i.e. the rows are delimited by new lines).

3 bytes saved by reversing the direction and using a different method: grade up rather than finding characters from the alphabet.

How?

Ṅ⁶ỤṪ$¦µQL>3µ¿ - Main link: Skittle text
      µ    µ  - monadic chain separation
            ¿ - while
       Q      - unique items
        L     - length
         >3   - greater than 3 (until only new lines, spaces and 'g's remain)
Ṅ             -     print z and a line feed, yield z
    $         -     treat last two links as a monad
  Ụ           -         grade up (get indices of: new lines; spaces; gs; os; ps; rs; ys)
   Ṫ          -         tail (the last of those, so last y if there is one, else last r, ...)
 ⁶            -     space character
     ¦        -     apply at index (replace that index with a space)
\$\endgroup\$
8
\$\begingroup\$

JavaScript (ES6), 74 75 74 bytes

Flavors are ordered as described in the challenge: grape, green apple, lemon, orange, strawberry.

Intermediate outputs are separated by newlines.

f=(s,n=3,r=s)=>(S=s.replace('oygp'[n],' '))!=s&&(r+=`
`+S)||n--?f(S,n,r):r

Test case

This test case is using the 5x5 example. Any other grid size should work as expected.

f=(s,n=3,r=s)=>(S=s.replace('oygp'[n],' '))!=s&&(r+=`
`+S)||n--?f(S,n,r):r

console.log(f(
` org 
prgrg
gggpr
oyyor
 r p 
`))

\$\endgroup\$
8
\$\begingroup\$

Bash, 48, 46 bytes

UPDATE:

  • Saved two bytes by using raw parameters to printf;

Golfed

sed -nz "p;:a;`printf "s/%s/ /p;ta;" p g y o`"

Takes input at stdin, prints to stdout. Eats purple, green, yellow and then orange.

An equivalent sed program would be:

p;:a;s/p/ /p;ta;s/g/ /p;ta;s/y/ /p;ta;s/o/ /p;ta

Sample output (delimiters are for clarity only)

-----
 org 
prgrg
gggpr
oyyor
 r p 
-----
-----
 org 
 rgrg
gggpr
oyyor
 r p 
-----
-----
 org 
 rgrg
ggg r
oyyor
 r p 
-----
-----
 org 
 rgrg
ggg r
oyyor
 r   
-----
-----
 or  
 rgrg
ggg r
oyyor
 r   
-----
-----
 or  
 r rg
ggg r
oyyor
 r   
-----
-----
 or  
 r r 
ggg r
oyyor
 r   
-----
-----
 or  
 r r 
 gg r
oyyor
 r   
-----
-----
 or  
 r r 
  g r
oyyor
 r   
-----
-----
 or  
 r r 
    r
oyyor
 r   
-----
-----
 or  
 r r 
    r
o yor
 r   
-----
-----
 or  
 r r 
    r
o  or
 r   
-----
-----
  r  
 r r 
    r
o  or
 r   
-----
-----
  r  
 r r 
    r
   or
 r   
-----
-----
  r  
 r r 
    r
    r
 r   
-----

Try it online !

\$\endgroup\$
7
\$\begingroup\$

Python 2, 60 57 56 bytes

def f(s):print s;q=max(s);q>'g'and f(s.replace(q,' ',1))

repl.it

Recursive function that eats in reverse alphabetical order, leaving the greens for last.

Input s is a string with a row delimiter with an ordinal less than that of a 'g' (for example a new line or a comma).

The function prints its input, and then recurses if that input contains anything greater than a 'g', passing the input with the first occurrence of the maximum character replaced by a space.

(Almost a port of my Jelly answer.)

\$\endgroup\$
6
\$\begingroup\$

Perl, 53 46 + 2 = 48 bytes

Run with -0n

-10 bytes thanks to @Dada

Edit: Also thanks to @Dada for pointing it out, I forgot to print the input as the first output. That's been fixed.

say;eval sprintf"say while s/%s/./;"x4,p,o,g,r

There's a little bit of trickery involved in this answer, so I'll break down what's going on.

First of all, Perl doesn't like multi-line parameters being passed. The variable $/ is the input record separator, and whenever any input encounters the character stored in it, the interpreter terminates that input and begins a new input. The default content is the newline character \n, which means that passing a multi-line string is not possible. To do that, we must unset $/ from its contents. That's where the -0 flag comes in: setting -0 will store null in the variable $/, allowing the interpreter to read everything into the implicit variable $_ at once.

The next bit of trickery is the eval statement. Just what exactly are we evaling? We're evaling the result of the sprintf statement, which is broken down as follows:

The first thing that sprintf is passed is the string "say while s/%s/./;" repeated 4 times, so:

say while s/%s/./;say while s/%s/./;say while s/%s/./;say while s/%s/./;

Then, sprintf is passed four bareword characters, p,o,g,r, which are interpolated into the sprintf statement, replacing each instance of %s. What we then get is the following string, which is passed to the eval function:

say while s/p/./;say while s/o/./;say while s/g/./;say while s/r/./;

Each while loop evaluates the expression s/[color]/./, which replaces the first instance of whatever color it is in the implicit variable $_ with a period. If a substitution is made, it returns 1, otherwise it returns nothing. Since s/// has side-effects, it modifies the original variable $_, whose contents are then printed via say. Four versions of this loop are performed, replacing the purples, the oranges, the greens, and then the reds, leaving only the yellows.

The reason that the yellows are left is because y cannot be a bareword, because it's actually a function, and having a y instead of any of those letters would throw an error. I could change this by putting quotes around it (+2 bytes), or using a capital Y and making the regex case-insensitive (+1 byte), but for , every byte counts, so I decided that I actually like lemon skittles the most.

TL;DR: Grape, Orange, Green Apple, Strawberry, Lemon

\$\endgroup\$
3
  • \$\begingroup\$ -0 flag should save you around 10 bytes \$\endgroup\$
    – Dada
    Commented Dec 6, 2016 at 17:27
  • \$\begingroup\$ Also, I'm afraid you missed the rule First output shall be the first input \$\endgroup\$
    – Dada
    Commented Dec 6, 2016 at 17:33
  • 1
    \$\begingroup\$ Good on you for sacrificing your own personal preference to save two bytes \$\endgroup\$
    – wnnmaw
    Commented Dec 6, 2016 at 18:33
4
\$\begingroup\$

Perl, 30 31 33 + 2 = 32 33 35 bytes

for$x(g,o,p,r){say;s/$x/ /&&redo}

Run with -n0 (2 byte penalty).

Apparently, I like to eat Skittles in alphabetical order, because the program turns out shorter that way. The program doesn't really need much explanation: -n0 reads the input implicitly (-n means "read input implicitly", -0 means "don't break input on newlines"); for$x(g..r) runs a loop with $x set from each letter from g to r in turn; say; prints the current input, after any mutations; s/$x/ / replaces one copy of $x (specifically, the first) with a space if possible; and &&redo repeats the code inside the braces (without advancing the loop counter) if the replacement was successful.

This program can easily be generalized to more flavours of Skittle without changing its length, and will work with a pile of any size.

Here's an Ideone link where you can test it. (Ideone doesn't allow you to specify command-line options, so I had to add a couple of lines at the start to set -n0 and the -M5.010 that you get for free.)

\$\endgroup\$
5
  • 1
    \$\begingroup\$ I'm not sure you are allowed to print several times the same pile of skittles several times.. (Actually I think you can't) Maybe switch to say;for$x(g..r){say while s/$x/ /} ? \$\endgroup\$
    – Dada
    Commented Dec 6, 2016 at 17:51
  • \$\begingroup\$ Ah right. I originally had for$x(p,o,g,r) which wouldn't. say while is only one byte longer, and something that I'd considered as an alternative, so I can simply change to that. \$\endgroup\$
    – user62131
    Commented Dec 6, 2016 at 17:53
  • \$\begingroup\$ And you need to start with a say; because the rules say First output shall be the first input \$\endgroup\$
    – Dada
    Commented Dec 6, 2016 at 17:56
  • \$\begingroup\$ Oh, in that case I'll go back to the for$x(g,o,p,r) version which does copy the input first. (It takes some extra time searching if there are colours missing, but you wouldn't expect to have a colour missing in a pack of skittles.) For the record, the version with say; first would be 37 bytes. \$\endgroup\$
    – user62131
    Commented Dec 6, 2016 at 18:10
  • \$\begingroup\$ Dada's original comment still stands, though--the code as it stands will print the same configuration twice in a row sometimes (once at the end of the greens and a second time at the beginning of the oranges, e.g.). \$\endgroup\$
    – DLosc
    Commented Mar 7, 2017 at 5:06
4
\$\begingroup\$

C#, 134 148 bytes

Order: G -> O -> Y -> P -> R

I=>{var v=new string(I)+";\n";int i,j=0,c;for(;j<4;){c="goyp"[j++];for(i=0;i<I.Length;i++)if(I[i]==c){ I[i]='.';v+=new string(I)+";\n";}}return v;};

Used some similar things from @Poke's answer, currently a bit longer though since I need to convert the character array to a string ;(

\$\endgroup\$
1
  • \$\begingroup\$ HA! beat you by 3 chars!!! \$\endgroup\$ Commented Dec 7, 2016 at 4:19
4
\$\begingroup\$

Java 7, 139 135 130 151 138 135 bytes

void t(char[]s){int i,j=-1;for(;++j<5;)for(i=-1;++i<109;)if(j>3|s[i]=="yogp!".charAt(j)){System.out.println(s);if(j>3)return;s[i]=32;}}

Eats skittles in the order: Yellow, Orange, Green, Purple, Red

I guess this is better than 2 print statements >.>

\$\endgroup\$
9
  • 1
    \$\begingroup\$ Of course you can, your function is named skit :P -3 right there! \$\endgroup\$
    – Yodle
    Commented Dec 6, 2016 at 16:03
  • 1
    \$\begingroup\$ @Yodle oops! hahaha \$\endgroup\$
    – Poke
    Commented Dec 6, 2016 at 16:04
  • 1
    \$\begingroup\$ If we're always receiving a 10x10 grid i could hardcode the length rather thatn using s.length \$\endgroup\$
    – Poke
    Commented Dec 6, 2016 at 16:26
  • 1
    \$\begingroup\$ Don't we need to print it out once at the start before eating any :s \$\endgroup\$
    – Yodle
    Commented Dec 6, 2016 at 16:29
  • 1
    \$\begingroup\$ @Yodle that's why I'm eating "!" skittles first ;) ...wait i think i broke that trick \$\endgroup\$
    – Poke
    Commented Dec 6, 2016 at 16:29
4
\$\begingroup\$

C 145 - 5 - 18 - 1 = 121 bytes

#define l(a)for(a=0;a<10;a++)
i,j,k,b='a';F(char a[][11]){while(b++<'x')l(i)l(j)if(a[i][j]==b){a[i][j]=32;l(k)puts(a[k]);puts("");}}  

ungolfed + pretty

#include<stdio.h>
#include<windows.h>
i,j,k;
F(char a[][11])
{
    char b='a';
    while(b++<'x')
        for(i=0;i<10;i++)
            for(j=0;j<10;j++)
                if(a[i][j]==b)
                {
                    system("cls");
                    a[i][j]=32;
                    for(k=0;k<10;k++)
                        puts(a[k]);
                    puts("");
                    Sleep(35);
                }
}
main()
{
    char a[][11]={
            "gggggggggg",
            "goooooooog",
            "goppppppog",
            "goprrrrpog",
            "gopryyrpog",
            "gopryyrpog",
            "goprrrrpog",
            "gopppppppg",
            "goooooooog",
            "gggggggggg"
    };
    for(i=0;a[i][j];)
        puts(a[i++]);
    F(a);
}  

Here a[][11] means taking n-strings of length 11 where 1 char is required for termination so, technically only 10 visible chars.

order : alphabetical
this function checks for 'g' in the given input and eliminates it 1/1 then increments the variable holding 'g' until it finds a next match(probably letter 'o') and then eliminates those matched characters.
The downside is that this function is just too careful.So, if your skittels were of 26 different colors code-named from letters a-z, this function will handle that input too...

\$\endgroup\$
2
  • \$\begingroup\$ A lot more than 3 now :P \$\endgroup\$
    – Yodle
    Commented Dec 7, 2016 at 5:21
  • \$\begingroup\$ @Yodle yeah..thanks to macros you can define with #define. That cut down 19 bytes \$\endgroup\$ Commented Dec 7, 2016 at 7:33
3
\$\begingroup\$

Octave, 49 bytes

Eats skittles in alphabetical order, highest ascii-code first.

A=input("");do [~,p]=max(A(:));A(p)=32 until A<33
\$\endgroup\$
3
\$\begingroup\$

ES6 (Javascript), 72,71 bytes

EDITS:

  • Minus 1 byte, by using template literal with of

A non-recursive version in Javascript.

Golfed

s=>{r=s;for(c of`pogy`)while(s!=(s=s.replace(c,' ')))r+=`
`+s;return r}

Input and output are multiline strings, eats pills in the "purple=>orange=>green=>yellow" order.

Test

S=s=>{r=s;for(c of`pogy`)while(s!=(s=s.replace(c,' ')))r+=`
`+s;return r}

console.log(
S(` org 
prgrg
gggpr
oyyor
 r p `)
);

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

Python 3 - 141 99 75 bytes

s=input();[exec("print(s);s=s.replace(c,' ',1);"*s.count(c))for c in'orgy']

Program eats skittles in this order - Orange Red Green Yellow Purple.

Edit - Thanks to Flp.Tkc who helped to cut down 24 bytes!

Input - 
ygro  goppr rppog rppog orgy

Output - 
ygro  goppr rppog rppog orgy
ygr   goppr rppog rppog orgy
ygr   g ppr rppog rppog orgy
ygr   g ppr rpp g rppog orgy
ygr   g ppr rpp g rpp g orgy
ygr   g ppr rpp g rpp g  rgy
yg    g ppr rpp g rpp g  rgy
yg    g pp  rpp g rpp g  rgy
yg    g pp   pp g rpp g  rgy
yg    g pp   pp g  pp g  rgy
yg    g pp   pp g  pp g   gy
y     g pp   pp g  pp g   gy
y       pp   pp g  pp g   gy
y       pp   pp    pp g   gy
y       pp   pp    pp     gy
y       pp   pp    pp      y
        pp   pp    pp      y
        pp   pp    pp  

I believe it can be further golfed as it looks very simple.

\$\endgroup\$
6
  • 2
    \$\begingroup\$ Looks like this is eating all of one color at a time whereas it should eat only one at a time \$\endgroup\$
    – wnnmaw
    Commented Dec 6, 2016 at 17:30
  • 1
    \$\begingroup\$ Also, you are taking input as a nest list, but producing strings, please modify your code such that both input and output are same format \$\endgroup\$
    – wnnmaw
    Commented Dec 6, 2016 at 17:36
  • \$\begingroup\$ @wnnmaw Changes made. I hope it is fine now :) \$\endgroup\$ Commented Dec 6, 2016 at 19:41
  • 1
    \$\begingroup\$ I know there's already a shorter solution, but staying with this algorithm you can golf it more to something like this. \$\endgroup\$
    – FlipTack
    Commented Dec 6, 2016 at 20:30
  • 3
    \$\begingroup\$ I like how you specifically chose the ordering that led to orgy. \$\endgroup\$
    – anon
    Commented Dec 7, 2016 at 8:55
2
\$\begingroup\$

Vim 57 55 bytes

Saving two bytes by removing my line delimiter. Unfortunately it makes it a lot harder to read and check for correctness :(.

:set ws!
yGP/o
qqnr G9kyGGp@qq@q/y
@q/p
@q/g
@qdG

Unprintables:

:set ws!
yGP^O/o
^Oqq^Hnr G9kyGGp@qq@q/y
^O@q/p
^O@q/g
^O@qdG

TryItOnline

Eats in the order oypg, leaving all of the r's for the end :)

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

Mathematica, 67 bytes

Most[#/.(i=0;#:>"."/;i++≤0&/@Characters@"ryop")&~FixedPointList~#]&

Eats reds, then yellows, then oranges, then purples.

\$\endgroup\$
1
  • \$\begingroup\$ Boy am I glad there isn't a built-in for this \$\endgroup\$
    – wnnmaw
    Commented Dec 8, 2016 at 20:52
1
\$\begingroup\$

Java 7, 125 bytes

Purple, Yellow, Green, Red, Orange. I'm enjoying that I get to pick my order in this solution. :D

Golfed

String s(String p){String r=p;for(String c:"pygr".split(""))for(;p.contains(c);r+="\n\n"+p)p=p.replaceFirst(c," ");return r;}

Ungolfed

String s(String p) {
    String r=p;
    for (String c : "pygo".split("")) {
        for (; p.contains(c); r += "\n\n" + p) {
            p = p.replaceFirst(c, " ");
        }
    }
    return r;
}

Try it here!

A different approach to the other Java answer by @Poke. We start by making a copy of the original string. Iterating through each color, we replace it each time it's found with a space, then append the new layout to the output string, returning after we've eaten everything but orange.

Notes

Seperation between steps is done with a double newline \n\n, but if the input grid can be taken with a trailing newline at the end, it can be shorted to just \n.

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

Haskell, 60 bytes

f x|(a,b:c)<-span(<maximum x)x,b>'g'=(:)<*>f$a++' ':c|1<2=[]

Input is a single string where the rows are separated with ,. Return value is a list of strings with all intermediate steps. Order is alphabetically, largest first, so green remains. Usage example:

*Main> mapM_ putStrLn $ f " org ,prgrg,gggpr,oyyor, r p "
 org ,prgrg,gggpr,o yor, r p 
 org ,prgrg,gggpr,o  or, r p 
 o g ,prgrg,gggpr,o  or, r p 
 o g ,p grg,gggpr,o  or, r p 
 o g ,p g g,gggpr,o  or, r p 
 o g ,p g g,gggp ,o  or, r p 
 o g ,p g g,gggp ,o  o , r p 
 o g ,p g g,gggp ,o  o ,   p 
 o g ,  g g,gggp ,o  o ,   p 
 o g ,  g g,ggg  ,o  o ,   p 
 o g ,  g g,ggg  ,o  o ,     
   g ,  g g,ggg  ,o  o ,     
   g ,  g g,ggg  ,   o ,     
   g ,  g g,ggg  ,     ,     

Simple recursion. Save the input list in for the return value, replace the largest element greater g with a space and call the function again. Base case is when there's no element left to remove.

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

MATL, 24 bytes

`tDX:t2#X>wx32w(10etun2>

Try it online! I prefer eating my skittles in reverse alphabetical order: green is my favourite colour. Explanation:

                           % Take input implicitly.
`                          % Start do ... while loop
 tD                        % Duplicate skittle pile (nom!), but give away for display
   X:                      % Put skittles in long row (like normal people do)
     t2#X>                 % Get least favourite skittle name and number in the row
          wx               % Discard the skittle name
            32w            % Put an eaten skittle on the stack (ASCII 32)
               (           % Put the eaten skittle back in the row of skittles.
                10e        % Shape the row back into a 10x10 array
                   tun     % Check the number of unique skittles
                      2>   % Loop while this number >2 (eaten skittles + favourite skittles)
                           % Implicit end of do... while loop. 
                           % Display last iteration implicitly, since it's still on the stack.
              
\$\endgroup\$
0
\$\begingroup\$

QBasic, 125 bytes

Creative rules abuse!

DATA 71,89,82,79
?INPUT$(109)
DO
READ s
FOR r=1TO 10
FOR c=1TO 10
IF s=SCREEN(r,c)THEN SLEEP 1:LOCATE r,c:?" "
NEXT
NEXT
LOOP

This submission assumes a lot of things are okay:

  • Input and output are uppercase (GORPY)
  • Input is taken as 109 successive keypresses, which are not echoed to the screen until the last one is entered. At the end of each row except the last one, the user must enter a carriage return.
  • Instead of printing the Skittles pile multiple times, the program displays it on the screen with a 1-second pause before each step. (QBasic doesn't have output scrollback, so printing the pile multiple times would only give you the last 2 1/2 steps. Also, this method is a much better depiction of how your pile of Skittles evolves as you eat them.)
  • The program ends with an error.

I also have a 130-byte version that uses lowercase and doesn't error.

Here's a sample run in QB64, with 109 changed to 29 for a 5x5 grid:

Eating Skittles

Explanation

DATA 71,89,82,79 stores the ASCII codes of G, Y, R, and O.

?INPUT$(109) gets 109 keypresses from the user and prints them.

We then enter an infinite DO ... LOOP construct. Each time through, we READ the ASCII code of the current Skittle into s. Then we loop over rows and columns from 1 to 10. SCREEN(r,c) gets the ASCII code of the character on the screen at row r, column c. If this is equal to the current Skittle s, we SLEEP for one second and then print a space at r, c.

The main loop runs four times, removing the green, yellow, red, and orange Skittles. On the fifth iteration, READ errors because we're out of data.

\$\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.