By Matt Gruskin

(You may also be interested in checking out a detailed walkthrough by Robin Deits of how to solve this puzzle.)

This puzzle is an image with a black background containing several lines of text, where each line is made up of colored letters. The text of each line is the full birth name of a famous actor. Each actor in this list has appeared in exactly one film that contains a color of the rainbow in its name.

Actor Film Color
COLIN LEWES DILLINGHAM ORANGE COUNTY ORANGE
RICHARD GILBERT EMERY YELLOW SUBMARINE YELLOW
CARLOS IRWIN ESTEVEZ RED DAWN RED
BONNIE LYNNE HUNT THE GREEN MILE GREEN
HOPE ELISE ROSS LANGE BLUE VELVET BLUE
SAOIRSE UNA RONAN VIOLET & DAISY VIOLET
AUDREY JUSTINE TAUTOU MOOD INDIGO INDIGO

The next step is to figure out how to use the colors of the letters. We can analyze the colors in the image using image editing tools (e.g., Photoshop/GIMP, ImageMagick, Python Imaging Library). Depending on the tools used, different clues might be noticed first.

When using tools that work with 8-bit color channels (e.g., GIMP, Python Imaging Library), examining a color histogram will reveal a disproportionate number of pixels with RGB value #010000. Highlighting these pixels produces the image below.

This image can be derived from the puzzle image using the following ImageMagick command:

```\$ convert puzzle.png \
-depth 8 \
-fill "#ff0000" -opaque "#010000" \
puzzle_shallow_red_clues.png```

This image contains the phrase COLORS MAY BE DEEPER THAN THEY APPEAR, which is a clue that the puzzle is a deep color image, with 16 bits of color per channel, for a total of 48. We can check the color depth of the image e.g., by using the ImageMagick identify command:

```\$ identify puzzle.png
puzzle.png PNG 600x336 600x336+0+0 16-bit DirectClass 15.8KB 0.000u 0:00.000```

Using tools that support 16-bit color channels (e.g., Photoshop, ImageMagick), separating the color channels and examining the color histograms for each channel will reveal more high-frequency almost-black color values, specifically the colors #000000010000 and #000000000001.

```\$ convert puzzle.png \
-fill "#0000ffff0000" \
-opaque "#000000010000" \
-opaque "#000000010001" \
-opaque "#010000010000" \
-opaque "#010000010001" \
-depth 8 \
puzzle_deep_green_clues.png```
```\$ convert puzzle.png \
-fill "#00000000ffff" \
-opaque "#000000000001" \
-opaque "#000000010001" \
-opaque "#010000000001" \
-opaque "#010000010001" \
-depth 8 \
puzzle_deep_blue_clues.png```

Let’s consider the green clues first (green does come before blue in the red green blue pixel order, after all). The green words read:
ROWETEL CODEC2
INPUT:
40 MILLISECOND FRAMES
1200 BITS PER SECOND
OUTPUT:
RAW SAMPLES
8KHZ 16-BIT SIGNED

The first few Google search results for Rowetel Codec2 explain what it is, and how to get it. It is very low bitrate audio encoding and decoding software.

1200 BITS PER SECOND is referring to a specific mode of Codec2 which encodes audio at 1200 bits/second. Mode 1200 uses 40 millisecond audio frames of 48 bits each, which is conveniently also the amount of color data we have per letter. We can treat each letter as a Codec2 audio frame by writing out the red component, followed by the green component, followed by the blue component, in network byte order (this is the order that is used by the PNG file format).

(Even if this byte order is not obvious, there are only really two choices, and therefore only four reasonable combinations: choosing between big- and little-endian byte order, and choosing between RGB vs BGR component order. The correct order of big-endian (network byte order) RGB can be determined by trial and error.)

We can concatenate the frames within a line together, and write them out into a Codec2-encoded audio file. Here is a Python program that does this for all of the lines in the puzzle image:

```import struct

from wand.color import Color
from wand.image import Image

CHAR_WIDTH = 24
LINE_HEIGHT = 32
LINE_SPACING = 16

CLUE_COLORS = [
Color("#010000000000"),
Color("#000000010000"),
Color("#000000000001"),
Color("#010000010000"),
Color("#010000000001"),
Color("#010000010001"),
]

def GetCharColorTuple(char_img):
max_color = Color("black")
max_color_count = 0
for color, count in char_img.histogram.items():
if color == Color("black"):
continue
if count > max_color_count:
max_color = color
max_color_count = count
if max_color == Color("black") or max_color in CLUE_COLORS:
return None
return (max_color.red_quantum, max_color.green_quantum, max_color.blue_quantum)

if __name__ == "__main__":
img = Image(filename="puzzle.png")
for y in xrange(0, img.height, LINE_HEIGHT + LINE_SPACING):
audio_file = open("line%d.bit" % (y / (LINE_HEIGHT + LINE_SPACING)), "wb")
for x in xrange(0, img.width, CHAR_WIDTH):
with img[x:(x + CHAR_WIDTH), y:(y + LINE_HEIGHT)] as char_img:
color_tuple = GetCharColorTuple(char_img)
if color_tuple != None:
r, g, b = color_tuple
audio_file.write(struct.pack("!HHH", r, g, b))
audio_file.close()```

Each Codec2-encoded audio file can then be decoded to a raw audio file using the Codec2 command line tools.

`\$ ./src/c2dec 1200 line0.bit line0.raw`

The last part of the green clue, RAW SAMPLES 8KHZ 16-BIT SIGNED, is instructing us how to decode and play back the raw audio file. These settings can be used when opening a raw audio file with Audacity, or using the play command line tool:

`\$ play -t raw -r 8000 -e signed-integer -b 16 line0.raw`

Playing back the sound associated with each line reveals a single spoken word. If we combine these words with the colors we found above, we get titles of songs. In each case, we’ll also figure out the artist that created the song, and we’ll look up their full birth name (just like the actor names provided at the beginning). Finally, we’ll use the blue numbers associated with each name as indices into the full artist birth names for each song.

Actor Film Spoken Word Song Artist Song Artist Birth Name Blue Number Indexed Letter
COLIN LEWES DILLINGHAM ORANGE COUNTY SODA
VIC MENSA VICTOR KWESI MENSAH (17/17) H
RICHARD GILBERT EMERY YELLOW SUBMARINE RAINCOAT
JUSTIN BIEBER JUSTIN DREW BIEBER (2/16) U
CARLOS IRWIN ESTEVEZ RED DAWN UMBRELLA
FAITH HILL AUDREY FAITH PERRY (10/16) T
BONNIE LYNNE HUNT THE GREEN MILE PANGEA
MARSIMOTO (or MARTERIA) MARTEN LACINY (6/12) N
HOPE ELISE ROSS LANGE BLUE VELVET BANDANA
JERROD NIEMANN JERROD LEE NIEMANN (6/16) D
SAOIRSE UNA RONAN VIOLET & DAISY AFFAIR
MARNIE HELEN MARNIE (8/11) R
AUDREY JUSTINE TAUTOU MOOD INDIGO CHILDREN
PUSCIFER JAMES HERBERT KEENAN (or MAYNARD JAMES KEENAN) (14/18) E

If we sort this table by the order of the colors of the rainbow, then the indexed letters spell out the answer THUNDER.