# Binary Numbers Magic Trick

The challenge is simply; output the following six 2D integer arrays:

[[ 1, 11, 21, 31, 41, 51],
[ 3, 13, 23, 33, 43, 53],
[ 5, 15, 25, 35, 45, 55],
[ 7, 17, 27, 37, 47, 57],
[ 9, 19, 29, 39, 49, 59]]

[[ 2, 11, 22, 31, 42, 51],
[ 3, 14, 23, 34, 43, 54],
[ 6, 15, 26, 35, 46, 55],
[ 7, 18, 27, 38, 47, 58],
[10, 19, 30, 39, 50, 59]]

[[ 4, 13, 22, 31, 44, 53],
[ 5, 14, 23, 36, 45, 54],
[ 6, 15, 28, 37, 46, 55],
[ 7, 20, 29, 38, 47, 60],
[12, 21, 30, 39, 52]]

[[ 8, 13, 26, 31, 44, 57],
[ 9, 14, 27, 40, 45, 58],
[10, 15, 28, 41, 46, 59],
[11, 24, 29, 42, 47, 60],
[12, 25, 30, 43, 56]]

[[16, 21, 26, 31, 52, 57],
[17, 22, 27, 48, 53, 58],
[18, 23, 28, 49, 54, 59],
[19, 24, 29, 50, 55, 60],
[20, 25, 30, 51, 56]]

[[32, 37, 42, 47, 52, 57],
[33, 38, 43, 48, 53, 58],
[34, 39, 44, 49, 54, 59],
[35, 40, 45, 50, 55, 60],
[36, 41, 46, 51, 56]]


What are these 2D integer arrays? These are the numbers used in a magic trick with cards containing these numbers:

The magic trick asks someone to think of a number in the range [1, 60], and give the one performing the magic trick all the cards which contain this number. The one performing the magic trick can then sum the top-left numbers (all a power of 2) of the given cards to get to the number the person was thinking of. Some additional explanation of why this works can be found here.

## Challenge rules:

• You can output the six 2D integer arrays in any reasonable format. Can be printed with delimiters; can be a 3D integer array containing the six 2D integer arrays; can be a string-list of lines; etc.
• You are allowed to fill the bottom right position of the last four cards with a negative value in the range [-60, -1] or character '*' instead of leaving it out to make the 2D integer arrays rectangular matrices (no, you are not allowed to fill them with 0 or a non-integer like null/undefined as alternative, with the exception of * since a star is also used in the actual cards).
• The order of the numbers in the matrices is mandatory. Although it doesn't matter for the physical magic trick, I see this challenge mainly as a - one, hence the restriction on order.
The order of the matrices themselves in the output list can be in any order, since it's clear from the top-left card which matrix is which.

## General rules:

• This is , so shortest answer in bytes wins.
Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
• Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
• Default Loopholes are forbidden.
• Related. (As in, it's referring to the same magic trick, but not really useful to get inspiration from for this challenge I think. That challenge asks to output a truthy/falsey value whether number n appears on the k'th card; where my challenge is a KC-challenge to output the six matrices.) – Kevin Cruijssen Apr 27 '19 at 8:29
• @DigitalTrauma Hm, I'm not so sure if this is really a duplicate, because your challenge is ascii-art (not tagged as such, but it is), while this one allows you to output the array in a way more lenient format (not just four essentially identical ways). I can't vote to reopen, though, because I have a hammer. – Erik the Outgolfer Apr 27 '19 at 17:58
• @EriktheOutgolfer Woops.. Forgot I have a hammer as well >.> Sometimes being able to close/open hammer is pretty annoying.. It had 2 votes already though, so with yours and mine in addition there were 4 open votes. But if someone wants to close it again I don't mind. They are indeed very similar, although his challenge is indeed an [ascii-art] challenge with strict (MD5) output rules, where mine are very flexible (and the rows/columns are swapped, and range is [1,60] instead of [1,63]; pretty minor differences, but still). – Kevin Cruijssen Apr 27 '19 at 18:02
• Looks like you didn't try to VTRO with an attitude of "this is my precious challenge!!!" at least... :P – Erik the Outgolfer Apr 27 '19 at 18:10
• I too forgot about the hammer. I still think this is close enough to vote to dup, though I'll defer to the wisdom of the community if it is reopened. – Digital Trauma Apr 27 '19 at 21:08

# MATL, 12 11 bytes

-1 byte thanks to the master himself:)

60:B"@fQ6eq


Explanation:

60:           % create a vector [1,2,3,...,60]
B          % convert to binary matrix (each row corresponds to one number)
"         % loop over the columns and execute following commands:
@f       % "find" all the nonzero entries and list their indices
Q      % increment everything
6e    % reshape and pad with a zero at the end
q   % decrement (reverts the increment and makes a -1 out of the zero
% close loop (]) implicitly
% display the entries implicitly


Try it online!

# Perl 6, 63 46 bytes

say grep(*+&2**$_,^61)[$_,*+5...*for ^5]for ^6


Try it online!

Outputs as 2D arrays on multiple lines, with the last array of each one cut off if necessary.

# Python 2, 76 bytes

r=range;print[[[i for i in r(61)if i&2**k][j::5]for j in r(5)]for k in r(6)]


Try it online!

The method here is to create a list of all possible numbers r(61) and then whittle that down to the list of numbers for a card i&2**k.

Then, by using list slicing, that 1D list of numbers is rearranged to the correct 6x5 card size [card nums][j::5]for j in r(5).

Then, this generator is just repeated for 6 cards for k in r(6).

While I could not find any solutions less than 76 bytes, here are two others that are also 76 bytes:

r=range;print[[[i for i in r(61)if i&1<<k][j::5]for j in r(5)]for k in r(6)]


Try it online!

This next one is inspired by Jonathan Allan.

k=32
while k:print[[i for i in range(61)if i&k][j::5]for j in range(5)];k/=2


Try it online!

# Charcoal, 26 bytes

Ｅ⁶Ｅ⁵⪫Ｅ⁶§⁺§⪪Φ⁶¹＆πＸ²ι⁵ν⟦*⟧λ


Try it online! Link is to verbose version of code. I tried calculating the entries directly but this was already 27 bytes before adjusting for the * in the bottom right. Outputs each row joined with spaces and a blank line between cards. Explanation:

Ｅ⁶                          Loop over 6 cards
Ｅ⁵                        Loop over 5 rows
Ｅ⁶                     Loop over 6 columns
Φ⁶¹              Filter over 0..60 where
π            Current value
＆             Bitwise And
²          Literal 2
Ｘ           Raised to power
ι         Card index
⪪        ⁵        Split into groups of 5
§          ν       Indexed by column
⁺                   Concatenated with
*     Literal string *
⟦ ⟧    Wrapped in an array
§                λ   Indexed by row
⪫                       Joined with spaces
Implicitly print

• I added that rule about * for fun after I saw the stars on the actual cards. Was wondering if there would be any languages using it, but I'm glad to see at least one did. :) Nice answer! – Kevin Cruijssen Apr 27 '19 at 10:44
• @KevinCruijssen Charcoal doesn't have a transpose operator, and the golfiest transpose requires a rectangular array of known size, so I need to add something to make up the size, and * is at least as short as anything else would be. – Neil Apr 27 '19 at 13:19
• I don't think this is 26 bytes... – Tvde1 Apr 29 '19 at 11:57
• @Tvde1 Charcoal, like many of the esolangs on this site, uses a custom code page. Characters from that page cost 1 byte, while other characters cost up to 4 bytes. – Neil Apr 29 '19 at 12:16

# 05AB1E, 16 bytes

60L2вíƶ0ζε0K5ô®ζ


Try it online!

Explanation

60L                 # push [1 ... 60]
2в               # convert each to a list of binary digits
í              # reverse each
ƶ             # multiply each by its 1-based index
0ζ           # transpose with 0 as filler
ε          # apply to each list
0K        # remove zeroes
5ô      # split into groups of 5
®ζ    # zip using -1 as filler


# 05AB1E, 17 bytes

6F60ÝNoôāÈÏ˜5ô®ζ,


Try it online!

Explanation

6F                  # for N in [0 ... 5] do
60Ý               # push [0 ... 60]
Noô            # split into groups of 2^N numbers
āÈÏ         # keep every other group
˜        # flatten
5ô      # split into groups of 5
®ζ    # transpose with -1 as filler
,   # print


# Husk, 13 bytes

ṠMöTC5Wnünḣ60


Try it online!

## Explanation

          ḣ60  Range [1..60]
ü      Uniquify using equality predicate
n     bitwise AND: [1,2,4,8,16,32]
M             For each number x in this list,
Ṡ     W        take the indices of elements of [1..60]
n       that have nonzero bitwise AND with x,
C5         cut that list into chunks of length 5
öT           and transpose it.


# Python 2, 828078 74 bytes

i=1
exec"print zip(*zip(*[(n for n in range(61)+[-1]if n&i)]*5));i*=2;"*6


Try it online!

-4 bytes, thanks to Jonathan Allan

# Japt, 14 bytes

6Æ60õ f&2pX)ó5


Try it

6Æ              Create a range from 0 to 5 (inclusive) and map each X into
60õ             Elements in the range [1..60]
f             Where
&2pX)          The number bitwise AND with X is not 0
ó5              Split into 5 arrays, where each array contains every 5th element

-Q flag is just for formatting purposes


# JavaScript (ES6),  90  88 bytes

_=>[1,2,4,8,16,32].map(n=>(g=i=>i<60?g(++i,i&n?m[y%5]=[...m[y++%5]||[],i]:0):m)(y=m=[]))


Try it online!

### Commented

_ =>                        // anonymous function taking no argument
[1, 2, 4, 8, 16, 32]      // list of powers of 2, from 2**0 to 2**5
.map(n =>                 // for each entry n in this list:
( g = i =>              //   g = recursive function taking a counter i
i < 60 ?              //     if i is less than 60:
g(                  //       recursive call:
++i,              //         increment i
i & n ?           //         if a bitwise AND between i and n is non-zero:
m[y % 5] =      //           update m[y % 5]:
[ ...m[y++ % 5] //             prepend all previous values; increment y
|| [],        //             or prepend nothing if it was undefined so far
i             //             append i
]               //           end of update
:                 //         else:
0               //           do nothing
)                   //       end of recursive call
:                     //     else:
m                   //       return m[]
)(y = m = [])           //   initial call to g with i = y = m = []
//   (i and y being coerced to 0)
)                         // end of map()


# Python 2, 73 bytes

Inspiration taken from both TFeld's and The Matt's.

k=32
while k:print zip(*zip(*[(i for i in range(61)+[-1]if i&k)]*5));k/=2


Try it online!

# C (gcc), 95 bytes

i,j,k;f(int o[][5][6]){for(i=6;i;)for(o[--i][4][5]=j=k=-1;j<60;)++j&1<<i?o[i][++k%5][k/5]=j:0;}


Try it online!

Returns the matrices as a 3D int array in o.

The last 4 matrices have -1 as their last value.

Saved 2 bytes thanks to Kevin Cruijssen.

Saved 7 8 bytes thanks to Arnauld.

• You can save 2 bytes by changing o[i][4][5]=-1;for(j=k=0; to for(o[i][4][5]=-1,j=k=0; so the brackets can be removed. Nice answer btw, +1 from me. – Kevin Cruijssen Apr 27 '19 at 10:05
• 95 bytes – Arnauld Apr 27 '19 at 11:16
• (Note that I'm not 100% sure if passing a 3D array already allocated with the correct dimensions is allowed. But I'll let regular C golfers provide a better insight about that.) – Arnauld Apr 27 '19 at 11:20
• @Arnauld I was thinking about that, but decided against it. – Matej Mulej Apr 27 '19 at 11:28
• better to leave out #include to show that it works without it – ASCII-only Apr 28 '19 at 0:09

## CJam (18 bytes)

6{61{2A#&},5/zp}fA


Online demo. This is a full program which outputs to stdout.

### Dissection

6{             }fA    # for A = 0 to 5
61{2A#&},           #   filter [0,61) by whether bit 2^A is set
5/z        #   break into chunks of 5 and transpose to get 5 lists
p       #   print


# Jelly, 13 bytes

60&ƇⱮs€5LÐṂZ€


A niladic Link which yields a list of (6) lists of lists of integers. (It outputs the using the default option of having no * or negative filler.)

Try it online!

### How?

Each matrix contains, in column-major order, the numbers up to $$\60\$$ which share the single set-bit with the top-left (minimal) number.

This program first makes all $$\60\$$ possible ordered lists of numbers in $$\[1,60]\$$ which share any set-bit(s) with their index number. It then splits each into chunks of $$\5\$$ and keeps only those with minimal length - which will be the ones where the index has only a single set-bit (and hence also being its minimal value). Finally it transposes each to put them into column-major order.

60&ƇⱮs€5LÐṂZ€ - Link: no arguments
60            - set the left argument to 60
Ɱ         - map across ([1..60]) with:  (i.e. [f(60,x) for x in [1..60]])
Ƈ          -   filter keep if:  (N.B. 0 is falsey, while non-zeros are truthy)
&           -     bitwise AND
€       - for each:
s 5      -   split into chunks of five
ÐṂ   - keep those with minimal:
L     -   length
Z€ - transpose each


Lots of 15s without realising the "minimal by length when split into fives" trick:

5Ż2*Ɱ60&ƇⱮs€5Z€
6µ’2*60&Ƈ)s€5Z€
60&ƇⱮLÞḣ6s€5Z€


...and, while attempting to find shorter, I got another 13 without needing the trick at all:

60B€Uz0Ts5ZƊ€


# Wolfram Language (Mathematica), 88 bytes

Transpose@Partition[#~Append~-1,5]&/@Last@Reap[Sow[,NumberExpand[,2]]~Do~{,60},Except@0]

• I took the liberty of adding a TIO link (based on @J42161217's answer). +1 from me. – Kevin Cruijssen Apr 27 '19 at 12:32
• – Mr. Xcoder Apr 27 '19 at 16:48
• @Mr.Xcoder Thanks. I've used this ~ trick in one more place and replaced the variable k by Null. Sorry, no time to add a tio link. – Bruno Le Floch May 7 '19 at 6:58

# Wolfram Language (Mathematica), 99 bytes

Transpose@Partition[#~FromDigits~2&/@Last@GatherBy[{0,1}~Tuples~6,#[[-k]]&],5]~Table~{k,6}/. 61->-1


Try it online!

• You can save a few char by: doing Transpose@ instead of Transpose[...]; padding to 30 entries before partitioning; using Table[...,{k,6}] to avoid needing k=#. – Bruno Le Floch Apr 27 '19 at 11:29
• @Bruno Le Floch Table may save one byte. Did you try transpose@? Because it doesn't work if you watch carefully. I'm afk but will golf later – J42161217 Apr 27 '19 at 11:37
• Sorry, Transpose@ works after you move PadRight inside Partition. Another comment is that the question does not seem to allow "" for the placeholder; you can replace it by -1 without losing any byte. – Bruno Le Floch Apr 27 '19 at 11:43

# Jelly, 13 bytes

60B€Uz0µTs5Z)


Try it online!

Loosely based on flawr’s MATL answer. A niladic link which outputs a list of lists as required.

# R, 73 bytes

!=as.raw;lapply(0:5,function(i)matrix(c((a=1:60)[(!a&!2^i)>0],-1),5,6))


I am not entirely sure if I have met the requirement for order, since R by default fills matrices by column, so the order such that it appears physically on the cards is the same as the way matrices are allocated in R.

Try it online!

• The output looks good. And if R fills matrices by columns before row instead of row before column like almost all other languages, it just means it's a good programming language to use for this challenge I guess. :) – Kevin Cruijssen Apr 29 '19 at 17:23

# T-SQL, (1,168 1,139 bytes)

I just wanted to know I could do it.

Optimised version

 WITH g AS(SELECT 1 AS n UNION ALL SELECT n+1 FROM g WHERE n+1<61),B as(SELECT cast(cast(n&32 as bit)as CHAR(1))+cast(cast(n&16 as bit)as CHAR(1))+cast(cast(n&8 as bit)as CHAR(1))+cast(cast(n&4 as bit)as CHAR(1))+cast(cast(n&2 as bit)as CHAR(1))+cast(cast(n&1 as bit)as CHAR(1))as b FROM g),P as(SELECT * from (values(1), (2), (4), (8), (16), (32)) as Q(p)),S as(select distinct p,p+(substring(b,6,1)*1)*(case when p=1 then 0 else 1 end)+(substring(b,5,1)*2)*(case when p=2 then 0 else 1 end)+(substring(b,4,1)*4)*(case when p=4 then 0 else 1 end)+(substring(b,3,1)*8)*(case when p=8 then 0 else 1 end)+(substring(b,2,1)*16)*(case when p=16 then 0 else 1 end)+(substring(b,1,1)*32)*(case when p=32 then 0 else 1 end)as e from P cross apply B),D as(select * from S where e>=p and e<61),R as(select p,(row_number()over(partition by p order by cast(e as int)))%5 as r,e from D),H as(select k.p,'['+stuff((select','+cast(l.e as varchar)from R l where l.p=k.p and l.r=k.r for xml path('')),1,1,'')+']'as s from R k group by k.p,k.r)select stuff((select','+cast(x.s as varchar)from H x where x.p=z.p for xml path('')),1,1,'')from H z group by z.p


Online demo

Try it online!

Verbose version - with notes as SQL comments

WITH gen -- numbers 1 to 60
AS (
SELECT 1 AS num
UNION ALL
SELECT num+1 FROM gen WHERE num+1<=60
),
BINARIES -- string representations of binaries 000001 through 111111
as (
SELECT
+cast( cast(num & 32 as bit) as CHAR(1))
+cast( cast(num & 16 as bit)  as CHAR(1))
+cast( cast(num & 8 as bit)  as CHAR(1))
+cast( cast(num & 4 as bit)  as CHAR(1))
+cast( cast(num & 2 as bit)   as CHAR(1))
+cast(cast(num & 1 as bit)  as CHAR(1)) as binry FROM gen
),
POWERS -- first 6 powers of 2
as (
SELECT * from (values(1), (2), (4), (8), (16), (32)) as Q(powr)
),
SETELEMENTS -- cross apply the six powers of 2 against the binaries
-- returns 2 cols. col 1 = the power of 2 in question.
-- col 2 is calculated as that power of 2 plus the sum of each power of 2 other than the current row's power value,
-- but only where a given power of 2 is switched "on" in the binary string,
-- ie. where the first digit in the string represents 32, the second represents 16 and so on.
-- That is, if the binary is 100100 then the number will be
-- the sum of (32 x 1) + (16 x 0) + (8 x 0) + (4 x 1) + (2 x 0) + (1 x 0)
-- but if the current row's power is 32 or 4, then just that number (32 or 4) is excluded from the sum.
-- rows are distinct.
as (
select distinct powr,
powr+
(substring(binry,6,1) * 1) * (case when powr = 1 then 0 else 1 end)
+(substring(binry,5,1) * 2) * (case when powr = 2 then 0 else 1 end)
+(substring(binry,4,1) * 4) * (case when powr = 4 then 0 else 1 end)
+(substring(binry,3,1) * 8) * (case when powr = 8 then 0 else 1 end)
+(substring(binry,2,1) * 16) * (case when powr = 16 then 0 else 1 end)
+(substring(binry,1,1) * 32) * (case when powr = 32 then 0 else 1 end) as elt
from POWERS cross apply BINARIES
),
DISTINCTELEMENTS -- purge calculated numbers smaller than the power of 2 or greater than 60
as (
select * from SETELEMENTS where elt >= powr and elt < 61
)--,
,
ROWNUMBERED -- for each power, number the rows repeatedly from 0 through 5, then back to 0 through 5 again, etc
as (
select powr, (row_number() over (partition by powr order by cast(elt as int)))%5 as r, elt  from DISTINCTELEMENTS
),
GROUPEDSETS -- for each row number, within each power, aggregate the numbers as a comma-delimited list and wrap in square brackets - the inner arrays
as (
select r1.powr, '['+stuff((select ',' + cast(r2.elt as varchar) from ROWNUMBERED r2 where r2.powr = r1.powr and r2.r = r1.r for xml path('')),1,1,'')+']' as s
from ROWNUMBERED r1
group by r1.powr,r1.r
)
select -- now aggregate all the inner arrays per power
stuff((select ',' + cast(g2.s as varchar) from GROUPEDSETS g2 where g2.powr = g1.powr for xml path('')),1,1,'')
from GROUPEDSETS g1
group by g1.powr


Voila!

Note 1: Some of the logic pertains to rendering square brackets and commas.

Note 2: Newer versions of SQLServer have more compact approaches to creating comma-delimited lists. (This was created on SQL Server 2016.)

Note 3: Arrays for a given card are not sorted (which is ok per the spec). Numbers within an array are correctly sorted. In this case, each "card" of the question, renders its arrays on a separate row in the results.

Shorter to hard-code arrays?

Yes.

Byte me.

• Jeez, wouldn't it be shorter to just hardcode the result? – Jo King Apr 30 '19 at 6:55
• Haha. Neither as fun, nor extensible. – youcantryreachingme Apr 30 '19 at 6:57
• I do not fully understand -- are you saying that your solution only works by chance or are you convinced you followed the specifications correctly? – Jonathan Frech Apr 30 '19 at 7:43
• @JonathanFrech - I did not explicitly code for the ordering of the numbers, although there may be an implicit condition in the language resulting in a guaranteed order. They render in correct ascending order. Separately, after posting, I realised I had misunderstood how the data were to be presented (in striped arrays per card, rather than one single set per card) - so have yet to solve that problem. As such, the result currently renders the correct numbers, in ascending order, within each of the 6 expected sets - see the linked sql fiddle. Still to do: break the sets into 5 subsets each. – youcantryreachingme May 1 '19 at 3:19
• I appreciate your effort but if your solution is not correct, please fix it or delete your post. We generally do not allow for invalid answers to linger. – Jonathan Frech May 1 '19 at 10:06

# C# (Visual C# Interactive Compiler), 112 bytes

_=>" ".Select(x=>Enumerable.Range(1,60).Where(l=>(l&x)>0).Select((a,b)=>new{a,b}).GroupBy(i=>i.b%5,i=>i.a))


Try it online!

# Red, 108 107 bytes

n: 32 until[b: collect[repeat k 60[if n and k = n[keep k]]]loop 5[print
extract b 5 b: next b]1 > n: n / 2]


Try it online!

# APL+WIN, 65 62 bytes

v←∊+\¨n,¨29⍴¨1↓¨(n⍴¨1),¨1+n←2*0,⍳5⋄((v=61)/v)←¯1⋄1 3 2⍉6 6 5⍴v


Try it online! Courtesy of Dyalog Classic

MATLAB, 155 bytes

cellfun(@disp,cellfun(@(x)x-repmat(62,5,6).*(x>60),cellfun(@(x)reshape(find(x,30),[5 6]),mat2cell(dec2bin(1:62)-48,62,ones(1,6)),'Uniform',0),'Uniform',0))


This could be shorter as multiple lines but I wanted to do it in one line of code.

• Could you perhaps add a TIO link with test code, so I can verify the output? – Kevin Cruijssen May 2 '19 at 6:49

# 05AB1E, 14 bytes

žOε60LDNo&ĀÏ5ι


Try it online!

• Why the žO instead of just 6L? I know you're not using them in your map, but I'm curious why you've used aeiouy to create a list with 6 values. xD Nice answer, btw! – Kevin Cruijssen Sep 5 '19 at 14:54
• @KevinCruijssen No particular reason, I just thought it was funnier than 6L, 6и, 5Ý, 5°, or 9!. – Grimmy Sep 5 '19 at 14:59
• It certainly caught my eye, that's for sure. ;) – Kevin Cruijssen Sep 5 '19 at 15:04
• @KevinCruijssen I just realized тœ, ₅œ, ₁œ, also work, those are pretty cool too (: – Grimmy Sep 5 '19 at 15:07
• ₆b` would work as well ;) – Kevin Cruijssen Sep 5 '19 at 16:45