91
\$\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\$
24
  • 22
    \$\begingroup\$ Were they bothering us? \$\endgroup\$ Feb 16, 2015 at 3:05
  • 7
    \$\begingroup\$ Objection: misleading title! \$\endgroup\$
    – My Name
    Feb 16, 2015 at 17:31
  • 24
    \$\begingroup\$ Will we see a Piet submission? \$\endgroup\$
    – randomra
    Feb 16, 2015 at 20:12
  • 11
    \$\begingroup\$ Not the pictures I thought we'd be generating for a 50 shades of grey contest. \$\endgroup\$
    – corsiKa
    Feb 18, 2015 at 15:54
  • 3
    \$\begingroup\$ @randomra ask and you shall receive: codegolf.stackexchange.com/questions/45736/fifty-shades-of-grey/… \$\endgroup\$
    – captncraig
    Feb 19, 2015 at 15:20

45 Answers 45

1
2
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\$
4
  • \$\begingroup\$ Those are not squares though, they’re circles. \$\endgroup\$ Feb 17, 2015 at 21:14
  • \$\begingroup\$ Better now? :)) \$\endgroup\$ Feb 17, 2015 at 22:51
  • 2
    \$\begingroup\$ ,ce=3,pc=15 gives real squares and saves a character \$\endgroup\$ Feb 18, 2015 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, 2015 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\$
4
  • \$\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\$ Feb 18, 2015 at 11:38
  • \$\begingroup\$ You're right. Worked fine on my Linux machine, but not so on Windows. Added an alternative avoiding this. \$\endgroup\$ Feb 18, 2015 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, 2015 at 18:47
  • \$\begingroup\$ I have provided a longer alternative, hope that works across platform \$\endgroup\$ Feb 18, 2015 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\$
4
  • 1
    \$\begingroup\$ So you include black as a shade of grey? \$\endgroup\$ Feb 19, 2015 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, 2015 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\$ Feb 19, 2015 at 18:41
  • \$\begingroup\$ @aditsu yeah it takes me 22 to get not black, replace UK with R1K \$\endgroup\$
    – Maltysen
    Feb 19, 2015 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\$
4
  • \$\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\$ Feb 18, 2015 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\$ Feb 19, 2015 at 15:11
  • 2
    \$\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\$ Feb 19, 2015 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\$ Feb 19, 2015 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\$
2
  • \$\begingroup\$ Thanks, @KSFT! I forgot my editor adds (and counts) a final newline automatically. \$\endgroup\$
    – Omar
    Feb 17, 2015 at 19:14
  • \$\begingroup\$ you can save a byte trivially by indenting your last line with one tab instead of two spaces \$\endgroup\$ Feb 18, 2015 at 3:25
1
\$\begingroup\$

Mathematica, 20 characters

ArrayPlot@{Range@50}

gives the following output:

ArrayPlot@{Range@50}

\$\endgroup\$
5
  • 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\$ Feb 17, 2015 at 18:53
  • \$\begingroup\$ This is a good point... \$\endgroup\$
    – Thomas
    Feb 17, 2015 at 20:22
  • \$\begingroup\$ Isn't that the same as ArrayPlot[Range@50], which is one character shorter? \$\endgroup\$
    – Omar
    Feb 17, 2015 at 21:32
  • \$\begingroup\$ @Omar No, ArrayPlot needs a 2-dim array. In your case it is 1-dim. \$\endgroup\$
    – Thomas
    Feb 17, 2015 at 21:34
  • \$\begingroup\$ Oh, sorry, I misread the first @ as @@. Ignore my comment. \$\endgroup\$
    – Omar
    Feb 17, 2015 at 21:48
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
  • 8
    \$\begingroup\$ These don't look very square to me. (in Chrome) \$\endgroup\$ Feb 17, 2015 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, 2015 at 16:47
  • 4
    \$\begingroup\$ @KSFT I see rectangles. \$\endgroup\$ Feb 17, 2015 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\$ Feb 17, 2015 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\$ Feb 17, 2015 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\$
0
\$\begingroup\$

Perl 5 + -M5.10.0, 39 bytes

Outputs PGM format.

say"P5 20 1000 50 ",map chr()x400,0..49

Try it online!

\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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