Python Challenge - Level 11

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:

http://www.pythonchallenge.com/pc/return/evil.html

Loading...