Kann die Zahl in Zweierpotenzen aufgeteilt werden?


33

Gestern habe ich beim Spielen mit meinem Kind die Nummer in seiner Spielzeugeisenbahn bemerkt:

4281

Wir haben also , die sich in oder

4281
4281
22212320

Einfache Herausforderung: Geben Sie bei einer nicht negativen Zahl als Eingabe konsistente Wahrheits- und False-Werte zurück, die angeben, ob die Zeichenfolgendarstellung der Zahl (in Basis 10 und ohne führende Nullen) in Zahlen mit Zweierpotenzen aufgeteilt werden kann .

Beispiele:

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

Das ist , also kann der kürzeste Code für jede Sprache gewinnen!


2
@StewieGriffin Anfangs dachte ich darüber nach, die Eingabenummer auf den Bereich eines Standardtyps int(4 Bytes) zu beschränken, aber eigentlich macht es mir nichts aus, wenn Ihr Code keine sehr großen Zahlen unterstützt. Geben Sie in Ihrer Antwort einfach die Einschränkungen Ihres Codes an.
Charlie

3
Vorgeschlagener Testfall: 101(falsch wegen der 0) ... oder sollte das noch stimmen ( 1 - 01)?
Shieru Asakoto

1
@ShieruAsakoto Ich habe den 101Fall mit den aktuellen Antworten getestet und sie alle kehren zurück true, weil es in 1-01zwei Potenzen aufgeteilt werden kann. Daher halte ich diesen Fall für wahr.
Charlie

6
Lassen Sie dies hier nur als Tipp für alle. Es gibt drei Möglichkeiten, um zu überprüfen, ob eine Zahl eine Potenz von 2 ist: 1) Überprüfen Sie, ob log2(n)nach dem Komma keine Dezimalstellen stehen. 2) Überprüfen Sie, ob n AND (n-1) == 0. 3) Erstellen Sie eine Liste mit Quadraten und prüfen Sie, ob sie nin dieser Liste enthalten sind.
Kevin Cruijssen

1
" square-nrs " sollte in meinem obigen Kommentar natürlich " Potenzen von 2 " sein ..>.>
Kevin Cruijssen

Antworten:


11

05AB1E , 9 8 Bytes

Ýos.œåPZ

-1 Byte danke an @Emigna mit Z(max) für die Liste der Nullen und Einsen, um einen anyBefehl für 1(truthy) nachzuahmen.

Probieren Sie es online aus oder überprüfen Sie alle Testfälle . (HINWEIS: Im тHeader werden 100nur die ersten 100 Potenzen von 2 Zahlen anstelle der ersten eingegebenen Potenz von 2 Zahlen angezeigt. Dies funktioniert auch mit der eingegebenen Potenz von 2, ist jedoch ziemlich ineffizient und kann zu Problemen führen Timeout bei TIO, wenn der Eingang groß genug ist.)

Erläuterung:

Ý            # 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
Schön, meine Lösung war .œ.²1%O0å(auch 9 Bytes). Meins schlug 0jedoch fehl .
Mr. Xcoder

@ Mr.Xcoder Ah, .²1%O0ist auch ziemlich schlau. Ich habe darüber nachgedacht, log2dies zu verwenden .²DïQ, aber es würde eine Karte erfordern, um dies für jede Zahl zu tun, und es funktionierte in der Tat nicht für Edge-Case 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)

Probieren Sie es online!

Eingabe als Nummer. Der logische Teil ist ziemlich verworren, also keine Ahnung, wie man ihn entwirrt und loswird q.

-11 Bytes durch Golfen des Power-of-2-Checks.



5

Gelee , 9 Bytes

ŒṖḌl2ĊƑ€Ẹ

Schauen Sie sich die Testsuite an!


Alternative

Funktioniert aufgrund von Genauigkeitsproblemen nicht für große Testfälle.

ŒṖḌæḟƑ€2Ẹ

Schauen Sie sich die Testsuite an!

Wie?

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

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

Probieren Sie es online!

Erstellt einen regulären Ausdruck /^(1|0*2|0*4|0*8|0*16|0*32|…|0*1)+$/mit Potenzen von 2 und testet ihn s.

Funktioniert natürlich nur bis zur Genauigkeit von JavaScript-Zahlen: Irgendwann sehen die Begriffe in der Regex wie 1.2345678e30(oder Inf) aus. Aber da Potenzen von 2 im Gleitkomma leicht genau darzustellen sind, werden sie niemals falsche ganze Zahlen sein, was disqualifizierender wäre, denke ich.

@tsh sparte 14 Bytes. Neato!





3

APL (NARS), 154 Zeichen, 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 ⍵}

Die Funktion für die Übung ist h. Der Algorithmus scheint nicht exponentiell oder faktoriell zu sein ...

  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

PHP, 101 Bytes

Kann nicht unter 100 kommen; aber ich könnte es auf 100 bringen, wenn 101es ein falscher Fall wäre.

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

NULL1

Variationen:

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 oder älter, 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

Rot , 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]

Probieren Sie es online!

Noch eine lange Einreichung, aber ich bin nicht völlig unzufrieden, da es keine eingebaute Funktion gibt, um alle Teilzeichenfolgen in Rot zu finden.

Besser lesbar:

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

Axiom, 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 und test

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 Bytes

Übernimmt die Eingabe als Zeichenfolge.

ÊÆòXÄÃex_&ZÉ

Versuch es


Der 0Fall gibt aus trueund damit Fälle wie 1010auch aus true.
Charlie

1

C # 157 Bytes

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

Sie können es online ausprobieren


1

APL (NARS), 70 Zeichen, 140 Byte

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

Prüfung:

  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

Ich versuche nicht, andere größere Zahlen zu machen ... Ich muss beachten, dass P keine normale Partition ist, sondern eine Partition, in der alle Elemente Teilmengen sind, deren Mitglieder beispielsweise alle aufeinanderfolgend sind

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

Beachten Sie, dass das Element ((ac) (b)) oder besser ,, ¨ ('ac') 'b' fehlt

  ⎕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))+

Dies ist völlig betrügerisch, basierend auf den großen Textzahlen (die von Ihrem Code nicht wirklich verarbeitet werden müssen) in der Frage. Es behandelt alle Werte im Größenbereich der Beispiele. Kann natürlich auf Kosten der Größe auf den gesamten Bereich von 32- oder 64-Bit-Integer-Typen erweitert werden. Ich habe es hauptsächlich als Demonstration geschrieben, wie das Problem natürlich zum Werkzeug passt. Eine unterhaltsame Übung wäre, sie als Programm umzuschreiben, das die ERE für einen beliebigen Bereich generiert und dann mit dieser übereinstimmt.


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

Probieren Sie es online!

Dadurch wird ein regulärer Ausdruck der Potenzen von 2 bis 2 ** 32 erstellt und dann die Eingabezeichenfolge mit dieser verglichen.


1

Powershell, 56 Bytes

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

Testskript:

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

Ausgabe:

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

Erläuterung:

Erstellt einen regulären Ausdruck ^(0*1|0*2|0*4|0*8|0*16|0*32|…)+$mit Potenzen von 2 und testet ihn anhand von Argumenten.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.