Print out the Smallest Perfect Squared Square
Mathematica 360 426
The code works by first drawing the perfect square of squares, rasterising and binarizing the image, and then converting 0 to "#" and 1 to " ".
The output is returned as ordinary ASCII characters in a table.
f@{n_,x_,y_}:=Rectangle[{x,y},{x+n,y+n}];t=Transpose;
Flatten[i=Rasterize[Graphics[{EdgeForm[{(*Thickness[.015],*)Black}],White,
f/@ Partition[{33,0,0,29,0,33,50,0,62,37,33,0,25,29,37,42,70,0,18,70,42,24,88,42,9,54,53,7,63,53,15,50,62,17,65,60,
11,82,66,19,93,66,35,50,77,27,85,85},3]
},ImageSize->70
],RasterSize->70]//Binarize//ImageData,1]/.{0:> "#",1:> " "};
GraphicsGrid@t@Most@Most@Rest@t[Most@Most[Rest[ArrayReshape[%,Dimensions[i]]]]]
I prefer this rendering, obtained by deleting Thickness[.015]
CJam, 88 84 83 bytes
'p:Ci_C*a*"2# *%!"{i_S*a*{3af.|W%z}4*1$0=C#C*f{\+}..e<{_C&{oNo}|}%}/
Test it here.
Explanation
Here is the basic idea: start with an "empty" 112x112 square. Now go through the squares in reading order (left to right, top to bottom). Add each square into the first available position. Afterwards, print all completed lines - this ensures that we only need to check the first (remaining) line to figure out where the next square goes.
The empty grid is initialised to p
s, because I needed a character with character code larger than space and #
, and because I could reuse its own character code 112
for the size of the initial grid. I made use of some of Dennis's ASCII art tricks here to fill the small squares into the grid.
'p:C e# Store the character 'p' in C.
i e# Convert to its character code 112.
_C*a* e# Generate a 112x112 array of p's.
"2# *%!" e# The 21 characters in this string correspond to the side lengths of
e# the squares in the solution in reading order.
{ e# For each character in that string...
i e# Convert to its character code (the current square's side length N).
_S*a* e# Generate an NxN array of spaces.
{ e# Run this block 4 times. Each iteration turns the leading column into #'s
e# and then rotates the square by 90 degrees.
3af.| e# For the first character in each row, take the bitwise OR with 3.
e# This turns spaces into #'s and leaves #'s unchanged.
W%z e# Reverse and transpose, which rotates by 90 degrees.
}4*
1$0= e# Copy the remaining grid and fetch the top row.
C# e# Find the index of the first 'p'.
C* e# Get a string of that many p's.
f{\+} e# Prepend this string to each row of the small square, which gives the
e# square the correct horizontal position.
..e< e# Take the pairwise minimum of the square and the remaining grid. The p's
e# prepended to the square will leave the grid unchanged, but the spaces
e# and #'s in the square will overwrite the p's in the grid.
{ e# Map this block onto each row of the grid.
_C& e# Copy the row and check if any p's are left.
{oNo}| e# If NOT, the row is complete and we print it together with a newline.
e# This also removes the row from the grid, such that the top row for
e# the next iteration will have space for the next square left.
}%
}/
Ruby, 180 bytes
Golfed version based on the ungolfed version below. We take advantage of the fact that there are typically 2 or 3 squares with the same y
coordinate for the top left corner.
The first magic string contains ASCII codes for the square sidelength+70
and y increment +40
. When encountering a square sidelength (Ascii code >67) we assume the next square is at the same y coordinate, and the x coordinate can be obtained by incrementing the current x coordinate by sidelength+2
. When encountering a y increment (Ascii code<67) we increment the y coordinate accordingly and reset the x coordinate to the figure encoded in the second magic string.
a=Array.new(112){?#*112}
x=y=1
j=9
'vg_CLW0SUO3J\,a]M*KV/T3n-Hi,e'.each_byte{|i|i>67?(s=i-70;(y..y+s-1).map{|i|a[i][x,s]=" "*s};x+=s+2):(x=')Fo_h){[~'[j-=1].ord-40;y+=i-40)}
puts a
Original version
This (completely ungolfed) solution contains 315 bytes, excluding unnecessary blank lines and indents. It simply creates an array of 112 strings of 112 #
's then replaces the insides of the squares with spaces.
$a=Array.new(112){"#"*112}
def f(x,y,s)
(y..y+s-1).map{|i|$a[i][x,s]=" "*s}
end
f(1,1,48)
f(51,1,33)
f(86,1,25)
f(86,28,6)
f(94,28,17)
f(51,36,13)
f(66,36,15)
f(83,36,9)
f(83,47,4)
f(89,47,22)
f(1,51,27)
f(30,51,23)
f(55,51,7)
f(64,53,5)
f(71,53,16)
f(55,60,14)
f(71,71,40)
f(30,76,2)
f(34,76,35)
f(1,80,31)
puts $a