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

The page source contains two large lists of numbers in an HTML comment:
<!--
first+second=?
first:
146,399,163,403,170,393,...
second:
156,141,165,135,...
-->
Each list is a flat array of (x, y) coordinate pairs. Connect them as polygons to reveal the hidden image.
Solution
Python
Pillow's ImageDraw.polygon() accepts a flat list of (x, y) pairs:
import urllib.request, re
from PIL import Image, ImageDraw
html = urllib.request.urlopen(
"http://www.pythonchallenge.com/pc/return/good.html"
).read().decode()
# Extract both coordinate lists from the HTML comment
blocks = re.findall(r"(first|second):\n([\d,\n]+)", html)
coords = {}
for name, data in blocks:
nums = list(map(int, re.findall(r"\d+", data)))
coords[name] = list(zip(nums[::2], nums[1::2])) # pair up as (x,y) tuples
img = Image.new("RGB", (500, 500), "black")
draw = ImageDraw.Draw(img)
draw.polygon(coords["first"], fill="white")
draw.polygon(coords["second"], fill="white")
img.show()
# Reveals a bull
Answer: bull
Go
Go's image/draw doesn't have a polygon primitive — use the golang.org/x/image/draw package or implement Bresenham polygon fill. The cleanest approach uses the freetype or gg graphics library:
package main
import (
"fmt"
"image"
"image/color"
"image/png"
"io"
"net/http"
"os"
"regexp"
"strconv"
"strings"
"github.com/fogleman/gg" // go get github.com/fogleman/gg
)
func extractCoords(data string) []float64 {
re := regexp.MustCompile(`\d+`)
var nums []float64
for _, s := range re.FindAllString(data, -1) {
n, _ := strconv.ParseFloat(s, 64)
nums = append(nums, n)
}
return nums
}
func main() {
resp, _ := http.Get("http://www.pythonchallenge.com/pc/return/good.html")
body, _ := io.ReadAll(resp.Body)
resp.Body.Close()
re := regexp.MustCompile(`(?s)(first|second):\n([\d,\n]+)`)
matches := re.FindAllStringSubmatch(string(body), -1)
dc := gg.NewContext(500, 500)
dc.SetRGB(0, 0, 0)
dc.Clear()
dc.SetRGB(1, 1, 1)
for _, m := range matches {
nums := extractCoords(m[2])
dc.NewSubPath()
for i := 0; i+1 < len(nums); i += 2 {
dc.LineTo(nums[i], nums[i+1])
}
dc.ClosePath()
}
dc.Fill()
dc.SavePNG("output.png")
fmt.Println("Saved output.png") // shows a bull
}
Rust
The imageproc crate provides polygon drawing:
use image::{Rgb, RgbImage};
use imageproc::drawing::draw_polygon_mut;
use imageproc::point::Point;
use regex::Regex;
fn parse_coords(data: &str) -> Vec<Point<i32>> {
let re = Regex::new(r"\d+").unwrap();
let nums: Vec<i32> = re.find_iter(data)
.map(|m| m.as_str().parse().unwrap())
.collect();
nums.chunks(2)
.map(|c| Point::new(c[0], c[1]))
.collect()
}
fn main() {
let html = reqwest::blocking::get(
"http://www.pythonchallenge.com/pc/return/good.html"
).unwrap().text().unwrap();
let re = Regex::new(r"(?s)(first|second):\n([\d,\n]+)").unwrap();
let mut img = RgbImage::new(500, 500);
for cap in re.captures_iter(&html) {
let pts = parse_coords(&cap[2]);
draw_polygon_mut(&mut img, &pts, Rgb([255u8, 255, 255]));
}
img.save("output.png").unwrap();
println!("Saved output.png"); // shows a bull
}
Language Comparison
| Feature | Python | Go | Rust |
|---|---|---|---|
| Polygon fill | ImageDraw.polygon() — stdlib via Pillow |
No stdlib polygon — use gg or freetype |
imageproc::drawing::draw_polygon_mut |
| Coordinate pairs from flat list | zip(nums[::2], nums[1::2]) — slice stepping |
Manual i += 2 loop |
.chunks(2).map(...) |
| Image output | .show() opens viewer; .save("out.png") saves |
dc.SavePNG() |
img.save() |
| 2D graphics stdlib depth | Deep — Pillow covers most 2D needs | Shallow — basic raster, no vector/polygon | Shallow — image crate is basic; use imageproc for drawing |
Key insight: Python's Pillow is an exceptionally rich 2D graphics library compared to what Go and Rust offer in their stdlib or even popular crates. ImageDraw.polygon() with scanline fill is a single call in Python; Go and Rust require external crates and more boilerplate. For image-manipulation puzzles and scripts, Python remains the most ergonomic choice.
Next Level
http://www.pythonchallenge.com/pc/return/bull.html
Username: huge | Password: file