30
\$\begingroup\$

The 16-color CGA palette (also known as the HTML colors) is a set of 16 colors used by early graphics adapters. The goal of this challenge is to output all 16 of them, in hex format (RRGGBB), in ascending order by hex value, separated by newlines. Thus, the output should be exactly this:

000000
000080
0000FF
008000
008080
00FF00
00FFFF
800000
800080
808000
808080
C0C0C0
FF0000
FF00FF
FFFF00
FFFFFF

A single trailing newline is allowed, but not required.

\$\endgroup\$

15 Answers 15

13
\$\begingroup\$

Jelly, 31 29 27 bytes

“×Ɗ¡‘ŒP»Ṫ¦209ṗ€3Fd⁴ịØHs3ṢQY

Try it online!

How it works

“×Ɗ¡‘ yield the code points of the characters between the quotes in Jelly's SBCS, which are 0x11 = 17, 0x91 = 145, and 0x00 = 0.

ŒP constructs the powerset of the array of code points, yielding

[[], [17], [145], [0], [17, 145], [17, 0], [145, 0], [17, 145, 0]]

The last two entries correspond to combinations that contain both 80 and FF, so we have to discard them.

»Ṫ¦209 consists of three parts:

  • (tail) removes the last array of code points, i.e., [17, 145, 0].

  • »209 takes the maximum of each integer in the remainder of the powerset and 0xD1 = 209, replacing all of them with 209.

  • ¦ (sparse) iterates over the elements of the remainder of the powerset. If the corresponding index is found in [17, 145, 0], the element is replaced with all 209's. If not, it is left untouched.

    ¦ isn't modular, so this modifies only the last array (index 0) in the remainder of the powerset. The indices 17 and 145 are too large and have no effect.

The result is as follows.

[[], [17], [145], [0], [17, 145], [17, 0], [209, 209]]

ṗ€3 computes the third Cartesian power of each array, i.e., the array of all 3-tuples of elements of each array.

Fd⁴ flattens the result and computes quotient and remainder of each integer divided by 16.

ịØH indexes (1-based) into "0123456789ABCDEF, so 0x11, 0x91, 0x00, and 0xD1 get mapped to "00", "80", "FF", and "C0" (resp.).

s3ṢQ splits the character pairs into 3-tuples, sorts the tuples, and deduplicates.

Finally, Y joins the unique tuples, separating by linefeeds.

\$\endgroup\$
11
\$\begingroup\$

Bash + GNU Utilities, 67

  • 2 bytes saved thanks to @manatwork
  • 2 bytes saved thanks to @zeppelin
a={00,80,FF}
eval echo $a$a$a|fmt -w9|sed '16iC0C0C0
/F0*8\|80*F/d'
  • The brace expansion {00,80,FF}{00,80,FF}{00,80,FF} gives all need combinations in the right order (excluding C0C0C0), along some extras. The extras are the ones that contain both F and 8 characters.
  • The result of the brace expansion is a single space-separated line. fmt puts each entry on its own line
  • The 1st line of the sed expression inserts C0C0C0 in the appropriate line
  • The 2nd line of the sed expression filters out the "extras" described above.

Ideone.

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

Jelly, 38 31 bytes

“mạ9ṣṃwɠƁ,¡ẓw’b4µża1$ị“08CF”s3Y

TryItOnline!

Base 250 compression of a number (“...’),
converted to base 4 (b4),
zipped (ż) with a copy of itself after a vectorised logical-and with 1 (a1$)*,
indexed () into the four characters used (“08CF”),
split into chunks of length 3 (s3),
and joined with line feeds (Y).

* Thus pairing each zero digit with another zero and each of any other digits with a one. Along with the following indexed fetch this means 'F' becomes paired with another 'F' while '0','8', and 'C' each pair with a '0'.

\$\endgroup\$
  • \$\begingroup\$ Minor edit to fix this answer: “0FC8”, as we have 00, FF, C0, and 80. \$\endgroup\$ – Sherlock9 Dec 10 '16 at 6:02
  • \$\begingroup\$ Oh wow, I did not notice! Thank you. \$\endgroup\$ – Jonathan Allan Dec 10 '16 at 6:15
3
\$\begingroup\$

Python 3, 134 129 125 108 91 90 bytes

I think there is still a lot of golfing to do here. Golfing suggestions welcome!

Edit: -9 bytes and many thanks to Mego for helping with the string formatting. -17 bytes from figuring out a better way to print the string in the first place. -17 bytes from figuring out a better way to write the for loop in the first place. -1 byte thanks to xnor's tip to use i%3//2*"\n" instead of "\n"*(i%3<2).

for i in range(48):print(end="F0C8F000"[0x10114abf7f75c147d745d55//4**i%4::4]+i%3//2*"\n")

Ungolfing

z = 0
a = [0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 2, 2, 2, 3, 3, 3, 1, 3, 3, 3, 1, 3, 1, 1, 3, 0, 0, 1, 1, 0, 1, 3, 3, 1, 1, 3, 1, 0, 1, 1, 3, 1, 1, 1, 1, 1]
for i in range(len(a)):
    z = (z + a[i]) * 4
z //= 4                   # we multiplied by 4 one too many times
for i in range(48):
    m = z // 4**j % 4
    s = "F0C8F000"[c::4]
    if i % 3 == 2:
        s += "\n"
    print(s, end="")
\$\endgroup\$
  • \$\begingroup\$ Try like this - you have to wrap the argument in parentheses (or square brackets) and splat it with *. \$\endgroup\$ – Mego Dec 10 '16 at 5:20
  • \$\begingroup\$ i%3//2*"\n" saves a byte. \$\endgroup\$ – xnor Dec 10 '16 at 6:47
  • \$\begingroup\$ This works with py 3 too \$\endgroup\$ – Miguel Dec 10 '16 at 8:45
  • \$\begingroup\$ @Miguel No, that's an edit I didn't clean up. It doesn't work with Python 2. \$\endgroup\$ – Sherlock9 Dec 10 '16 at 8:46
2
\$\begingroup\$

JavaScript (ES6), 109 107 bytes

Saved 2 bytes, thanks to Neil

This is 7 9 bytes shorter than just returning the raw string in backticks.

_=>[...'1121173113106393'].map(v=>[4,2,0].map(x=>'08CF'[x=n>>x&3]+'000F'[x],n+=+v||21).join``,n=-1).join`
`

Test

let f =

_=>[...'1121173113106393'].map(v=>[4,2,0].map(x=>'08CF'[x=n>>x&3]+'000F'[x],n+=+v||21).join``,n=-1).join`
`

console.log(f())

\$\endgroup\$
  • 1
    \$\begingroup\$ Interestingly .replace(/./g) is the same length as .map().join, but .map(x=>'08CF'[x=n>>x&3]+'000F'[x],n+=+v||21) saves two bytes. \$\endgroup\$ – Neil Dec 10 '16 at 11:25
2
\$\begingroup\$

PowerShell, 113 106 bytes

'777
7780
77FF
7807
78080
7FF7
7FFFF
8077
80780
80807
808080
C0C0C0
FF77
FF7FF
FFFF7
FFFFFF'-replace7,'00'

Yeah, I haven't found anything shorter than just printing the literal string... Thanks to @Martin Smith for shaving down 7 bytes using a simple replacement (which I completely overlooked). So, we're at least 7 bytes shorter than simply hardcoding it. Yay!

But that's boring!

So instead ...

PowerShell v4, 128 bytes

[consolecolor[]](0,7+9..15)+-split'Lime Maroon Navy Olive Purple Silver Teal'|%{-join"$([windows.media.colors]::$_)"[3..8]}|sort

The [system.consolecolor] namespace defines the console colors (natively) available to the PowerShell console. If we reference them via an integer array like this, the default value is the name (e.g., Black or White or the like). We combine that with a string that has been -split on spaces, so now we have an array of strings of color names.

We loop through those |%{...} and each iteration pull out the corresponding [system.windows.media.colors] value. The default stringification for those objects is the color in #AARRGGBB format as a hex value, so we leverage that by encapsulating that call in a string with a script block "$(...)". But, since we don't want the alpha values or the hash, we take the back end [3..8] of the string, and need to -join that resulting char-array back into a string. Then, a simple Sort-Object to put them in the right order.

\$\endgroup\$
  • 1
    \$\begingroup\$ There are 21 instances of 00 and .Replace(7,'00') is < 21 chars. \$\endgroup\$ – Martin Smith Dec 11 '16 at 17:07
  • \$\begingroup\$ I don't know how to use PowerShell, but it might be worth it to also replace 80 and FF. \$\endgroup\$ – nedla2004 Dec 11 '16 at 18:31
  • \$\begingroup\$ @nedla2004 Doing the -replace for 8 and 80 is the same byte count (saves 12 zeros, which is -replace8,80 length). Doing it for the FF is longer by two bytes because of the quotes needed around the "FF" in the -replace2,"FF" statement. \$\endgroup\$ – AdmBorkBork Dec 12 '16 at 15:17
  • \$\begingroup\$ Ok, I was wondering if you could combine the replacements somehow. \$\endgroup\$ – nedla2004 Dec 12 '16 at 18:01
1
\$\begingroup\$

Pyth - 64 48 44 bytes

Super simple base compression.

jcs@L"FC80"jC"ÿÿûÿ¿û¿ðÿ¿»¿»·wðð\0ð\0"4 6

Try it online here.

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

MATL, 39 bytes

'80FFC000'2e'3na:1Fswv1=`uIn'F4:ZaZ)6e!

Try it online!

'80FFC000'         % Push this string
2e                 % Reshape with 2 rows. So 1st column contains '80', 2nd 'FF' etc
'3na:1Fswv1=`uIn'  % Push this string
F4:Za              % Convert from base 95 to alphabet [1 2 3 4]
Z)                 % Use as column indices into the first string
6e!                % Reshape with 6 rows and transpose.
                   % Implicitly display
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 57 bytes

•P{Ætg7«r¨ëÅ,…}ù¢Ý%Vt®£8ãøÚ$0óDÛY²Zþ…ð7ê‘Ó{òìàYëØU¥•hR6ô»

Try it online!

What we need to output is basically (reversed and split):

FFFFFF00FFFFFF00FF0000FF0C0C0C080808000808080008000008FFFF0000FF00080800000800FF0000080000000000

Which, in decimal is:

39402003857025890357721060524755992261661062099432941475272448103296644696683709026793043150430945208910007869898752

Which in Base-214 is:

P{Ætg7«r¨ëÅ,…}ù¢Ý%Vt®£8ãøÚ$0óDÛY²Zþ…ð7ê‘Ó{òìàYëØU¥

This is the simplest solution I could come up with, because there's no way in hell I'm beating Dennis. Spent an hour trying and nothing beat his idea.

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

PHP, 92 Bytes

<?=strtr("000
001
002
010
011
020
022
100
101
110
111
333
200
202
220
222",["00",80,FF,CO]);

Try it online!

simply replacement from the digits as key in the array with the values strtr

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

Batch, 137 bytes

@for %%c in (000000 000080 0000FF 008000 008080 00FF00 00FFFF 800000 800080 808000 808080 C0C0C0 FF0000 FF00FF FFFF00 FFFFFF)do @echo %%c

Yes, it's that boring. Previous 148-byte attempt:

@if "%2"=="" (call %0 000000 80&call %0 C0C0C0 FF)|sort&exit/b
@echo %1
@for %%c in (0000%2 00%200 00%2%2 %20000 %200%2 %2%200 %2%2%2)do @echo %%c

Unfortunately you can't pipe the output of a for or a call: command, so I have to invoke myself recursively.

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

Pyke, 42 bytes

"80FF"2c8DF3"00"]F3+b2tRT`_R.:(s}"C0"3*+SJ

Try it here!

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

Befunge, 83 69 bytes

<v"UVTYZQPefij?EDA@"
v>>9\:4/:\4/>4%:3g,0`
<^_@#:,+55$_^#!-9:,g3
F08C

Try it online!

The colours are encoded in the string you see on the first line, two bits per colour component, with an additional high bit set to force each value into the ASCII range (except in the case of 63, which would be out of range as 127).

The list of colours on the stack is then processed as follows:

9\          9 is pushed behind the current colour to serve as a marker.
:4/:\4/     The colour is repeatedly divided by 4, splitting it into 3 component parts.

>           The inner loop deals with each of the 3 components. 
 4%         Modulo 4 masks out the 2 bits of the colour component that we care about.
 :3g,       That is used as an index into the table on line 4 to get the character to output.
 0`3g,      For component values greater than 0 the second char is a '0', otherwise an 'F'. 
 :9-!       Check if the next component is our end marker.
^           If not, repeat the inner loop.

55+,        Output a newline.
:_          Repeat the outer loop until there are no more colours on the stack. 
\$\endgroup\$
0
\$\begingroup\$

C#, 195 bytes

void n(){string a="000000\r\n000080\r\n0000FF\r\n008000\r\n008080\r\m00FF00\r\n00FFFF\r\n800000\r\n800080\r\n808000\r\n808080\r\nC0C0C0\r\nFF0000\r\nFF00FF\r\nFFFF00\r\nFFFFFF";Console.Write(a);}

Sadly this beats, by a huge margin, the more interesting albeit incredibly convoluted (I had tons more fun writing it) C#, 270 bytes

void n(){string a,b,c,d;a="00";b="80";c="C0";d="FF";for(int i=0;i<16;i++){Console.WriteLine((i<7?a:i<11?b:i>11?d:c)+(i<3?a:i<5?b:i<7?d:i<9?a:i<11?b:i==11?c:i<14?a:d)+(i==0||i==3||i==5|i==7||i==9||i==12||i==14?a:i==1||i==4||i==8||i==10?b:i==2||i==6||i==13||i==15?d:c));}}
\$\endgroup\$
  • \$\begingroup\$ You could just directly return the string in your function - no need to store it in a variable and then print it. Also, a) you can use a lambda, and b) I'm certain there is a solution that beats simply dumping the string. \$\endgroup\$ – Mego Dec 12 '16 at 17:26
  • \$\begingroup\$ @Mego this is my first C# post in golf, not sure how I do a lambda function in all honesty! \$\endgroup\$ – Alfie Goodacre Dec 12 '16 at 17:27
  • \$\begingroup\$ I would suggest looking through this list to find some improvements to make. \$\endgroup\$ – Mego Dec 12 '16 at 17:28
  • \$\begingroup\$ @Alfie Goodacre: C# lambda that just returns a value: ()=>@"string_here" (this casts to Action<string>). I also suggest using a verbatim string (@) so that you can just put the new lines directly in the string without needing to escape them. \$\endgroup\$ – milk Dec 12 '16 at 18:38
0
\$\begingroup\$

C (gcc), 99 bytes

f(i){for(i=48;i--;)printf("%.2s%s","FFC08000"+("#&/28MNQRSV]^_ab"[i/3]-35>>i%3*2&3)*2,"\n\0"+i%3);}

Try it online!

After having made an attempt involving creating a list of numbers and outputting them while sorting, I compared to the naïve solution, which was sobering:

f(){puts("000000\n000080\n0000FF\n008000\n008080\n00FF00\n00FFFF\n800000\n800080\n808000\n808080\nC0C0C0\nFF0000\nFF00FF\nFFFF00\nFFFFFF");}

That one clocks in at 140 bytes compared to my try at 200 and change.

The solution was to think of it as text like any other, albeit with a small alphabet. Each colour could be thought of as a triplet of 2-bit indices into the alphabet {0xff, 0xc0, 0x80, 00}. The process of colour -> triplet -> number -> character (with offset +35 to make them all printable and avoid any need for escapes) can be illustrated as such:

000000  333     63  b
000080  332     62  a
0000FF  330     60  _
008000  323     59  ^
008080  322     58  ]
00FF00  303     51  V
00FFFF  300     48  S
800000  233     47  R
800080  232     46  Q
808000  223     43  N
808080  222     42  M
C0C0C0  111     21  8
FF0000  033     15  2
FF00FF  030     12  /
FFFF00  003     3   &
FFFFFF  000     0   #

Then it's just a matter of iterating over the resulting string and cutting out the appropriate parts of the alphabet string.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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