92
\$\begingroup\$

Boys and girls are excited to see Fifty Shades of Grey on the silver screen, we just want to code without being bothered, so here's a challenge to pick our brain.

You have to:

  • Print on the screen fifty squares filled each with a different shade of grey
  • If your language of choice lacks image processing capabilities, you could output an image file
  • Squares must be visible, at least 20 x 20 pixels
  • You cannot use random numbers unless you make sure each shade is unique.
  • You cannot connect to any service over any network
  • You cannot read any files in your program.
  • You cannot use any libraries out of the standard libraries of your language of choice.

This is code golf so shortest code wins.

\$\endgroup\$

45 Answers 45

3
\$\begingroup\$

R 45 42 characters

New version, after some comments (thanks!):

plot(1:50%%5,col=gray(1:50/60),ce=5,pc=15)

enter image description here

Old version

It generates an error, but works fine :)

plot(x<-1:50,x%%5,col=gray(x/60),lw=30,pc=22)

enter image description here

\$\endgroup\$
  • \$\begingroup\$ Those are not squares though, they’re circles. \$\endgroup\$ – Konrad Rudolph Feb 17 '15 at 21:14
  • \$\begingroup\$ Better now? :)) \$\endgroup\$ – bartektartanus Feb 17 '15 at 22:51
  • 2
    \$\begingroup\$ ,ce=3,pc=15 gives real squares and saves a character \$\endgroup\$ – koekenbakker Feb 18 '15 at 8:39
  • 2
    \$\begingroup\$ You can shorten it further by replacing x<-1:50,x%%5 with 1:50%%5 and gray(x/60) with gray(1:50/60). Also, it seems to work with co instead of col. \$\endgroup\$ – freekvd Feb 18 '15 at 9:39
3
\$\begingroup\$

R - 35 characters

Barplot uses gray.colors by default, helpful to save some bytes. To make sure the size is sufficient regardless of the screen size, the window size has to be defined beforehand, with x and y size picked as to generate a 1:1 aspect ratio.

x11(,1.7,23);barplot(matrix(1,50))

Output, rotated 90° and sized down:

enter image description here

As per comments below, the x11() results vary between machines. Hence, a safer option - also forcing aspect ratio of 1 - is dev.new. Run from terminal:

dev.new(height=20);barplot(matrix(1,50),as=1) 

That's 46 characters. If manual resizing is allowed, barplot(matrix(1,50),as=1) is enough - only 27 characters.

\$\endgroup\$
  • \$\begingroup\$ The x11 doesn’t actually yield reliable results. On my OS X the code doesn’t produce squares anyway. Just remove it. As far as I’m concerned, barplot(matrix(1,50)) is the shortest valid R code so far. 21 characters. It’s just a shame that rep(1,50) doesn’t work in place of matrix; t(t(rep(1,50)) does, but it’s longer. \$\endgroup\$ – Konrad Rudolph Feb 18 '15 at 11:38
  • \$\begingroup\$ You're right. Worked fine on my Linux machine, but not so on Windows. Added an alternative avoiding this. \$\endgroup\$ – koekenbakker Feb 18 '15 at 12:08
  • \$\begingroup\$ xcode-select: note: no developer tools were found at '/Applications/Xcode.app', requesting install. Choose an option in the dialog to download the command line developer tools. Error in x11(h = 20) : X11 module cannot be loaded. I can't use this on OSX :( \$\endgroup\$ – freekvd Feb 18 '15 at 18:47
  • \$\begingroup\$ I have provided a longer alternative, hope that works across platform \$\endgroup\$ – koekenbakker Feb 18 '15 at 20:53
3
\$\begingroup\$

Pyth - 23 21 bytes

Is similar to CJam solution. Outputs is PGM format, save output as foo.pgm and view here. Edited it to make it conform to PGM specs so that lines are less than 70 chars long, in fact they are only one pixel long.

K50"P2"*KKKKVKjbS*UKK

Generates: Is fifty fifty by fifty squares. Goes from black to 49/50 of the way to white.

K50             K=50
"P2"            Prints P2 or pgm header magic #
*KK             Prints the length: 50*50
K               Prints width: 50
K               Prints value of white: 50
V         K     Do 50 times to make height of square 50
 j              joins by
  b             linebreaks
   S            Sort to bring out make each shade consecutive
    *  K        Times 50 to make length 50
     UK         Unary range 50 (0-49)
\$\endgroup\$
  • 1
    \$\begingroup\$ So you include black as a shade of grey? \$\endgroup\$ – aditsu Feb 19 '15 at 6:51
  • \$\begingroup\$ @aditsu is that not allowed? The only reason I didn't include white was because range(50) only goes up to 49. \$\endgroup\$ – Maltysen Feb 19 '15 at 17:34
  • \$\begingroup\$ I'm not sure, but I excluded it. Otherwise I can also get 21 bytes. I guess I should ask... \$\endgroup\$ – aditsu Feb 19 '15 at 18:41
  • \$\begingroup\$ @aditsu yeah it takes me 22 to get not black, replace UK with R1K \$\endgroup\$ – Maltysen Feb 19 '15 at 23:21
3
\$\begingroup\$

C++ Win32: 141 chars and 171 chars

C++ 171 chars

#include"stdafx.h"#include<windows.h>int _tmain(){HDC h=GetDC(0);for(int i=0;i<50;i++){SelectObject(h,CreatePen(0,9,RGB(64+i,64+i,64)));Rectangle(h,i*9,i*9,i*9+9,i*9+9);}}

This draws 50 grey boxes to your desktop.

Which is super long, but pretty good for actually drawing squares in C++. I doesn't think I was ever going to win/not-come-last but I'm pretty satisfied with this. I can't guarantee the whole pixel thing as I use coordinates, but IWOMM :D.

I don't know if win32 counts as a standard library of c++, but I was more interested in the win32 than the c++ tbh. I had a crack at GDI, which look prettier but is super verbose. I was hoping I could get a win32 ColorChooser and turn them all grey for instant victory, but alas no.

Here's the idea (I've removed the resource leak from this extended version):

#include "stdafx.h"
#include <windows.h>
int _tmain(int a, _TCHAR* b[])
{
   HDC h=GetWindowDC(GetDesktopWindow()); //Zero works for GetDesktopWindow() as  Konrad Rudolph points out. GetDC is a good as GetWindowDC.
   for (int i = 0; i < 50; i++){
       HPEN p = CreatePen(PS_COSMETIC, 9, RGB(64 + i, 64 + i, 64)); //PS_COSMETIC is 0
       SelectObject(h, p); MoveToEx(h, 0, 0, NULL); //We can get away with removing MoveToEx and assuming it starts in the top left
       Rectangle(h, i * 9, i * 9, i * 9 + 9, i * 9 + 9); DeleteObject(p);
   }
   DeleteDC(h); //Or was it releaseDC? Who cares. The golf'd code leaks it anyway.
}

enter image description here

Also this can happen. When you want to get rid of it you just 'wipe' it away with another window. You would also not believe how slow this is to execute. Output

Konrad Rudolph's comment: C++ 141

// stdafx.h isn’t needed.
// However, we DO need the line break after the include,
// even in the golf version.
#include <windows.h>
// _tmain => main; VC++ accepts both.
int main()
{
   HDC h = GetDC(0);
  // Remove i++ here …
  for (int i = 0; i < 50;){
  // 65793 == 0x010101; multiplying with 1…50 generates
  // grey tones and is much shorter than RGB macro use
  SelectObject(h, CreatePen(0, 9, i*65793));
  // i * 9 + 9 == i * 10
  // … add i++ here.
  Rectangle(h, i * 9, i * 9, i * 10, i++ * 10);
  }
}

short.cpp

#include <windows.h>
int main(){HDC h=GetDC(0);for(int i=0;i<50;){SelectObject(h,CreatePen(0,9,i*65793));Rectangle(h,i*9,i*9,i*10,i++*10);}}
//141 with the line break
\$\endgroup\$
  • \$\begingroup\$ I vaguely remember that it sometimes worked to use 0 instead of the Desktop DC (or was it the hWND?). However, that’s definitely not kosher and it might not work any more (it never worked reliably, as far as I remember). \$\endgroup\$ – Konrad Rudolph Feb 18 '15 at 11:30
  • \$\begingroup\$ @KonradRudolph Good trick. Apparently in WinUser.h it defines: #define HWND_DESKTOP ((HWND)0) and MapWindowPoints doco seems to suggest HWND_DESKTOP and NULL are both kosher. However, obviously outside of golfing using 0 would be horrible. Also, I've just noticed GetDCis just as good as GetWindowDC \$\endgroup\$ – Nathan Cooper Feb 19 '15 at 15:11
  • 1
    \$\begingroup\$ You can make this much shorter actually. Since it’s too much for a comment, I’ve created a gist with the changes: gist.github.com/klmr/864a87d25c048736a11f – Result: 140 characters. There’s probably more room for improvement if you accept different colours/positions, by choosing colours and positions so that fewer computations are necessary. But then, according to the rules the squares probably shouldn’t overlap and be larger. \$\endgroup\$ – Konrad Rudolph Feb 19 '15 at 15:37
  • 1
    \$\begingroup\$ Okay. Wow. (You could tweet that now). Good stuff, thanks for the link. Thinking back, I should have seen that having macros probably means that the code isn't effectively golfed. I hope you don't mind if I add an attributed section. \$\endgroup\$ – Nathan Cooper Feb 19 '15 at 15:55
3
\$\begingroup\$

HTML/CSS - 81 characters

This is a very borderline solution because the shades aren't displayed very accurately (Chrome and Firefox both just use dithering), but in theory it "should" display 50 distinct shades. Also, the code is probably not very W3C compliant, but it compiles on any browser that knows CSS3.

<div style="height:1000px;width:20px;background:linear-gradient(#000,#303030);"/>

Note that 0x30 is 50 and 1000 is 50*20.

\$\endgroup\$
3
\$\begingroup\$

C (73 65 characters)

Outputs a binary PGM to stdout, 20x20 squares.

s;main(){puts("P5 1000 20 50");while(s<2e4)putchar(s++%1000/20);}

Moar tricks would have been possible with 2^n instead of 50 shades, but nevermind.

\$\endgroup\$
2
\$\begingroup\$

CoffeeScript, 86 bytes

As per edc56's comment on the JavaScript solution:

i=90;document.write '<p style=background:#'+i+i+i--+';height:1em;width:1em>'while i>40
\$\endgroup\$
2
\$\begingroup\$

Python 2, 78 characters

This prints an image in PGM format to standard output (I took the idea from aditsu's CJam answer):

print"P2 2500 50 51"
r=range(50)
for x in r:
 for y in r:
  for z in r:print y

I wish Python would let me put all 3 fors on the same line. At least it lets me use a single space (or single tab) for each indentation level. I tried using variants of for t in itertools.product(r,r,r) instead, but the import is long and kills the benefit.

\$\endgroup\$
  • \$\begingroup\$ Thanks, @KSFT! I forgot my editor adds (and counts) a final newline automatically. \$\endgroup\$ – Omar Feb 17 '15 at 19:14
  • \$\begingroup\$ you can save a byte trivially by indenting your last line with one tab instead of two spaces \$\endgroup\$ – undergroundmonorail Feb 18 '15 at 3:25
1
\$\begingroup\$

Mathematica, 20 characters

ArrayPlot@{Range@50}

gives the following output:

ArrayPlot@{Range@50}

\$\endgroup\$
  • 2
    \$\begingroup\$ I deliberately did not post this, because you need to scale up the result manually in order to make the squares 20 pixels on a side. The default size is much smaller than that. \$\endgroup\$ – Martin Ender Feb 17 '15 at 18:53
  • \$\begingroup\$ This is a good point... \$\endgroup\$ – Thomas Feb 17 '15 at 20:22
  • \$\begingroup\$ Isn't that the same as ArrayPlot[Range@50], which is one character shorter? \$\endgroup\$ – Omar Feb 17 '15 at 21:32
  • \$\begingroup\$ @Omar No, ArrayPlot needs a 2-dim array. In your case it is 1-dim. \$\endgroup\$ – Thomas Feb 17 '15 at 21:34
  • \$\begingroup\$ Oh, sorry, I misread the first @ as @@. Ignore my comment. \$\endgroup\$ – Omar Feb 17 '15 at 21:48
1
\$\begingroup\$

enter image description here

A basic javaScript code is given by:

<script>
"use strict";
var Div=null;
window.onload=function ()
{
 Div=document.getElementsByTagName("div")[0];
 var c=150,n=0,p=null;
 do {
     p=document.createElement("p");
     p.style.backgroundColor="rgb(" + c + "," + c + "," + c + ")";
     Div.appendChild(p);
     if ( ++n<50 ) c+=2; else break;
 } while ( true );
};
</script>
\$\endgroup\$
  • 5
    \$\begingroup\$ Welcome to the site. You should make some attempt to actually golf your answer (that means make it as short as possible). After you are done with that, tack on a header like #HTML - X Characters where X is the length of your code, including newlines and other whitespace. Lettercount.com works fine if you wrote your code in ASCII (which you did). Read the tag wiki for code-golf for a better explanation. Check out the other answers to get an idea of what yours should look like. \$\endgroup\$ – Rainbolt Feb 18 '15 at 2:08
  • \$\begingroup\$ @Rainbolt Thanks. I'll check it by following your advice. \$\endgroup\$ – Felix Marin Feb 18 '15 at 2:09
  • 1
    \$\begingroup\$ The question asks to output squares, but from your image it looks like you output rectangles. \$\endgroup\$ – ProgramFOX Feb 18 '15 at 7:18
  • \$\begingroup\$ @ProgramFOX Thanks. Maybe I didn't read it carefully. I'll check everything a little bit later. \$\endgroup\$ – Felix Marin Feb 19 '15 at 20:29
1
\$\begingroup\$

Haskell 133

import Data.List
r=replicate 20
f 0=""
f i=(f(i-1))++(concat$r$'\n':(intercalate " "$r$show i))
main=putStr $"P2\n20 1000\n50"++f 50

outputs in Netpbm Format to stdout

\$\endgroup\$
1
\$\begingroup\$

FFmpeg, 61 bytes

ffplay -f lavfi color=s=1000x20,format=y8,geq=8+4*trunc(X/20)

enter image description here

\$\endgroup\$
0
\$\begingroup\$

Javascript (60 char)

for(i=51;i--;)document.write("<hr color="+i+i+i+" size=20>")

\$\endgroup\$
  • 8
    \$\begingroup\$ These don't look very square to me. (in Chrome) \$\endgroup\$ – Martin Ender Feb 17 '15 at 10:04
  • 2
    \$\begingroup\$ @MartinBüttner There are definitely squares. There are just also round parts. There's no rule against extra output. \$\endgroup\$ – KSFT Feb 17 '15 at 16:47
  • 4
    \$\begingroup\$ @KSFT I see rectangles. \$\endgroup\$ – Martin Ender Feb 17 '15 at 16:49
  • 1
    \$\begingroup\$ @KSFT I think this falls under this standard loophole. The question asks for 50 squares, not for squares embedded in arbitrary shapes. \$\endgroup\$ – Martin Ender Feb 17 '15 at 18:58
  • 2
    \$\begingroup\$ @KSFT I didn't say they shouldn't be. But still, IMHO, just printing arbitrary shapes and saying there's a square in there is a lot more cheating than printing 50 squares, and also plotting axes or something like that. \$\endgroup\$ – Martin Ender Feb 17 '15 at 19:04
0
\$\begingroup\$

Python, 72 bytes

print'P2 1000 20 50 '+20*(''.join([20*(str(x)+' ')for x in range(50)]))

Another PPM answer, usage:

python golf_grey.py > grey.ppm
\$\endgroup\$
0
\$\begingroup\$

Excel VBA, 60 Bytes

Anonymous VBE immediate window function that takes no input and outputs to the range [A1:A50] on the ActiveSheet object

For i=1To 50:j=5*i:Cells(i,1).Interior.Color=RGB(j,j,j):Next
\$\endgroup\$

protected by Community Feb 19 '15 at 10:41

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

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