Truque de mágica de números binários


28

O desafio é simplesmente; produz as seis seguintes matrizes inteiras 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]]

O que são essas matrizes inteiras 2D? Estes são os números usados ​​em um truque de mágica com cartões contendo estes números:

insira a descrição da imagem aqui

O truque de mágica pede que alguém pense em um número no intervalo [1, 60] e dê a quem executa o truque de mágica todas as cartas que contêm esse número. O jogador que executa o truque de mágica pode somar os números do canto superior esquerdo (com potência de 2) das cartas dadas para chegar ao número em que a pessoa estava pensando. Algumas explicações adicionais sobre por que isso funciona podem ser encontradas aqui.

Regras do desafio:

  • Você pode gerar as seis matrizes inteiras 2D em qualquer formato razoável. Pode ser impresso com delimitadores; pode ser uma matriz inteira 3D contendo as seis matrizes inteiras 2D; pode ser uma lista de linhas de linhas; etc.
  • Você pode preencher a posição inferior direita dos últimos quatro cartões com um valor negativo no intervalo [-60, -1]ou no caractere, em '*'vez de deixá-lo de fora para criar matrizes retangulares de matrizes inteiras 2D (não, não é permitido preenchê-las com 0ou sem -integer como null/ undefinedcomo alternativa, com a exceção de *que uma estrela também é usada nas cartas reais).
  • A ordem dos números nas matrizes é obrigatória. Embora não importe para o truque de mágica física, vejo esse desafio principalmente como uma - , daí a restrição de ordem.
    A ordem das matrizes na lista de saída pode estar em qualquer ordem, pois fica claro no cartão superior esquerdo qual matriz é qual.

Regras gerais:

  • Isso é , então a resposta mais curta em bytes vence.
    Não permita que idiomas com código de golfe o desencorajem a postar respostas com idiomas que não sejam codegolf. Tente encontrar uma resposta o mais curta possível para 'qualquer' linguagem de programação.
  • As regras padrão se aplicam à sua resposta com as regras de E / S padrão , para que você possa usar STDIN / STDOUT, funções / método com os parâmetros adequados e programas completos do tipo retorno. Sua chamada.
  • As brechas padrão são proibidas.
  • Se possível, adicione um link com um teste para o seu código (ou seja, TIO ).
  • Além disso, é altamente recomendável adicionar uma explicação para sua resposta.

Relacionado. (Como se refere, está se referindo ao mesmo truque de mágica, mas não é realmente útil para me inspirar nesse desafio que eu acho. Esse desafio pede para gerar um valor de verdade / falsey se o número naparecer na k'ª carta'; onde meu desafio é um Desafio KC para produzir as seis matrizes.)
Kevin Cruijssen

1
@DigitalTrauma Hm, não tenho tanta certeza se isso é realmente uma duplicata, porque seu desafio é ascii-art (não marcado como tal, mas é), enquanto este permite que você produza a matriz em um formato muito mais brando (não apenas quatro maneiras essencialmente idênticas). Não posso votar para reabrir, porque tenho um martelo.
Erik the Outgolfer

@EriktheOutgolfer Woops .. Esqueci que também tenho um martelo>.> Às vezes, poder fechar / abrir um martelo é muito chato .. Já tinha 2 votos, porém, com o seu e o meu, além disso, houve 4 votos em aberto. Mas se alguém quiser fechá-lo novamente, não me importo. Eles são realmente muito parecidos, embora seu desafio seja realmente um [ascii-art]desafio com regras de saída estritas (MD5), onde as minhas são muito flexíveis (e as linhas / colunas são trocadas e o intervalo é, em [1,60]vez de [1,63]; diferenças muito pequenas, mas ainda assim).
Kevin Cruijssen 27/04

Parece que você não tentou VTRO com uma atitude de "este é meu desafio precioso !!!" pelo menos ...: P
Erik the Outgolfer

1
Eu também esqueci o martelo. Eu ainda acho que isso está perto o suficiente para votar no dup, embora eu adie a sabedoria da comunidade se ela for reaberta.
Digital Trauma

Respostas:


6

MATL , 12 11 bytes

-1 byte graças ao próprio mestre :)

60:B"@fQ6eq

Explicação:

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

Experimente online!



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

Experimente online!

O método aqui é criar uma lista de todos os números possíveis r(61)e depois reduzi-los à lista de números de um cartão i&2**k.

Em seguida, usando o fatiamento de lista, a lista de números 1D é reorganizada no tamanho de cartão 6x5 correto [card nums][j::5]for j in r(5).

Então, este gerador é repetido apenas para 6 cartões for k in r(6).


Embora eu não tenha encontrado soluções com menos de 76 bytes, aqui estão outras duas que também têm 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)]

Experimente online!

Este próximo é inspirado em 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

Experimente online!

Quaisquer comentários são muito apreciados.


6

Carvão , 26 bytes

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

Experimente online! Link é a versão detalhada do código. Tentei calcular as entradas diretamente, mas isso já tinha 27 bytes antes de ajustar para o *no canto inferior direito. Produz cada linha unida com espaços e uma linha em branco entre os cartões. Explicação:

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

Eu adicionei essa regra *por diversão depois de ver as estrelas nas cartas reais. Estava imaginando se haveria algum idioma para usá-lo, mas fico feliz em ver pelo menos um. :) Boa resposta!
Kevin Cruijssen 27/04

1
O @KevinCruijssen Charcoal não possui um operador de transposição, e a transposição para golfistas exige uma matriz retangular de tamanho conhecido, por isso preciso adicionar algo para compensar o tamanho e *é pelo menos tão curta quanto qualquer outra coisa.
Neil

Eu não acho que isso é 26 bytes ...
Tvde1 29/04

@ Tvde1 Charcoal, como muitos dos esolangs deste site, usa uma página de código personalizada. Os caracteres dessa página custam 1 byte, enquanto outros caracteres custam até 4 bytes.
Neil

6

05AB1E , 16 bytes

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

Experimente online!

Explicação

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

Experimente online!

Explicação

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

Casca , 13 bytes

ṠMöTC5Wnünḣ60

Experimente online!

Explicação

          ḣ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

Japonês , 14 bytes

6Æ60õ f&2pX)ó5

Tente

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

Experimente online!

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

Experimente online!

Retorna as matrizes como uma matriz int 3D em o.

As últimas 4 matrizes têm -1 como seu último valor.

Economizou 2 bytes graças a Kevin Cruijssen.

Economizou 7 8 bytes graças a Arnauld.


Você pode salvar 2 bytes alterando o[i][4][5]=-1;for(j=k=0;para, for(o[i][4][5]=-1,j=k=0;para que os colchetes possam ser removidos. Resposta agradável btw, +1 de mim.
Kevin Cruijssen 27/04


(Observe que não tenho 100% de certeza se a passagem de uma matriz 3D já alocada com as dimensões corretas é permitida. Mas deixarei os jogadores regulares de C fornecerem uma melhor visão sobre isso.)
Arnauld

@ Arnauld Eu estava pensando sobre isso, mas decidi contra.
Matej Mulej 27/04

melhor deixar de fora #includepara mostrar que ele funciona sem ele
apenas ASCII

3

CJam (18 bytes)

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

Demonstração online . Este é um programa completo com saída para stdout.

Dissecação

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

Gelatina , 13 bytes

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

Um link niládico que gera uma lista de (6) listas de listas de números inteiros. (Ele gera a opção padrão de não ter *ou nenhum preenchimento negativo.)

Experimente online!

Quão?

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

Muitos 15s sem perceber o truque "mínimo de comprimento quando dividido em cinco":

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

... e, enquanto tentava achar menor, consegui outros 13 sem precisar do truque:

60B€Uz0Ts5ZƊ€

3

Wolfram Language (Mathematica) , 88 bytes

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

Tomei a liberdade de adicionar um link TIO (com base na resposta de @ J42161217 ). +1 de mim.
Kevin Cruijssen 27/04


@ Mr.Xcoder Obrigado. Eu usei esse ~truque em mais um lugar e substituí a variável kpor Null. Desculpe, não há tempo para adicionar um link de 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

Experimente online!


Você pode salvar alguns caracteres: fazendo em Transpose@vez de Transpose[...]; preenchendo 30 entradas antes da partição; usando Table[...,{k,6}]para evitar a necessidade k=#.
Bruno Le Floch 27/04

@Bruno Le Floch Table pode economizar um byte. Você tentou transpor @? Porque não funciona se você assistir com cuidado. Estou afk, mas vou jogar golfe mais tarde
J42161217 27/04

Desculpe, Transpose@funciona depois que você se muda para PadRightdentro Partition. Outro comentário é que a pergunta parece não permitir ""o espaço reservado; você pode substituí-lo -1sem perder nenhum byte.
Bruno Le Floch 27/04


2

R , 73 bytes

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

Não tenho certeza absoluta de que atendi ao requisito de ordem, já que R, por padrão, preenche matrizes por coluna. Portanto, a ordem em que aparece fisicamente nos cartões é a mesma que a maneira como as matrizes são alocadas em R.

Experimente online!


A saída parece boa. E se R preenche matrizes por colunas antes da linha, em vez de linha antes da coluna, como quase todas as outras linguagens, significa que é uma boa linguagem de programação a ser usada para esse desafio, eu acho. :)
Kevin Cruijssen 29/04

2

T-SQL, ( 1.168 1.139 bytes)

Eu só queria saber que eu poderia fazer isso.

Versão otimizada

 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

Demonstração online

Experimente online!

Versão detalhada - com notas como comentários 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 da lógica se refere à renderização de colchetes e vírgulas.

Nota 2: As versões mais recentes do SQLServer têm abordagens mais compactas para criar listas delimitadas por vírgulas. (Isso foi criado no SQL Server 2016.)

Nota 3: As matrizes para um determinado cartão não são classificadas (o que é aceitável de acordo com as especificações). Os números em uma matriz são classificados corretamente. Nesse caso, cada "cartão" da pergunta renderiza suas matrizes em uma linha separada nos resultados.

Matrizes mais curtas para codificar?

Sim.

Byte me.


Eita, não seria mais curto apenas codificar o resultado?
Jo King

Haha Nem divertido, nem extensível.
youcantryreachingme

Não entendo completamente - você está dizendo que sua solução funciona apenas por acaso ou está convencido de que seguiu as especificações corretamente?
Jonathan Frech

@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

Agradecemos seu esforço, mas se sua solução não estiver correta, corrija-a ou exclua sua postagem. Geralmente, não permitimos respostas inválidas para permanecer.
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))

Isso poderia ser mais curto como várias linhas, mas eu queria fazê-lo em uma linha de código.


1
Você poderia adicionar um link TIO com código de teste para que eu possa verificar a saída?
Kevin Cruijssen

1

05AB1E , 14 bytes

žOε60LDNo&ĀÏ5ι

Experimente online!


1
Por que ao žOinvés de apenas 6L? Sei que você não os está usando no seu mapa, mas estou curioso para saber por que você aeiouycriou uma lista com 6 valores. xD Boa resposta, btw!
Kevin Cruijssen 5/09

1
@KevinCruijssen Sem razão particular, eu apenas pensei que era mais engraçado do que 6L, , , , ou 9!.
Grimmy 5/09

Certamente chamou minha atenção, isso é certo. ;)
Kevin Cruijssen

@KevinCruijssen Eu só percebi тœ, ₅œ, ₁œ, também trabalho, aqueles são muito legal também (:
Grimmy

₆bfuncionaria também;)
Kevin Cruijssen
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.