Il numero può essere diviso in potenze di 2?


33

Ieri mentre giocavo con mio figlio ho notato il numero nel suo trenino:

4281

Quindi abbiamo che possono essere divisi in o

4281
4281
22212320

Sfida così semplice: dato un numero non negativo come input, restituisce valori di verità e falsità coerenti che rappresentano se la rappresentazione in stringa del numero (nella base 10 e senza zeri iniziali) può essere in qualche modo suddivisa in numeri che sono potenze di 2 .

Esempi:

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

Questo è , quindi può vincere il codice più breve per ogni lingua!


2
@StewieGriffin inizialmente ho pensato di limitare il numero di input all'intervallo di un inttipo standard (4 byte), ma in realtà non mi dispiace se il tuo codice non supporta numeri molto grandi. Indica nella tua risposta i limiti del tuo codice.
Charlie,

3
Caso di prova suggerito: 101(falsa a causa dello 0) ... o dovrebbe essere ancora vero ( 1 - 01)?
Shieru Asakoto,

1
@ShieruAsakoto Ho testato il 101caso con le risposte attuali e tutti ritornano true, perché può essere suddiviso in 1-01entrambi i poteri di 2, quindi considererò quel caso come veritiero.
Charlie,

6
Lasciando questo qui come suggerimento per tutti. Ecco tre modi possibili per verificare se un numero è una potenza di 2: 1) Controlla se log2(n)non contiene cifre decimali dopo la virgola. 2) Controlla se n AND (n-1) == 0. 3) Creare un elenco di quadrati e verificare se si ntrova in tale elenco.
Kevin Cruijssen,

1
" Square-nrs " dovrebbe essere " potenze di 2 " nel mio commento sopra ovviamente ..>.>
Kevin Cruijssen,

Risposte:


11

05AB1E , 9 8 byte

Ýos.œåPZ

-1 byte grazie a @Emigna utilizzando Z(max) per l'elenco di 0 e 1 secondi per simulare un anycomando per 1(verità).

Provalo online o verifica tutti i casi di test . (NOTA: тnell'intestazione si 100ottiene solo la prima 100 potenza di 2 numeri, invece della prima quantità di potenza di input di 2 numeri. Funziona anche con la quantità di potenza di input di 2, ma è piuttosto inefficiente e potrebbe timeout su TIO se l'ingresso è abbastanza grande.)

Spiegazione:

Ý            # 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
.œ.²1%O0åBene , la mia soluzione era (anche 9 byte). Il mio fallì 0, comunque.
Mr. Xcoder,

@ Mr.Xcoder Ah, .²1%O0è anche abbastanza intelligente. Ho pensato di usare in log2questo modo .²DïQ, ma avrebbe richiesto una mappa attorno per farlo per ogni numero, e in effetti non ha funzionato per il caso limite 0.
Kevin Cruijssen,


6

JavaScript (Node.js) , 69 64 58 byte

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

Provalo online!

Inserisci come numero. La parte logica è piuttosto contorta, quindi non ho idea di come districare e sbarazzarsi di q.

-11 byte giocando a golf il controllo power-of-2.



5

Gelatina , 9 byte

ŒṖḌl2ĊƑ€Ẹ

Dai un'occhiata alla suite di test!


Alternativa

Non funziona per i casi di test di grandi dimensioni a causa di problemi di precisione.

ŒṖḌæḟƑ€2Ẹ

Dai un'occhiata alla suite di test!

Come?

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

Programma 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 byte

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

Provalo online!

Costruisce una regex come /^(1|0*2|0*4|0*8|0*16|0*32|…|0*1)+$/dei poteri di 2 e lo mette alla prova s.

Funziona solo con la precisione dei numeri JavaScript, ovviamente: alla fine i termini nella regex appariranno 1.2345678e30(o Inf). Ma poiché i poteri di 2 sono facili da rappresentare accuratamente in virgola mobile, non saranno mai numeri interi sbagliati , il che sarebbe più squalificante, penso.

@tsh ha salvato 14 byte. Neato!





3

APL (NARS), 154 caratteri, 308 byte

∇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 ⍵}

La funzione per l'esercizio è h. L'algoritmo non sembra esponenziale o fattoriale ... 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

Rubino , 49 byte

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

Provalo online!

Funziona solo in teoria. Prende un'eternità per grandi valori din


2

PHP, 101 byte

Non riesco a ottenere questo sotto 100; ma potrei arrivare a 100 se 101fosse un 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;}

NULL1

varianti:

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 o precedente, 95 byte

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

2

Rosso , 212 211 byte

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]

Provalo online!

Un'altra lunga presentazione, ma non sono completamente insoddisfatto, perché non esiste un built-in per trovare tutte le sottostringhe in Red.

Più leggibile:

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

Assioma, 198 byte

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 prova

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

Japt -!, 12 byte

Accetta l'input come stringa.

ÊÆòXÄÃex_&ZÉ

Provalo


Il 0case genera truee quindi anche casi come 1010output true.
Charlie,

1

C # 157 byte

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

Puoi provarlo online


1

APL (NARS), 70 caratteri, 140 byte

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

test:

  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

non provo a fare altri numeri più grandi ... devo notare che P non è una partizione normale, ma è una partizione in cui tutti gli elementi sono sottogruppi che hanno membri tutti consecutivi, ad esempio

  ⎕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
└∊──────────────────────────────────────────────────┘

si noti che è assente l'elemento ((ac) (b)) o meglio ,, ¨ ('ac') 'b'

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

1

POSIX ERE, 91 byte

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

Questo è totalmente barare, basato sul grande numero di testo (non necessario per essere gestito dal tuo codice) nella domanda; gestisce tutti i valori nell'intervallo di dimensioni degli esempi. Ovviamente può essere esteso a tutta la gamma di tipi interi a 32 o 64 bit a scapito delle dimensioni. L'ho scritto principalmente come dimostrazione di come il problema si adatta naturalmente allo strumento. Un esercizio divertente sarebbe riscriverlo come un programma che genera l'ERE per un intervallo arbitrario e poi si abbina contro di esso.


1

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

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

Provalo online!

Questo crea una regex dei poteri da 2 a 2 ** 32, e quindi confronta la stringa di input contro di essa.


1

Powershell, 56 byte

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

Script di prova:

$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"
}

Produzione:

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

Spiegazione:

Costruisce una regex come ^(0*1|0*2|0*4|0*8|0*16|0*32|…)+$dei poteri di 2 e lo mette alla prova su argomenti.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.