Truco de magia de números binarios


28

El desafío es simple; genera los siguientes seis conjuntos enteros 2D:

[[ 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]]

¿Qué son estas matrices enteras 2D? Estos son los números utilizados en un truco de magia con cartas que contienen estos números:

ingrese la descripción de la imagen aquí

El truco de magia le pide a alguien que piense en un número en el rango [1, 60], y le da al que realiza el truco de magia todas las cartas que contienen este número. El que realiza el truco de magia puede sumar los números de la parte superior izquierda (todo un poder de 2) de las cartas dadas para llegar al número en el que la persona estaba pensando. Puede encontrar alguna explicación adicional de por qué esto funciona aquí.

Reglas de desafío:

  • Puede generar las seis matrices enteras 2D en cualquier formato razonable. Se puede imprimir con delimitadores; puede ser una matriz de enteros en 3D que contiene las seis matrices de enteros en 2D; puede ser una lista de cadenas de líneas; etc.
  • Se le permite llenar la posición inferior derecha de las últimas cuatro cartas con un valor negativo en el rango [-60, -1]o carácter en '*'lugar de dejarlo fuera para hacer que las matrices enteras 2D sean matrices rectangulares (no, no está permitido llenarlas con 0o sin -integer como null/ undefinedcomo alternativa, con la excepción de que *también se usa una estrella en las cartas reales).
  • El orden de los números en las matrices es obligatorio. Aunque no importa el truco de magia física, veo este desafío principalmente como una : , de ahí la restricción en el orden.
    El orden de las matrices en la lista de salida puede estar en cualquier orden, ya que está claro en la tarjeta superior izquierda qué matriz es cuál.

Reglas generales:

  • Este es el , por lo que la respuesta más corta en bytes gana.
    No permita que los lenguajes de code-golf lo desanimen a publicar respuestas con lenguajes que no sean codegolfing. Trate de encontrar una respuesta lo más breve posible para 'cualquier' lenguaje de programación.
  • Las reglas estándar se aplican a su respuesta con las reglas de E / S predeterminadas , por lo que puede usar STDIN / STDOUT, funciones / método con los parámetros adecuados y programas completos de tipo retorno. Tu llamada.
  • Las lagunas predeterminadas están prohibidas.
  • Si es posible, agregue un enlace con una prueba para su código (es decir, TIO ).
  • Además, se recomienda agregar una explicación para su respuesta.

Relacionado. (Al igual que en, se refiere al mismo truco de magia, pero creo que no es realmente útil para inspirarse en este desafío. Ese desafío pide obtener un valor verdadero / falso si el número naparece en la k'ésima carta; donde mi desafío es un KC-challenge para generar las seis matrices.)
Kevin Cruijssen

1
@DigitalTrauma Hm, no estoy tan seguro de si esto es realmente un duplicado, porque su desafío es ascii-art (no etiquetado como tal, pero lo es), mientras que este le permite generar la matriz en un formato mucho más indulgente (no solo cuatro formas esencialmente idénticas). Sin embargo, no puedo votar para reabrir porque tengo un martillo.
Erik el Outgolfer

@EriktheOutgolfer Woops ... Olvidé que también tengo un martillo>.> A veces poder cerrar / abrir el martillo es bastante molesto ... Sin embargo, ya tenía 2 votos, así que con el tuyo y el mío, además, hubo 4 votos abiertos. Pero si alguien quiere cerrarlo de nuevo, no me importa. De hecho, son muy similares, aunque su desafío es un [ascii-art]desafío con reglas de salida estrictas (MD5), donde las mías son muy flexibles (y las filas / columnas se intercambian, y el rango es en [1,60]lugar de [1,63]; diferencias bastante menores, pero aún así).
Kevin Cruijssen

Parece que no intentaste VTRO con una actitud de "¡este es mi precioso desafío!" al menos ...: P
Erik the Outgolfer

1
Yo también me olvidé del martillo. Todavía creo que esto está lo suficientemente cerca como para votar a dup, aunque diferiré a la sabiduría de la comunidad si se vuelve a abrir.
Trauma digital

Respuestas:


6

MATL , 12 11 bytes

-1 byte gracias al propio maestro :)

60:B"@fQ6eq

Explicación:

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

Pruébalo en línea!


8

Perl 6 , 63 46 bytes

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

Pruébalo en línea!

Salidas como matrices 2D en varias líneas, con la última matriz de cada una cortada si es necesario.


7

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)]

Pruébalo en línea!

El método aquí es crear una lista de todos los números posibles r(61)y luego reducirla a la lista de números para una tarjeta i&2**k.

Luego, al usar el corte de lista, esa lista de números 1D se reorganiza al tamaño correcto de tarjeta 6x5 [card nums][j::5]for j in r(5).

Entonces, este generador solo se repite para 6 cartas for k in r(6).


Si bien no pude encontrar ninguna solución de menos de 76 bytes, aquí hay otras dos que también tienen 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)]

Pruébalo en línea!

El siguiente está inspirado en 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

Pruébalo en línea!

Cualquier comentario es muy apreciado.


6

Carbón , 26 bytes

E⁶E⁵⪫E⁶§⁺§⪪Φ⁶¹&πX²ι⁵ν⟦*⟧λ 

Pruébalo en línea! El enlace es a la versión detallada del código. Intenté calcular las entradas directamente, pero esto ya era de 27 bytes antes de ajustarlo *en la parte inferior derecha. Emite cada fila unida con espacios y una línea en blanco entre tarjetas. Explicación:

E⁶                          Loop over 6 cards
  E⁵                        Loop over 5 rows
     E⁶                     Loop over 6 columns
           Φ⁶¹              Filter over 0..60 where
               π            Current value
              &             Bitwise And
                 ²          Literal 2
                X           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

Agregué esa regla *por diversión después de ver las estrellas en las cartas reales. Me preguntaba si habría algún idioma usándolo, pero me alegra ver que al menos uno lo hizo. :) ¡Buena respuesta!
Kevin Cruijssen

1
@KevinCruijssen Charcoal no tiene un operador de transposición, y la transposición de golf requiere una matriz rectangular de tamaño conocido, por lo que necesito agregar algo para compensar el tamaño, y *es al menos tan corto como cualquier otra cosa.
Neil

No creo que sean 26 bytes ...
Tvde1

@ Tvde1 Charcoal, como muchos de los esolangs en este sitio, utiliza una página de códigos personalizada. Los caracteres de esa página cuestan 1 byte, mientras que otros caracteres cuestan hasta 4 bytes.
Neil

6

05AB1E , 16 bytes

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

Pruébalo en línea!

Explicación

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ô®ζ,

Pruébalo en línea!

Explicación

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

5

Casco , 13 bytes

ṠMöTC5Wnünḣ60

Pruébalo en línea!

Explicación

          ḣ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.


5

Japt , 14 bytes

6Æ60õ f&2pX)ó5

Intentalo

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

4

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=[]))

Pruébalo en línea!

Comentado

_ =>                        // 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()


4

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;}

Pruébalo en línea!

Devuelve las matrices como una matriz int 3D en o.

Las últimas 4 matrices tienen -1 como último valor.

Guardado 2 bytes gracias a Kevin Cruijssen.

Guardado 7 8 bytes gracias a Arnauld.


Puede guardar 2 bytes cambiando o[i][4][5]=-1;for(j=k=0;a for(o[i][4][5]=-1,j=k=0;para que se puedan eliminar los corchetes. Buena respuesta por cierto, +1 de mi parte.
Kevin Cruijssen


(Tenga en cuenta que no estoy 100% seguro si se permite pasar una matriz 3D ya asignada con las dimensiones correctas. Pero dejaré que los golfistas regulares de C proporcionen una mejor idea al respecto.)
Arnauld

@Arnauld Estaba pensando en eso, pero decidí no hacerlo.
Matej Mulej

es mejor dejar de lado #includepara demostrar que funciona sin él
solo ASCII

3

CJam (18 bytes)

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

Demo en línea . Este es un programa completo que sale a stdout.

Disección

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

3

Jalea , 13 bytes

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

Un enlace niládico que produce una lista de (6) listas de listas de enteros. (Produce el uso de la opción predeterminada de no tener *o relleno negativo).

Pruébalo en línea!

¿Cómo?

60

60[1,60]5

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

Un montón de 15 sin darse cuenta del truco "mínimo por longitud cuando se divide en cinco":

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

... y, mientras intentaba encontrar más corto, obtuve otros 13 sin necesitar el truco en absoluto:

60B€Uz0Ts5ZƊ€

3

Wolfram Language (Mathematica) , 88 bytes

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

Me tomé la libertad de agregar un enlace TIO (basado en la respuesta de @ J42161217 ). +1 de mi parte
Kevin Cruijssen


@ Mr.Xcoder Gracias. He usado este ~truco en un lugar más y he reemplazado la variable kpor Null. Lo sentimos, no hay tiempo para agregar un enlace tio.
Bruno Le Floch

2

Wolfram Language (Mathematica) , 99 bytes

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

Pruébalo en línea!


Puede guardar algunos caracteres: haciendo en Transpose@lugar de Transpose[...]; relleno a 30 entradas antes de la partición; utilizando Table[...,{k,6}]para evitar la necesidad k=#.
Bruno Le Floch

@Bruno Le Floch Table puede guardar un byte. ¿Intentaste transponer @? Porque no funciona si miras con cuidado. Estoy afk pero
jugaré

Lo sentimos, Transpose@funciona después de mover PadRighten el interior Partition. Otro comentario es que la pregunta no parece permitir ""el marcador de posición; puede reemplazarlo -1sin perder ningún byte.
Bruno Le Floch


2

R , 73 bytes

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

No estoy completamente seguro de haber cumplido con el requisito de orden, ya que R por defecto llena las matrices por columna, por lo que el orden que aparece físicamente en las tarjetas es el mismo que la forma en que se asignan las matrices en R.

Pruébalo en línea!


La salida se ve bien. Y si R llena las matrices por columnas antes de la fila en lugar de la fila antes de la columna como casi todos los demás lenguajes, supongo que es un buen lenguaje de programación para este desafío. :)
Kevin Cruijssen

2

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

Solo quería saber que podía hacerlo.

Versión optimizada

 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

Demostración en línea

Pruébalo en línea!

Versión detallada - con notas como comentarios SQL

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!

Nota 1: parte de la lógica se refiere a la representación de corchetes y comas.

Nota 2: Las versiones más recientes de SQLServer tienen enfoques más compactos para crear listas delimitadas por comas. (Esto fue creado en SQL Server 2016).

Nota 3: Las matrices para una tarjeta determinada no están ordenadas (lo cual está bien según las especificaciones). Los números dentro de una matriz están ordenados correctamente. En este caso, cada "carta" de la pregunta presenta sus matrices en una fila separada en los resultados.

¿Más corto a las matrices de código duro?

Sí.

Byte me


Por Dios, ¿no sería más corto simplemente codificar el resultado?
Jo King

Jaja. Ni tan divertido ni extensible.
youcantryreachingme

No entiendo completamente: ¿está diciendo que su solución solo funciona por casualidad o está convencido de que siguió las especificaciones correctamente?
Jonathan Frech

@JonathanFrech: no codifiqué explícitamente el orden de los números, aunque puede haber una condición implícita en el lenguaje que resulte en un orden garantizado. Se procesan en orden ascendente correcto. Por separado, después de publicar, me di cuenta de que había entendido mal cómo se iban a presentar los datos (en matrices rayadas por tarjeta, en lugar de un solo conjunto por tarjeta), por lo que todavía tengo que resolver ese problema. Como tal, el resultado actualmente representa los números correctos, en orden ascendente, dentro de cada uno de los 6 conjuntos esperados; vea el violín sql vinculado. Aún por hacer: dividir los conjuntos en 5 subconjuntos cada uno.
youcantryreachingme

Agradezco su esfuerzo, pero si su solución no es correcta, corríjala o elimine su publicación. Generalmente no permitimos respuestas inválidas para quedarse.
Jonathan Frech




1

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))

Esto podría ser más corto como líneas múltiples, pero quería hacerlo en una línea de código.


1
¿Podría agregar un enlace TIO con código de prueba para que pueda verificar la salida?
Kevin Cruijssen

1

05AB1E , 14 bytes

žOε60LDNo&ĀÏ5ι

Pruébalo en línea!


1
¿Por qué en žOlugar de solo 6L? Sé que no los está usando en su mapa, pero tengo curiosidad por qué ha usado aeiouypara crear una lista con 6 valores. xD Buena respuesta, por cierto!
Kevin Cruijssen

1
Sin @KevinCruijssen razón en particular, sólo pensaba que era más divertido que 6L, , , , o 9!.
Grimmy

Ciertamente me llamó la atención, eso es seguro. ;)
Kevin Cruijssen

@KevinCruijssen Me acabo de dar cuenta тœ, ₅œ, ₁œ, también el trabajo, son muy bien también (:
Grimmy

₆bfuncionaría bien;)
Kevin Cruijssen
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.