Skip to content

Instantly share code, notes, and snippets.

@perey
Created July 16, 2015 08:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save perey/c00d2c703d6692feed0d to your computer and use it in GitHub Desktop.
Save perey/c00d2c703d6692feed0d to your computer and use it in GitHub Desktop.
"The Colors in Our Stars" Code Golf Challenge
#!/usr/bin/env python3
"""Pretty star picture maker.
This is the ungolfed version.
http://codegolf.stackexchange.com/questions/53124/the-colors-in-our-stars
"""
from collections import namedtuple
from math import floor, sqrt
CHANNEL_DEPTH = 8
CHANNEL_MAX = 2 ** CHANNEL_DEPTH - 1
Star = namedtuple('Star', 'x y intensity red green blue')
def dist_euclid(x1, y1, x2, y2):
"""Calculate the Euclidean distance between two points."""
dx = x1 - x2
dy = y1 - y2
return sqrt(dx ** 2 + dy ** 2)
def dist_manhattan(x1, y1, x2, y2):
"""Calculate the Manhattan distance between two points."""
dx = x1 - x2
dy = y1 - y2
return abs(dx) + abs(dy)
def parse_input(i):
"""Read the input format to get image dimensions and stars."""
lines = iter(i)
width, height = (int(coord) for coord in next(lines).split())
stars = []
for line in lines:
stars.append(Star(*(int(val) for val in line.split())))
return width, height, stars
def pixel(x, y, stars, dist_fn=dist_euclid):
"""Calculate the colour values at a given pixel."""
for channel in ('red', 'green', 'blue'):
yield min(floor(sum((star.intensity * getattr(star, channel) /
(dist_fn(star.x, star.y, x, y) + 1))
for star in stars)),
CHANNEL_MAX)
def make_image(infile, outfile, dist_fn=dist_euclid):
"""Create the star image."""
print('P3', file=outfile)
width, height, stars = parse_input(infile)
print(width, height, CHANNEL_MAX, file=outfile)
for y in range(height):
for x in range(width):
print(' '.join(str(channel) for channel in pixel(x, y, stars,
dist_fn)),
file=outfile)
if __name__ == '__main__':
infile = '''400 400
123 231 5 206 119 85
358 316 5 170 47 99
95 317 5 202 42 78
251 269 5 142 150 153
43 120 5 145 75 61
109 376 5 230 231 52
331 78 5 31 81 126
150 330 5 8 142 23
69 155 5 142 251 199
218 335 5 183 248 241
204 237 5 112 253 34
342 89 5 140 11 123'''.splitlines()
with open('test.pnm', 'w') as outfile:
make_image(infile, outfile, dist_manhattan)
from sys import stdin as f
o,m,r=print,map,range
w,h=m(int,f.readline().split())
S=[list(m(int,l.split())) for l in f]
p=lambda x,y:(min(int(sum((I*C[c]/(abs(X-x)+abs(Y-y)+1))for X,Y,I,*C in S)),255)for c in r(3))
o('P3',w,h,255)
for y in r(h):
for x in r(w):
o(' '.join(m(str,p(x,y))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment