Mean bits: an average challenge

30

1

Given an integer N >= 1, output the mean number of bits in an integer from 0 to N - 1

Specification

  • The output can be calculated as the sum of the number of bits in the binary representation of each integer from 0 to N-1, divided by N.
  • The binary representation of an integer has no leading zeroes in this context, with the exception of zero, which is represented as 0 in binary.
  • The output should be accurate to at least 7 significant figures.

Example

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

Mean number of bits = (1 + 1 + 2 + 2 + 3 + 3) / 6 = 2

Test cases

Input => output

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

Leaderboard Snippet

(from here)

var QUESTION_ID=80586,OVERRIDE_USER=20283;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:400px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

Note that the sum (before dividing to find the mean) is a sequence on OEIS.

trichoplax

Posted 2016-05-25T01:57:01.960

Reputation: 10 499

6Nice name, very punny. – Rɪᴋᴇʀ – 2016-05-25T02:04:38.750

3For anyone who doesn't know, I'm more likely to upvote solutions with an explanation – trichoplax – 2016-05-25T02:48:35.283

4Not enough puns, you need a bit more for this to be perfect. – clismique – 2016-05-25T07:12:29.430

1I'm assuming that by "each number" you mean "each integer"? – Cyoce – 2016-05-28T19:45:55.633

@Cyoce yes, thank you for pointing that out - I've edited to clarify. – trichoplax – 2016-05-28T22:41:38.600

Answers

13

Pyth, 6 bytes

.Oml.B

Try it online here.

.Oml.BdUQ              Filling in implict vars

.O                     Average of list
 m   UQ                Map over [0..input)
  l                    Length of
   .B                  Binary string representation of int
    d                  Lambda var

Maltysen

Posted 2016-05-25T01:57:01.960

Reputation: 25 023

Joint first place but you weren't showing up on the leaderboard - I've made a minor edit to the header to fix it. – trichoplax – 2016-05-25T10:36:58.330

9

Jelly, 6 bytes

R’BFL÷

Try it online!

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]

Leaky Nun

Posted 2016-05-25T01:57:01.960

Reputation: 45 011

7

Octave, 29 bytes

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

Explanation

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

Sample run on ideone.

beaker

Posted 2016-05-25T01:57:01.960

Reputation: 2 349

6

Python 3, 43 bytes

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

Makes use of the formula on the OEIS page. Surprisingly, a named function is somehow cheaper here because of the assignment to x.

Alternative approach for 46 bytes:

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

Unfortunately, the -~ is necessary since (0).bit_length() is 0, but even then it'd be a byte too long.

Sp3000

Posted 2016-05-25T01:57:01.960

Reputation: 58 729

6

Julia, 27 bytes

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

Try it online!

How it works

Since * is string concatenation in Julia, prod can be used to concatenate an array of strings. It optionally takes a function as first argument that it maps over the second one before taking the actual "product", so prod(bin,0:n-1) is the string of the binary representation of all integers in the desired range. Taking the length with endof and dividing by n yields the mean.

Dennis

Posted 2016-05-25T01:57:01.960

Reputation: 196 637

5

Julia, 28 bytes

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

Since bin doesn't automatically map over arrays, we're using ceil(log2(n)) to get the number of bits in n-1. This works out nicely because Julia's a:b notation is inclusive on both ends, so 2:n is a range from 2 to n, but we're really calculating the number of bits for numbers in the range 1:n-1. Unfortunately though, we need to tack on an extra 2 to account for 0.

Try it online!

Sp3000

Posted 2016-05-25T01:57:01.960

Reputation: 58 729

5

MATL, 9 bytes

q:ZlksG/Q

Try it Online!

Modified version with all test cases

Explanation

    % 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

Suever

Posted 2016-05-25T01:57:01.960

Reputation: 10 257

Snap!! (filler) – David – 2016-05-25T03:48:06.417

@David Actually, yours was correct. Duplicating the input at the beginning doesn't work for other values... you need the G/Q at the end. – beaker – 2016-05-25T04:42:38.480

5

MATL, 9 bytes

:qBYszQG/

Try it online!

Explanation

: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

beaker

Posted 2016-05-25T01:57:01.960

Reputation: 2 349

5

Jelly, 8 bytes

Not shorter, but interesting algorithm, and my first Jelly submission:

Rl2Ċ»1S÷

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

Adám

Posted 2016-05-25T01:57:01.960

Reputation: 37 779

4

Java, 135 95 90 bytes

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

Shaun Wild

Posted 2016-05-25T01:57:01.960

Reputation: 2 329

I think you can get rid of the interface and simply create a function or lambda. Also you can return the value instead of printing it to stdout – Frozn – 2016-05-25T11:39:05.170

Okay, I'll re implement with those rules. – Shaun Wild – 2016-05-25T11:58:58.237

I think it should be allowed. As the OP didn't specify anything I think standard I/O rules apply.

– Frozn – 2016-05-25T13:02:31.463

Yes a function is fine - you don't need a complete program. Note that the leaderboard picks up the score on the first line, so your score currently shows as 135 instead of 95. – trichoplax – 2016-05-25T20:57:41.007

@trichoplax Still last place. I blame Java personally... – Shaun Wild – 2016-05-26T08:14:46.583

We can try to fix this. But the declaration and initialization of i behind the one of t. Also you can remove the { and } from the for loop – Frozn – 2016-05-26T09:59:14.430

Oops, that was on my original answer but I had netbeans auto format it and it placed the braces automatically. – Shaun Wild – 2016-05-26T10:52:25.850

Check the other side of the leaderboard - yours is currently the top Java solution... :P – trichoplax – 2016-05-26T11:51:16.763

@trichoplax The only Java solution... aha – Shaun Wild – 2016-05-26T12:00:28.923

I know it's almost two years, but you can golf int to Integer and Integer.toString to i.toString to save 2 bytes, as well as return t/(n+0f); to return(t+0f)/n; to save an additional byte. Alternatively you could make it a Java 8 lambda with Integer parameter: n->{int i=0,t=0;for(;i<n;)t+=n.toString(i++,2).length();return(t+0f)/n;} (72 bytes) Try it online.

– Kevin Cruijssen – 2018-01-24T10:12:55.587

4

Jelly, 10 bytes

BL©2*2_÷+®

From Sp3000's suggestion.

Try it here.

Jelly, 11 bytes

æḟ2’Ḥ÷_BL$N

Not very short but I need some tips.

Try it here.

Using the same formula as in Sp3000's answer. (It's not very hard to get it yourself, by differentiating geometric progression.)

jimmy23013

Posted 2016-05-25T01:57:01.960

Reputation: 34 042

Look at my Jelly answer for your reference.

– Leaky Nun – 2016-05-25T09:45:11.180

@LeakyNun It's using a different approach, which I don't think it would ever be shorter than yours. But the _BL$N seemed quite long... – jimmy23013 – 2016-05-25T09:48:36.083

So basically, your code is "floor to nearest power of 2, minus 1, double, divide by input, minus binary length of input, negative"? – Leaky Nun – 2016-05-25T09:50:45.647

@LeakyNun Yes.. – jimmy23013 – 2016-05-25T09:56:53.850

I can't golf that further... – Leaky Nun – 2016-05-25T10:04:40.340

3Only marginally better: BL©2*2_÷+® – Sp3000 – 2016-05-25T10:10:06.607

3

Python 3, 46 Bytes

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

Call it like

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

I had to revert the map revision because it failed for input of 5

Keatinge

Posted 2016-05-25T01:57:01.960

Reputation: 481

3

05AB1E, 9 7 bytes

Code:

L<bJg¹/

Explanation:

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

Try it online

Edit: saved 2 bytes thanks to @Adnan

Emigna

Posted 2016-05-25T01:57:01.960

Reputation: 50 798

@Adnan: Thanks! Forgot about J. – Emigna – 2016-05-25T09:03:56.830

3

C#, 87 bytes

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

I wrote a C# answer because I didn't see one. This is my first post to one of these, so please let me know if I'm doing anything wrong.

raive

Posted 2016-05-25T01:57:01.960

Reputation: 31

Welcome to Programming Puzzles and Code Golf. This is a great first answer, +1. Could you change double to float to save one byte, or do you need the precision? – wizzwizz4 – 2016-06-01T18:28:42.483

2@wizzwizz4 Thanks! I had the same thought, but Average() returns a double. If I change my return type to float then I have to explicitly cast the double and gain 7 bytes on that. – raive – 2016-06-01T19:58:21.563

2

J, 21 17 15 bytes

From 17 bytes to 15 bytes thanks to @Dennis.

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

Can anyone help me golf this?...

Ungolfed version

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

Leaky Nun

Posted 2016-05-25T01:57:01.960

Reputation: 45 011

I tried an alternate approach, by stringifying the list of binary numerals, and came out with 25 bytes: %~>:@#@([:":10#.[:#:i.)-]. Your solution is looking rather optimal. – Conor O'Brien – 2016-05-25T17:51:57.600

2

JavaScript (ES7), 38 32 bytes

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

Using @sp3000's formula (previous version was a recursive solution). ES6 version for 34 bytes:

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

Explanation of formula: Consider the case of N=55. If we write the binary numbers (vertically to save space), we get:

                                11111111111111111111111
                111111111111111100000000000000001111111
        11111111000000001111111100000000111111110000000
    111100001111000011110000111100001111000011110000111
  11001100110011001100110011001100110011001100110011001
0101010101010101010101010101010101010101010101010101010

The size of this rectangle is nl so the average is just l but we need to exclude the blanks. Each row of blanks is twice as long as the previous so the total is 2 + 4 + 8 + 16 + 32 = 64 - 2 = 2l - 2.

Neil

Posted 2016-05-25T01:57:01.960

Reputation: 95 035

2

Perl 6,  34  32 bytes

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

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

Explanation:

{ 
  $_  # 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
}

Test:

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)

Brad Gilbert b2gills

Posted 2016-05-25T01:57:01.960

Reputation: 12 713

2

Dyalog APL, 14 bytes

(+/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

Adám

Posted 2016-05-25T01:57:01.960

Reputation: 37 779

2

Clojure, 71 64 63 bytes

It looks like ratios are ok according to Which number formats are acceptable in output?

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

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

ungolfed (and slightly rewritten for ease of explanation)

(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

old answer that used (float):

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

output is like:

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

mark

Posted 2016-05-25T01:57:01.960

Reputation: 251

The question of whether fractions or ratios are acceptable hadn't been raised before. For this challenge I'll accept whatever consensus is reached on what the default should be.

– trichoplax – 2016-05-28T13:20:34.667

1

AWK, 59 bytes

{for(s=1;++n<$0;s+=int(log(n*2)/log(2)));printf"%.8g",s/$0}

Since AWK only does base-10 logs, I had to convert to base-2 and I chose to multiply the argument by 2 rather than add 1 to the result. It's the same byte-count, but I like it. :)

Try it online!

Robert Benson

Posted 2016-05-25T01:57:01.960

Reputation: 1 339

1

Japt, 6 bytes

o¤xÊ/U

Try it


Explanation

           :Implicit input of integer U
o          :Range [0,U)
 ¤         :Convert each to a base-2 string
   Ê       :Get length of each
  x        :Reduce by addition
    /U     :Divide by U
           :Implicit output of result

Shaggy

Posted 2016-05-25T01:57:01.960

Reputation: 24 623

1

K4, 16 bytes

Solution:

(1+#,/2\:'!x)%x:

Example:

(1+#,/2\:'!x)%x:5
1.8
(1+#,/2\:'!x)%x:6
2f
(1+#,/2\:'!x)%x:7
2.142857

Explanation:

Convert each number to binary, sum up the bits, add 1 for 0, divide by input.

(1+#,/2\:'!x)%x: / the solution
              x: / store input as x
(           )%   / divide left by right
          !x     / range 0..x-1
      2\:'       / convert each (') to bits (2\:)
    ,/           / flatten result
   #             / count length of list
 1+              / add one (as 0 contains 0 bits!)

Extra:

Precision is determined by the P system setting. Default is 7, max is 17

\P 7
(1+#,/2\:'!x)%x:7
2.142857

\P 12
(1+#,/2\:'!x)%x:7
2.14285714286

\P 17
(1+#,/2\:'!x)%x:7
2.1428571428571428

streetster

Posted 2016-05-25T01:57:01.960

Reputation: 3 635

1

Pyt, 8 bytes

⁻řļ⌊⁺Á1µ

Explanation:

                Implicit input (N)
⁻               Decrement by 1 (N-1)
 ř              Push [1,2,...,N-1]
  ļ             element-wise log base 2 of [1,2,...,N-1]
   ⌊⁺           element-wise floor and increment
     Á          Push contents of array onto stack
      1         Push 1
       µ        Get mean of stack
                Implicit output

Try it online!

mudkip201

Posted 2016-05-25T01:57:01.960

Reputation: 833

1

R, 51 bytes

Takes input from stdin. Uses the OEIS formula and then divides by n.

(2+ceiling(log2(n<-scan()))*n-2^ceiling(log2(n)))/n

Try it online!

rturnbull

Posted 2016-05-25T01:57:01.960

Reputation: 3 689

1

Minkolang 0.15, 23 bytes

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

Try it here!

Explanation

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.

Pretty straightfoward implementation.

El'endia Starman

Posted 2016-05-25T01:57:01.960

Reputation: 14 504

1

JavaScript ES5, 55 bytes

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

Explanation

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  

Downgoat

Posted 2016-05-25T01:57:01.960

Reputation: 27 116

1

Hoon, 71 bytes

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

...I'm pretty sure this is actually the first time I've used Hoon's floating point cores. It's actually an implementation written in Hoon that jets out to SoftFloat, since the only data types in Hoon are atoms and cells.

Create a function that takes an atom, r. Create a list from [0..(r - 1)], map over the list taking the binary logarithm of the number, then fold over that list with ++add. Convert both the output of the fold and r to @rq (quad-precision floating point numbers) with ++sun:rq, and then divide one by the other.

The oddest thing in this snippet is the :.^rq at the end. a:b in Hoon means "evaluate a in the context of b". ++rq is the core that contains the entire quad-precision implementation, like a library. So running (sun 5):rq is the same thing as doing (sun:rq 5).

Luckily, cores in Hoon are like nesting dolls; when you evaluate the arm ++rq to get the core, it adds the entire stdlib to it as well, so you get to keep roll and turn and gulf and all that fun stuff instead of being stuck with only the arms defined in ++rq. Unluckily, rq redefines ++add to be floating-point add instead, along with not having r in its context. . (the entire current context) does, however.

When evaluating an expression in a context, the compiler looks for the limb depth-first. In our case of a:[. rq] it would look in the entire current context for a before moving on to looking in rq. So add will look up the function that works on atoms instead of floating-point numbers...but so will div. Hoon also has a feature where using ^name will ignore the first found reference, and look for the second.

From there, it's simply using the syntatic sugar of a^b being equal to [a b] to evaluate our snippet with both our current context and the quad-precision float library, ignoring the atomic div in favor of ++div:rq.

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

RenderSettings

Posted 2016-05-25T01:57:01.960

Reputation: 620

1

Actually, 7 bytes:

;r♂├Σl/

Try it online!

Explanation:

;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

If it weren't for a bug that I just discovered, this solution would work for 6 bytes:

r♂├♂læ

æ is the builtin mean command.

Mego

Posted 2016-05-25T01:57:01.960

Reputation: 32 998

Isn't this 10 bytes? I checked at bytesizematters.com. – m654 – 2016-05-25T10:39:40.970

1@m654 Actually doesn't use UTF-8, it uses CP437 (or something like that). – Alex A. – 2016-05-25T17:44:48.840

@AlexA. Oh, didn't know that. – m654 – 2016-05-25T17:47:49.317

1

@m654 Bytesizematters uses a completely made up encoding that does not (and cannot) exist in practice. For UTF-8, use https://mothereff.in/byte-counter.

– Dennis – 2016-05-25T23:26:46.787

@Dennis Thanks for the info, I'll keep that in mind. – m654 – 2016-05-26T04:39:36.757

1

CJam, 13 12 11 bytes

One byte saved thanks to @Sp3000, and another thanks to @jimmy23013

rd_,2fbs,\/

Try it online!

Explanation

Straightforward. Applies the definition.

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 

Luis Mendo

Posted 2016-05-25T01:57:01.960

Reputation: 87 464

1

Vitsy, 26 bytes

This is a first attempt, I'll golf this down more and add an explanation later.

0vVV1HV1-\[2L_1+v+v]v1+V/N

Try it online!

Addison Crump

Posted 2016-05-25T01:57:01.960

Reputation: 10 763

1

Perl 5.10, 54 bytes

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

Pretty much straightforward. sprintf"%b" is a neat way to output a number in binary in Perl without using additional libraries.

Try it online!

Paul Picard

Posted 2016-05-25T01:57:01.960

Reputation: 863

1

PowerShell v2+, 64 bytes

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

Very straightforward implementation of the spec. Loops from 0 to $n-1 with |%{...}. Each iteration, we [convert] our input number $_ to a string base2 and take its length. We accumulate that in $o. After the loops, we simply divide $o/$n, leaving that on the pipeline, and output is implicit.

As long as this is, it's actually shorter than the formula that Sp & others are using, since [math]::Ceiling() and [math]::Log() are ridiculously wordy. Base conversion in PowerShell is yucky.

AdmBorkBork

Posted 2016-05-25T01:57:01.960

Reputation: 41 581

1

Jolf, 10 bytes

/uΜr0xdlBH

Try it here!

Explanation

/uΜr0xdlBH
  Μr0x      map range 0..x
      dlBH  over lengths of binary elements
/u          divide sum of this
            by implicit input (x)

Conor O'Brien

Posted 2016-05-25T01:57:01.960

Reputation: 36 228

1

Swift, 72 bytes

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

John McDowall

Posted 2016-05-25T01:57:01.960

Reputation: 161

2You don't need to call the function, leaving it as a defined function is okay. Nice first post. – Rɪᴋᴇʀ – 2016-05-26T14:23:34.847

1

J, 15 bytes

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

This is a monadic verb, used as follows:

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

Try it here!

Explanation

I implemented the challenge spec pretty literally. There are other approaches, but all turned out to be longer.

%~[:+/#@#:"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.

Zgarb

Posted 2016-05-25T01:57:01.960

Reputation: 39 083

0

PHP, 48 bytes

a direct port of Sp3000´s answer

<?=(2-2**$x=strlen(decbin($n=$argv[1]))-2)/$n+$x

Titus

Posted 2016-05-25T01:57:01.960

Reputation: 13 814

0

Perl 5, 44 43 + 2 (-pa) = 45 bytes

-1 thanks to @DomHastings

$\+=(length sprintf'%b',$_)/"@F"while$_--}{

Try it online!

Xcali

Posted 2016-05-25T01:57:01.960

Reputation: 7 671

Good idea to add cumulatively... You can save 1 byte using "@F" instead of $F[0]! – Dom Hastings – 2018-02-07T08:32:10.760

0

Ruby, 44 34 bytes

Now starring the formula used by @Sp3000

->x{(2.0-2**b=x.to_s(2).size)/x+b}

Old version:

->x{r=0.0;x.times{|i|r+=i.to_s(2).size};r/x}

Value Ink

Posted 2016-05-25T01:57:01.960

Reputation: 10 608

0

Mathematica, 28 bytes

(Tr@⌈Log2@Range@#⌉+1)/#&

or

Tr@⌈Log2@Range@#⌉/#+1/#&

In either case, it's an unnamed function which takes N as an input and returns an exact (rational) result for the mean.

Martin Ender

Posted 2016-05-25T01:57:01.960

Reputation: 184 808

0

Pyke, 8 bytes

Qmb2slQ/

Try it here!

Blue

Posted 2016-05-25T01:57:01.960

Reputation: 26 661

0

Haskell, 50 bytes

r x|x<1=0|1<2=1+r(x/2)
f n=(sum(r<$>[0..n-1])+1)/n

Michael Klein

Posted 2016-05-25T01:57:01.960

Reputation: 2 111

0

J, 22 bytes

[:(+/%#)[:([:##:)"0 i. Usage:

    bin =: [:(+/%#)[:([:##:)"0 i.
    bin 7
2.14286

ljeabmreosn

Posted 2016-05-25T01:57:01.960

Reputation: 341