Um número inteiro é pesado de binário se sua representação binária contiver mais 1
s que 0
s, ignorando os zeros à esquerda. Por exemplo 1 é binário pesado, como sua representação binária é simplesmente 1
, no entanto 4 não é binário pesado, como é sua representação binária 100
. No caso de um empate (por exemplo 2, com uma representação binária de 10
), o número não é considerado pesado como binário.
Dado um número inteiro positivo como entrada, produza um valor de verdade, se for pesado binário, e um valor de falsey, se não for.
Casos de teste
Formato: input -> binary -> output
1 -> 1 -> True
2 -> 10 -> False
4 -> 100 -> False
5 -> 101 -> True
60 -> 111100 -> True
316 -> 100111100 -> True
632 -> 1001111000 -> False
2147483647 -> 1111111111111111111111111111111 -> True
2147483648 -> 10000000000000000000000000000000 -> False
Pontuação
Isso é código-golfe, e o menor número de bytes em cada idioma ganha
code-golf
number
decision-problem
binary
Skidsdev
fonte
fonte
Respostas:
Código da máquina x86,
1514 bytesEssa é uma função que usa a convenção de chamada __fastcall da Microsoft (o primeiro e único parâmetro em ecx, o valor de retorno em eax, o callee é permitido desobstruir o edx), embora possa ser modificado trivialmente para outras convenções de chamada que transmitem argumentos nos registros.
Retorna 255 como verdade e 0 como falsey.
Ele usa o código de operação não documentado (mas amplamente suportado)
salc
.Desmontagem abaixo:
Experimente online!
Agradecemos a Peter Cordes por sugerir a substituição
lzcnt
porbsr
.fonte
popcnt
antes de rolar para baixo para procurar respostas, mas não tinha pensadolzcnt
em lidar apenas com os dígitos significativos, conforme exigido pela pergunta.bsr
vez delzcnt
(akarep bsr
)? Você precisaria usarsub
emlea
vez disso, já que fornece 32-lzcnt. (Ou deixa o dst não modificada para src = 0, em todo o hardware Intel e AMD existente AMD mesmo documentos este comportamento, mas a Intel diz indefinido ... Enfim, OP disse. Positiva , o que exclui0
.)popcnt
ebsr
, mas tinha 17 bytes. Eu estava pensando que era muito bom em comparação com a primeira resposta asm que eu vi , mas esselea
truque inteligente supera isso. Eu também olhei para compararbsf
epopcnt
. Mas não estou vendo nenhuma maneira de superar essa solução, mesmo levando em consideração o byte de 1 byte que você poderia salvar ao soltar orep
prefixo.salc
não é equivalente asetc al
: os últimos conjuntosal
para 1 se CF definidos, não a 255.salc
ésbb al, al
, mas você obtém uma economia de 1 byte para codificá-lo. A propósito, ele é documentado pela AMD e é amplamente suportado pela Intel, com o mnemônico vindo do mapa de códigos op6 P6 da Intel. Portanto, este é realmente bastante seguro de usar. Além disso, uma boa melhoria aqui para pensar em usar essa instrução! Isso é basicamente o que meu rascunho original fez, exceto que (1) eu usei o código x86-64, entãoinc
tinha o dobro do tempo para codificar e (2) eu não tinha pensado nissosalc
, então estava fazendo o mesmo trabalho em um caminho mais longo. Pena que só posso votar uma vez.Gelatina , 5 bytes
Produz saída não vazia (verdade) ou saída vazia (falso).
Experimente online!
Como funciona
fonte
Bo-S
, mas eu não poderia encontrar um átomo de 1 byte que converteria positiva / não-positiva em truthy / Falsas ...Æṃ
não existia naquela época.Python 2 , 35 bytes
Experimente online!
Resposta antiga, 38 bytes
Saídas
0
como Falsas e-2
ou-1
como truthyExperimente online!
fonte
bin
causa esta solução problemas?max
funciona. No caso de um empate, max retornará o primeiro valor no iterável que possui o valor máximo. Esse código usa esse fato para garantir que 1 seja retornado no caso de um empate, o que realmente significa que há mais do que zeros, pois um zero extra foi adicionado porbin
. Na verdade, seria incorreto quando escrito dessa maneira, se não fosse o zero extra.cmp
retornos0
quando ambos são iguaisOitava , 18 bytes
O TIO não funciona, pois a caixa de ferramentas de comunicação não está incluída. Pode ser testado no Octave-Online .
Como isso funciona:
de2bi
converte um número decimal em um vetor numérico binário, não uma string comodec2bin
faz.mode
retorna o dígito mais frequente no vetor. O padrão é o mais baixo em caso de empate.fonte
JavaScript (ES6),
3634 bytesfonte
f=(n,x=0)=>n?f(n>>>1,x+=n%2-.5):x>0
por 35 bytes.n>>1
vez den>>>1
para salvar um byte, pois a entrada nunca é negativa.n/2|0
não é melhor: /MATL , 3 bytes
Experimente online!
Eu realmente não conheço o MATL, apenas notei que isso
mode
poderia funcionar na resposta Octave do alephalpha e achei que havia algum equivalente no MATL.fonte
Mathematica, 22 bytes
Salvo um byte graças a @MartinEnder e @JungHwanMin .
fonte
@@
.#>#2&@@#~DigitCount~2&
Braquilog , 6 bytes
Experimente online!
Explicação
Como
ḃ
nunca unificará sua saída com uma lista de dígitos com zeros à esquerda, sabemos que as ocorrências de1
sempre serão as primeiras e as ocorrências de0
sempre serão as seguintesọ
.fonte
Python 3 ,
44(obrigado @ c-mcavoy) 40 bytesExperimente online!
fonte
C (gcc) ,
51484140 bytesExperimente online!
fonte
unsigned
n>>=1
paran/=2
. Eu também acho que você pode usar~n
em vez den^-1
, que também deve permitir que você mude&&
para&
n
, e não se preocupe em mudar&&
para&
, acho que não funcionaria. Mas alterá-lo para*
parece funcionar&&
foi apenas para lidar com o caso não assinado, mas como eu só preciso lidar com números inteiros positivos, posso removê-lo todos juntos. Bom pouint sobre/=
ser mais curto que>>=
, porém, obrigado!n&1?++i:--1
parai+=n%2*2-1
. Você também pode ser capaz de se livrar de>0
, afirmando que irá imprimir zero para pesado e diferente de zero para não pesadoR ,
545351 bytes-1 byte graças a Max Lawnboy
lê de stdin; retorna
TRUE
para números pesados binários.d
é o número de dígitos binários;sum(n%/%2^(0:d)%%2
calcula a soma dos dígitos (ou seja, número de unidades).Experimente online!
fonte
log2(n)
em vez delog(n,2)
salvar 1 bytecódigo de máquina x86_64,
232221 bytesDesmontado:
Obrigado @Ruslan, @PeterCordes pelo
-1
byte!Experimente online!
fonte
8d 1f
vez de89 fb
?add eax, 2
+dec eax
, mas seus comentários sugerem que você deseja incrementarebx
, nãoeax
.jnz Next
/add
/dec
(7 bytes) porlea -1(%rax, %rbx, 2), %eax
(4 bytes) a ser executadoeax += 2*ebx - 1
(como na outra resposta do código de máquina x86 ). Depois, fora do loop,neg %eax
(2 bytes) antes de mudar o bit de sinal para o fundo. Economia líquida de 1 byte. Outest %eax,%eax
/setge %al
também funcionaria, se o seu valor de retorno for umbool
ouint8_t
.lea -1(%rax,rbx,2)
apenaslea -1(%eax,%eax,2)
e desperdiçado bytes dessa maneira. Enfim, vocês dois estavam certos, posso salvar um byte como esse. Muito obrigado (em troca, vou mudar issolea
por ummov
tempo)!Perl 6 ,
3230 bytesTeste-o
Teste-o
Expandido:
fonte
Sábio ,
4039 bytesExperimente online!
Explicação
fonte
Haskell,
4134Se
n
for ímpar, pegue um-1
se for par, pegue um1
. Adicione uma chamada recursiva comn/2
e pare sen = 0
. Se o resultado for menor que0
o número, será muito pesado.Experimente online!
Edit: @ Ørjan Johansen encontrou alguns atalhos e salvou 7 bytes. Obrigado!
fonte
mod n 2
pode ser juston
e é um byte mais curto sem um acumulador. Experimente online!Retina ,
3734 bytesExperimente online! O link inclui casos de teste menores (os maiores provavelmente ficarão sem memória). Editar: salvou 3 bytes graças a @MartinEnder. Explicação: O primeiro estágio é convertido de decimal em unário, e os próximos dois estágios são convertidos de unário em binário (isso é quase direto na página aritmética unária no wiki da Retina, exceto pelo uso em
@
vez de0
). O terceiro estágio procura pares de caracteres diferentes, que podem ser um@1
ou1@
, e os exclui até que não restem mais. O último estágio verifica os 1s restantes.fonte
${1}
pode ser$+
. Ou você pode usar em!
vez de0
e encurtar01|10
para.\b.
.$+
a coisa certa quando o padrão contém um|
? Gostaria de saber se eu poderia ter usado isso antes ...$+
é super estúpido e simplesmente usa o grupo com o maior número, tenha sido usado ou não. Só é útil para jogar golfe quando você tem mais de nove grupos ou em uma situação como a daqui, e não sei por que o usaria em um regex de produção.R , 43 bytes
Experimente online!
fonte
intToBits
Kotlin , 50 bytes
Lambda do tipo implícito
(Int) -> Boolean
. Versão 1.1 e superior apenas devido ao uso deInt.toString(radix: Int)
.Infelizmente, o tempo de execução Kotlin do TIO parece ser 1.0.x, então aqui está um cachorro triste em vez de um link do TIO:
fonte
Pitão,
97 bytesExperimente aqui.
-2 graças a FryAmTheEggman .
fonte
>ysJjQ2lJ
.B
!)R,
3937 bytesEssa é uma combinação dos métodos usados pelo @MickyT e pelo @ Giuseppe, economizando mais alguns bytes.
sum(intToBits(x) > 0)
conta a quantidade de1
bits e2+log2(x)/2
é metade da quantidade total de bits, quando arredondado para baixo. Não precisamos arredondar para baixo por causa do comportamento quando os dois valores são iguais.fonte
C # (.NET Core) ,
62, 49 bytesSem LINQ.
EDIT: dana com um golf de -13 bytes alterando o tempo para um recursivo e retornando um bool ao invés de inteiro.
Experimente online!
fonte
Regex (ECMAScript),
857371 bytesExperimente online!
explicação por Deadcode
A versão anterior de 73 bytes é explicada abaixo.
^((?=(x*?)\2(\2{4})+$)\2|(?=(x*?)(\4\4xx)*$)(\4|\5(x*)\7\7(?=\4\7$)\B))+$
Devido às limitações da expressão regular ECMAScript, uma tática eficaz é frequentemente transformar a etapa número um de cada vez, mantendo a propriedade requerida invariável a cada etapa. Por exemplo, para testar um quadrado perfeito ou uma potência de 2, reduza o número em tamanho, mantendo um quadrado ou uma potência de 2 (respectivamente) a cada etapa.
Aqui está o que essa solução faz a cada etapa:
1
1
1
10
01
01
Quando essas etapas repetidas não puderem avançar, o resultado final será uma sequência de
1
bits contígua , que é pesada, e indica que o número original também era pesado, ou uma potência de 2, indicando que o número original não era pesado.E, é claro, embora essas etapas sejam descritas acima em termos de manipulações tipográficas na representação binária do número, elas são realmente implementadas como aritmética unária.
fonte
\5
posteriores são desativadas uma a uma). Estudei isso, expliquei e comentei na minha resposta (porque o StackExchange não permite respostas de várias linhas).Regex (ECMAScript), 183 bytes
Esse foi outro problema interessante a ser resolvido com o regex ECMA. A maneira "óbvia" de lidar com isso é contar o número de
1
bits e compará-lo ao número total de bits. Mas você não pode contar diretamente as coisas na expressão regular ECMAScript - a falta de referências persistentes significa que apenas um número pode ser modificado em um loop e, a cada passo, só pode ser diminuído.Esse algoritmo unário funciona da seguinte maneira:
1
bit mais significativo para a posição menos significativa onde houver um0
pouco. Cada uma dessas etapas é uma subtração. No final do loop, o número restante (como seria representado em binário) é uma sequência de1
s sem0
s. Essas operações são realmente feitas em unário; é apenas conceitualmente que eles estão sendo feitos em binário.1
s" com a raiz quadrada obtida anteriormente. Se a raiz quadrada tiver que ser arredondada para baixo, use uma versão duplicada. Isso garante que a "sequência binária de1
s" seja necessária para ter mais da metade dos dígitos binários que N para que haja uma correspondência final.Para obter a raiz quadrada, é usada uma variante do algoritmo de multiplicação descrita brevemente no meu post de regex de números Rocco . Para identificar o
0
bit menos significativo , é usado o algoritmo de divisão descrito brevemente no meu número de fatorial regex post . Estes são spoilers . Portanto , não leia mais se não quiser que você estrague uma mágica avançada de expressões regulares unárias . Se você quiser tentar descobrir essa mágica, eu recomendo começar resolvendo alguns problemas na lista de problemas recomendados consecutivamente identificados por spoilers neste post anterior e tentando apresentar os insights matemáticos de forma independente.Sem mais delongas, a regex:
^(?=.*?(?!(x(xx)+)\1*$)(x)*?(x(x*))(?=(\4*)\5+$)\4*$\6)(?=(((?=(x(x+)(?=\10$))*(x*))(?!.*$\11)(?=(x*)(?=(x\12)*$)(?=\11+$)\11\12+$)(?=.*?(?!(x(xx)+)\14*$)\13(x*))\16)*))\7\4(.*$\3|\4)
Experimente online!
fonte
Gelatina , 6 bytes
Experimente online!
fonte
Bo-S
pode ser usado para calcular o "peso" binário da entrada, infelizmente, a maneira mais curta de usar que parece serBo-S>0
... #Ḷ
funciona: PJ , 12 bytes
J executa verbos da direita para a esquerda, então vamos começar no final e trabalhar para o começo.
Explicação
fonte
(#<2*+/)@#:
deve salvar 1, a menos que esteja faltando alguma coisa.Julia, 22 bytes
fonte
Oitava , 26 bytes
Experimente online!
fonte
mode(dec2bin(a)-48)
PHP , 44 bytes
Experimente online!
PHP , 48 bytes
Experimente online!
fonte
Python 2 , 44 bytes
Experimente online!
Resposta antiga, 47 bytes
Esta é simplesmente uma porta da resposta C do @ cleblanc . É mais longo que as outras respostas do Python, mas achei que valia a pena postar, pois é um método completamente diferente de encontrar a resposta.
Experimente online!
fonte
C #, 82 bytes
fonte
n=>{var s=Convert.ToString(n,2);return s.Count(c=>c=='1')>s.Length/2;}
Convert
e incluir totalmenteusing System.Linq;
(escrito mais curto comonamespace System.Linq{}
). A boa ideia simplesmente não raspa o suficiente para justificar a economia nesse caso.