Paredes binárias enfraquecidas

21

Inspirado por Criar uma parede binária

Dada uma lista de números inteiros positivos, podemos escrevê-los todos acima um do outro, assim, por [2, 6, 9, 4]exemplo:

0010
0110
1001
0100

Podemos imaginar isso como uma parede:

..#.
.##.
#..#
.#..

No entanto, este é um muro muito fraco e entrou em colapso! Cada 1( #) cai até atingir o "solo" ou outro 1( #). Os 0s .estão presentes nos pontos deixados pelos 1s movidos .

Isso se torna o seguinte:

....
....
.##.
####

O que se traduz novamente em:

0000
0000
0110
1111

Qual, como uma lista de números, é [0, 0, 6, 15].

Outro caso de teste

[10, 17, 19, 23]

Isso se torna:

01010
10001
10011
10111

que se torna:

00000
10011
10011
11111

traduzindo de volta para:

[0, 19, 19, 31]

Desafio

Dada uma lista de números inteiros positivos, aplique essa transformação à lista. Entrada / Saída como listas de números inteiros positivos em qualquer formato razoável. Aplicam-se brechas padrão.

Este é um , então a resposta mais curta em bytes vence!

HyperNeutrino
fonte
Sandbox Post
HyperNeutrino
1
Mais casos de teste? Você sabe, casos de teste não quadrados seriam bons.
Freira vazando
@LeakyNun Claro. Eu farei isso.
HyperNeutrino
Isso é apenas um problema de classificação para matrizes de bits.
Marcus Müller
@ MarcusMüller Você está certo - eu percebi que após a resposta do MATL: P
HyperNeutrino

Respostas:

29

MATL , 4 bytes

BSXB

Experimente no MATL Online

Explicação

    % Implicitly grab input as an array 
    %   STACK: [10, 17, 19, 23]
B   % Convert each element to binary where each decimal number results in a row
    %   STACK: [0 1 0 1 0;
    %           1 0 0 0 1;
    %           1 0 0 1 1;
    %           1 0 1 1 1]
S   % Sort each column, placing all of the 1's at the bottom of each column
    %   STACK: [0 0 0 0 0;
    %           1 0 0 1 1;
    %           1 0 0 1 1;
    %           1 1 1 1 1] 
XB  % Convert each row from its binary representation to its decimal number
    %   STACK: [0, 19, 19, 31]
    % Implicitly display the result
Suever
fonte
o_O Como isso funciona: o
HyperNeutrino
1
O MATL acabou de superar o Jelly por 4 bytes ? o_O
totallyhuman
5 bytes agora :-p
Leaky Nun
Eu nunca pensei que haveria um built-in para mover os para o fundo xD +1
HyperNeutrino 29/07
1
@totallyhuman bem, espere até Dennis vem
JungHwan Min
5

Python , 68 bytes

f=lambda a:a and[x|y&a[0]for x,y in zip([0]+f(a[1:]),f(a[1:])+[-1])]

Experimente online!

Anders Kaseorg
fonte
5

JavaScript (ES6), 50 bytes

f=a=>a.map(_=>a.map((e,i)=>a[a[i]|=a[--i],i]&=e))&&a

Explicação: Suponha que duas linhas da parede sejam assim:

0011
0101

O resultado precisa ser este:

0001
0111

Em outras palavras, a primeira linha se torna o AND das duas linhas e a segunda linha se torna o OU das duas linhas. Isso só precisa ser repetido vezes suficientes para que todos os bits caiam no fundo.

Neil
fonte
2

Japonês , 16 bytes

m¤z3 ®¬n qÃz mn2

Experimente online! usando o -Qsinalizador para formatar o resultado da matriz.

Explicação

m¤z3 ®¬n qÃz mn2    Implicit: U = input array.
                        [10, 17, 19, 23]
m¤z3                Map U to binary strings and rotate the array left 90°
                         1010       0111
                        10001   ->  1011
                        10011       0001
                        10111       1000
                                     111
®¬n qà              Sort each binary string, putting 0s and spaces at the start
                        0111
                        0111
                        0001
                        0001
                         111
z mn2               Rotate right 90° and convert each back to a number
                         0000       0
                        10011   ->  19
                        10011       19
                        11111       31
                    Implicit output of resulting array
Justin Mariner
fonte
Eu acho que você pode salvar um byte commì2 z3 mn z mì2
ETHproductions
@ETHproductions Parece que girar a matriz 2D, em vez de girar a matriz de strings, preenche cada matriz interna em nullvez de espaços. Então, isso não parece funcionar. E nullé classificado à direita dos 1s, diferentemente dos espaços, que são classificados à esquerda.
23717 Justin Mariner
2

Mathematica, 64 bytes

#~FromDigits~2&/@(Sort/@(PadLeft[#~IntegerDigits~2&/@#]))&

 é \[Transpose]

Isso converte a entrada (uma lista de números) em uma lista de listas de dígitos, forma uma matriz quadrada, transpõe, classifica as linhas para que o 1 "caia" no fundo, transponha de volta e depois converta novamente em números .

DanTheMan
fonte
2

Oitava, 29 25 bytes

4 bytes salvos graças a @Stewie

@(x)bi2de(sort(de2bi(x)))
Suever
fonte
de2bi/bi2desalva 4 bytes na oitava. Funciona em octave-online.net.
Stewie Griffin
@StewieGriffin Thanks!
Suever 30/07
1

J , 13 bytes

/:~"1&.|:&.#:

Experimente online!

Explicação

/:~"1&.|:&.#:  Input: array M
           #:  Convert each in M to binary with left-padding
       |:&     Transpose
/:~"1&         Sort each row
     &.|:      Inverse of transpose (which is just transpose)
         &.#:  Inverse of converting to binary
milhas
fonte
Há aquele preenchimento esquerdo binário novamente, +1. E também, você pode explicar por que precisaria usar o inverso da transposição, uma vez que é apenas transposição?
Zacharý
@ Zacharý Os inversos são usados ​​para desfazer as operações usadas antes de classificar cada linha. É verdade que o inverso da transposição é apenas transposição, mas outra maneira de ver isso é como <convert from binary> <transpose> <sort each row> <transpose> <convert to binary> M, onde as duas primeiras funções são apenas as inversas das duas últimas.
milhas
1

05AB1E , 9 bytes

bí0ζR€{øC

Experimente online!

Algoritmo meio diferente do Magic.

Erik, o Outgolfer
fonte
ζ, droga. Meu excluído, pegue meu +1.
Magic Octopus Urn
@MagicOctopusUrn Por que você excluiu o seu? Sem necessidade de.
Erik the Outgolfer
Não é realmente muito diferente (em termos de algoritmo) e isso foi 25% melhor.
Magic Octopus Urn
1

Dyalog APL, 24 21 19 bytes

2⊥↑{⍵[⍋⍵]}¨↓2⊥⍣¯1⊢⎕

Experimente online! (modificado para que o TryAPL aceite como válido)

Quão?

  • entrada avaliada (matrizes são separadas por espaço)
  • 2⊥⍣¯1⊢ converte cada um dos argumentos em binário (transposto do que está em questão)
  • transforma uma matriz 2D em um vetor de vetores
  • {⍵[⍋⍵]}¨ classifica cada um dos elementos do vetor
  • transforma o vetor de vetores em uma matriz 2D novamente
  • 2⊥ converter de binário (uma vez que o transpõe, chegamos ao resultado correto)
Zacharý
fonte
1

Dyalog APL (23 caracteres)

{2⊥¨↓⍉↑{⍵[⍋⍵]}¨↓2⊥⍣¯1⊢⍵}
  1. Converta os argumentos de entrada em uma matriz binária
  2. Dividir a matriz em colunas
  3. Classifique as colunas em ordem crescente
  4. Converta as linhas classificadas novamente em decimal

Exemplo

  {2⊥¨↓⍉↑{⍵[⍋⍵]}¨↓2⊥⍣¯1⊢⍵}10 17 19 23
      0 19 19 31

Obrigado a Zacharý por me corrigir neste.

James Heslip
fonte
Você pode substituir (⊥⍣¯1)⍵por ⊥⍣¯1⊢⍵. Além disso, acho que você não precisa da especificação do eixo na divisão ( ↓[1]=> ).
Zacharý
Ah, e você deve convertê-lo novamente em uma lista!
Zacharý
Isto é inválido.
Zacharý
Obrigado, Zacharý, eu estava trabalhando tarde da noite passada e acho que interpretei mal o problema. Eu modifiquei minha solução agora.
James Heslip
1
Bom trabalho! ( ⊥⍣¯1realmente precisa ser um builtin). E obrigado por realmente ter acertado meu nome de usuário.
Zacharý
0

JavaScript, 127 125 bytes

a=>a[m='map'](_=>b[m]((n,i)=>n&&(b[i]--,d|=1<<i),d=0)&&d,b=[...Array(32)][m]((_,c)=>a[m](e=>d+=!!(2**c&e),d=0)&&d)).reverse()

Experimente online

-2 bytes graças ao vacas charlatão


fonte
(1<<c)&epode se tornar2**c&e
Kritixi Lithos
0

Python 2, 142 bytes

... e ainda jogando golfe ... espero - Qualquer ajuda apreciada!

def c(l):b=[bin(n)[2:]for n in l];print[int(n,2)for n in map(''.join,zip(*map(sorted,zip(*['0'*(len(max(b,key=len))-len(x))+x for x in b]))))]

Uma grande parte disso é para preencher os números com zeros.

Mais legível:

def collapse(nums):
    bins = [bin(n)[2:] for n in nums]
    bins = [('0'*(len(max(bins, key = len)) - len(x))) + x for x in bins]
    print [int(n, 2) for n in map(''.join, zip(*map(sorted, zip(*bins))))]

Isso cria uma matriz de representações de cadeias binárias, a preenche, gira 90º no sentido horário, classifica cada linha, gira 90º para trás e cria números inteiros a partir de cada linha.

Daniel
fonte
142 bytes , você tem alguns parênteses redundantes.
Mr. Xcoder
@ Mr.Xcoder, oh sim que era bobagem
Daniel