# 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.) Apr 27, 2019 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. Apr 27, 2019 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). Apr 27, 2019 at 18:02
• Looks like you didn't try to VTRO with an attitude of "this is my precious challenge!!!" at least... :P Apr 27, 2019 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. Apr 27, 2019 at 21:08

# 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!

# 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!

# 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! Apr 27, 2019 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, 2019 at 13:19
• I don't think this is 26 bytes... Apr 29, 2019 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, 2019 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

• Nice. The iter keyword is redundant here since a generator will do the job just as well. Apr 27, 2019 at 14:05
• @JonathanAllan Cool, thanks :D Apr 27, 2019 at 17:13

# 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. Apr 27, 2019 at 10:05
• 95 bytes Apr 27, 2019 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.) Apr 27, 2019 at 11:20
• @Arnauld I was thinking about that, but decided against it. Apr 27, 2019 at 11:28
• better to leave out #include to show that it works without it Apr 28, 2019 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. Apr 27, 2019 at 12:32
• Apr 27, 2019 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. May 7, 2019 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=#. Apr 27, 2019 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 Apr 27, 2019 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. Apr 27, 2019 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. :) Apr 29, 2019 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, 2019 at 6:55
• Haha. Neither as fun, nor extensible. Apr 30, 2019 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? Apr 30, 2019 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. May 1, 2019 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. May 1, 2019 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? May 2, 2019 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! Sep 5, 2019 at 14:54
• @KevinCruijssen No particular reason, I just thought it was funnier than 6L, 6и, 5Ý, 5°, or 9!. Sep 5, 2019 at 14:59
• It certainly caught my eye, that's for sure. ;) Sep 5, 2019 at 15:04
• @KevinCruijssen I just realized тœ, ₅œ, ₁œ, also work, those are pretty cool too (: Sep 5, 2019 at 15:07
• ₆b` would work as well ;) Sep 5, 2019 at 16:45