Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs

Dashboard
Notifications
Mark all as read
Challenges

Coat of Many Colours

+7
−0

Challenge

Given a list of unique colour names as input, sort them in the order that they first appear in Joseph's Amazing Technicolour Dreamcoat.


Example

Input:  green, blue, red, brown
Output: red, green, brown, blue

The full list of colours, in order, is:

 1. red
 2. yellow
 3. green
 4. brown
 5. scarlet
 6. black
 7. ochre
 8. peach
 9. ruby
10. olive
11. violet
12. fawn
13. lilac
14. gold
15. chocolate
16. mauve
17. cream
18. crimson
19. silver
20. rose
21. azure
22. lemon
23. russet
24. grey
25. purple
26. white
27. pink
28. orange
29. blue

Or as an array of strings:

["red","yellow","green","brown","scarlet","black","ochre","peach","ruby","olive","violet","fawn","lilac","gold","chocolate","mauve","cream","crimson","silver","rose","azure","lemon","russet","grey","purple","white","pink","orange","blue"]

Rules

  • You may take input by any reasonable, convenient means (e.g., an array of strings, a delimited string, individual strings), but please specify your input method in your answer.
  • You may do the same for your output.
  • The input will only ever contain colours from the above list.
  • Your solution should be able to handle empty inputs.
  • You may choose whether all words in the input are consistently uppercase, lowercase or title case but your output's casing must match your input's.
  • This is code-golf so lowest byte count in each language wins.
  • As always, standard loopholes are forbidden.

Test cases

Input:  []
Output: []

Input:  ["green", "blue", "red", "brown"]
Output: ["red", "green", "brown", "blue"]

Input:  ["gold", "grey", "green"]
Output: ["green", "gold", "grey"]

Input:  ["ruby","yellow","red","grey"]
Output: ["red", "yellow", "ruby", "grey"]

Input:  ["gold", "green", "fawn", "white", "azure", "rose", "black", "purple", "orange", "silver", "ruby", "blue", "lilac", "crimson", "pink", "cream", "lemon", "russet", "grey", "olive", "violet", "mauve", "chocolate", "yellow", "peach", "brown", "ochre", "scarlet", "red"]
Output: ["red", "yellow", "green", "brown", "scarlet", "black", "ochre", "peach", "ruby", "olive", "violet", "fawn", "lilac", "gold", "chocolate", "mauve", "cream", "crimson", "silver", "rose", "azure", "lemon", "russet", "grey", "purple", "white", "pink", "orange", "blue"]
Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

5 answers

+4
−0

Scala, 119 bytes

Saved 26 bytes after porting Moshi's solution!

_ sortBy("y gree br sc bla oc pe rub ol v f li go ch m cre c s ro a l ru g pu w p o b"split " "indexWhere _.startsWith)

Original solution, 145 130 bytes

Saved 15 bytes after looking at Moshi's solution!

_ sortBy("d,ll,ee,ow,ar,ack,h,ac,b,iv,ol,w,la,ld,o,uv,ea,im,l,se,ur,m,s,e,r,i,n,a,u"split ","indexWhere _.substring(2).startsWith)

Try it in Scastie!

It turns out that after dropping the first 2 letters, the first 2 letters after that (and in some cases 1 or 3) are enough to identify colors.

_ sortBy( //Sort the input by this function:
 "..." //Take the comma separated string of colors
 .split(",") //Split on commas
 indexWhere  //And find the index where
 _.substring(2) //The current string with the 1st 2 chars removed
  .startsWith //Starts with that color prefix
)
Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

+3
−0

JavaScript (Node.js), 153 147 bytes

-6 bytes thanks to Shaggy!

a=>a.sort((x,y)=>g(x)-g(y),g=x=>"y gree br sc bla oc pe rub ol v f li go ch m cre c s ro a l ru g pu w p o b".split` `.findIndex(t=>!x.indexOf(t)))

Try it online!

Inspired by user's solution, I found the minimum number of initial characters that uniquely identified each color. I then golfed if further by realizing the ones at the end of the list don't actually have to uniquely identify the color, because the ones it couldn't determine would have been caught already. (E.g. green and grey need the gree to determine green, but if it isn't green then it must be grey and we can catch that with just g)


Old answer, 219 bytes

a=>"red yellow green brown scarlet black ochre peach ruby olive violet fawn lilac gold chocolate mauve cream crimson silver rose azure lemon russet grey purple white pink orange blue".split(' ').filter(i=>a.includes(i))

Try it online!

Why does this post require moderator attention?
You might want to add some details to your flag.

1 comment thread

147 bytes (2 comments)
+2
−0

C (gcc), 302 bytes

Function taking in an array of null-terminated strings and the array's length.

#include <string.h>
#include <stdlib.h>
char*s="d llow een own arlet ack hre ach by ive olet wn lac ld ocolate uve eam imson lver se ure mon sset ey rple ite nk ange ue";int g(const void*a,const void*b){return strstr(s,*(char**)a+2)-strstr(s,*(char**)b+2);}void f(char**a,int l){qsort(a,l,sizeof*a,g);}

Try it online!

I shamelessly stole the idea of removing the first two characters from user's solution.

Why does this post require moderator attention?
You might want to add some details to your flag.

1 comment thread

Is there any way for you to drop some letters off the end too (or would that increase the byte count)... (3 comments)
+2
−0

C, 534 bytes

Strictly conforming program.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char i=1,**c,**d,*t[30]={"red","yellow","green","brown","scarlet","black","ochre","peach","ruby","olive","violet","fawn","lilac","gold","chocolate","mauve","cream","crimson","silver","rose","azure","lemon","russet","grey","purple","white","pink","orange","blue"};int f(const void*a,const void*b){c=d=t;for(;*c;)if(!strcmp(*c++,*(char**)a))break;for(;*d;)if(!strcmp(*d++,*(char**)b))break;return c<d?-1:c!=d;}int main(int c,char**v){qsort(v+1,c-1,8,f);for(;i<c;)puts(v[i++]);}

The char* casts are a bit questionable in a strictly conforming program since they remove const qualifiers. My argument for why it is valid, is that the effective type of the argv strings ought to be char[].

I couldn't figure out how to use massive amounts of command line arguments on tio.run, here's a Godbolt with the worst test case entered: https://godbolt.org/z/vbdYe6cxx

Why does this post require moderator attention?
You might want to add some details to your flag.

3 comment threads

Golfing thread (4 comments)
Use string find instead of array find (1 comment)
TIO (4 comments)
+0
−0

Python 3, 349 bytes

a=["red","yellow","green","brown","scarlet","black","ochre","peach","ruby","olive","violet","fawn","lilac","gold","chocolate","mauve","cream","crimson","silver","rose","azure","lemon","russet","grey","purple","white","pink","orange","blue"]
def f(b):
	c=[]
	for i in range(len(a)):
		for j in range(len(b)):
			if b[j]==a[i]:c.append(a[i])
	return c

Try it online!

Uses functions, where a list is used as the function's argument. Basically, it figures out where the strings lie and adds the correct order under a new list. As defined from the challenge, empty lists are, by default, handled. All test cases are in the footer.

Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

Sign up to answer this question »

This community is part of the Codidact network. We have other communities too — take a look!

You can also join us in chat!

Want to advertise this community? Use our templates!