Чи можна поділити число на потужності 2?


33

Вчора під час гри з дитиною я помітив номер у його іграшковому поїзді:

4281

Отже, у нас є

4281
який можна розділити на
4281
або
22212320

Настільки простий виклик: задавши невід'ємне число як вхідне значення, поверніть послідовні значення truthy та falsey, які представляють, чи може бути рядкове представлення числа (у базі 10 та без провідних нулів) можна якось розділити на числа, що мають потужність 2 .

Приклади:

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

Це , тому може виграти найкоротший код для кожної мови!


2
@StewieGriffin спочатку думав про обмеження вхідного номера діапазоном стандартного intтипу (4 байти), але насправді я не проти, якщо ваш код не підтримує дуже великі числа. Просто вкажіть у відповіді обмеження вашого коду.
Чарлі

3
Пропонований тестовий випадок: 101(хибність через 0) ... чи це все-таки має бути правдою ( 1 - 01)?
Шиеру Асакото

1
@ShieruAsakoto Я перевіряв 101справу з поточними відповідями, і всі вони повертаються true, тому що це може бути розділено на 1-01обидві сили 2, тому я вважаю цей випадок правдивим.
Чарлі

6
Просто залишивши це тут, як пораду для всіх. Ось три можливі способи перевірити, чи число є потужністю 2: 1) Перевірте, чи log2(n)не містить десяткових цифр після коми. 2) Перевірте, чи є n AND (n-1) == 0. 3) Створіть список квадратних ліній і перевірте, чи nє в цьому списку.
Кевін Крейссен

1
У моєму коментарі вище " квадратиків " повинні бути " сили 2 ".>.>
Кевін Круїссен

Відповіді:


11

05AB1E , 9 8 байт

Ýos.œåPZ

-1 байт завдяки @Emigna , використовуючи Z(max) для списку 0 і 1s, щоб імітувати anyкоманду for 1(truthy).

Спробуйте в Інтернеті або перевірте всі тестові справи . (ПРИМІТКА. У тзаголовку 100потрібно отримати лише перші 100 потужностей з 2 чисел, замість першого вхідного значення потужності 2 чисел. Це також працює з вхідною потужністю 2, але є досить неефективною і може бути тайм-аут у TIO, якщо вхід досить великий.)

Пояснення:

Ý            # 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å(також 9 байт). 0Однак міна провалилася .
Містер Xcoder

@ Mr.Xcoder Ах, .²1%O0також досить розумний. Я думав про log2подібне використання .²DïQ, але для цього потрібно буде карта навколо нього, щоб це зробити для кожного номера, і воно справді не працювало для кращого регістру 0.
Кевін Кройсейсен




5

Желе , 9 байт

ŒṖḌl2ĊƑ€Ẹ

Перевірте тестовий набір!


Альтернатива

Не працює для великих тестових випадків через проблеми з точністю.

ŒṖḌæḟƑ€2Ẹ

Перевірте тестовий набір!

Як?

Програма 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.

Програма 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 байт

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

Спробуйте в Інтернеті!

Створює регулярний вираз, як /^(1|0*2|0*4|0*8|0*16|0*32|…|0*1)+$/потужність 2, і тестує йогоs .

Зрозуміло, працює лише до точності номерів JavaScript: з часом терміни в регулярному виразі будуть виглядати 1.2345678e30(або Inf). Але оскільки сили 2 легко представити точно з плаваючою точкою, вони ніколи не помиляться цілими числами, що було б більш дискваліфікуючим, я думаю.

@tsh зберегло 14 байт. Неато!





3

APL (NARS), 154 символів, 308 байт

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

Функцією для вправи є h. Алгоритм не здається експоненціальним чи факторіальним ... тест:

  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 байт

Здається, це не може бути нижче 100; але я міг би отримати його до 100, якби 101був хибний випадок.

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

повертає NULL для помилкових і 1за правдою. Спробуйте в Інтернеті .

варіації:

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 або старше, 95 байт

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

2

Червоний , 212 211 байт

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]

Спробуйте в Інтернеті!

Ще одне довге подання, але я не цілком незадоволений, тому що немає вбудованого для пошуку всіх підрядів у червоному кольорі.

Більше читати:

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

Аксіома, 198 байт

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 і тест

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

APL (NARS), 70 символів, 140 байт

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

тест:

  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

я не намагаюся робити інші більші числа ... Я повинен зазначити, що P не є нормальним розділом, але це один розділ, де всі елементи підмножини, які мають член усі послідовно, наприклад

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

зауважте, що немає елемента ((ac) (b)) або краще ,, ¨ ('ac') 'b'

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

1

POSIX ERE, 91 байт

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

Це цілком обман, виходячи з тексту великій кількості (не дуже потрібно, щоб обробляти ваш код) у запитанні; він обробляє всі значення в діапазоні розмірів прикладів. Очевидно, може бути розширений до повного діапазону 32- або 64-бітних цілочисельних типів за рахунок розміру. Я в основному писав це як демонстрацію того, як проблема, природно, відповідає інструменту. Веселою вправою було б переписати його як програму, яка генерує ERE для довільного діапазону, а потім відповідає проти нього.


1

C (gcc) ,-DA=asprintf(&c, + 108 = 124 байт

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

Спробуйте в Інтернеті!

Це створює регекс потужностей від 2 до 2 ** 32, а потім відповідає вхідному рядку проти нього.


1

Powershell, 56 байт

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

Тестовий сценарій:

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

Вихід:

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

Пояснення:

Будує регулярний вираз, як ^(0*1|0*2|0*4|0*8|0*16|0*32|…)+$потужність 2, і тестує його на аргументах.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.