O número pode ser dividido em potências de 2?


33

Ontem, enquanto brincava com meu filho, notei o número em seu trem de brinquedo:

4281

Portanto, temos que podem ser divididos em ou

4281
4-2-8-1
22-21-23-20 0

Desafio tão simples: dado um número não negativo como entrada, retorne valores de verdade e falsey consistentes que representam se a representação em cadeia do número (na base 10 e sem zeros à esquerda) pode ou não ser dividida em números com potências de 2 .

Exemplos:

4281      truthy (4-2-8-1)
164       truthy (16-4 or 1-64)
8192      truthy (the number itself is a power of 2)
81024     truthy (8-1024 or 8-1-02-4)
101       truthy (1-01)
0         falsey (0 cannot be represented as 2^x for any x)
1         truthy
3         falsey
234789    falsey
256323    falsey (we have 256 and 32 but then 3)
8132      truthy (8-1-32)

Tests for very large numbers (not really necessary to be handled by your code):
81024256641116  truthy (8-1024-256-64-1-1-16)
64512819237913  falsey

Este é o ; portanto, pode ganhar o código mais curto para cada idioma!


2
@ StewieGriffin Inicialmente, pensei em limitar o número de entrada ao intervalo de um inttipo padrão (4 bytes), mas na verdade não me importo se o seu código não suportar números muito grandes. Apenas indique na sua resposta as limitações do seu código.
Charlie

3
Caso de teste sugerido: 101(falso por causa do 0) ... ou isso ainda deve ser verdade ( 1 - 01)?
Shieru Asakoto

1
@ShieruAsakoto Venho testando o 101caso com as respostas atuais e todas elas retornam true, porque pode ser dividido em 1-01duas potências de 2, então considerarei esse caso verdadeiro.
11118 Charlie

6
Apenas deixando isso aqui como uma dica para todos. Aqui estão três maneiras possíveis de verificar se um número é uma potência de 2: 1) Verifique se log2(n)não contém dígitos decimais após a vírgula. 2) Verifique se n AND (n-1) == 0. 3) Crie uma lista de quadrados-nrs e verifique se nestá nessa lista.
Kevin Cruijssen 11/10/1918

1
" square-nrs " deve ser " powers of 2 " no meu comentário acima, é claro ..>.>
Kevin Cruijssen

Respostas:


11

05AB1E , 9 8 bytes

Ýos.œåPZ

-1 byte, graças a @Emigna , usando Z(max) para a lista de 0s e 1s para imitar um anycomando para 1(verdade).

Experimente online ou verifique todos os casos de teste . (OBSERVAÇÃO: O тcabeçalho serve 100apenas para obter as 100 primeiras potências de 2 números, em vez da primeira quantidade de entrada de potência de 2 números. Ele funciona com a quantidade de entrada de potência 2, mas é bastante ineficiente e pode tempo limite no TIO se a entrada for grande o suficiente.)

Explicação:

Ý            # Create a list in the range [0,n], where n is the (implicit) input
             # (or 100 in the TIO)
             #  i.e. 81024 → [0,1,2,3,...,81024]
 o           # Raise 2 to the `i`'th power for each `i` in the list
             #  → [1,2,4,8,...,451..216 (nr with 24391 digits)]
  s          # Swap to take the input
           # Create each possible partition of this input
             #  i.e. 81024 → [["8","1","0","2","4"],["8","1","0","24"],...,["8102","4"],["81024"]]
     å       # Check for each if it's in the list of powers of 2
             #  → [[1,1,0,1,1],[1,1,0,0],...,[0,1],[0]]
      P      # Check for each inner list whether all are truthy
             #  → [0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0]
       Z     # Take the maximum (and output implicitly)
             #  → 1 (truthy)

2
Bom, minha solução foi .œ.²1%O0å(9 bytes também). A minha falhou 0, no entanto.
Mr. Xcoder

@ Mr.Xcoder Ah, também .²1%O0é muito inteligente. Pensei em usar log2assim .²DïQ, mas seria necessário um mapa para fazer isso para cada número e, de fato, não funcionou para casos extremos 0.
Kevin Cruijssen 11/11


6

JavaScript (Node.js) , 69 64 58 bytes

f=(x,m=10,q=!(x%m&x%m-1|!x))=>x<m?q:q&&f(x/m|0)||f(x,10*m)

Experimente online!

Insira como número. A parte lógica é bastante complicada, por isso não faz ideia de como desembaraçar e se livrar q.

-11 bytes, jogando a verificação de potência de 2.



5

Geléia , 9 bytes

ŒṖḌl2ĊƑ€Ẹ

Confira a suíte de testes!


Alternativo

Não funciona para os grandes casos de teste devido a problemas de precisão.

ŒṖḌæḟƑ€2Ẹ

Confira a suíte de testes!

Quão?

Programa I

ŒṖḌl2ĊƑ€Ẹ     Full program. N = integer input.
ŒṖ            All possible partitions of the digits of N.
  Ḍ           Undecimal (i.e. join to numbers).
   l2         Log2. Note: returns (-inf+nanj) for 0, so it doesn't fail.
     ĊƑ€      For each, check if the logarithm equals its ceil.
        Ẹ     Any. Return 0 if there are no truthy elements, 1 otherwise.

Programa II

ŒṖḌæḟƑ€2Ẹ     Full program. N = integer input.
ŒṖ            All possible partitions of the digits of N.
  Ḍ           Undecimal (i.e. join to numbers).
     Ƒ€       For each partition, check whether its elements are invariant under...
   æḟ  2      Flooring to the nearest power of 2.
        Ẹ     Any. Return 0 if there are no truthy elements, 1 otherwise.


5

JavaScript, 59 bytes

s=>eval(`/^(${(g=x=>x>s?1:x+'|0*'+g(x+x))(1)})+$/`).test(s)

Experimente online!

Constrói uma regex semelhante a /^(1|0*2|0*4|0*8|0*16|0*32|…|0*1)+$/potências de 2 e a testa s.

Somente funciona com a precisão dos números JavaScript, é claro: eventualmente os termos no regex serão parecidos com 1.2345678e30(ou Inf). Mas como potências de 2 são fáceis de representar com precisão em ponto flutuante, elas nunca serão números inteiros errados , o que seria mais desqualificante, eu acho.

@tsh salvou 14 bytes. Neato!





3

APL (NARS), 154 caracteres, 308 bytes

∇r←f w;g;b;z;k
   g←{⍵≤0:1⋄t=⌊t←2⍟⍵}⋄→A×⍳∼w≤9⋄r←g w⋄→0
A: z←w⋄b←0⋄k←1
B: b+←k×10∣z⋄z←⌊z÷10
   →C×⍳∼g b⋄r←∇z⋄→0×⍳r
C: k×←10⋄→B×⍳z≠0
   r←0
∇
h←{⍵=0:0⋄f ⍵}

A função para o exercício é h. O algoritmo não parece exponencial ou fatorial ... test:

  h¨ 4281 164 8192 81024 101 
1 1 1 1 1 
  h¨ 0 1 3 234789 256323 8132
0 1 0 0 0 1 
  h 81024256641116
1
  h 64512819237913
0




2

Ruby , 49 bytes

->n{n.to_s=~/^(0*(#{(0..n).map{|x|2**x}*?|}))*$/}

Experimente online!

Só funciona em teoria. Leva uma eternidade para grandes valores den


2

PHP, 101 bytes

Não parece conseguir isso abaixo de 100; mas eu poderia chegar a 100 se 101fosse um caso falso.

function f($s){for($x=.5;$s>=$x*=2;)if(preg_match("/^$x(.*)$/",$s,$m)?!~$m[1]||f(+$m[1]):0)return 1;}

Nvocêeueu1

variações:

for($x=.5;$s>=$x*=2;)
while($s>=$x=1<<$i++)   # yields notices "undefined variable $i"

?!~$m[1]||f(+$m[1]):0
?~$m[1]?f(+$m[1]):1:0

PHP 5 ou mais, 95 bytes

function f($s){while($s>=$x=1<<$i++)if(ereg("^$x(.*)$",$s,$m)?$m[1]>""?f(+$m[1]):1:0)return 1;}

2

Vermelho , 212 211 bytes

func[n][g: func[x][(log-2 do x)% 1 = 0]repeat i 2 **((length? s: form n)- 1)[b: a:
copy[] k: i foreach c s[append b c if k % 2 = 0[alter a g rejoin b
b: copy[]]k: k / 2]append a g form c if all a[return on]]off]

Experimente online!

Outro envio longo, mas não estou totalmente insatisfeito, porque não há um recurso interno para encontrar todas as substrings em vermelho.

Mais legível:

f: func [ n ] [
    g: func [ x ] [ (log-2 do x) % 1 = 0 ]
    repeat i 2 ** ((length? s: form n) - 1) [
        b: a: copy []
        k: i
        foreach c s [
            append b c
            if k % 2 = 0 [ 
                append a g rejoin b
                b: copy []
            ]
            k: k / 2 
        ]
        append a g form c
        if all a[ return on ]
    ]
    off
]

2

Axioma, 198 bytes

G(a)==(a<=1=>2>1;x:=log_2 a;x=floor x)
F(n)==(n<=9=>G n;z:=n;b:=0;k:=1;repeat(b:=b+k*(z rem 10);z:=z quo 10;if G b and F z then return 2>1;k:=k*10;z<=0=>break);1>1)
H(n:NNI):Boolean==(n=0=>1>1;F n)

ungolf e teste

g(a)==(a<=1=>2>1;x:=log_2 a;x=floor x)
f(n)==
   n<=9=>g n
   z:=n;b:=0;k:=1
   repeat
      b:=b+k*(z rem 10);z:=z quo 10;
      if g b and f z then return 2>1
      k:=k*10
      z<=0=>break
   1>1
h(n:NNI):Boolean==(n=0=>1>1;f n)

(15) -> [[i,h i] for i in [4281,164,8192,81024,101]]
   (15)  [[4281,true],[164,true],[8192,true],[81024,true],[101,true]]
                                                      Type: List List Any
(16) -> [[i,h i] for i in [0,1,3,234789,256323,8132]]
   (16)  [[0,false],[1,true],[3,false],[234789,false],[256323,false],[8132,true]]
                                                      Type: List List Any
(17) -> [[i,h i] for i in [81024256641116, 64512819237913]]
   (17)  [[81024256641116,true],[64512819237913,false]]
                                                      Type: List List Any
(18) -> h 44444444444444444444444444
   (18)  true
                                                            Type: Boolean
(19) -> h 44444444444444444128444444444
   (19)  true
                                                            Type: Boolean
(20) -> h 4444444444444444412825444444444
   (20)  false
                                                            Type: Boolean
(21) -> h 2222222222222244444444444444444412822222222222210248888888888882048888888888888888
   (21)  true
                                                            Type: Boolean
(22) -> h 222222222222224444444444444444441282222222222225128888888888882048888888888888888
   (22)  true
                                                            Type: Boolean

1

Japonês -!, 12 bytes

Recebe a entrada como uma sequência.

ÊÆòXÄÃex_&ZÉ

Tente


o 0 caso é gerado truee, portanto, casos como 1010também são gerados true.
Charlie

1

Bytes C # 157

bool P(string s,int i=1)=>i>=s.Length?((Func<ulong,bool>)((x)=>(x!=0)&&((x&(x-1))==0)))(ulong.Parse(s)):(P(s,i+1)||(P(s.Substring(0,i))&&P(s.Substring(i))));

Você pode experimentá-lo online


1

APL (NARS), 70 caracteres, 140 bytes

P←{k←↑⍴⍵⋄x←11 1‼k k⋄y←⍵⋄∪{x[⍵;]⊂y}¨⍳↑⍴x}
f←{⍵=0:0⋄∨/∧/¨y=⌊y←2⍟⍎¨¨P⍕⍵}

teste:

  f¨ 4281 164 8192 81024 101
1 1 1 1 1 
  f¨ 0 1 3 234789 256323 8132
0 1 0 0 0 1 
  f 126
0

Eu não tento fazer outros números maiores ... Eu tenho que observar que P não é partição normal, mas é uma partição em que todos os elementos são subconjuntos que têm membros consecutivos, por exemplo

  ⎕fmt P 'abc'
┌4──────────────────────────────────────────────────┐
│┌1─────┐ ┌2─────────┐ ┌2─────────┐ ┌3─────────────┐│
││┌3───┐│ │┌2──┐ ┌1─┐│ │┌1─┐ ┌2──┐│ │┌1─┐ ┌1─┐ ┌1─┐││
│││ abc││ ││ ab│ │ c││ ││ a│ │ bc││ ││ a│ │ b│ │ c│││
││└────┘2 │└───┘ └──┘2 │└──┘ └───┘2 │└──┘ └──┘ └──┘2│
│└∊─────┘ └∊─────────┘ └∊─────────┘ └∊─────────────┘3
└∊──────────────────────────────────────────────────┘

note que está ausente o elemento ((ac) (b)) ou melhor ,, ¨ ('ac') 'b'

  ⎕fmt ,,¨('ac')'b'
┌2─────────┐
│┌2──┐ ┌1─┐│
││ ac│ │ b││
│└───┘ └──┘2
└∊─────────┘

1

POSIX ERE, 91 bytes

(0*([1248]|16|32|64|128|256|512|1024|2048|4096|8192|16384|32768|65536|131072|262144|524288))+

Isso é uma trapaça total, com base no grande número de textos (não é realmente necessário ser tratado pelo seu código) na pergunta; ele lida com todos os valores no intervalo de tamanho dos exemplos. Obviamente, pode ser estendido até a faixa completa de tipos inteiros de 32 ou 64 bits, à custa do tamanho. Eu o escrevi principalmente como uma demonstração de como o problema se encaixa naturalmente na ferramenta. Um exercício divertido seria reescrevê-lo como um programa que gera o ERE para um intervalo arbitrário e depois o compara.


1

C (gcc) , -DA=asprintf(&c,+ 108 = 124 bytes

p,c;f(a,i){c="^(0*(1";for(i=0;i<31;)A"%s|%d",c,1<<++i);A"%s))+$",c);regcomp(&p,c,1);a=!regexec(&p,a,0,0,0);}

Experimente online!

Isso cria uma regex dos poderes de 2 até 2 ** 32 e, em seguida, combina a string de entrada com ela.


1

PowerShell, 56 bytes

$x=(0..63|%{1-shl$_})-join'|0*'
"$args"-match"^(0*$x)+$"

Script de teste:

$f = {

    $x=(0..63|%{1-shl$_})-join'|0*'
    "$args"-match"^(0*$x)+$"

}

@(
    ,(4281            ,$true)
    ,(164             ,$true)
    ,(8192            ,$true)
    ,(81024           ,$true)
    ,(101             ,$true)
    ,(0               ,$false)
    ,(1               ,$true)
    ,(3               ,$false)
    ,(234789          ,$false)
    ,(256323          ,$false)
    ,(8132            ,$true)
    ,("81024256641116"  ,$true)
    ,("64512819237913"  ,$false)
) | % {
    $n, $expected = $_
    $result = &$f $n
    "$($result-eq$expected): $result <- $n"
}

Saída:

True: True <- 4281
True: True <- 164
True: True <- 8192
True: True <- 81024
True: True <- 101
True: False <- 0
True: True <- 1
True: False <- 3
True: False <- 234789
True: False <- 256323
True: True <- 8132
True: True <- 81024256641116
True: False <- 64512819237913

Explicação:

Constrói um regex semelhante a ^(0*1|0*2|0*4|0*8|0*16|0*32|…)+$potências de 2 e testa-o em argumentos.


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.