평균 비트 : 평균 도전


30

정수 N> = 1이 주어지면 0에서 N-1의 정수로 평균 비트 수를 출력하십시오.

사양

  • 출력은 0에서 N-1까지의 각 정수의 이진 표현에서 비트 수의 합계를 N으로 나눈 값으로 계산할 수 있습니다.
  • 이 문맥에서 정수의 이진 표현은 이진수에서 0으로 표시되는 0을 제외하고 선행 0을 갖지 않습니다.
  • 출력은 유효 숫자가 7 자리 이상이어야합니다.

N = 6

0: 0   : 1 bit
1: 1   : 1 bit
2: 10  : 2 bits
3: 11  : 2 bits
4: 100 : 3 bits
5: 101 : 3 bits

평균 비트 수 = (1 + 1 + 2 + 2 + 3 + 3) / 6 = 2

테스트 사례

입력 => 출력

1 => 1
2 => 1
3 => 1.3333333
4 => 1.5
5 => 1.8
6 => 2
7 => 2.1428571

리더 보드 스 니펫

( 여기에서 )

합 (평균 을 구하기 전에 나누기)은 OEIS시퀀스입니다 .


6
좋은 이름, 아주 punny .
Rɪᴋᴇʀ

3
모르는 누군가를 위해, 나는 설명과 함께 솔루션 찬성 투표 할 가능성이있어
trichoplax

4
말장난이 충분하지 않으면, 이것이 완벽하기 위해서는 조금 더 필요합니다 .
clismique

1
"각 숫자"로 "각 정수 " 를 의미한다고 가정합니다 .
Cyoce

@Cyoce 네, 지적 해 주셔서 감사합니다. 명확히하기 위해 편집했습니다.
trichoplax

답변:



9

젤리, 6 바이트

R’BFL÷

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

R’BFL÷  Main monadic chain. Argument: n

R       yield [1, 2, ..., n]
 ’      decrement; yield [0, 1, ..., n-1]
  B     convert to binary; yield [[0], [1], [1,0], [1,1], ...]
   F    flatten list; yield [0, 1, 1, 0, 1, 1, ...]
    L   length of list
     ÷  divide [by n]

7

옥타브, 29 바이트

@(n)1+sum(fix(log2(1:n-1)))/n

설명

              log2(1:n-1)       % log2 of numbers in range [1..n-1]
                                % why no 0? because log2(0) = -Inf  :/
          fix(           )      % floor (more or less, for positive numbers)
      sum(                )     % sum... wait, didn't we miss a +1 somewhere?
                                % and what about that missing 0?
                           /n   % divide by n for the mean
    1+                          % and add (1/n) for each of the n bit lengths 
                                % (including 0!)

ideone에서 샘플 실행 .


6

파이썬 3, 43 바이트

def f(n):x=len(bin(n))-2;return(2-2**x)/n+x

OEIS 페이지 의 수식을 사용 합니다 . 놀랍게도 명명 된 함수는에 할당되어 있기 때문에 어떻게 든 더 저렴합니다 x.

46 바이트에 대한 대체 접근법 :

lambda n:-~sum(map(int.bit_length,range(n)))/n

불행하게도,이 -~때문에 필요 (0).bit_length()하다 0,하지만 그렇다하더라도 너무 긴 바이트가 될 것입니다.


6

줄리아, 27 바이트

n->endof(prod(bin,0:n-1))/n

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

작동 원리

*Julia에서는 문자열 연결 이므로 문자열 prod배열을 연결하는 데 사용할 수 있습니다. 선택적으로 함수는 실제 "제품"을 가져 오기 전에 두 번째 인수에 맵핑되는 첫 번째 인수로 사용되므로 prod(bin,0:n-1)원하는 범위의 모든 정수에 대한 2 진 표현 문자열도 선택됩니다. 길이를 n으로endof 나누면 n이 나옵니다.


5

줄리아, 28 바이트

n->mean(ceil(log2([2;2:n])))

bin배열을 자동으로 매핑하지 않기 때문에 ceil(log2(n))의 비트 수를 얻는 데 사용 하고 n-1있습니다. Julia의 a:b표기법이 양쪽 끝에 포함되어 있기 때문에 2:n2에서 ~까지의 범위 이기 때문에 잘 작동 n하지만 실제로는 범위의 숫자에 대한 비트 수를 계산합니다 1:n-1. 불행히도, 우리 2는 0을 설명하기 위해 여분의 것을 택해야합니다 .

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


5

MATL, 9 바이트

q:ZlksG/Q

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

모든 테스트 사례가 포함 된 수정 된 버전

설명

    % Implicitly grab input (N)
q:  % Create array from 1:N-1
Zl  % Compute log2 for each element of the array
k   % Round down to the nearest integer
s   % Sum all values in the array
G   % Explicitly grab input again
/   % Divide by the input
Q   % Add 1 to account for 0 in [0, ... N - 1]
    % Implicitly display the result

스냅!! (filler)
David

@David 사실, 당신의 말이 맞았습니다. 처음에 입력을 복제해도 다른 값에는 작동하지 않습니다 G/Q. 끝에는 필요합니다 .
비커

5

MATL, 9 바이트

:qBYszQG/

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

설명

:qBYszQG/
:               % take vector [1..n]
 q              % decrement by 1 to get [0..n-1]
  B             % convert from decimal to binary
   Ys           % cumulative sum (fills in 0's after first 1)
     z          % number of nonzero elements
      Q         % increment by 1 to account for zero
       G        % paste original input (n)
        /       % divide for the mean

5

젤리, 8 바이트

짧지는 않지만 재미있는 알고리즘과 첫 번째 젤리 제출 :

Rl2Ċ»1S÷

R         1 to n
 l2       log2
   Ċ      ceiling
    »1    max of 1 and...
      S   sum
       ÷  divided by n

4

젤리, 10 바이트

BL©2*2_÷+®

Sp3000의 제안에서.

여기에서 시도하십시오.

젤리, 11 바이트

æḟ2’Ḥ÷_BL$N

아주 짧지는 않지만 몇 가지 팁이 필요합니다.

여기에서 시도하십시오.

Sp3000의 답변 과 동일한 수식을 사용합니다 . (기하학적 진행을 차별화하여 스스로 얻는 것은 그리 어렵지 않습니다.)


내 젤리 답변을 참조하십시오.
Leaky Nun

@LeakyNun 그것은 다른 접근법을 사용하고 있는데, 나는 그것이 당신보다 짧을 것이라고 생각하지 않습니다. 그러나 _BL$N꽤 길어 보였다 ...
jimmy23013

그래서 기본적으로 코드는 "2의 가장 가까운 거듭 제곱, -1, 두 배, 입력으로 나누기, 입력의 이진 길이 빼기-음수"입니까?
Leaky Nun

@LeakyNun 예 ..
jimmy23013 2016 년

3
BL©2*2_÷+®
조금만

4

자바, 135 95 90 바이트

float a(int n){int i=0,t=0;for(;i<n;)t+=Integer.toString(i++,2).length();return t/(n+0f);}

인터페이스를 제거하고 단순히 함수 또는 람다를 만들 수 있다고 생각합니다. 또한 값을 stdout에 인쇄하는 대신 반환 할 수 있습니다
Frozn

좋아, 나는 그 규칙으로 다시 구현할 것이다.
Shaun Wild

나는 그것이 허용되어야한다고 생각합니다. OP가 아무것도 지정하지 않았으므로 표준 I / O 규칙이 적용된다고 생각 합니다.
Frozn

예, 기능은 정상입니다. 완전한 프로그램이 필요하지 않습니다. 순위표는 첫 번째 줄에서 점수를
얻으므로

@trichoplax 아직도 마지막 장소. 나는 자바를 개인적으로 탓한다 ...
Shaun Wild

3

파이썬 3, 46 바이트

lambda x:sum(len(bin(i))-2for i in range(x))/x

처럼 불러

f = lambda x: sum(len(bin(i))-2for i in range(x))/x
print(f(6))
# 2.0

5를 입력하지 못해지도 수정본을 되돌려 야했습니다.


3

05AB1E, 9 7 바이트

암호:

L<bJg¹/

설명:

L<         # range from 0..input-1
  b        # convert numbers to binary
   J       # join list of binary numbers into a string
    g      # get length of string (number of bits)
     ¹/    # divide by input

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

편집 : @Adnan 덕분에 2 바이트를 절약했습니다.


@Adnan : 감사합니다! J.에 대해 잊어 버렸
Emigna

3

C #, 87 바이트

double f(int n){return Enumerable.Range(0,n).Average(i=>Convert.ToString(i,2).Length);}

C # 답변을 보지 못했기 때문에 C # 답변을 작성했습니다. 이 중 하나에 대한 첫 번째 게시물이므로 잘못된 일이 있으면 알려주십시오.


프로그래밍 퍼즐과 코드 골프에 오신 것을 환영합니다. 이것은 훌륭한 첫 번째 대답입니다 (+1). 1 바이트를 저장 double하도록 변경 float하거나 정밀도가 필요합니까?
wizzwizz4 2016 년

2
@ wizzwizz4 감사합니다! 나는 같은 생각을했지만 Average ()는 두 배를 반환합니다. 반환 유형을 부동으로 변경하면 명시 적으로 더블을 캐스팅하고 7 바이트를 가져와야합니다.
raive

2

자바 스크립트 (ES7), 38 32 바이트

n=>(l=-~Math.log2(n))-(2**l-2)/n

@ sp3000의 공식 사용 (이전 버전은 재귀 솔루션이었습니다). 34 바이트 용 ES6 버전 :

n=>(l=-~Math.log2(n))-((1<<l)-2)/n

공식 설명 : N = 55 인 경우를 고려하십시오. 공간을 절약하기 위해 이진 숫자를 쓰면 다음과 같은 결과를 얻습니다.

                                11111111111111111111111
                111111111111111100000000000000001111111
        11111111000000001111111100000000111111110000000
    111100001111000011110000111100001111000011110000111
  11001100110011001100110011001100110011001100110011001
0101010101010101010101010101010101010101010101010101010

이 사각형의 크기는 nl 이므로 평균은 l 이지만 공백은 제외해야합니다. 공백의 각 행은 이전보다 두 배 길므로 총계는 2 + 4 + 8 + 16 + 32 = 64-2 = 2 l -2입니다.


2

J, 21 17 15 바이트

@Dennis 덕분에 17 바이트에서 15 바이트까지.

+/@:%~#@#:"0@i.

누구든지 이것을 도와 줄 수 있습니까? ...

언 골프 버전

range        =: i.
length       =: #
binary       =: #:
sum          =: +/
divide       =: %
itself       =: ~
of           =: @
ofall        =: @:
binarylength =: length of binary "0
average      =: sum ofall divide itself
f            =: average binarylength of range

이진 숫자 목록을 문자열 화하여 대체 접근법을 시도하고 25 바이트가 나왔습니다 %~>:@#@([:":10#.[:#:i.)-]. 귀하의 솔루션은 다소 최적입니다.
코너 오브라이언

2

펄 6 ,  34  32 바이트

{$_ R/[+] map *.base(2).chars,^$_}

{$_ R/[+] map {(.msb||0)+1},^$_}

설명:

{ 
  $_  # the input
  R/  # divides ( 「$a R/ $b」 is the same as 「$b / $a」 )
  [+] # the sum of:
  map
    {
      (
       .msb # the most significant digit (0 based)
       || 0 # which returns Nil for 「0.msb」 so use 0 instead
            # should be 「(.msb//0)」 but the highlighting gets it wrong
            # it still works because it has the same end result 
      ) 
      + 1   # make it 1 based
    },
    ^$_ # 「0 ..^ $_」 all the numbers up to the input, excluding the input
}

테스트:

use v6.c;

# give it a name
my &mean-bits = {$_ R/[+] map {(.msb||0)+1},^$_}

for 1..7 {
  say .&mean-bits
}

say '';

say mean-bits(7).perl;
say mean-bits(7).base-repeating(10);
1
1
1.333333
1.5
1.8
2
2.142857

<15/7>
(2. 142857)

2

Dyalog APL , 14 바이트

(+/1⌈(⌈2⍟⍳))÷⊢

range ← ⍳
log   ← ⍟
log2  ← 2 log range
ceil  ← ⌈
bits  ← ceil log2
max   ← ⌈
fix0  ← 1 max bits
sum   ← +/
total ← sum fix0
self  ← ⊢
div   ← ÷
mean  ← sum div self

2

클로저, 71 64 63 바이트

출력어떤 숫자 형식사용할 수 있습니까? 에 따라 비율 이 괜찮은 것 같습니다 .

(fn[n](/(inc(apply +(map #(.bitLength(bigint %))(range n))))n))

  • n = 1 => 1
  • n = 7 => 15/7

ungolfed (및 설명의 편의를 위해 약간 다시 작성)

(fn [n]
 (->
  (->>
   (range n)                      ;;Get numbers from 0 to N
   (map #(.bitLength (bigint %))) ;;Cast numbers to BigInt so bitLength can be used
   (apply +)                      ;;Sum the results of the mapping
   (inc))                         ;;Increment by 1 since bitLength of 0 is 0
  (/ n)))                         ;;Divide the sum by N

사용 된 이전 답변 (부동) :

(fn[n](float(/(inc(apply +(map #(..(bigint %)bitLength)(range n))))n)))

출력은 다음과 같습니다

  • n = 1 => 1.0
  • n = 7 => 2.142857

분수 또는 비율이 허용 가능한지에 대한 질문은 이전에 제기되지 않았습니다. 이 도전에 대해 나는 기본값이 무엇인지에 대한 합의에 도달 한 것을 받아 들일 것이다 .
trichoplax

1

Minkolang 0.15 , 23 바이트

n$z1z[i1+2l$M$Y+]kz$:N.

여기 사용해보십시오!

설명

n$z                       Take number from input and store it in register (n)
   1                      Push 1 onto the stack
    z[                    For loop that repeats n times
      i1+                 Loop counter + 1
         2l$M             log_2
             $Y           Ceiling
               +          Add top two elements of stack
                ]         Close for loop
                 z$:      Float divide by n
                    N.    Output as number and stop.

매우 간단한 구현입니다.


1

자바 스크립트 ES5, 55 바이트

n=>eval(`for(o=0,p=n;n--;o+=n.toString(2).length/p);o`)

설명

n =>   // anonymous function w/ arg `n`
  for( // loop
      o=0,  // initalize bit counter to zero
      p=n   // copy the input
    ;n-- // will decrease input every iteration, will decrease until it's zero
    ;o+=    // add to the bitcounter
        n.toString(2)  // the binary representation of the current itearations's
                     .length // length
        /p   // divided by input copy (to avergage)
   );o       // return o variable  

1

71 바이트

|=
r/@
(^div (sun (roll (turn (gulf 0 (dec r)) xeb) add)) (sun r)):.^rq

... 이것이 실제로 Hoon의 부동 소수점 코어를 사용한 첫 번째 것입니다. 실제로 Hoon으로 작성된 구현은 Hoon의 유일한 데이터 유형이 원자와 셀이기 때문에 SoftFloat로 제트됩니다.

원자를 취하는 함수를 만듭니다 r. [0 .. (r-1)]에서 목록을 생성하고 이진수를 사용하여 목록을 매핑 한 다음로 그 목록을 접습니다 ++add. 상기 스크롤의 출력 모두 변환 r@rq부착 (쿼드 정밀도 부동 소수점 수) ++sun:rq하고 다른 하나를 나눈다.

이 스 니펫에서 가장 이상한 점 :.^rq은 끝에 있습니다. a:bHoon은 "b의 맥락에서 a를 평가합니다"를 의미합니다. ++rq라이브러리와 같이 전체 쿼드 정밀도 구현을 포함하는 핵심입니다. 따라서 달리기 (sun 5):rq는 것과 같은 것 (sun:rq 5)입니다.

다행히 Hoon의 코어는 중첩 인형과 같습니다. 당신이 팔을 평가할 때 ++rq핵심을 얻기 위해 당신이 롤을 유지하고 켜고 걸프에 도착하고 재미있는 물건 대신이 붙어되는 모든 있도록, 그것은뿐만 아니라 그것에 전체 다음 stdlib을 추가 단지 에 정의 된 팔 ++rq. 불행히도, rq 는 컨텍스트에 ++add없는 것과 함께 부동 소수점 추가가되도록 재정의 합니다 r. .그러나 (현재의 전체 맥락)

컨텍스트에서 표현식을 평가할 때 컴파일러는 사지 깊이 우선을 찾습니다. 우리의 경우에는 a:[. rq]살펴보기 a전에 전체 현재 컨텍스트를 살펴볼 것 입니다 rq. 따라서 add부동 소수점 숫자 대신 원자에서 작동하는 함수를 찾을 것 div입니다. Hoon은 또한 사용 ^name하는 첫 번째 참조를 무시하고 두 번째를 찾는 기능을 가지고 있습니다.

거기에서 그것은 현재의 문맥과 쿼드 정밀도 플로트 라이브러리로 스 니펫을 평가 a^b하기 [a b]위해 동등한 동등 의 syntatic sugar를 사용 하고 원자 div를 무시합니다 ++div:rq.

> %.  7
  |=
  r/@
  (^div (sun (roll (turn (gulf 0 (dec r)) xeb) add)) (sun r)):.^rq
.~~~2.1428571428571428571428571428571428

1

실제로 7 바이트 :

;r♂├Σl/

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

설명:

;r♂├Σl/
;        duplicate input
 r       push range(0, n) ([0, n-1])
  ♂├     map binary representation
    Σ    sum (concatenate strings)
     l/  divide length of string (total # of bits) by n

방금 발견 한 버그가 아닌 경우이 솔루션은 6 바이트 동안 작동합니다.

r♂├♂læ

æ 내장 평균 명령입니다.


이 10 바이트 아닌가요? bytesizematters.com에서 확인했습니다.
m654

1
@ m654 실제로 UTF-8을 사용하지 않고 CP437 (또는 이와 유사한 것)을 사용합니다.
Alex A.

@AlexA. 아, 몰랐어
m654

1
@ m654 Bytesizematters는 실제로 존재 하지 않는 (및 불가능한 ) 완전히 구성된 인코딩을 사용합니다 . UTF-8의 경우 mothereff.in/byte-counter를 사용 하십시오 .
Dennis

@Dennis 정보 주셔서 감사합니다, 나는 그것을 명심할 것입니다.
m654


1

PowerShell v2 +, 64 바이트

param($n)0..($n-1)|%{$o+=[convert]::ToString($_,2).Length};$o/$n

사양을 매우 간단하게 구현합니다. 에서 루프 0$n-1|%{...}. 각 반복마다 [convert]입력 번호 $_를 문자열 기준 2으로 가져 와서을 가져옵니다 length. 우리는에 그것을 축적합니다 $o. 루프 후, 우리는 단순히 나누기$o/$n 파이프 라인에 남겨두고 출력은 암시 적입니다.

이후 한은이있다, 그것은, SP 및 다른 사람이 사용하는 공식 실제로 더 짧다 [math]::Ceiling()과는 [math]::Log()터무니없이 장황하다. PowerShell의 기본 변환은 좋지 않습니다.


1

Perl 5.10, 54 바이트

for(1..<>){$u+=length sprintf"%b",$_;$n++}$u/=$n;say$u

매우 간단합니다. sprintf"%b"추가 라이브러리를 사용하지 않고 Perl에서 이진수로 숫자를 출력하는 깔끔한 방법입니다.

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


1

CJam, 13 12 11 바이트

@ Sp3000 덕분에 1 바이트가 절약되고 @ jimmy23013 덕분에 1 바이트가 절약되었습니다.

rd_,2fbs,\/

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

설명

똑바로. 정의를 적용합니다.

rd      e# read input and convert to double 
_       e# duplicate 
,       e# range from 0 to input minus 1
2fb     e# convert each element of the array to binary 
s       e# convert to string. This flattens the array
,       e# length of array 
\       e# swap 
/       e# divide 


1

스위프트, 72 바이트

func f(n:Double)->Double{return n<1 ?1:f(n-1)+1+floor(log2(n))}
f(N-1)/N

2
정의 된 함수는 그대로두고 함수를 호출 할 필요가 없습니다. 좋은 첫 번째 게시물.
Rɪᴋᴇʀ

1

J, 15 바이트

%~[:+/#@#:"0@i.

이것은 다음과 같이 사용되는 모나 딕 동사입니다.

   f =: %~[:+/#@#:"0@i.
   f 7
2.14286

여기 사용해보십시오!

설명

나는 문자 그대로 도전 사양을 구현했습니다. 다른 접근법이 있지만 모두 길어졌습니다.

%~[:+/#@#:"0@i.  Input is y
             i.  Range from 0 to y-1.
          "0@    For each number in this range:
      #@           Compute the length of
        #:         its base-2 representation.
  [:+/           Take the sum of the lengths, and
%~               divide by y.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.