Python Challenge - Level 11
- Link: http://www.pythonchallenge.com/pc/return/5808.html
- Username: huge
- Password: file
Problem

The title of the page is odd even.
The clue implies that the image cave.jpg is an interlaced composite of two distinct sub-images: one formed by pixels at (x, y) where (x + y) is even, and the other where (x + y) is odd (or simply separating even and odd coordinates).
Solution
Separating pixels at (2x, 2y) from the original image produces a clear, downscaled image revealing the hidden word.
Python
from PIL import Image
im = Image.open("cave.jpg")
w, h = im.size
even_img = Image.new(im.mode, (w // 2, h // 2))
odd_img = Image.new(im.mode, (w // 2, h // 2))
for x in range(w):
for y in range(h):
pixel = im.getpixel((x, y))
if (x + y) % 2 == 0:
even_img.putpixel((x // 2, y // 2), pixel)
else:
odd_img.putpixel((x // 2, y // 2), pixel)
even_img.save("even.jpg")
odd_img.save("odd.jpg")
Viewing even.jpg clearly reveals the word evil.
Go
Using Go's standard library image and image/jpeg:
package main
import (
"image"
"image/color"
"image/jpeg"
"os"
)
func main() {
f, err := os.Open("cave.jpg")
if err != nil {
panic(err)
}
defer f.Close()
img, err := jpeg.Decode(f)
if err != nil {
panic(err)
}
bounds := img.Bounds()
w, h := bounds.Dx(), bounds.Dy()
even := image.NewRGBA(image.Rect(0, 0, w/2, h/2))
for y := 0; y < h; y++ {
for x := 0; x < w; x++ {
if (x+y)%2 == 0 {
r, g, b, a := img.At(x, y).RGBA()
even.Set(x/2, y/2, color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)})
}
}
}
out, _ := os.Create("even.jpg")
defer out.Close()
jpeg.Encode(out, even, &jpeg.Options{Quality: 95})
}
Rust
Using the image crate in Rust:
use image::{ImageBuffer, Rgb, RgbImage};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let img = image::open("cave.jpg")?.to_rgb8();
let (w, h) = img.dimensions();
let mut even: RgbImage = ImageBuffer::new(w / 2, h / 2);
for y in 0..h {
for x in 0..w {
if (x + y) % 2 == 0 {
let pixel = img.get_pixel(x, y);
even.put_pixel(x / 2, y / 2, *pixel);
}
}
}
even.save("even.jpg")?;
Ok(())
}
Language Comparison
| Feature | Python (Pillow) | Go (image) |
Rust (image crate) |
|---|---|---|---|
| Pixel Access Overhead | getpixel/putpixel have high per-pixel Python interpreter overhead; load() improves it |
img.At(x, y) performs virtual interface dispatch; concrete type assertion (*image.RGBA) is faster |
Direct contiguous memory indexing (&img[(y * w + x) * 3..]), zero-cost abstractions |
| Standard Library | Third-party (Pillow) required |
Standard library (image, image/jpeg, image/color) |
Ecosystem crate (image) required |
| Coordinate System | (x, y) tuples |
(x, y) integers via image.Point / image.Rectangle |
(x, y) u32 integers |
| Performance | ~100–300 ms | ~10–20 ms | ~2–5 ms |
Key insight: Go's standard library ships with built-in JPEG and PNG encoders/decoders, making standard image manipulation fully dependency-free. Python requires external Pillow, and Rust uses the ubiquitous image crate. Rust's strict typing ensures channel depth and color format safety at compile time.
Next Level
Replace 5808 with evil: