비트, 니블 또는 바이트?


45

이 도전에서 영감을 얻은

범위에 정수가 주어지면 0 <= n < 2**64적합 할 수있는 최소 크기의 컨테이너를 출력하십시오

  • 비트 : 1
  • 니블 : 4
  • 바이트 : 8
  • 짧은 : 16
  • 정수 : 32
  • 긴 : 64

테스트 케이스 :

0 -> 1
1 -> 1
2 -> 4
15 -> 4
16 -> 8
123 -> 8
260 -> 16
131313 -> 32
34359750709 -> 64

이것은 이므로 바이트 단위의 최단 답변이 이깁니다.


10
2출력이 너무
좋으면

1
@ETHproductions 그것은 아쉽지만, 그렇지 않습니다 (알고리즘을 작성하는 데 오래 걸렸습니다)
Blue

문제를 이해했으면합니다. ... 잠깐, 다음 기본 구조로 반올림하여 숫자를 포함하는 데 필요한 비트의 양만 있으면됩니다.
z0rberg의

2
감사! 댓글을 쓰고 너무 늦게 편집했을 때 깨달았습니다. 대화를하려면 고무 오리가 필요하다고 생각합니다.
z0rberg 's

2
@Daniel 여기의 답변은 다른 질문과 완전히 다른 접근법을 취합니다. 내가 '영감하다'고 말할 때 '중복'을 의미하는 것은 아닙니다. 이 질문에 대한 답을 사소하게 수정할 수 없습니다
Blue

답변:


3

05AB1E , 10 바이트

bg.²îD1Q+o

설명

bg         Push the length of the binary representation of input without leading zeros
  .²î      Push x = ceil(log2(length))
     D1Q+  Add 1 if x == 1 or add 0 otherwise
         o Push pow(2,x) and implicitly display it

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


22

파이썬, 39 바이트

f=lambda n:4**(n>1)*(n<16)or 2*f(n**.5)

2의 출력을 피하기 위해 특수 케이스를 사용하여 n아래에 있기 위해 제곱근을 몇 번이나 가져야하는지 계산합니다 16.

2가 포함되면 할 수 있습니다

f=lambda n:n<2or 2*f(n**.5)

1에 대해 True로.


41 바이트 :

f=lambda n,i=1:i*(2**i>n)or f(n,i<<1+i%2)

i까지까지 지수를 두 배로 반복합니다 2**i>n. 홀수 일 때 추가 비트를 이동하여 에서 i=1로 건너 뜁니다 .i=4i

Alt 45 바이트 :

f=lambda n,i=4:4**(n>1)*(2**i>n)or 2*f(n,i*2)

7
문제에 대한 많은 해결책을 제시 할 수있는 방법을 놀라게하는 것은 결코 끝나지 않습니다. 기본적으로 프로그래머로서 문제에 대한 해결책을 찾고 문제가 해결 될 때까지 문제를 해결하는 방법을 배웠습니다. 나는 아직도 골프에 대해 배울 것이 많다고 생각한다! 존경.
ElPedro

@ xnor, 10 또는 1의 제곱근이 항상 1 (무한 재귀 or 2*f(n**.5)) 일 때 첫 번째 답변은 어떻게 출력 됩니까?
dfernan

2
@ dfernan 나는 그 or이전의 부분이 잘못된 것으로 평가되는 경우에만 그 부분을 평가한다고 믿습니다. 는 N = 0, 그리고 N = 1에 대한 n>1평가 False수치 표현으로 제로로 취급하고, n<16평가 True숫자 식의 하나로서 취급된다. 그래서 4**(n>1)*(n<16)1입니다.
trichoplax

1
@trichoplax, 맞습니다. 설명 주셔서 감사합니다.
dfernan

12

J, 19 바이트

오른쪽의 숫자를 가져 와서 컨테이너 크기를 뱉어내는 수도원 동사. 그것을 쓰는 두 가지 동등한 방법이 있으므로 두 가지를 모두 포함했습니다.

2^2(>.+1=>.)@^.#@#:
2^s+1=s=.2>.@^.#@#:

폭발로 설명 :

2^2(>.+1=>.)@^.#@#: NB. takes one argument on the right...
                 #: NB. write it in binary
               #@   NB. length (i.e. how many bits did that take?)
  2          ^.     NB. log base 2 of that
   (>.     )@       NB. ceiling
      +1=>.         NB. +1 if needed (since no container is two bits wide)
2^                  NB. base 2 exponential

멋진 점은 J에서 log base 2를 취하는 두 가지 방법이 있다는 것입니다. 첫 번째는 명백합니다 2^.. 이는 숫자 로그입니다. 두 번째는 #@#:"base-2 표현의 길이"로 읽을 수 있습니다. 이것은 one-plus-floor-of-logor-base-base-2와 거의 동일합니다. 단 #:0하나의 요소 인 list 0는 우리가 원하는 것입니다. 이것은 1+2<.@^.1&>.8 바이트로 이깁니다 .

REPL에서 사용 중 :

   f =: 2^2(>.+1=>.)@^.#@#:
   f 131313
32
   f 34359750709
64
   (,.f"0) 0 1 2 15 16 123 260
  0  1
  1  1
  2  4
 15  4
 16  8
123  8
260 16

오래되고 지나치게 영리한 20 바이트 솔루션.

2&^.(>.+1=>.&.)@#@#: NB. takes one argument on the right...
                #@#: NB. how many bits
2&^.                 NB. log base 2 of that
     >.              NB. ceiling
       +1=>.         NB. +1 if needed (since no container is two bits wide)
    (       &.)      NB. undo log base 2

9

파이썬, 53 50 49 바이트

lambda n:[w for w in[1,4,8,16,32,64]if n<2**w][0]

1
lambda n:[w for w in[1,4,8,16,32,64]if n<2**w][0]1 바이트 더 짧음
Blue

비슷한 것을 게시하려고했습니다. +1
ElPedro

8

매스 매 티카, 44 39 38 바이트

5 바이트의 경우 @orlp, 1 바이트의 경우 @MartinEnder에게 감사합니다.

FirstCase[{1,4,8,16,32,64},x_/;2^x>#]&

{1, 4, 8, 16, 32, 64}2 ^ number가 입력 값보다 큰 목록에서 첫 번째 요소를 찾습니다 .


8

, 19 바이트

(a<2**_FI2**,7RM2i)

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

작동 원리

                     a is 1st cmdline arg, i is 0 (implicit)
         2**,7       Construct powers of 2 from 0 to 6 [1 2 4 8 16 32 64]
              RM2    Remove 2
       FI            Filter for elements for which:
 a<2**_                a is less than 2 to that element
(                i)  Get 0th item of resulting list and autoprint

7

자바 스크립트 (ES7), 35 바이트

n=>[1,4,8,16,32,64].find(b=>2**b>n)

2
와 같은 재귀 버전 f=(n,b=1)=>2**b>n&&b-2?b:f(n,b*2)은 약간 짧아야합니다.
Arnauld

6

매스 매 티카, 46 43 38 바이트

3 바이트를 절약 한 JungHwan Min과 Martin Ender에게 감사드립니다! ngenisis 덕분에 5 바이트를 크게 절약 할 수 있습니다!

2^⌈Log2@BitLength@#⌉/.{2->4,0->1}&

명명되지 않은 함수는 음수가 아닌 정수를 입력으로 사용하고 양의 정수를 반환합니다. BitLength@#입력의 비트 수를 2^⌈Log2@...⌉계산 한 다음 비트 수만큼 큰 2의 최소 제곱 을 계산합니다. 마지막으로 /.{2->4,0->1}비트와 nybble 사이에 "niblit"이없는 특수한 경우를 처리하고 이상한 입력에 대한 답변을 수정합니다 0.


2
BitLength@#대신에 3 바이트를 절약하십시오 ⌊1+Log2@#⌋. 그럼 대체하지 않고 함께 1당신을 대체 할 수있는 0다른 2 바이트를 저장하고, 먼저 공동 있습니다.
ngenisis

1
이것은 실제로 전적으로 할 수 있습니다 BitLength. 내 답변
ngenisis

4

줄리아, 40 바이트

n->filter(x->n<big(2)^x,[1;2.^(2:6)])[1]

이것은 2를 제외하고 0에서 6까지 2의 거듭 제곱 배열을 생성하고 2 x 가 입력보다 큰 요소 x 로만 필터링하는 익명 함수입니다 . 첫 번째 요소는 답입니다. 불행히도 x = 64 에서 오버플 로 를 피 하려면 2를 a 로 승격해야합니다 .BigInt

이것은 실제로 orlp의 Python 답변과 매우 유사하지만이 접근법을 조정하기 전에는 보지 못했습니다.

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


4

펄 6 , 30 바이트

{first 1+<*>$_,1,4,8,16,32,64}

+<Perl 6의 왼쪽 비트 시프트 연산자는 다른 많은 언어에서 호출 <<합니다.


4

하스켈, 31 바이트

f n=[2^i|i<-0:[2..],2^2^i>n]!!0

32 바이트 대체 :

f n|n<2=1|n<16=4|1>0=2*f(sqrt n)

2

자바, 143 바이트

int f(long a){a=Long.toBinaryString(a).length();if(a<2)return 1;if(a<5)return 4;if(a<9)return 8;if(a<17)return 16;if(a<33)return 32;return 64;}

1
나는 이것을 더 짧게 만들 수 있다는 것을 알고있다. 나는 컴퓨터에있을 때 그것을한다.
Pavel

2
50 바이트 저장 : return a<2?1:a<5?4:a<9?8:a<17?16:a<33?32:64;
Mindwin

@Mindwin 알고 있지만 여행 중이며 한동안 컴퓨터에 액세스 할 수 없습니다. 내가 갈게
Pavel


2

하스켈, 43 바이트

f x=head$filter((>x).(2^))$[1,4,8,16,32,64]

2

루비, 39 36 바이트

->n{2**[0,*2..6].find{|p|2**2**p>n}}

골프를 도와 주셔서 감사합니다 GB


괄호 없이도 작동해야합니다. 또한 목록은 0,2,3,4,5,6이며 1 << 2 ** p를 사용합니다.
GB

... 0, * 2..6을 사용할 수 있기 때문입니다.
GB

2

자바 8, 65 55 바이트

이것은 a를 가져와을 long반환하는 람다 식입니다 int. 이전에는 Java에서 골프를 타지 않았으므로 쉽게 이길 수 있습니다.

x->{int i=1;while(Math.pow(2,i)<=x)i<<=1+i%2;return i;}

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


들어 47 바이트 , 우리는 할 수 :

x->{int i=1;while(1L<<i<=x)i<<=1+i%2;return i;}

그러나 1L<<i반환 값이 32보다 크면 오버플로되므로 최종 테스트 사례에서는 실패합니다.


1
이 반환 4테스트 할 때 16이 또한 8을 반환하도록되어 때 할 수 있습니다 여전히 골프 주위에 괄호를 제거하여이 솔루션 i<<=1+i%2;없이 이후 {}의, 그동안됩니다 루프 다음 줄을 실행
Kritixi LITHOS

@KritixiLithos는 이제 고쳐 져야합니다-죄송합니다, Java가 녹슬 었습니다 ...
FlipTack

2

Mathematica, 30 바이트

2^(f=BitLength)[f@#-1]/. 2->4&

설명:

하자 N음이 아닌 정수들의 집합. 두 함수를 정의 N, BitLength그리고 NextPower다음과 같이 :

BitLength(n) := min {x in N : 2^x - 1 >= n}
NextPower(n) := 2^(min {x in N : 2^x >= n})

이 솔루션은 기본적으로 NextPower(BitLength(n))정수를 계산 합니다 n >= 0. 를 들어 n > 0, 우리가 볼 수 NextPower(n) = 2^BitLength(n-1)있도록, NextPower(BitLength(n)) = 2^BitLength(BitLength(n)-1).

이제 Mathematica BitLength내장은 내가 준 정의에 동의합니다 n >= 0. 를 들어 n < 0, BitLength[n] == BitLength[BitNot[n]] == BitLength[-1-n]그래서 BitLength[-1] == BitLength[0] == 0. 따라서 우리는 원하는 답변을 얻기 1를 들어 n==0.

우리는 비트에서 니블로 바로 건너 뛸 수 있기 때문에, 우리의 대답 교체해야 2와를 4.


1
멋지게 건설되었습니다! (공간이 필요하다는 것이 부끄러운 일입니다.)
Greg Martin

2

bash, 49 바이트 48 바이트

for((y=1;$[y==2|$1>=1<<y];$[y*=2])){ :;};echo $y

또는

for((y=1;$[y==2|$1>=1<<y];)){ y=$[y*2];};echo $y

스크립트에 저장하고 테스트 할 숫자를 인수로 전달하십시오.

편집 : 교체 || 인수는 항상 0 또는 1이므로 |로 작동합니다.

참고 : 이것은 bash 버전이 처리 할 수있는 최대 양의 정수까지의 정수에서 작동합니다. 시간이 있으면 32 비트 부호있는 산술을 사용하는 bash 버전에서 최대 2 ^ 64-1까지 작동하도록 수정합니다.

한편, 다음은 임의의 숫자로 작동하는 64 바이트 솔루션입니다 (모든 bash 버전에서).

for((x=`dc<<<2o$1n|wc -c`;$[x==2||x&(x-1)];$[x++])){ :;};echo $x

2

스택 형, 34 30 바이트

@n 1 2 6|>2\^,:n 2 log>keep 0#

또는

{!1 2 6|>2\^,:n 2 log>keep 0#}

첫 번째는 TOS에서 입력을 받고 TOS에서 출력을 남겨 둡니다. 두 번째는 함수입니다. 여기 사용해보십시오!

설명

@n 1 2 6|>2\^,:n 2 log>keep 0#
@n                               set TOS to `n`
   1 2 6|>2\^,                   equiv. [1, ...2 ** range(2, 6)]
              :                  duplicate it
               n                 push `n`
                 2 log           log base-2
                      >          element-wise `>`
                       keep      keep only truthy values
                            0#   yield the first element

다음 은 repl에서 작동하는 예입니다 .

> 8    (* input *)
(8)
> @n 1 2 6|>2\^,:n 2 log>keep 0#    (* function *)
(4)
>    (* output *)
(4)

테스트 사례

> {!1 2 6|>2\^,:n 2 log>keep 0#} @:f
()
> (0 1 2 15 16 123 260 131313 34359750709) $f map
((1 1 4 4 8 8 16 32 64))
> 

또는 전체 프로그램으로 :

{!1 2 6|>2\^,:n 2 log>keep 0#} @:f

(0 1 2 15 16 123 260 131313 34359750709) $f map

out

2

라켓 45 바이트

(findf(λ(x)(>(expt 2 x)m))'(1 4 8 16 32 64))

언 골프 드 :

(define (f m)
  (findf (λ (x) (> (expt 2 x) m))          ; find first function
         '(1 4 8 16 32 64)))

다른 버전 :

(define (f1 m)
  (for/last ((i '(1 4 8 16 32 64))         ; using for loop, taking last item
             #:final (> (expt 2 i) m))     ; no further loops if this is true
    i))

문자열 길이 사용 :

(define (f2 m)
  (for/last
      ((i '(1 4 8 16 32 64))
       #:final (<= (string-length
                    (number->string m 2))  ; convert number to binary string
                   i))
    i))

테스트 :

(f 0)
(f 1)
(f 2)
(f 15)
(f 16)
(f 123)
(f 260)
(f 131313)
(f 34359750709)

산출:

1
1
4
4
8
8
16
32
64

1

옥타브, 40 36 31 29 바이트

간단한 익명 기능. 입력 값이 정수라고 가정합니다. 끝에주의하십시오.

@(a)(b=2.^[0 2:6])(a<2.^b)(1)

코드는 다음과 같이 작동합니다.

  • 먼저 허용 된 비트 길이 (1,4,8,16,32,64)의 배열이 생성되어에 저장됩니다 b.

  • 다음 a으로 각 컨테이너의 최대 크기와 비교 하여 입력 숫자를 저장하는 데 필요한 비트 수를 찾아서 b어느 것이 큰지 확인합니다.

  • 그런 다음 결과 인덱스 벡터를 사용하여 컨테이너 크기를 b다시 추출 합니다.

  • 마지막으로 결과 배열에서 가장 작은 컨테이너가 될 첫 번째 요소를 가져옵니다.

여기에서 온라인으로 사용해 볼 수 있습니다 .

다음 코드를 실행 한 다음 수행하십시오 ans(x).


이것에 대한 유일한주의 사항은 배정 밀도가 기본적으로 상수에 사용된다는 것입니다. 즉 2 ^ 64 미만의 배정 밀도 부동 소수점으로 나타낼 수있는 최고 값까지만 작동합니다.

함수에 제공되는 숫자가 double이 아닌 정수가되도록하여이를 해결할 수 있습니다. 예를 들어 다음과 같이 함수를 호출하면됩니다 ans(uint64(x)).


1

PHP, 49 46 44 바이트

echo(2**ceil(log(log(1+$argn,2),2))-2?:2)+2;

다음과 같이 실행하십시오.

echo 16 | php -R 'echo(2**ceil(log(log(1+$argv[1],2),2))-2?:2)+2;';echo

설명

echo                       # Output the result of the expression
  (
    2**                    # 2 to the power
      ceil(log(            # The ceiling of the power of 2 of bitsize
        log(1+$argn,2),    # Number of bits needed
        2
      ))
      - 2 ?:               # Subtract 2 (will be added back again)
      2;                   # If that results in 0, result in 2 (+2=4).
  ) + 2                    # Add 2.

조정

  • $r=할당을 제거하여 3 바이트 절약
  • 사용 가능 -R하도록 $argn사용 하여 2 바이트 절약

1

CJam , 18 바이트

2ri2b,2mLm]_({)}|#

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

설명

2                   Push 2
 ri                 Read an integer from input
   2b,              Get the length of its binary representation
      2mLm]         Take the ceiling of the base-2 log of the length
           _(       Duplicate it and decrement it
             {)}|   Pop the top element, if it's 0, increment the next element
                     Effectively, if ceil(log2(input)) was 1, it's incremented to 2,
                     otherwise it stays the same.
                 #  Raise 2 to that power

0

C, 71 52 바이트

i;f(long long n){for(i=1;n>>i;i*=2);return i-2?i:4;}

(1<<15)+1의 서명 된 동작으로 인해 입력이 더 이상 깨지지 long long않습니까? 당신이 정말로 원하는 유형은 uint64_t어떤 필요로 #include <stdint.h>되는 여전히 에 비해 패자 unsigned long long! 헤더는 c.
dmckee

@ dmckee 나는 그것을 깨뜨릴 수 있다고 생각하지만 적어도 내 컴퓨터에서는 작동하는 것 같습니다. 작동하지 않는 예를 찾지 못했습니다. unsigned long long또는 사용을 생각 uint64_t했지만 작동하는 것 같아서 long long함께했습니다.
Steadybox

0

QBIC , 27 바이트

:~a<2|_Xq]{~a<2^t|_Xt\t=t*2

설명

:        Get cmd line parameter N, call it 'a'
~a<2     IF 'a' is 0 or 1 (edge case)
|_Xq]    THEN quit, printing 1 ('q' is auto-initialised to 1). ']' is END-IF
{        DO - infinite loop
    2^t  't' is our current number of bits, QBIC sets t=4 at the start of the program.
         2^t gives the maximum number storable in t bytes.
 ~a<     IF the input fits within that number,
|_Xt     THEN quit printing this 't'
\t=t*2   ELSE jump to the next bracket (which are spaced a factor 2 apart, from 4 up)
         DO-loop is auto-closed by QBIC.

0

파이크, 13 바이트

7Zm@2-#2R^<)h

여기 사용해보십시오!

7Zm@          -   [set_bit(0, i) for i in range(7)] <- create powers of 2
    2-        -  ^.remove(2)
      #    )h - filter(^, V)[0]
       2R^    -   2 ** i
          <   -  input < ^

0

PHP, 43 바이트

for(;1<<2**$i++<=$argn;);echo 2**$i-=$i!=2;

로 실행하십시오 echo <number> | php -R '<code>'.

입력보다 클 $i때까지 반복 됩니다 2**(2**$i). (비틀기 <<대신 **괄호를 제거하기 위해)
, 루프를 난 후 하나 너무 높은 $; 따라서 출력을 계산하기 전에 감소
하지만 감소 하지는 않습니다 $i==2.

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