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\$ Commented Feb 16, 2015 at 3:05
  • 7
    \$\begingroup\$ Objection: misleading title! \$\endgroup\$ Commented Feb 16, 2015 at 17:31
  • 24
    \$\begingroup\$ Will we see a Piet submission? \$\endgroup\$
    – randomra
    Commented 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
    Commented 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
    Commented Feb 19, 2015 at 15:20

45 Answers 45

58
\$\begingroup\$

Mathematica, 30 bytes

Here is another Mathematica approach:

ArrayPlot[#+5#2&~Array~{5,10}]

enter image description here

or

ArrayPlot[5#+#2&~Array~{10,5}]

enter image description here

The first one simply creates an array

{{6, 11, 16, 21, 26, 31, 36, 41, 46, 51}, 
 {7, 12, 17, 22, 27, 32, 37, 42, 47, 52}, 
 {8, 13, 18, 23, 28, 33, 38, 43, 48, 53}, 
 {9, 14, 19, 24, 29, 34, 39, 44, 49, 54}, 
 {10, 15, 20, 25, 30, 35, 40, 45, 50, 55}}

and the second one

{{6, 7, 8, 9, 10},
 {11, 12, 13, 14, 15},
 {16, 17, 18, 19, 20},
 {21, 22, 23, 24, 25},
 {26, 27, 28, 29, 30},
 {31, 32, 33, 34, 35},
 {36, 37, 38, 39, 40},
 {41, 42, 43, 44, 45},
 {46, 47, 48, 49, 50},
 {51, 52, 53, 54, 55}}

Then, ArrayPlot plots them as a grid and, by default, uses greyscale to visualise the values.

\$\endgroup\$
4
  • \$\begingroup\$ Lovely use of ArrayPlot. \$\endgroup\$
    – DavidC
    Commented Feb 16, 2015 at 14:42
  • 4
    \$\begingroup\$ That's funny, MatrixPlot seems to use colors by default, it's lucky for this challenge that ArrayPlot uses grayscale and it is one letter shorter than MatrixPlot. \$\endgroup\$
    – Omar
    Commented Feb 16, 2015 at 15:00
  • \$\begingroup\$ You could do ArrayPlot@{Range@50}, which is only 20 bytes. \$\endgroup\$
    – Greg Hurst
    Commented Sep 8, 2015 at 19:43
  • \$\begingroup\$ @ChipHurst when I do that, the default size is too small to meet the 20x20 pixels requirement. \$\endgroup\$ Commented Sep 8, 2015 at 20:17
36
\$\begingroup\$

CJam - 23 (no actual graphical output)

Since CJam can't draw on the screen (yet?), I wrote a program that outputs an image in plain pgm format.
Save the output to a file called 50.pgm and open with an image viewer/editor.

"P2"1e3K51_,1>K*$K*~]N*

Try it online

The result looks like this:

50.png

Explanation:

"P2"     push "P2" (netpbm magic number)
1e3K     push 1000 and K=20 (image size)
51       push 51 (value of white)
_,       duplicate 51 and convert to an array [0 1 2 ... 50]
1>       remove 0 (slice from 1)
K*       repeat the array 20 times
$        sort, to get [(20 1's) (20 2's) ... (20 50's)]
K*       repeat the array 20 times
~        dump the elements on the stack
]        put everything from the stack in an array
N*       join with newlines
\$\endgroup\$
6
  • 3
    \$\begingroup\$ So being happy increments the elements!? \$\endgroup\$
    – Caridorc
    Commented Feb 16, 2015 at 20:11
  • 7
    \$\begingroup\$ @Caridorc of arrays containing numbers, yes. And being sad decrements them :p \$\endgroup\$ Commented Feb 16, 2015 at 21:05
  • \$\begingroup\$ You don't follow the PGM's specification: No line should be longer than 70 characters. \$\endgroup\$
    – kiwixz
    Commented Feb 19, 2015 at 1:39
  • \$\begingroup\$ @iKiWiXz updated \$\endgroup\$ Commented Feb 19, 2015 at 6:47
  • 2
    \$\begingroup\$ @iKiWiXz Should, not must. Lines may be longer than that but programs that generate PGM images should try to keep them under 70 characters. \$\endgroup\$
    – FUZxxl
    Commented Feb 19, 2015 at 10:47
30
\$\begingroup\$

Mathematica 72 61 59 43 35 34 bytes

Current version (34 bytes)

GrayLevel[#/50]~Style~50 &~Array~50    

grid2


Earlier version (59 bytes), thanks to Martin Büttner.

Graphics[{GrayLevel[#/50],Cuboid@{#~Mod~9,#/9}}&/@Range@50]

Blue borders added to highlight position of squares.

Graphics[{EdgeForm[Blue], GrayLevel[#/50], Cuboid@{#~Mod~9, #/9}} & /@Range@50]

blue

Number of squares:

    Length[%[[1]]]

50


First attempt (72 bytes)

If the squares can overlap. As Zgarb notes, there is a remote possibility that one square would hide another.

  Graphics@Table[{GrayLevel@k,Cuboid[{0,15}~RandomReal~2]},{k,.4,.89,.01}]

enter image description here

\$\endgroup\$
2
  • \$\begingroup\$ I'm guessing that one square could in principle cover another completely, so that less than 50 would be visible? \$\endgroup\$
    – Zgarb
    Commented Feb 16, 2015 at 12:29
  • 2
    \$\begingroup\$ Definitely the most esthetically pleasing answer. \$\endgroup\$
    – Dan
    Commented Feb 17, 2015 at 14:08
29
\$\begingroup\$

Sage - 26 24 35 29 characters

matrix(5,10,range(50)).plot()

It looks like this:

5x10 shades of grey

Previous attempts: First I had Matrix([range(50)]).plot(), then matrix_plot([range(50)]). These looked like this:

50 shades of grey

User @flawr pointed out that the squares produced with default settings are too small. Adding a figsize options fixes it, but it is 6 characters longer than the 5x10 version at the top of this answer:

matrix_plot([range(50)],figsize=20)
\$\endgroup\$
5
  • \$\begingroup\$ Looks like 51 shades and the squares look smaller than 20x20px, is it bigger when produced by your program? \$\endgroup\$
    – flawr
    Commented Feb 16, 2015 at 13:50
  • \$\begingroup\$ I don't think extra output is forbidden, @flawr, I didn't bother removing the frame, tickmarks and numbers either. You might be right about the squares being too small, I'll check. \$\endgroup\$
    – Omar
    Commented Feb 16, 2015 at 14:48
  • \$\begingroup\$ Argh! @flawr is right the squares are smaller than 20px by 20px. \$\endgroup\$
    – Omar
    Commented Feb 16, 2015 at 15:04
  • \$\begingroup\$ I would say extra output should be forbidden. The question specifies '50', not '50 or more'. \$\endgroup\$
    – Joe
    Commented Feb 16, 2015 at 18:16
  • 1
    \$\begingroup\$ Am I understanding correctly, @Joe, that you don't object to the frame and the numbers outside the frame, only to the number of squares? If that's the case, just replace 50 with 49. \$\endgroup\$
    – Omar
    Commented Feb 16, 2015 at 18:26
25
\$\begingroup\$

MATLAB, 24 bytes

Second attempt, now actually conforming to the rules.

imshow(0:1/49:1,'I',2e3)

The 'I' stands for 'InitialMagnification', but apparently Matlab will autocomplete names in name/value pairs. Sure is a good golfing trick!

enter image description here

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

R, 47 42 39 38 37 36 35 bytes

Assuming they're allowed to overlap, this works. Symbols requires a vector that holds the size for each square, and I'm saving space by reusing the same vector for all function parameters. The largest square is always 1 inch wide. With 50:99 as the range of integers, the smallest square will be around half an inch wide, so 36 pixels at 72 dpi.

symbols(x,,,x<-50:99,bg=gray(x/99))

Thanks to everyone for the comments and suggestions, I'm pretty new to R so this is all very educational.

new and improved?

Previous versions:

symbols(x,sq=x<-50:99,bg=gray(x/99))            #36
x=50:99;symbols(x,sq=x,bg=gray(x/99))           #37
x<-50:99;symbols(x,sq=x,bg=gray(x/99))          #38
x<-1:50;symbols(x,sq=x/x,bg=gray(x/50))         #39
x<-1:50/50;symbols(x,sq=x/x,bg=rgb(x,x,x))      #42
x<-1:50/50;symbols(x,squares=x/x,bg=rgb(x,x,x)) #47

Previous image: 50 shades of R

\$\endgroup\$
7
  • \$\begingroup\$ Could save a few more with symbols(x<-50:99,sq=x,bg=gray(x/99)) \$\endgroup\$
    – MickyT
    Commented Feb 16, 2015 at 19:03
  • \$\begingroup\$ Minus two! Thanks @MickyT, I thought it was done already. \$\endgroup\$
    – freekvd
    Commented Feb 16, 2015 at 19:19
  • 1
    \$\begingroup\$ @freekvd It does in general, it depends on the order in which the arguments are accessed inside the function (since arguments are lazily evaluated). You can test this by having f = function (a, b) { a; b} and then calling f(x <- 5, x). This works as expected. Once you reverse the arguments in f’s definition (and rm(x)), it doesn’t work any more. \$\endgroup\$ Commented Feb 17, 2015 at 15:40
  • 1
    \$\begingroup\$ Looks like evaluation starts at sq=x, so I can trim off another char with this. Thanks @KonradRudolph \$\endgroup\$
    – freekvd
    Commented Feb 17, 2015 at 16:13
  • 1
    \$\begingroup\$ Cut down by 1 byte symbols(x,,,x<-50:99,bg=gray(x/99)) \$\endgroup\$
    – Vlo
    Commented Feb 17, 2015 at 20:04
21
\$\begingroup\$

Java - 180

Pretty straightforward, just drawing boxes.

import java.awt.*;void f(){new Frame(){public void paint(Graphics g){for(int i=1;i<51;g.setColor(new Color(328965*i)),g.fillRect(i%8*20,i++/8*20,20,20))setSize(600,600);}}.show();}

enter image description here

With line breaks:

import java.awt.*;
    void f(){
        new Frame(){
            public void paint(Graphics g){
                for(int i=1;
                    i<51;
                    g.setColor(new Color(328965*i)),
                    g.fillRect(i%8*20,i++/8*20,20,20))
                    setSize(600,600);
            }
        }.show();
    }
\$\endgroup\$
11
  • \$\begingroup\$ If anyone objects to the last box being technically white, just change the color multiplier to 263172. Same byte count, I just think it looks better this way. \$\endgroup\$
    – Geobits
    Commented Feb 16, 2015 at 2:40
  • \$\begingroup\$ I think you could also use int i; instead of int i=1 but then use ++i on the first use of i instead of i++ in the last occurence, would save 2 bytes. BTW: I didn't even know you can make a java program without class MyClass ... public static void main(...!!! \$\endgroup\$
    – flawr
    Commented Feb 16, 2015 at 14:18
  • \$\begingroup\$ @flawr Nah, Java won't initialize local variables to default values. It might work if I moved it outside the function. If I was giving a full program instead, I'd try it that way (this is just a function, plus the necessary import). Thanks, though :) \$\endgroup\$
    – Geobits
    Commented Feb 16, 2015 at 14:28
  • 2
    \$\begingroup\$ @flawr If it was a full program then yes, you'd need that. This is just a function, since the question doesn't specify. \$\endgroup\$
    – Geobits
    Commented Feb 16, 2015 at 14:36
  • 1
    \$\begingroup\$ @AJMansfield I know, but I consider Processing a different language, and I like to golf in Java Java. \$\endgroup\$
    – Geobits
    Commented Feb 16, 2015 at 17:58
17
\$\begingroup\$

BBC BASIC, 57

FORn=51TO2STEP-1VDU19;-1,n,n,n:RECTANGLEFILL0,0,n*20NEXT

The squares have to be at least 20 pixels but there's nothing to say they have to be the same size, so I guess this qualifies.

It may be possible to shorten this by using more low-level VDU codes. But changing from this pattern to a less interesting one is unlikely to make it shorter.

enter image description here

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Remember your BBC Basic abbreviations? F.,N.,S.,V. -> F.n=51TO2S.-1V.19;-1,n,n,n:RECTANGLEFILL0,0,n*20N. \$\endgroup\$
    – SeanC
    Commented Feb 17, 2015 at 23:29
  • \$\begingroup\$ @SeanCheshire bbcbasic.co.uk/bbcwin/bbcwin.html does support those abbreviations, I never thought to check! Your way counts as 50. The tokenised filesize is 41 bytes (each keyword tokenisied to a single byte outside the ASCII range) though I don't often count that way. I will use your tip in future though! \$\endgroup\$ Commented Feb 17, 2015 at 23:59
17
\$\begingroup\$

ipython 2, 54 bytes

The best I could do was with an ipython program. Starting ipython with ipython -pylab and executing this program will show a graph with 50 shades of grey in 50 squares:

t=arange(50);c=t/50.;scatter(t%5,t,500,zip(c,c,c),'s')

Output:

grey50

Solution 2:

Here is another program (61 bytes):

imshow(arange(50).reshape(5,10)*.02,'Greys',None,1,'nearest')

that displays the following window:

grey50b

\$\endgroup\$
1
  • 1
    \$\begingroup\$ However note that ipython is not a language and what you used is Python library matplotlib, which is an external lib. \$\endgroup\$ Commented Feb 20, 2015 at 13:14
15
\$\begingroup\$

JavaScript (72, 70, 67 bytes)

72: original (borrowing the clever &#9632; usage from Sphinxxx's answer):

for(i=90;i>40;)document.write('<font color=#'+i+i+i--+' size=7>&#9632;')

70: stealing shamelessly from Ismael Miguel (who deserves the votes), a shorter for loop and allowing the browser to correct for a lack of # proceeding the colour code...

for(i=60;--i>9;)document.write('<font color='+i+i+i+' size=7>&#9632;')

67 bytes (65 chars): swapping the entity for the unicode character:

for(i=60;--i>9;)document.write('<font color='+i+i+i+' size=7>■')

\$\endgroup\$
15
  • \$\begingroup\$ I think you should start at i=51. If I counted correctly, there are only 49 squares? \$\endgroup\$
    – flawr
    Commented Feb 16, 2015 at 14:02
  • 1
    \$\begingroup\$ I really like your answer! Dear lord, why I didn't though about it? +1 on this one! I would reduce this one to for(i=0;i++<50;)document.write('<font color=#'+i+i+i+' size=7>&#9632;') or similar. Untested but it might work! \$\endgroup\$ Commented Feb 16, 2015 at 15:25
  • 1
    \$\begingroup\$ Since you are stealing from me, at least steal properly. Remove the # character to have a 70-byte long solution. \$\endgroup\$ Commented Feb 18, 2015 at 12:02
  • 1
    \$\begingroup\$ I was just about to recommend that. The default is counting bytes, but you should use the Unicode character because it is still fewer bytes. \$\endgroup\$ Commented Feb 18, 2015 at 14:42
  • 1
    \$\begingroup\$ Did the question say exactly 50 squares? :) (The other solutions also draw extra stuff.) With that and the unicode literal, down to 65 bytes (63 chars): for(i=90;i;)document.write('<font color=#'+i+i+i--+' size=7>■') - BUT at least on my browser's default settings (OSX/Chrome) the box is a bit smaller than 20x20 pixels anyway, so these ■ based solutions are questionable. \$\endgroup\$
    – tuomassalo
    Commented Feb 19, 2015 at 13:44
13
\$\begingroup\$

C++, 98 83 characters

Okay so, you are going to need a terminal emulator that supports true colors. For mac os there are the nightly builds of iTerm2, for example. For unix I believe konsole supports it. Here's a list, just in case: https://gist.github.com/XVilka/8346728#now-supporting-truecolor

Compile with g++ (\e is compiler dependent).

For the squares to have enough area, you will have to change your terminal font size.

#include <cstdio>
int main(){for(int i=51;i--;)printf("\e[48;2;%i;%i;%im ",i,i,i);}

Using C libraries instead of C++ allows for shaving some characters.

C, 61 58 characters

This is the same program but in C, which assumes untyped function declarations to return int, and which doesn't need includes for some of the standard library functions, like in this case, printf. Suggested by @cartographer. Three characters less thanks to @user3601420

main(i){for(i=51;i--;)printf("\e[48;2;%i;%i;%im ",i,i,i);}

Compiles with a couple of warnings (for assuming main's return type to be int and for implicitly including the declaration of printf).

\$\endgroup\$
5
  • 2
    \$\begingroup\$ If you switch this to C you can drop the include and the int in front of main and have it compile with just a couple of warnings with gcc. \$\endgroup\$ Commented Feb 17, 2015 at 0:55
  • \$\begingroup\$ Yes, but that would be another language. Anyway, I'll append it, thank you! \$\endgroup\$
    – ror3d
    Commented Feb 17, 2015 at 8:42
  • 1
    \$\begingroup\$ You can remove a few characters from the C version if you make i the first argument to main, as in: main(i){for(i=51;i--;)printf(... \$\endgroup\$
    – Functino
    Commented Feb 17, 2015 at 20:44
  • \$\begingroup\$ Only one additional character to make it standard: \e\33 \$\endgroup\$
    – Holger
    Commented Feb 19, 2015 at 12:45
  • \$\begingroup\$ This is code-golf! \$\endgroup\$
    – ror3d
    Commented Feb 20, 2015 at 21:38
11
\$\begingroup\$

J (43 41 40 38 33 29 characters)

After suggestions from randomra.

1!:2&4'P2 ',":(,*:,],*:#?~)50

This solution does not display anything as the standard library of J does not contain GUI routines. Instead, I generate an image and write it to standard output. The output is randomized, it ensured that all shades are distinct. Here is a some sample output and the image converted to png and rotated by 90° for easier viewing:

50 shades of gray

\$\endgroup\$
4
  • \$\begingroup\$ Pushing the 50 from the header into the generated part using 50*50 squares saves 1 byte: 1!:2&4'P2 50 2500 ',":(,*:#i.)50. \$\endgroup\$
    – randomra
    Commented Feb 16, 2015 at 15:59
  • \$\begingroup\$ That's a neat idea. \$\endgroup\$
    – FUZxxl
    Commented Feb 16, 2015 at 16:03
  • \$\begingroup\$ Even more: push all numbers in 1!:2&4'P2 ',":(,*:,],*:#i.)50 for 29 chars! Btw plot isn't part of the standard J library? \$\endgroup\$
    – randomra
    Commented Feb 16, 2015 at 16:05
  • \$\begingroup\$ @randomra plot is one of the auxiliary packages you can download from the package manager. I would hardly see it as a part of the standard library. \$\endgroup\$
    – FUZxxl
    Commented Feb 16, 2015 at 16:10
11
\$\begingroup\$

Piet- 2*103 = 206

This is unique in that the source code and the output fulfill the challenge:

piet

Most of it is decorative, so I only counted the top two rows, which stand alone just fine. Outputs a grayscale ppm like some others have done.

\$\endgroup\$
10
\$\begingroup\$

Python 2, 125 115 104 bytes

from turtle import*
shape("square")
bk(500)
ht()
pu()
exec'color((xcor()/2e3+.5,)*3);stamp();fd(21);'*50

Sample output:

enter image description here

Good old turtle. This was the only method I could think of in Python which prints images to a screen using only the standard libraries.

The square turtle shape just happens to be 21 by 21, which is very convenient. This can be seen by digging through turtle.py:

"square" : Shape("polygon", ((10,-10), (10,10), (-10,10), (-10,-10)))

If you have a high res monitor or don't mind a few squares being off-screen, then this is 93 bytes:

from turtle import*
shape("square")
ht()
pu()
exec'color((xcor()/2e3,)*3);stamp();fd(21);'*50

Demo

(This demo uses Skulpt by adapting the snippet found here. It is only included to give an idea as to what the code does — I had to modify a few bits to get it working.)

function out(a){var b=document.getElementById("output");b.innerHTML+=a}function builtinRead(a){if(void 0===Sk.builtinFiles||void 0===Sk.builtinFiles.files[a])throw"File not found: '"+a+"'";return Sk.builtinFiles.files[a]}
$(document).ready(function run(){Sk.canvas="canvas";Sk.configure({output:out,read:builtinRead});try{Sk.importMainWithBody("<stdin>",!1,'import turtle\nt=turtle.Turtle()\nt.speed(9)\nt.shape("square")\n\nt.bk(500)\nt.ht()\nt.pu()\nfor i in range(50):t.color(64+2*i,64+2*i,64+2*i);t.stamp();t.fd(21)')}catch(a){throw Error(a.toString());}})
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script><script src="http://www.skulpt.org/static/skulpt.min.js" type="text/javascript"></script><script src="http://www.skulpt.org/static/skulpt-stdlib.js" type="text/javascript"></script>
<canvas height="100" width="1200" id="canvas" style="border:1px solid gray">Your browser does not support HTML5 Canvas!</canvas>

\$\endgroup\$
1
  • \$\begingroup\$ Ah I see how you realised skulpt has updated. Thanks for this, I will probably use it to update the snippet. \$\endgroup\$
    – ArtOfCode
    Commented Feb 19, 2015 at 1:18
10
\$\begingroup\$

Excel vba, 81

In the immediate window:

for i=1 to 9:for j=1 to 9:k=i+j*10:cells(i,j).interior.color=rgb(k,k,k):next:next

on the active sheet:

81 shades is just as much code as 50

{81 shades is just as much code as 50}

\$\endgroup\$
6
  • \$\begingroup\$ Well, some people are interpreting the "50" to mean exactly 50. In that case, it's probably one more character to get 50=10*5 than it is to get 81=9*9. \$\endgroup\$
    – Omar
    Commented Feb 17, 2015 at 17:41
  • \$\begingroup\$ @Omar, 0 to 9 and 1 to 5 will produce exactly 50 in the same number of characters.... This also means I can write the sequel too, in the same number of bytes - 0 to 9 twice \$\endgroup\$
    – SeanC
    Commented Feb 17, 2015 at 23:22
  • 1
    \$\begingroup\$ Oh, 0 to 9! I thought that for the cells(i,j) you needed i>0 and j>0. \$\endgroup\$
    – Omar
    Commented Feb 18, 2015 at 4:27
  • \$\begingroup\$ @Omar, damn, you're right. I couldn't use zero \$\endgroup\$
    – SeanC
    Commented Feb 18, 2015 at 14:03
  • 1
    \$\begingroup\$ Slightly shorter (61) For i=1 To 50:Cells(i,1).Interior.Color=RGB(i*5,i*5,i*5):Next \$\endgroup\$ Commented Feb 18, 2015 at 17:22
8
\$\begingroup\$

R, 37 32 characters1:

image(t(1:50),c=gray.colors(50))

However, the display for this looks … meh (image rotated 90° to fit better into text; compressed, original square side length > 20px):

boring

Here’s a nicer version which plots the squares in random order inside a matrix (50 characters):

image(matrix(sample(1:50),10),c=gray.colors(50))

exciting!

(And yes, the three adjacent squares of seemingly identical colours are actually three different shades of grey.)

1 Yes, another R answer, and not even the shortest (now the shortest for R) – apologies. I was missing a pretty rendering in R.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ How did you fix the aspect ratio? \$\endgroup\$ Commented Feb 17, 2015 at 19:38
  • \$\begingroup\$ ? Basically the same as second version @ 37 image(matrix(1:50,5),c=gray(1:50/51)) \$\endgroup\$
    – Vlo
    Commented Feb 17, 2015 at 20:18
  • \$\begingroup\$ @koekenbakker It’s not fixed, I’m manually adjusting the output window. It’s not perfect but the code does produce squares for a given window, and other code here has comparable issues. \$\endgroup\$ Commented Feb 17, 2015 at 21:09
8
\$\begingroup\$

Matlab 35 thanks to sanchises

imshow(int8(ones(20,1)*(0:.05:51)))

Matlab 36

imshow(uint8(ones(20,1)*(0:.05:51)))

Displays 50 squares filled with gray values 1 to 50 and 2 additional rectangles filled with gray value 0 and 51:

enter image description here

Matlab, 45

imshow(uint8(ones(20,1)*floor(1:0.05:50.95)))
\$\endgroup\$
5
  • \$\begingroup\$ You can shave off a whopping 1 byte by using int8 instead of uint8. \$\endgroup\$
    – Sanchises
    Commented Feb 19, 2015 at 18:05
  • \$\begingroup\$ sanchises's solution is better! \$\endgroup\$
    – Memming
    Commented Feb 21, 2015 at 15:37
  • \$\begingroup\$ @Memming It does hinge on some obscure (undocumented?) feature that I only found out by trying it out for the heck of it. Give Steffen credit were it's due :) \$\endgroup\$
    – Sanchises
    Commented Feb 25, 2015 at 19:23
  • \$\begingroup\$ @TheBestOne / JaBe: Your answer actually doesn't work since it does not display squares. Steffen uses int8 to round the 1000 or so values to 50 squares. \$\endgroup\$
    – Sanchises
    Commented Feb 26, 2015 at 11:51
  • \$\begingroup\$ you can actually get rid of most of this, imshow(int8(1:50)) works just as well. if you want the greys to look equidistant you can do imshow(uint8((0:4^8/50:4^8).^.5)) \$\endgroup\$
    – guest4308
    Commented Jul 15 at 17:07
7
\$\begingroup\$

JavaScript, 87 90 bytes

for(i=90;i>40;)document.write('<p style=background:#'+i+i+i--+';height:9ex;width:9ex>')

This outputs squares to the HTML, because it is really JavaScript's only method of graphical output. Thanks to edc65 for shaving off 3 bytes.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Save 3 bytes: for(i=90;i>40;)document.write('<p style=background:#'+i+i+i--+';height:9ex;width:9ex>'). Can't use single digits because grays would not be unique (#111 same color as #111111) \$\endgroup\$
    – edc65
    Commented Feb 16, 2015 at 7:49
  • \$\begingroup\$ You can use other units. 1cm or 19mm would be better and more widely supported. Without changing your byte count. \$\endgroup\$ Commented Feb 18, 2015 at 12:03
7
\$\begingroup\$

PHP, 96 88 74 bytes

Thanks to Ismael Miguel for saving 22 bytes!

for($i=60;--$i>9;)echo"<p style=background:#$i$i$i;height:9mm;width:9mm>";

Writes 50 <p>s with 9mm as height and width (which should be bigger than 20px on the majority of screens), stacked on each other, all with a minor difference in shade.

Generated result (the image is zoomed out and 90° rotated):

Result

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

Matlab - 33 bytes

surf(meshgrid(1:7)),colormap gray

Despite the verbose commands, the result is still quite compact. It looks a bit better if you replace surf with surface but that costs 3 chars.

If you don't notice the 50th gray square that is because it is a bit bigger than the others!

\$\endgroup\$
1
  • \$\begingroup\$ Use ndgrid! (2 bytes less). And, is each square a different gray? \$\endgroup\$
    – Luis Mendo
    Commented Feb 22, 2015 at 21:04
7
\$\begingroup\$

Javascript (77 71 bytes):

This answer is no longer IE11 based. It works because the browser converts the bad color codes into usable ones (by adding # to the number).

Here is the code:

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

Firefox still has the quirk of making circles.

(Small edit: Changed for(i=61;i-->9;) to for(i=59;i-->9;) because it was producing 52 squares)


Old answer:

This is based on my PHP answer, and uses almost the same ways to make the squares:

for(i=51;i--;)document.write("<hr color=rgb("+[i,i,i]+") size=20 width=20>");

Not the shortest answer, but it's worth adding here.


This solution isn't compatible with Chrome (produces multiple green colors) and Firefox (same result, but produces circles? o.O WTH?)

Since this is code-golf, a solution working with a specific version or a specific software is acceptable.

\$\endgroup\$
15
  • 2
    \$\begingroup\$ It might just be me, but running this code snippet produces mostly green and blue circles. I see @MartinBüttner beat me to this comment so it's not just me... \$\endgroup\$
    – MrLemon
    Commented Feb 16, 2015 at 14:43
  • \$\begingroup\$ @MrLemon I guess chrome doesn't like RGB -.- But it does work on IE11. Since I'm not trying to make a cross-browser solution, this is acceptable. I will add this to the answer. \$\endgroup\$ Commented Feb 16, 2015 at 15:06
  • \$\begingroup\$ @IsmaelMiguel That's alright I guess. But just for clarity, I'm on FF right now. Can confirm it working on IE11 though. \$\endgroup\$
    – MrLemon
    Commented Feb 16, 2015 at 15:09
  • \$\begingroup\$ @MrLemon It works on IE11, since I tried at home. I can provide print-screen if required. Firefox makes circles with it. I have no f#$%ing idea how. There is no way to revert it. I was expecting IE to have the quirks, not Firefox. \$\endgroup\$ Commented Feb 16, 2015 at 15:10
  • \$\begingroup\$ Firefox seems to put half-circles on the ends of <hr>, probably to make it look more smooth. No clue as to what happens with the colors. Anyway have my +1 for baffling me. \$\endgroup\$
    – MrLemon
    Commented Feb 16, 2015 at 15:17
6
\$\begingroup\$

JavaScript - 70 bytes

for(i=51;i-=1;)document.write('<a style=opacity:'+i/50+'>&#9632;</a>')

\$\endgroup\$
7
  • 6
    \$\begingroup\$ The box size is smaller than 20 pixel \$\endgroup\$
    – edc65
    Commented Feb 16, 2015 at 7:29
  • 1
    \$\begingroup\$ Then you need to adjust your browser's font size ;) \$\endgroup\$
    – Sphinxxx
    Commented Feb 16, 2015 at 9:22
  • 1
    \$\begingroup\$ You have to use font:3em a or font-size:3em. I'm downvoting this one due to the size of the boxes. Until you fix. \$\endgroup\$ Commented Feb 16, 2015 at 9:37
  • 3
    \$\begingroup\$ You can use i-- instead of i-=1. \$\endgroup\$
    – flawr
    Commented Feb 16, 2015 at 14:05
  • 1
    \$\begingroup\$ You can use the <b> tag. It won't change the code in any way, except ensuring that the text will be black. This isn't a requirement, but it might be a good idea. \$\endgroup\$ Commented Feb 16, 2015 at 15:44
6
\$\begingroup\$

Processing, 66 characters:

size(1000,20);for(int i=0;i<981;i+=20){fill(i/4);rect(i,0,20,20);}

gray shades in Processing

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

PHP (62 60 63 72 71 62 59 bytes):

I've made the shortest I could find:

for($i=59;$i-->9;)echo"<hr color=$i$i$i size=20 width=20>";

This is exactly the same code as my Javascript answer (with 71 bytes).

But SO MUCH shorter!

This have a quirk in Firefox: instead of squares, Firefox makes circles! (Go insanity!)
Othen than that, all the browsers produce the right color (even with the missing # on the color attribute).


Invalid submits and changelog:

Old answer, with 62 bytes.

while($i++<51)echo"<hr color=rgb($i,$i,$i) size=20 width=20>";

All shades are perfectly aligned.

This solution won't work for Chrome (will produce squares with multiple colors) and Firefox (which makes circles o.O Yes, circles with <hr>! Horizontal ruler is a circle on Firefox!).
You can test it on IE11 and it should be fine.


(simply removed from above)

I've noticed something awful: It was outputting #111 instead of #010101 for some colors.

This meant that some colors were repeating.

Therefore, I had to sacrifice a few bytes:

<?while(f>$c=dechex(65-$i++))echo"<hr color=#$c$c$c size=20 width=20>";

Outputs the 50 shades in perfect order, from lighter to darker.

Due to a correct point made by @edc65, I had to add width=20, to produce perfect squares.

Reduced one more byte by replacing f!=$c with f>$c, which works perfectly.


Final version, without width=20:

<?while(f!=$c=dechex(65-$i++))echo"<hr color=#$c$c$c size=20>";

This is invalid because it is required to output squares.
This outputs the shades from lighter to darker.


Reduced 1 byte by switching to a while loop, like this:

<?while($c=dechex(50-$i++))echo"<hr color=#$c$c$c size=20>";

First solution:

<?for($i=50;$c=dechex($i--);)echo"<hr color=#$c$c$c size=20>";

This doesn't have the shades neatly ordered, but there are 50 different ones.

There is nothing stating that they must be ordered, but there is a requirement on size.

I hope I can reduce it a lot more.

You can test it on http://writecodeonline.com/php/ (click on "Display as HTML").

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

PostScript, 34 bytes

In ISO-Latin-1 encoding:

20’›‡üˆì0{’81e3’6’–10’k0ˆ                   (note, this is a Line Feed)
’c’§}’H

This is the binary equivalent to:

20 setlinewidth 1020 -20 0 { dup 1e3 div setgray 10 moveto 0 10 lineto stroke } for

(This assumes that you are using it on a device that is at least 1000 points [= 10 inches = 25.4 cm] wide.)

\$\endgroup\$
4
  • \$\begingroup\$ Give us a series of hex encoded octets (ie: 0f 4e 75 a3 ...). \$\endgroup\$ Commented Feb 16, 2015 at 16:29
  • \$\begingroup\$ @haneefmubarak I will, I just need to get home so I can use my golfer program. (The online postscript compactor doesn't ever seem to work.) \$\endgroup\$ Commented Feb 16, 2015 at 16:38
  • \$\begingroup\$ @haneefmubarak OK, updated with a direct representation of the file, although its not the hex octets. (I'll add that later once I can use the real converter program.) \$\endgroup\$ Commented Feb 16, 2015 at 17:54
  • \$\begingroup\$ A bit shorter: 1020 -20 0{dup 1e3 div setgray 10 20 20 rectfill}for which compresses down to 27 bytes (87fc0388ec307b923831653392369296880a8814323092807d9248 according to xxd -ps). \$\endgroup\$ Commented Apr 27, 2022 at 16:11
5
\$\begingroup\$

CSS (87 chars)

Uses animation ;)

:after{content:'\25A0';font:9em z;animation:g 8s steps(50)}@keyframes g{to{color:#fff}}

The runnable version is longer since Webkit still needs the vendor prefix. :(

:after{content:'\25A0';font:9em z;-webkit-animation:g 8s steps(50);animation:g 8s steps(50)}@-webkit-keyframes g{to{color:#fff}}@keyframes g{to{color:#fff}}

If we're allowed a random, empty <a> element, we can get it down to just 72 characters:

a{padding:3em;animation:g 8s steps(50)}@keyframes g{to{background:#000}}

See? CSS is a legit programming language!

\$\endgroup\$
4
\$\begingroup\$

R, 36 bytes

I can make freekvd's answer shorter trivially.

x=9:59/59;symbols(x,sq=x,bg=gray(x))

Output

(Sorry for not making a comment under his solution. Stackexchange does not allow me to make comments, vote etc yet).

\$\endgroup\$
3
  • \$\begingroup\$ Doesn't this produce 51 squares? \$\endgroup\$
    – MickyT
    Commented Feb 16, 2015 at 19:16
  • \$\begingroup\$ This makes the smallest square less than 20 pixels wide? It depends on your dpi, but the largest square is 1 inch so a 72 dpi image will have a smalllest square of 11 pixels. \$\endgroup\$
    – freekvd
    Commented Feb 17, 2015 at 5:48
  • \$\begingroup\$ Though if you make it 1:99 you could argue that the 50 largest squares meet the criteria. \$\endgroup\$
    – freekvd
    Commented Feb 17, 2015 at 5:50
4
\$\begingroup\$

DrRacket - 83

Just for the sake of firing up DrRacket 1 year after "Introduction to Systematic Program Design".

EDIT:

(require htdp/image)(map(λ(i)(rectangle 50 50'solid(make-color i i i)))(range 50))
\$\endgroup\$
2
  • \$\begingroup\$ Save a couple of characters: switch from 2htdp/image to htdp/image, change the string "solid" to the symbol 'solid. For bigger savings, change the (range 9 209 4) to (range 50): the shades of grey are just required to be distinct, not easy to tell apart for the human eye! \$\endgroup\$
    – Omar
    Commented Feb 17, 2015 at 17:38
  • \$\begingroup\$ You can save a few characters using for/set: (require htdp/image)(for/set([i 50])(rectangle 50 50'solid(make-color i i i))) \$\endgroup\$ Commented Feb 22, 2015 at 10:31
4
\$\begingroup\$

C# - 173

Using LINQPAD

var b=new Bitmap(1000,20);var g=Graphics.FromImage(b);for(int i=0;i<50;i++)g.FillRectangle(new SolidBrush(Color.FromArgb(i*5,i*5,i*5)),new Rectangle(i*20,0,20,20));b.Dump();

Expanded:

var b = new Bitmap(1000, 20);
var g = Graphics.FromImage(b);
for (int i = 0; i < 50; i++)
    g.FillRectangle(new SolidBrush(Color.FromArgb(i * 5, i * 5, i * 5)), new Rectangle(i * 20, 0, 20, 20));
b.Dump();

Output:

output

\$\endgroup\$
2
  • \$\begingroup\$ Suggestion: for(int i=0;i<250;i+=5) and then FromArgb(i,i,i) and Rectangle(i*4,0,20,20) gives 168 \$\endgroup\$ Commented Mar 5, 2015 at 23:05
  • \$\begingroup\$ Furthermore, FillRectangle() has an overload which takes the rectangle coordinates directly, so you can remove the new Rectangle() and get away with 153 \$\endgroup\$ Commented Mar 5, 2015 at 23:07
4
\$\begingroup\$

JavaScript, 152 bytes.

Okay, so maybe this isn't the best solution but here is mine.

function b(a){c=document
e=c.createElement('p')
with(e.style){background="rgb("+[a,a,a]+")"
width=height="20px"}c.body.appendChild(e)
a<245&&b(a+5)}b(0)

Here is the output with css float left (just so it is easier to count the squares) and without:

with css float

without css float

\$\endgroup\$
11
  • 2
    \$\begingroup\$ You can save some bytes by using one-letter variable names, dropping all var keywords and removing unnecessary whitespace. Also, please include the language name and the byte count in your answer. \$\endgroup\$
    – ProgramFOX
    Commented Feb 18, 2015 at 19:11
  • \$\begingroup\$ Thanks for the input. I reduced white space and added byte count but I'm not sure what you mean by dropping the var keywords. \$\endgroup\$ Commented Feb 18, 2015 at 19:28
  • \$\begingroup\$ Never mind. I feel dumb. \$\endgroup\$ Commented Feb 18, 2015 at 19:29
  • \$\begingroup\$ Use c+=5 instead of c=c+5. Also, you can save 2 chars by putting n=c.toString() at the end of the previous line, and then that line at the end of the previous line again. So your 2nd line would be function w(){if(c<250){n=c.toString() \$\endgroup\$
    – mbomb007
    Commented Feb 20, 2015 at 22:42
  • \$\begingroup\$ Also, I'm pretty sure you can omit px for the height and width. \$\endgroup\$
    – mbomb007
    Commented Feb 20, 2015 at 22:44

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.