90
\$\begingroup\$

Write a program that takes in a string or text file whose first line has the form

width height

and each subsequent line has the form

x y intensity red green blue

where:

  • width and height may be any positive integers.
  • x and y may be any integers.
  • intensity may be any non-negative integer.
  • red, green, and blue may be any integers from 0 to 255 inclusive.

Your program must output a truecolor image in any common lossless image file format whose dimensions are width by height. Each x y intensity red green blue line represents a colorful star or orb that must be drawn on the image. There may be any number of stars to draw, including 0. You may assume the string or file has a trailing newline.

The algorithm for drawing the image is as follows, though you may implement it in any way you like as long as the result is identical:

For every pixel (X,Y) in the image (where X is 0 at the leftmost edge and width-1 at the rightmost edge, and Y is 0 at the top edge and height-1 at the bottom edge), the color channel C ϵ {red, green, blue} (a value pinned between 0 to 255) is given by the equation:

color channel equation

Where the dist function is either Euclidean distance:

Euclidean distance equation

Or Manhattan distance:

Manhattan distance equation

Choose whichever distance function you prefer, based on golfability or aesthetics.

Each of the lines in the input besides the first is an element of the Stars set. So, for example, Sx represents the x value on one of the input lines, and SC represents either red, green, or blue, depending on which color channel is currently being calculated.

Examples

Example A

If the input is

400 150
-10 30 100 255 128 0

the output should be

Example A, Euclidean

if you're using Euclidean distance, and

Example A, Manhattan

if you're using Manhattan distance.

Example B

If the input is

200 200
100 100 10 255 255 255
20 20 40 255 0 0
180 20 40 255 255 0
180 180 40 0 255 0
20 180 40 0 0 255

the respective outputs for Euclidean and Manhattan distance should be

Example B, Euclidean and Example B, Manhattan.

Example C

If the input is

400 400
123 231 10 206 119 85
358 316 27 170 47 99
95 317 3 202 42 78
251 269 17 142 150 153
43 120 3 145 75 61
109 376 6 230 231 52
331 78 21 31 81 126
150 330 21 8 142 23
69 155 11 142 251 199
218 335 7 183 248 241
204 237 13 112 253 34
342 89 18 140 11 123

the output should be

Example C, Euclidean

if you're using Euclidean distance, and

Example C, Manhattan

if you're using Manhattan distance.

Example D

If the input is

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

the output should be

Example D, Euclidean

if you're using Euclidean distance, and

Example D, Manhattan

if you're using Manhattan distance.

Example E

If the input is

100 1

then the output should be a 100 pixel wide by 1 pixel tall image that is completely black.

Notes

  • Take the input string or the name of a text file that contains it from stdin or the command line, or you may write a function that takes in a string.
  • "Outputting" the image means either:
    • Saving it to a file with the name of your choice.
    • Printing the raw image file data to stdout.
    • Displaying the image, such as with PIL's image.show().
  • I won't be checking that your images are pixel perfect (Stack Exchange lossily compresses images anyway) but I will be very suspicious if I can visually tell any difference.
  • You may use graphics/image libraries.

Winning

The shortest submission in bytes wins. In case of ties, the earliest submission wins.

Fun Bonus: Give the input for a truly spectacular output image.

\$\endgroup\$
  • 38
    \$\begingroup\$ +1 Wow. This is gorgeous. (And an appropriate time for posting, as we hear word from a healthy New Horizons spacecraft!) \$\endgroup\$ – BrainSteel Jul 15 '15 at 1:02
  • \$\begingroup\$ Does the input have to be in that space separated format, or can it be comma separated? Anyways, +1. \$\endgroup\$ – Maltysen Jul 15 '15 at 1:34
  • 1
    \$\begingroup\$ @Maltysen Space separated. (I know that's stingy but it's easier than allowing a dozen input variants.) \$\endgroup\$ – Calvin's Hobbies Jul 15 '15 at 1:35
  • 4
    \$\begingroup\$ I can't decide if the orbs or stars are more beautiful. \$\endgroup\$ – trichoplax Jul 15 '15 at 2:14
  • \$\begingroup\$ For pixel-perfection you could compare the bitmap's hash \$\endgroup\$ – Tobias Kienzler Jul 16 '15 at 17:59

14 Answers 14

26
\$\begingroup\$

Pyth - 46 bytes

This was fun! I finally got to use Pyth's image I/O features. Does euclidean distance because of golfiness, though manhattan is just a short change.

Krz7.wcmmsm/*@b+3k@b2h.a,<b2_.DdhKrR7.zU3*FKhK

This just loops through all the pixels with the formula's though it condenses the pixel loop into one loop and uses divmod since Pyth only supports 3 nested maps and the calculations take two (one for RGB and one for the stars).

Saves image as o.png. Pretty slow, does the first 2 tests in <2 min, but the other 2 take on the order of half an hour.

There is a bug in .w that no one noticed because no one uses it ;) but I put in a pull request so use my fork to test if isn't merged soon. Merged!

Examples Outputs

Example A

Example A

Example B

Example B

Example C

Example C

Example D

Example D

\$\endgroup\$
  • 7
    \$\begingroup\$ Wow, didn't know Pyth could do that. One day we might end up writing business software in Pyth. It's less code to write, so it should be faster and easier to refactor. :D \$\endgroup\$ – Cristian Lupascu Jul 15 '15 at 7:46
  • 7
    \$\begingroup\$ @w0lf "programmer time is more important than execution time" and we all know that Pyth helps reducing programmer time :) The image I/O was added recently after Pyth was left out from a graphical output challenge. It uses Pillow internally. \$\endgroup\$ – Maltysen Jul 15 '15 at 8:19
  • 11
    \$\begingroup\$ @Nit Absolutely. It also has nothing to do with how fast it is to write. My previous comment was a joke. \$\endgroup\$ – Cristian Lupascu Jul 15 '15 at 9:57
  • 2
    \$\begingroup\$ You guys forgot one important thing - its easier to debug too, since the code is less ;) \$\endgroup\$ – Optimizer Jul 15 '15 at 12:42
  • 14
    \$\begingroup\$ By reducing programmer time you mean "They're playing code golf with pyth and so have less time to write 'real' code"? \$\endgroup\$ – user12166 Jul 15 '15 at 13:06
42
\$\begingroup\$

JavaScript 394 344

function X(a){for(l=a.match(/\d+/g),h=document,v=h.body.appendChild(h.createElement("canvas")),v.width=W=l[0],v.height=H=l[1],w=v.getContext("2d"),e=w.createImageData(W,H),d=e.data,N=W*H;N--;)for(i=2,c=N*4,d[c+3]=255;i<l.length;)for(x=N%W-l[i++],y=~~(N/W)-l[i++],k=l[i++],q=0;q<3;)d[c+q++]+=k*l[i++]/-~Math.sqrt(x*x+y*y);w.putImageData(e,0,0);}

Edit: shortened the code a lot by applying wolfhammer's awesome suggestions.

Test

Note: Wait a few seconds for the snippet below to render (takes ~4 seconds on my machine).

function X(a){for(l=a.match(/\d+/g),h=document,v=h.body.appendChild(h.createElement("canvas")),v.width=W=l[0],v.height=H=l[1],w=v.getContext("2d"),e=w.createImageData(W,H),d=e.data,N=W*H;N--;)for(i=2,c=N*4,d[c+3]=255;i<l.length;)for(x=N%W-l[i++],y=~~(N/W)-l[i++],k=l[i++],q=0;q<3;)d[c+q++]+=k*l[i++]/-~Math.sqrt(x*x+y*y);w.putImageData(e,0,0);}

var start = Date.now();

X("400 150\n" +
  "-10 30 100 255 128 0");

X("200 200\n" +
  "100 100 10 255 255 255\n" +
  "20 20 40 255 0 0\n" +
  "180 20 40 255 255 0\n" +
  "180 180 40 0 255 0\n" +
  "20 180 40 0 0 255");

X("400 400\n" +
  "123 231 10 206 119 85\n" +
  "358 316 27 170 47 99\n" +
  "95 317 3 202 42 78\n" +
  "251 269 17 142 150 153\n" +
  "43 120 3 145 75 61\n" +
  "109 376 6 230 231 52\n" +
  "331 78 21 31 81 126\n" +
  "150 330 21 8 142 23\n" +
  "69 155 11 142 251 199\n" +
  "218 335 7 183 248 241\n" +
  "204 237 13 112 253 34\n" +
  "342 89 18 140 11 123");

X("400 400\n" +
  "123 231 5 206 119 85\n" +
  "358 316 5 170 47 99\n" +
  "95 317 5 202 42 78\n" +
  "251 269 5 142 150 153\n" +
  "43 120 5 145 75 61\n" +
  "109 376 5 230 231 52\n" +
  "331 78 5 31 81 126\n" +
  "150 330 5 8 142 23\n" +
  "69 155 5 142 251 199\n" +
  "218 335 5 183 248 241\n" +
  "204 237 5 112 253 34\n" +
  "342 89 5 140 11 123");

var end = Date.now();

console.log('Done in ' + (end - start)/1000 + 's.');
canvas {
  display: block;
  padding: 10px;
}

You can also run it in JSFiddle.

Bonus: Blue Eclipse

function X(a){for(l=a.match(/\d+/g),h=document,v=h.body.appendChild(h.createElement("canvas")),v.width=W=l[0],v.height=H=l[1],w=v.getContext("2d"),e=w.createImageData(W,H),d=e.data,N=W*H;N--;)for(i=2,c=N*4,d[c+3]=255;i<l.length;)for(x=N%W-l[i++],y=~~(N/W)-l[i++],k=l[i++],q=0;q<3;)d[c+q++]+=k*l[i++]/-~Math.sqrt(x*x+y*y);w.putImageData(e,0,0);}

var j = 0;
var renderFrame = function () {
  if(window.h && window.v){h.body.removeChild(v);} // clear prev frame
  X("225 150\n" +
    (70 + j) + " " + (120 - j) + " 170 135 56 0\n" + 
    j * 5 + " " + j * 3 + " 64 0 50 205");       
  if(++j < 50) { setTimeout(renderFrame, 1); } else { console.log('done!'); }
};
setTimeout(renderFrame, 10);

You can also run it in JSFiddle.

Description

This is a straightforward JavaScript + HTML5 canvas implementation: a function that takes a string argument (without trailing spaces/newlines) and displays the output in the DOM. It uses Euclidean distance.

Here is the readable code:

X = function (str) {
  var lines = str.split("\n");  
  var canvas = document.createElement('canvas');
  var z = lines[0].split(u=' ');
  var width = z[0], height = z[1];

  canvas.width = width;
  canvas.height = height;
  document.body.appendChild(canvas);

  var ctx = canvas.getContext("2d");
  var imageData = ctx.createImageData(width, height);

  for(var y = 0; y < height; y++){
    for(var x=0; x < width; x++){
      var coord = (y * width + x) * 4;

      for(i=1; i < lines.length;i++){
        var t = lines[i].split(u);

        var 
          dx = x - t[0], 
          dy = y - t[1];

        var distance = Math.sqrt(dx * dx + dy * dy);

        for(var channel = 0; channel < 3; channel++) {
          var channelIndex = coord + channel;
          imageData.data[channelIndex] += t[2] * t[3 + channel] / (distance + 1);
        }
      }

      var alphaIndex = coord + 3;
      imageData.data[alphaIndex] = 255;
    }
  }

  ctx.putImageData(imageData, 0, 0);
};
\$\endgroup\$
  • \$\begingroup\$ I love how halos glued together in Blue Eclipse, can you add manhatan style? \$\endgroup\$ – PTwr Jul 17 '15 at 13:48
  • 1
    \$\begingroup\$ @PTwr Sure, here it is: jsfiddle.net/pjLnazw1 \$\endgroup\$ – Cristian Lupascu Jul 17 '15 at 13:53
  • \$\begingroup\$ Awesome! (7 more to go... ugh) \$\endgroup\$ – PTwr Jul 17 '15 at 13:56
  • \$\begingroup\$ @w0lf You can shave some bytes off your function by combining the x and y iterators. jsfiddle \$\endgroup\$ – wolfhammer Jul 20 '15 at 4:53
  • \$\begingroup\$ @wolfhammer Wow, that's now just "some bytes", it's a lot of improvement. I'll take a look at that later, as I believe there's something to be fixed about the indexing (for sample images 2, 3 and 4 the pixels on the left appear to wrap around). Thanks! \$\endgroup\$ – Cristian Lupascu Jul 20 '15 at 6:33
26
\$\begingroup\$

Java - 627 bytes

Java is indeed one of the best golfing languages :)

import java.awt.image.*;class M{void f(String n)throws Exception{String[]p=n.split("\n");int[]b=s(p[0]);BufferedImage o=new BufferedImage(b[0],b[1],2);for(int i=0;i<b[0];i++)for(int j=0;j<b[1];j++){int[]c=new int[3];for(int l=1;l<p.length;l++){int[]r=s(p[l]);for(int k=0;k<3;k++){c[k]+=r[2]*r[3+k]/(Math.sqrt(Math.pow(i-r[0],2)+Math.pow(j-r[1],2))+1);if(c[k]>255)c[k]=255;}}o.setRGB(i,j,new java.awt.Color(c[0],c[1],c[2]).getRGB());}javax.imageio.ImageIO.write(o,"png",new java.io.File("o.png"));}int[]s(String s){String[]a=s.split(" ");int[]r=new int[a.length];for(int i=0;i<a.length;i++)r[i]=Integer.valueOf(a[i]);return r;}}

Using the input below, you can create a somewhat realistic model of our solar system (the size of some planets is wrong, but the distance between them should be accurate). I tried to give rings to saturn, but it didn't work... Source

1950 50
-15 25 25 255 255 0
39 25 1 255 0 0
55 25 3 255 140 0
68 25 4 0 191 255
92 25 2 255 0 0
269 25 10 245 222 179
475 25 7 245 245 220
942 25 6 0 250 150
1464 25 6 0 0 255
1920 25 1 255 245 238

Solar system with pluto

Full HD picture, which doesn't look thaaat great... Would be happy if someone could improve it!

\$\endgroup\$
  • 15
    \$\begingroup\$ +1 for Solar System. -1 for leaving Pluto (now that we even know its real color and size) \$\endgroup\$ – Optimizer Jul 15 '15 at 11:14
  • 1
    \$\begingroup\$ Also, it would be really nice if a full 1080p wallpaper is linked :) \$\endgroup\$ – Optimizer Jul 15 '15 at 11:14
  • \$\begingroup\$ @Optimizer I added pluto ;) Lets see what I can do about the wallpaper \$\endgroup\$ – CommonGuy Jul 15 '15 at 11:18
  • 1
    \$\begingroup\$ @Sp3000 Ups, forgot the intensity when I added pluto \$\endgroup\$ – CommonGuy Jul 15 '15 at 14:49
  • 2
    \$\begingroup\$ Note that Saturn isn't the only planet with rings. If you get rings to work, you should add them to Uranus also. \$\endgroup\$ – mbomb007 Jul 15 '15 at 19:05
20
\$\begingroup\$

Bash, 147 145 bytes

ImageMagick is used to manipulate images. Euclidean distance is used.

read w h
o=o.png
convert -size $w\x$h canvas:black $o
while read x y i r g b
do
convert $o -fx "u+$i*rgb($r,$g,$b)/(hypot(i-$x,j-$y)+1)" $o
done
\$\endgroup\$
  • \$\begingroup\$ You can save a byte with $w\x$h. \$\endgroup\$ – deltab Jul 18 '15 at 17:39
  • \$\begingroup\$ ... and another with o=o.png. \$\endgroup\$ – deltab Jul 18 '15 at 17:41
16
\$\begingroup\$

Python 3, 189 bytes

I'm nobody's idea of an expert golfer, but here goes.

  • Input comes from stdin and goes to stdout in PPM format.
  • Run it like so: python3 codegolf_stars_golfed.py < starfield.txt > starfield.pnm

First, Manhattan distance:

import sys
(w,h),*S=[list(map(int,l.split()))for l in sys.stdin]
print('P3',w,h,255,*(min(int(sum((I*C[z%3]/(abs(X-z//3%h)+abs(Y-z//3//h)+1))for
X,Y,I,*C in S)),255)for z in range(h*w*3)))

And secondly, Euclidean distance:

import sys
(w,h),*S=[list(map(int,l.split()))for l in sys.stdin]
print('P3',w,h,255,*(min(int(sum((I*C[z%3]/(abs(X-z//3%h+(Y-z//3//h)*1j)+1))for
X,Y,I,*C in S)),255)for z in range(h*w*3)))

I could save four bytes by using integer division instead of int(), and in fact that seems to be what the original images do--you can just barely make out some striations in the dark fringes of the star glow that aren't present in strictly correct code. As it stands, though, this code follows the description, not the images.

The ungolfed version, and my original golfing before the many optimisations that others pointed out or that I stumbled upon myself, are in this gist.

EDIT: I saved 7 bytes by moving for x and for y into a single print (or o) function, but this produces a PNM file with a very long line, which may or may not cause some problems.

EDIT 2: Maltysen saved me another 20 bytes. Thanks!

EDIT again: Now that there's only one print, the o alias is a liability, not a saving. 4 more bytes off.

EDIT some more: Sp3000 saved me 2 more bytes. Meanwhile, aliasing map to m wasn't saving anything, so in the interests of readability(!) I've expanded it again. It's now a nice round 28 bytes.

EDIT the last(?): Now with Euclidean distance support--and by abusing complex numbers, I did it in exactly the same number of bytes!

EDIT, the Hollywood reboot: Sp3000's next suggestion knocked off 5 bytes.

EDIT, the stupidly named sequel: 6 bytes trimmed off, thanks to a suggestion Maltysen made that I didn't grasp until Sp3000 repeated it... then another 8 bytes from % abuse. And talking it out in chat knocked off a phenomenal 21 26 bytes. I'm humbled.

\$\endgroup\$
  • \$\begingroup\$ @Maltysen: Quite right. 20 bytes saved! \$\endgroup\$ – Tim Pederick Jul 15 '15 at 9:35
  • \$\begingroup\$ some more: instead of that complicated sys.stdin stuff with EOFs you can use iter() with sentinel values: docs.python.org/2/library/functions.html#iter as iter(raw_input,''), also put w,h,S on the same line with extended unpacking. \$\endgroup\$ – Maltysen Jul 15 '15 at 9:43
  • \$\begingroup\$ @Maltysen: I'm not sure that would work. I was doing almost exactly that already, but it hits EOFError (and so I needed a try block), because there's no blank line in the input file and I'm not sure the challenge allows me to add one. Or am I missing something? \$\endgroup\$ – Tim Pederick Jul 15 '15 at 9:56
  • \$\begingroup\$ I think if you the sentinel value thing, you could just terminate by a blank line versus feeding the file in, though ,yeah, the file thing wouldn't work. \$\endgroup\$ – Maltysen Jul 15 '15 at 9:59
  • \$\begingroup\$ @Sp3000: Surprisingly, yes! I was expecting it to complain that stdin wasn't an iterator. \$\endgroup\$ – Tim Pederick Jul 15 '15 at 12:57
10
\$\begingroup\$

C++, 272 bytes

#include<png.hpp>
#define G(a)i>>C;for(x=0;x<w*h;++x){auto&p=img[x%h][x/h];c=p.a+I*C/(abs(x/h-X)+abs(x%h-Y)+1);p.a=c>255?255:c;}
auto&i=std::cin;main(){int w,h,x,X,Y,I,c,C;i>>w>>h;png::image<png::rgb_pixel>img(w,h);while(i>>X>>Y>>I){G(red)G(green)G(blue)}img.write("a");}

Needs a lenient C++11 compiler (GCC 4.9.2 is only slightly displeased), and the png++ library, which itself requires libpng. Manhattan distance used. Takes input on stdin, outputs to a file named "a" in the current directory in PNG format.

Example D:

enter image description here


enter image description here


enter image description here

\$\endgroup\$
  • 1
    \$\begingroup\$ I like the PCG image :) (Though PPCG is my preferred abbreviation ;) ) \$\endgroup\$ – Calvin's Hobbies Jul 19 '15 at 10:39
8
\$\begingroup\$

Python 2, 240 232 228 bytes

from PIL.Image import*
def f(S):
 L=map(int,S.split());t=a,b=L[:2];I=new("RGB",t)
 for k in range(a*b):I.load()[k/a,k%a]=tuple(sum(x[2]*x[c]/(abs(x[0]-k/a)-~abs(x[1]-k%a))for x in zip(*[iter(L[2:])]*6))for c in(3,4,5))
 I.show()

Uses Manhattan distance. This would probably be even shorter in Python 3, but I messed up my Python packages recently and I'm having trouble reinstalling Pillow. PPM would probably be even shorter, but I like PIL.

For fun, I tried to apply the algorithm as is in the L*a*b* color space instead, thinking it would give better colour blending (especially in example B). Unfortunately, Calvin's algorithm lets channels go over their max values, which makes the images look a little less awesome than I hoped...

enter image description here

\$\endgroup\$
6
\$\begingroup\$

Mathematica, 146 bytes

Image@Table[Total[#3{##4}/255&@@@{##2}/(1+#~ManhattanDistance~{x,y}&/@({#1,#2}&@@@{##2}))],{y,0,Last@#-1},{x,0,#&@@#-1}]&@@#~ImportString~"Table"&

A pure function taking a string. To run it in a reasonable amount of time, replace the 1 in 1+#~ManhattanDistance... with a 1.; this forces numeric computation instead of symbolic.

Ungolfed:

Image[
    Table[
        Total[
        (#3 * {##4} / 255 & @@@ {##2})
            / (1 + ManhattanDistance[#, {x, y}]& /@ ({#1, #2}& @@@ {##2}) )
        ], {y, 0, Last[#]-1}, {x, 0, First[#]-1}
    ] (* Header is #, data is {##2} *)
]& @@ ImportString[#, "Table"]&
\$\endgroup\$
6
\$\begingroup\$

Python 2, 287 251 bytes

A golfed version of the original code I used to generate the images. Could probably be golfed a bit more (by a better golfer than me). It's a function that takes in the full input string. Image processing done with PIL's Image Module. Uses Manhattan distance.

from PIL import Image
def S(I,r=range):
 I=map(int,I.split());w,h=I[:2];M=Image.new('RGB',(w,h));P=M.load()
 for z in r(w*h):
  P[z%w,z/w]=tuple(int(sum(I[i+2]*I[i+j+3]/(1.+abs(I[i]-z%w)+abs(I[i+1]-z/w))for i in r(2,len(I),6)))for j in r(3))
 M.show()

Using Euclidean distance is 5 bytes longer (256 bytes):

from PIL import Image
def O(I,r=range):
 I=map(int,I.split());w,h=I[:2];M=Image.new('RGB',(w,h));P=M.load()
 for z in r(w*h):
  P[z%w,z/w]=tuple(int(sum(I[i+2]*I[i+j+3]/(1+((I[i]-z%w)**2+(I[i+1]-z/w)**2)**.5)for i in r(2,len(I),6)))for j in r(3))
 M.show()

Here's a complete test suite that runs examples A through E from the question, for both distance metrics:

from PIL import Image
def S(I,r=range):
 I=map(int,I.split());w,h=I[:2];M=Image.new('RGB',(w,h));P=M.load()
 for z in r(w*h):
  P[z%w,z/w]=tuple(int(sum(I[i+2]*I[i+j+3]/(1.+abs(I[i]-z%w)+abs(I[i+1]-z/w))for i in r(2,len(I),6)))for j in r(3))
 M.show()

def O(I,r=range):
 I=map(int,I.split());w,h=I[:2];M=Image.new('RGB',(w,h));P=M.load()
 for z in r(w*h):
  P[z%w,z/w]=tuple(int(sum(I[i+2]*I[i+j+3]/(1+((I[i]-z%w)**2+(I[i+1]-z/w)**2)**.5)for i in r(2,len(I),6)))for j in r(3))
 M.show()

A = """400 150
-10 30 100 255 128 0"""
B = """200 200
100 100 10 255 255 255
20 20 40 255 0 0
180 20 40 255 255 0
180 180 40 0 255 0
20 180 40 0 0 255"""
C = """400 400
123 231 10 206 119 85
358 316 27 170 47 99
95 317 3 202 42 78
251 269 17 142 150 153
43 120 3 145 75 61
109 376 6 230 231 52
331 78 21 31 81 126
150 330 21 8 142 23
69 155 11 142 251 199
218 335 7 183 248 241
204 237 13 112 253 34
342 89 18 140 11 123"""
D = """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"""
E = """100 1"""
for i in (A, B, C, D, E):
    S(i) #S for Star
    O(i) #O for Orb

They all look indistinguishable. The larger ones may take a few seconds to run.

\$\endgroup\$
  • \$\begingroup\$ I believe you can save a bunch of bytes by changing for x in r(I[0]):...for y in r(I[1]): by changing it to for x in r(I[0]*I[1]):. You can then take every indent level within down by 1, and replace x with x/I[1] and y with y%I[1]. \$\endgroup\$ – Kade Jul 15 '15 at 13:18
  • \$\begingroup\$ You could save 5 bytes by replacing from PIL import Image to from PIL import* \$\endgroup\$ – sagiksp Mar 31 '17 at 16:39
6
\$\begingroup\$

C, 247 bytes

Not going to win, but I like to golf in C. No external image library used, outputs to stdout in PPM format. Takes input on stdin. Uses Manhattan distance for golfiness.

j,w,h,k,*b,t[6];main(){scanf("%d %d",&w,&h);b=calloc(w*h,24);for(;~scanf("%d",t+j++%6);)for(k=0;j%6?0:k<3*w*h;k++)b[k]=fmin(b[k]+t[2]*t[3+k%3]/(abs(k/3%w-*t)+abs(k/3/w-t[1])+1),255);printf("P6\n%d %d\n255\n",w,h);for(k=0;k<3*w*h;putchar(b[k++]));}

Here's the Euclidean distance variant (257 bytes):

j,w,h,k,*b,t[6];main(){scanf("%d %d",&w,&h);b=calloc(w*h,24);for(;~scanf("%d",t+j++%6);)for(k=0;j%6?0:k<3*w*h;k++)b[k]=fmin(b[k]+t[2]*t[3+k%3]/(sqrt(pow(k/3%w-*t,2)+pow(k/3/w-t[1],2))+1),255);printf("P6\n%d %d\n255\n",w,h);for(k=0;k<3*w*h;putchar(b[k++]));}
\$\endgroup\$
6
\$\begingroup\$

CJam, 86 bytes

q~]"P3 "\_2>:T;2<_S*" 255 "@:,~\m*{(+0a3*T6/{_2<3$.-:z~+)d\2>(f*\f/.+}/:i255fe<\;S*S}/

While this may look kind of lengthy for a golfing language, I believe that of the solutions posted so far, it's the shortest that does not use image output functionality. This produces a PPM file in ASCII form. The image below was converted from PPM to PNG using GIMP.

I do not recommend to run the code in the online CJam interpreter. At least not for the full size images. My browser locked up, most likely because of the memory usage. It completes the 400x400 images in the second range with the offline version.

Example C

Explanation:

q~      Read and parse input.
]       Wrap it in an array.
"P3 "   Output start of PPM header.
\       Swap input to top.
_2>     Slice off first two values, leaving the star descriptors.
:T;     Store star descriptors in variable T.
2<      Get first two values in input, which is the image size.
_S*     Leave a copy of the size in the output for the PPM header.
" 255 " Rest of PPM header, range of color values.
@       Pop sizes to top.
:,      Expand sizes to ranges.
~       Unwrap size ranges into separate stack elements.
\       Swap ranges, since we need x-range second for Cartesian product.
m*      Generate all coordinate pairs with Cartesian product.
{       Loop over pixel coordinate pairs.
  (+      Swap values in coordinate pair to get x-coordinate first again.
  0a3*    Generate [0 0 0] array. Will be used to sum up colors from stars.
  T       Get list of stars.
  6/      Split into sub-lists with 6 values for each star.
  {       Loop over the stars.
    _2<     Get the first two values (position) of the star.
    3$      Pull current pixel coordinates to top of stack.
    .-      Subtract pixel coordinates from star position.
    :z      Absolute value of difference.
    ~+      Unpack differences and add them to get Manhattan distance.
    )d      Add 1 and convert to double to get denominator of formula.
    \       Swap star values to top.
    2>      Slice off first two values, leaving intensity and color.
    (       Pop off intensity.
    f*      Multiply it with color values.
    \       Swap denominator to top.
    f/      Perform division of color components by denominator.
    .+      Add it to sum of colors.
  }/      End loop over stars.
  :i      Convert double values for colors to integer.
  255fe<  Cap color components at 255.
  \;      Swap pixel coordinate to top and pop it.
  S*S     Join color components with space, and add another space.
}/      End loop over coordinate pairs.
\$\endgroup\$
5
\$\begingroup\$

C# 718 bytes

I realize that c# is terrible for golfing, but here's my attempt at 718 bytes

namespace System{using Collections.Generic;using Drawing;using Linq;using O=Convert;class P{int j,i;List<S> s=new List<S>();Image G(string t){var l=t.Replace("\r","").Split('\n');var w=O.ToInt32(l[0].Split(' ')[0]);var h=O.ToInt32(l[0].Split(' ')[1]);for(i=1;i < l.Length;i++){var p=l[i].Split(' ');s.Add(new S{X=O.ToInt32(p[0]),Y=O.ToInt32(p[1]),I=O.ToSingle(p[2]),R=O.ToByte(p[3]),G=O.ToByte(p[4]),B=O.ToByte(p[5])});}var b=new Bitmap(w,h);for(j=0;j<h;j++)for(i=0;i<w;i++)b.SetPixel(i,j,C());return b;}Color C(){return Color.FromArgb(X(x=>x.R),X(x=>x.G),X(x=>x.B));}int X(Func<S,float>f){return(int)Math.Min(s.Sum(x=>x.I*f(x)/(Math.Sqrt((x.X-i)*(x.X-i)+(x.Y-j)*(x.Y-j))+1)),255);}class S{public float X,Y,R,G,B,I;}}}

If anyone has any suggestions to shorten it, feel free to let me know.

\$\endgroup\$
  • \$\begingroup\$ You've missed the Color.FromArgb(int, int, int) overload. Would save 4 bytes... \$\endgroup\$ – Melvyn Jul 17 '15 at 17:45
  • \$\begingroup\$ Also, you should probably be using .Length instead of .Count(). one byte less, and more efficient. And by the way, you could save a lot more bytes by using the new expression-bodied members of C#6, if you are willing to. \$\endgroup\$ – Melvyn Jul 17 '15 at 18:15
  • \$\begingroup\$ Good points on both the length and the overload, adjusting now. And looking into the expression-bodied members. Haven't seen those before. Thanks \$\endgroup\$ – Allan Harper Jul 18 '15 at 17:58
4
\$\begingroup\$

Python, 259 bytes

Finally done! First code golf I've tried, decided to use Python and went with the Manhattan distance. Shoutout to Maltysen for helping me with the iterators, reduced the total size to almost half!

from PIL.Image import new
N,*s=[list(map(int,i.split()))for i in iter(input,'')]
q,m=new("RGB",(N[0],N[1])),[]
[m.append(tuple(sum(k[2]*k[i]//(abs(k[1]-x)+abs(k[0]-y)+1)for k in s)for i in(3,4,5)))for x in range(N[1])for y in range(N[0])]
q.show(q.putdata(m))
\$\endgroup\$
  • \$\begingroup\$ I know there must be a way to make one calculation for all of them, but I honestly don't know Python that well. \$\endgroup\$ – Nicolás Siplis Jul 15 '15 at 7:03
  • \$\begingroup\$ Let us continue this discussion in chat. \$\endgroup\$ – Maltysen Jul 15 '15 at 7:11
  • \$\begingroup\$ Your's still doesn't work properly, have to switch the k[0] and k[1] in the calculations. \$\endgroup\$ – Maltysen Jul 16 '15 at 0:08
  • \$\begingroup\$ Took me like 10 minutes to realize why it was working on my machine, turns out I did invert them but forgot to change it here. \$\endgroup\$ – Nicolás Siplis Jul 16 '15 at 0:20
2
\$\begingroup\$

CJam, 70 bytes

"P3"l_~\:W*255\,[q~]6Te]6/f{\[Wmd\]f{.-Z/~\)\~mh)/f*}:.+{i255e<}/}~]S*

Euclidean distance, ASCII PPM output. Try it online

It should be possible to squeeze a few more bytes, but I don't want to spend too much time.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.