15
\$\begingroup\$

Write a program or function that takes no input but prints or returns a constant textual depiction of a rectangle made of the 12 distinct pentominoes:

12 pentominoes

The rectangle may have any dimensions and be in any orientation, but all 12 pentominoes must be used exactly once, so it will have area 60. Each different pentomino must be composed of a different printable ASCII character (you don't need to use the letters from above).

For example, if you chose to output this 20×3 pentomino rectangle solution:

3x20 solution

Your program's output might look something like this:

00.@@@ccccF111//=---
0...@@c))FFF1//8===-
00.ttttt)))F1/8888=-

Alternatively, you might find it easier to golf this 6×10 solution:

000111
203331
203431
22 444
2   46
57 666
57769!
58779!
58899!
5889!!

Any rectangle solution will do, your program only needs to print one. (A trailing newline in the output is fine.)

This great website has loads of solutions for various rectangle dimensions and it's probably worth browsing them to make sure your solution is as short as possible. This is code-golf, the shortest answer in bytes wins.

\$\endgroup\$
6
  • 15
    \$\begingroup\$ Bonus if it's a "quine" in Piet. \$\endgroup\$
    – mbomb007
    Nov 9, 2015 at 22:57
  • \$\begingroup\$ @mbomb007 That's pretty much impossible with just 12 blocks to play with :P \$\endgroup\$
    – Sp3000
    Nov 10, 2015 at 1:51
  • \$\begingroup\$ I don't think that spaces should be allowed on the borders. But since they are, can I omit trailing spaces? Do I get a bonus if I print a vertical 5x12 solution with an I out of spaces at the end? \$\endgroup\$ Nov 10, 2015 at 10:54
  • \$\begingroup\$ @Sp3000 how about a Piet program composed entirely of pentomino rectangle solutions? \$\endgroup\$ Nov 10, 2015 at 10:56
  • \$\begingroup\$ @JanDvorak You can't omit trailing spaces if you have them. They are characters just like the rest of printable ASCII. \$\endgroup\$ Nov 10, 2015 at 10:57

7 Answers 7

5
\$\begingroup\$

CJam (44 bytes)

Given in xxd format because it contains control characters (including a raw tab, which plays really badly with MarkDown):

0000000: 2202 7e0d 8ef3 570d e085 e168 cf27 092c
0000010: a235 0c22 3235 3662 3562 332f 5f2c 2c2e
0000020: 7b32 2f27 412b 662b 7d7a 4e2a 

which decodes to something along the lines of

"MAGIC STRING"256b5b3/_,,.{2/'A+f+}zN*

Slightly ungolfed online demo which doesn't contain control characters and so plays nicely with browser URI decoding library functions.

The basic principle is that since no piece spans more than 5 rows we can encode an offset from a linear function of the row number compactly (in base 5, in fact, although I haven't tried to determine whether this would always be the case).

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

Bash + common Linux utils, 50

xxd -s20 -p -c2 $0
#<30 bytes of binary data>

To recreate this from encoded base64:

base64 -d <<< eHhkIC1zMjAgLXAgLWMyICQwCiMiImaSaZlmkDAAMwSjRKNEqoGogYhRVVF7UXu7d3s= > pent.sh

Since there are 12 pentominoes, their colours are easily encoded in hex nybbles.

Output:

$ ./pent.sh
2222
6692
6999
6690
3000
3304
a344
a344
aa81
a881
8851
5551
7b51
7bbb
777b
$ 
\$\endgroup\$
4
\$\begingroup\$

J, 49 bytes

u:64++/\|:3#.inv 1377859090 1567813024 1337683230

You can choose the letters in a way that the maximal increments between vertically adjacent letters are 2. We use this fact to encode vertical increments in base3. After that we create the running sums and add an offset to get the ASCII codes of the letters.

Definitely golfable. (I yet to find a way to input extended precision base36 numbers but simple base36 should save 3 bytes alone.)

Output:

AAA
ABA
BBB
DBC
DCC
DCC
DEE
DFE
FFE
FGE
FGG
GGH
HHH
IIH
JII
JJI
JKK
JKL
KKL
LLL

Try it online here.

\$\endgroup\$
3
  • \$\begingroup\$ Very nice. With base-256 encoding applying this difference encoding in CJam gives 33 bytes (48 byte version without b256). \$\endgroup\$ Nov 10, 2015 at 15:15
  • \$\begingroup\$ This is awesome! It would also work with the 4x15, which would work well for packing four numbers into a byte, if you store data widthways rather than lengthways. You'd need a layout that has the U pentomino facing the right way. There are plenty in the link at the question. \$\endgroup\$ Nov 10, 2015 at 23:10
  • \$\begingroup\$ @steveverrill You would need a starting offset for that because there will be more than 4 pieces starting on the first line, so you can't code those into base4. With this extra offset (e.g. 3#i.5 which is 0 0 0 1 1 1 ... 4 4 4) it can work but probably won't be shorter (at least the way I tried). \$\endgroup\$
    – randomra
    Nov 11, 2015 at 11:24
2
\$\begingroup\$

Microscript II, 66 bytes

Lets start with the simple answer.

"00.@@@ccccF111//=---\n0...@@c))FFF1//8===-\n00.ttttt)))F1/8888=-"

Hooray implicit printing.

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

Pyth, 37 bytes

jc4.HC"&f3ªªwril3:[·)ÌDU[r)ÌDA»

Demonstration

Uses a very straightforward approach: Use hex bytes as numbers. Convert to a hex number, base 256 encode that. That gives the magic string above. To decode, use Pyth's base 256 decoder function, convert to hex, split into 4 chunks, and join on newlines.

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

Ruby

Rev 3, 55bytes

i=1
'S, OJ1*$HCH(#%0'.bytes{|e|puts "%x"%i+=e*130&9011}

As a further development on Randomra's idea, consider the output and difference table below. The difference table can be compressed as before, and expanded by multiplying by 65=binary 1000001 and applying a mask 11001100110011. However, Ruby does not work predictably with 8 bit characters (it tends to interpret them as Unicode.)

Surprisingly, the last column is entirely even. Because of this, in compression we can perform a rightshift on the data. This ensures all codes are 7 bit ASCII. In expansion we simply multiply by 65*2=130 instead of 65.

The first column is also entirely even. Therefore we can add 1 to each element (32 to each byte) where necessary, to avoid any control characters. The unwanted 1 is removed by using the mask 10001100110011=9011 instead 11001100110011.

Solution 59 of document linked in question

Start0001

Out  Diff
2223 2222
2433 0210
2433 0000
4445 2012
6555 2110
6577 0022
6687 0110
6887 0200
8897 2010
aa99 2202
caa9 2010
cab9 0010
cbbb 0102
cdbd 0202
cddd 0020

Although I use 15 bytes for the table, I only really use 6 bits of each byte, which is a total of 90 bits. There are in fact only 36 possible values for each byte, which is 2.21E23 possibities in total. That would fit in 77 bits of entropy.

Rev 2, 58 bytes, using Randomra's incremental approach

i=0
'UPEIP@bPHPBETTEPRADT'.bytes{|e|puts "%x"%i+=e*65&819}

Finally, something shorter than the naive solution. Randomra's incremental approach, with the bytepacking method of Rev 1.

Rev 1, 72 bytes, golfed version of rev 0

Some changes were made to the baseline to accomodate a reordering of the code for golfing reasons, but still came in longer than the naive solution.

i=0
'UPUIYD&!)$&V*).);c+*'.bytes{|e|i+=1;puts "%x"%(i/2*273+(e*65&819))}

The offsets are encoded into each character of the magic string in base 4 in format BAC, ie with the 1's representing the righthand symbol, the 16's representing the middle symbol, and the lefthand symbol shoehorned into the 4's position. In order to extract them, the ascii code is multiplied by 65 (binary 1000001) to give BACBAC, then it is anded with 819 (binary 1100110011) to give .A.B.C.

Some of the ascii codes have the 7th bit set, i.e. they are 64 higher than the required value, to avoid control characters. Because this bit is removed by the mask 819, this is inconsequential, except when the value of C is 3, which causes a carryover. This has to be corrected in one place only (instead of g we have to use c.)

Rev 0, ungolfed version

a= %w{000 010 000 201 100 100 011 021 110 120 011 112 111 221 211 221 122 123 112 222}
i=2
a.each{|e|puts "%x"%(i/2*273+e.to_i(16));i+=1} 

Output

111
121
222
423
433
433
455
465
665
675
677
778
888
998
a99
aa9
abb
abc
bbc
ccc

Explanation

From the following solution, I subtract the baseline, giving the offset which I store as data. The baseline is regenerated as a hexadecimal number in the code by i/2*273 (273 decimal = 111 hex.)

solution   baseline   offset
AAA        AAA        000
ABA        AAA        010
BBB        BBB        000
DBC        BBB        201
DCC        CCC        100
DCC        CCC        100
DEE        DDD        011
DFE        DDD        021
FFE        EEE        110
FGE        EEE        120
FGG        FFF        011
GGH        FFF        112
HHH        GGG        111
IIH        GGG        221
JII        HHH        211
JJI        HHH        221
JKK        III        122
JKL        III        123
KKL        JJJ        112
LLL        JJJ        222
\$\endgroup\$
4
  • \$\begingroup\$ That looks like essentially the same approach as mine, but you've managed to avoid the single delta of 4 which forced me to encode in base 5. Looks like I chose the wrong labelling for the pieces. \$\endgroup\$ Nov 10, 2015 at 14:27
  • \$\begingroup\$ I saw your answer after I posted mine. I can't follow Cjam, but from what you said in your answer it's a similar approach. I actually only have a single 3 in the whole table (right near the bottom) so I think by increasing the baseline by slightly more than 0.5 every line it may actually be possible to use base 3. Feel free to try that. (For golfing reasons it seems I'm going to have to change the baseline slightly, which gives me rather more 3's, and unfortunately its looking like its going to be 1 byte longer than the naive solution in Ruby.) \$\endgroup\$ Nov 10, 2015 at 19:38
  • \$\begingroup\$ In case I wasn't clear earlier, my intention was to congratulate you on doing a better job than me, not to accuse you of copying. And I'm not going to try using a growth rate of 2.5 because I don't think it will beat randomra's difference encoding approach. \$\endgroup\$ Nov 10, 2015 at 22:33
  • \$\begingroup\$ @PeterTaylor thanks, I did get that you were congratulating me. On the other hand, you got in first with basically the same idea and made it much shorter, so congratulations to you, too. With randomra's difference approach finally I can get shorter than the naive solution. It would work well at 4x15 too (given the right pentomino layout). That's the way I'd do it in C or any other language that works well with 8.bit strings. As Ruby supports unicode, it tries to interpret 8 bit strings as unicode and can give some annoying error messages. \$\endgroup\$ Nov 10, 2015 at 23:33
0
\$\begingroup\$

Foo, 66 Bytes

"00.@@@ccccF111//=---\n0...@@c))FFF1//8===-\n00.ttttt)))F1/8888=-"
\$\endgroup\$
2
  • \$\begingroup\$ This is character-for-character identical to the Microscript II solution above... I assume these languages are related? \$\endgroup\$ Nov 10, 2015 at 14:34
  • 1
    \$\begingroup\$ @DatrelHoffman not really, foo basically just prints everything in quotes \$\endgroup\$
    – Teoc
    Nov 10, 2015 at 14:47

Your Answer

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

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