숫자를 2의 거듭 제곱으로 나눌 수 있습니까?


33

어제 내 아이와 놀면서 장난감 기차에서 숫자를 보았습니다.

4281

따라서 우리는 4 2 8 1 또는 2 22 12 32 0 으로 나눌 수있는

4281
이 있습니다.
4281
2221220

그래서 간단한 도전 : 음수가 아닌 숫자를 입력으로 받으면 숫자의 문자열 표현 (기본 10과 선행 0 없음)을 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 바이트) 의 범위로 제한하는 것에 대해 생각 했지만 실제로 코드가 매우 큰 숫자를 지원하지 않으면 신경 쓰지 않습니다. 답변에 코드의 한계를 명시하십시오.
Charlie

3
제안 된 테스트 사례 : 101(0 때문에 거짓) ... 또는 여전히 그렇 1 - 01습니까 ( )?
Shieru Asakoto

1
@ShieruAsakoto 나는 101현재 답변으로 사례를 테스트 해 왔으며 모두 2의 거듭 제곱으로 true나눌 수 있기 때문에 모두 돌아 1-01왔다. 그래서 나는 그 경우가 진실하다고 생각할 것이다.
Charlie

6
여기에 모두를위한 팁으로 남겨 두십시오. 숫자가 2의 거듭 제곱인지 확인하는 세 가지 가능한 방법은 다음과 같습니다. 1) log2(n)쉼표 뒤에 10 진수가 포함되어 있지 않은지 확인하십시오 . 2) 확인하십시오 n AND (n-1) == 0. 3) square-nrs 목록을 작성하고 해당 목록에 있는지 확인 n하십시오.
Kevin Cruijssen

1
" square-nrs "는 물론 위의 코멘트에서 " 2의 거듭 제곱 "이어야합니다 ..>.>
Kevin Cruijssen

답변:


11

05AB1E , 9 8 바이트

Ýos.œåPZ

@Emigna 덕분에 -1 바이트 덕분 Z에 0과 1의 목록에 (max)를 사용하여 (truthy)에 대한 any명령 을 모방했습니다 1.

온라인으로 시도 하거나 모든 테스트 사례를 확인하십시오 . (참고 : т헤더 100의 첫 번째 입력 전력 2 개 숫자 대신 처음 2의 100 제곱을 얻는 것입니다. 입력 전력의 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그러나 광산은 실패했습니다 .
Mr. Xcoder

@ Mr.Xcoder Ah, .²1%O0꽤 똑똑합니다. 나는 log2이것처럼 사용하는 것에 대해 생각 .²DïQ했지만 각 숫자 마다이 작업을 수행하기 위해 주위에지도가 필요하며 실제로 edge-case에서는 작동하지 않았습니다 0.
Kevin Cruijssen




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

자바 스크립트, 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 101falsy 사건이었다.

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

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]

온라인으로 사용해보십시오!

또 다른 긴 제출물이지만 Red의 모든 하위 문자열을 찾을 수있는 내장 기능이 없기 때문에 완전히 불만족스럽지 않습니다.

더 읽기 쉬운 :

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)

풀고 테스트

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

파워 쉘, 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의 거듭 제곱 과 같은 정규 표현식 을 작성하고 인수에서 테스트합니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.