Average Length of Google

24

1

I was messing around with Pyth's url request feature, and noticed that google always gave a response with a slightly different length for me, usually ~10500 characters.

So your task in this challenge is to print out the average length of the html response from http://google.com.

Specs

  • You will take an input n which is the number of requests to make.
  • For each request, you will make an HTTP get request.
  • You will count the response body (the html text), not the headers.
  • Output the arithmetic mean of the lengths of the responses.
  • You can only access the url http://google.com, not any other.
  • This is , so shortest code in bytes wins!

Sample output for input 10: 10560.1

(I used Python's urllib for that)

P.S: does anyone know why google does this?

Maltysen

Posted 2017-02-26T22:13:38.743

Reputation: 25 023

1Strange, http://google.com always returns 261 bytes for me... https://google.com/ncr might return more though. – Neil – 2017-02-26T22:19:21.120

@Neil Odd, http://google.com always returns 10422 bytes for me... – LegionMammal978 – 2017-02-26T23:40:44.717

Can a ratio of integers (i.e., an exact fraction) be returned? – LegionMammal978 – 2017-02-26T23:43:21.963

@LegionMammal978 no, sorry. – Maltysen – 2017-02-27T00:34:57.557

5@Neil You get 261 bytes because you actually receive an URL redirection, code 302, which has in the body the new URL to follow. Some programs, like curl on linux, need a specific argument to follow that new URL automatically. – seshoumara – 2017-02-27T06:39:00.303

3@seshoumara TBH the challenge does not specify to follow redirections, so I would expect Neil's answer to be the correct answer by default, since it handles the actual HTTP response that http://google.com sends. Of course this isn't the point of the challenge, so the challenge should IMO be edited to reflect that. – Aaron – 2017-02-27T14:29:07.163

@Aaron I agree, my comment above was more of an explanation to why he felt it was strange getting 261 bytes. I should have not mentioned the second part, but I was writing my own answer at that time with redirection, so I didn't realized it wasn't actually necessary. – seshoumara – 2017-02-27T14:34:27.710

Which average?` – theonlygusti – 2017-02-27T21:56:16.627

@theonlygusti the arithmtic mean – Maltysen – 2017-02-28T01:49:51.580

Answers

20

Bash + system utilities, 56 53 49 48 bytes

Update: saved 4 bytes thanks to Digital Trauma and 1 byte more thanks to Dennis

curl -L `yes google.com|sed $1q`|wc|dc -e1k?$1/p

In my original answer I was using yes in combination with xargs to emulate a for loop. But curl can accept as input a list of URLs, so only the output from yes is actually needed.

When curl accesses google.com, it receives a 302 redirection page that has the new URL in the body section, so the -L option is needed to follow it.

Run example: answer is printed to STDOUT, I redirect STDERR just for clarity

me@LCARS:/PPCG$ ./google_length.sh "8" 2> /dev/null
10583.2

Explanation: (of the initially submitted code)

yes google.com|     # repeatedly output a line containing the string "google.com"
sed $1q|            # print the first $1 lines only (shorter than head -$1)
xargs curl -sL|     # xargs reads the input lines and executes "curl -sL" with the
                    #current input line as an additional argument.
wc -m|              # count the number of characters
dc -e1k?$1/p        # dc script: set precision to 1, read input, push $1 and divide

Edit: I replaced wc -m with wc, because even if without arguments it prints 2 more statistics than the one I wanted, the same dc script following this output still works, because the count we want is, happily, placed on top of the stack during parsing.

seshoumara

Posted 2017-02-26T22:13:38.743

Reputation: 2 878

@DigitalTrauma Very nice, no need for xargs. Thanks, I updated the answer. – seshoumara – 2017-02-27T21:59:51.727

2You don't need -s. Stray output to STDERR is allowed by default. – Dennis – 2017-02-27T23:17:45.100

@Dennis Thanks, answer updated. – seshoumara – 2017-02-28T19:17:15.970

17

MATL, 28 bytes

:"'http://google.com'Xin]vYm

Gif or it didn't happen:

enter image description here

How it works

:                      % Implicitly input n. Push [1 2 ... n]
"                      % For each
  'http://google.com'  %   Push this string
  Xi                   %   URL read. Gives a string
  n                    %   Number of elements
]                      % End
v                      % Concatenate stack contents into a vertical vector
Ym                     % Mean. Implicitly display

Luis Mendo

Posted 2017-02-26T22:13:38.743

Reputation: 87 464

12

PowerShell, 48 bytes

1.."$args"|%{irm google.com}|measure Le* -a|% A*

Explanation

  1. Create a range from 1 to the input integer.
  2. For each value in the range Invoke-RestMethod (irm) the google homepage. The result is not JSON so it will return the body verbatim instead of deserializing it.
  3. Send that to Measure-Object (measure), getting an average of the Length property of the input strings (the bodies).
  4. Expand the resulting Average property.

briantist

Posted 2017-02-26T22:13:38.743

Reputation: 3 110

did not know |% A* was possible, i've always avoided measure because I thought you couldn't wildcard the property name... – colsw – 2017-02-27T10:43:26.960

2@ConnorLSW yeah this is something I discovered recently while preparing a presentation on code golf in PowerShell. Check out |? A* for some cool stuff as well. I need to look at my presentation files and add this stuff to the tips thread. – briantist – 2017-02-27T15:00:29.850

@ConnorLSW added some detailed info on these usages in the tips page.

– briantist – 2017-02-27T15:40:05.110

10

Java 8, 197 184 182 181 bytes

Golfed:

n->{int s=0,i=0;while(i++<n)try{s+=new java.util.Scanner(new java.net.URL("http://google.com").openStream()).useDelimiter("\\A").next().length();}catch(Exception e){}return s*1f/n;}

Ungolfed:

public class AverageLengthOfGoogle {

  public static void main(String[] args) {
    float bytes = f(n -> {
      int s = 0, i = 0;
      while (i++ < n) {
        try {
          s += new java.util.Scanner(new java.net.URL("http://google.com").openStream())
              .useDelimiter("\\A").next().length();
        }
        catch (Exception e) {
        }
      }
      return s * 1f / n;
    } , 10);
    System.out.println(bytes);
  }

  private static float f(java.util.function.IntFunction<Float> f, int n) {
    return f.apply(n);
  }
}

This leaks resources, but that is a small price to pay in search of the fewest bytes.

user18932

Posted 2017-02-26T22:13:38.743

Reputation:

1

Possible improvements:

  1. double -> float
  2. http://www.google.com -> http://google.com
  3. maybe specifying encoding is not necessary, there should be some deprecated method

You should save some 20 bytes

– kukis – 2017-02-27T14:01:50.153

@kukis thanks, that shaved off 13 bytes. – None – 2017-02-27T14:42:58.553

n->{int s=0,i=0;for(;i<n;++i)try{...}catch(Exception e){}return s*1.0/n;}. Not sure whether you can replace s*1.0/n in the return with s*1f/n, but it's worth a try – Roman Gräf – 2017-02-27T20:38:25.417

@RomanGräf yes, that works. Thanks! – None – 2017-02-27T21:04:52.280

for(;i<n;++i) can be changed to for(;i++<n;) for -1 byte. – Kevin Cruijssen – 2017-02-28T08:52:09.327

You can save 2 bytes by changing System.out.println(bytes); to System.out.print(bytes); – KBusc – 2017-02-28T17:38:50.717

@KBusc the main method as a whole is not included in the byte count for golfing purpose. Only the lambda counts, and it simply returns the value which is allowed in these competitions unless otherwise specified. So println() has no bearing on the score for the function I wrote. Besides, Java is inconsistent with flushing the buffer before the program terminates: sometimes it will, sometimes it will not. – None – 2017-02-28T19:25:56.953

7

Pyth, 25 bytes

.OmslM'"http://google.com

' is the open function in Pyth, and when given a string starting with http, it performs a GET resuest to that website. The return value is a list of bytes objects. Unfortunately, Pyth's s doesn't know how to concatenate these objects, so instead of ls, I use slM to get the total length. This is performed a number of times equal to the input by m, and the results are averaged by .O.

isaacg

Posted 2017-02-26T22:13:38.743

Reputation: 39 268

7

PHP, 90 78 bytes

while($i++<$argv[1]){$s+=strlen(file_get_contents('http://google.com'));}echo $s/$argv[1];

while($i++<$argv[1])$s+=strlen(join(file('http://google.com')));echo$s/($i-1);
  • Used shorter functions/variables and removed unnecessary syntactic construct as mentioned by commenters

Michael Tsang

Posted 2017-02-26T22:13:38.743

Reputation: 171

2Wellcome to codegolf.se ! join(file()) instead of file_get_contents() saves you a few bytes. – Christoph – 2017-02-27T07:10:40.883

2In addition you can drop the curly braces and the space after the echo. Also you can use $i instead of $argv[1] as the divisor. – user59178 – 2017-02-27T12:09:44.840

7

05AB1E, 15 bytes

Code:

F’Š¹.ŒŒ’.wgO}¹/

Explanation:

F           }     # Input times do..
 ’Š¹.ŒŒ’          #   Push the string "google.com"
        .w        #   Read all and wrap into a string
          g       #   Get the length
           O      #   Sum it up with the total
             ¹/   # Divide by input

Uses the CP-1252 encoding. When run in the offline interpreter I get the following:

> py -3 05AB1E.py -c test.abe
1
11039.0

> py -3 05AB1E.py -c test.abe
2
11070.0

> py -3 05AB1E.py -c test.abe
3
11046.666666666666

> py -3 05AB1E.py -c test.abe
4
11029.75

> py -3 05AB1E.py -c test.abe
5
11015.8

Adnan

Posted 2017-02-26T22:13:38.743

Reputation: 41 965

Either you have a built-in for google.com or something else is going on! – Pureferret – 2017-02-28T07:59:11.780

@Pureferret It's actually a dictionary compressed string. You can try it out here :).

– Adnan – 2017-02-28T08:01:12.610

Is using languages dedicated to golfing allowed? If so, then I can theoretically make up language that will do all of these things in one byte – kukis – 2017-02-28T14:41:11.443

@kukis Using dedicated golfing languages are allowed, if and only if the language version that is used doesn't postdate the challenge. If you make up a language that can do all these things in one byte, but the compiler was made after the challenge, it is a violation of both this and this.

– Adnan – 2017-02-28T17:46:49.997

6

Mathematica, 58 bytes

N@Mean[StringLength@URLFetch@"http://google.com"~Table~#]&

Anonymous function. Takes a number as input, and returns a number as output.

LegionMammal978

Posted 2017-02-26T22:13:38.743

Reputation: 15 731

Why do you need N@? You aren't printing it, so there's no reason to format it nicely. – Pavel – 2017-02-27T03:01:56.850

@Pavel OP specified that exact fractions aren't allowed. – LegionMammal978 – 2017-02-27T03:07:37.787

3

Python, 102 bytes

import urllib2
f=lambda n:sum([len(urllib2.urlopen(x).read()) for x in ['http://google.com']*n],0.0)/n

Or, if we can return integers rather than floats, the answer can be 98 bytes:

import urllib2
f=lambda n:sum([len(urllib2.urlopen(x).read()) for x in ['http://google.com']*n])/n

totallyaguest

Posted 2017-02-26T22:13:38.743

Reputation: 31

1You can remove a couple spaces in there. )for x in[. Also, if you restrict yourself to Python 3, the division will automatically be float division, and you can remove 0.0. – mbomb007 – 2017-02-27T14:52:14.613

1You also don't need the [] in the 2nd case - sum takes a generator – Bahrom – 2017-02-27T22:03:35.833

3

CJam, 23 bytes

rd_"google.com"a*:gs,\/

Doesn't work on TIO for security reasons.

Test run

$ echo -n 'rd_"google.com"a*:gs,\/' > google-avg.cjam
$ wc -c google-avg.cjam
23 google-avg.cjam
$ java -jar cjam-0.6.5.jar google-avg.cjam <<< 10; echo
10663.2
$ java -jar cjam-0.6.5.jar google-avg.cjam <<< 10; echo
10650.0
$ java -jar cjam-0.6.5.jar google-avg.cjam <<< 10; echo
10651.0
$ java -jar cjam-0.6.5.jar google-avg.cjam <<< 10; echo
10651.4
$ java -jar cjam-0.6.5.jar google-avg.cjam <<< 10; echo
10673.5

How it works

 rd                      e# Read a double from STDIN. Let's call it D.
   _                     e# Push a copy of D.
    "google.com"a        e# Wrap the string in an array, pushing ["google.com"].
                 *       e# Repeat the array D times.
                  :g     e# Map `get` over the array, making D requests to the URL.
                    s    e# Combine all D responses into a single string.
                     ,   e# Compute the length.
                      \  e# Swap the length with the original D.
                       / e# Perform division.

Dennis

Posted 2017-02-26T22:13:38.743

Reputation: 196 637

1

CJam, 27 bytes

{"google.com"g,}ri*]_:+\,d/

CJam assumes HTTP if not specified.

Explanation

{"google.com"g,}             A block which fetches from http://google.com and gets its length
                ri*          Run this block a number of times equal to the input
                   ]         Collect all the results in an array
                    _        Duplicate the array
                     :+      Sum it
                       \     Swap back to the original array
                        ,    Get its length
                         d/  Cast to double and divide 
                              (without casting, it would be integer division)

Business Cat

Posted 2017-02-26T22:13:38.743

Reputation: 8 927

1

Clojure, 102 bytes

(fn[n](/(reduce + 0.0(repeatedly n #(count(slurp(clojure.java.io/reader"http://www.google.com")))))n))

Ungolfed:

(fn [n]
  (/
   (reduce + 0.0
           (repeatedly n
                       #(count (slurp (clojure.java.io/reader "http://www.google.com")))))
   n))

#(count (slurp (clojure.java.io/reader "http://www.google.com"))) is a local function which counts the bytes from an http request to google, repeatedly calls the function n times and makes a list from the returned counts, reduce sums the results together, and finally that is divided by n to make an average. The reduce is started at 0.0 to force the result into a float- otherwise the division would result in a rational. Whole thing is wrapped in an anonymous function which takes the number of times to name the request.

djeis

Posted 2017-02-26T22:13:38.743

Reputation: 281

I swear I didn't copy this answer! Mine ended up quite close to yours. The (clojure.java.io/reader) part is unnecessary btw. It's done automatically behind the scenes if you pass a string. – Carcigenicate – 2017-02-28T20:07:02.837

1

Python 3, 95 bytes

Recursive solution

import requests as r
f=lambda n,t:f(n-1,t+len(r.get('http://google.com').text)) if n>0 else t/i

where n=i=int(input())

requests library

Miguel

Posted 2017-02-26T22:13:38.743

Reputation: 131

Requests seems to be an external library, so you'll want to add a link to that. Something like Python 3 + [Requests](http://docs.python-requests.org/en/master/user/install/#install), 95 bytes – Value Ink – 2017-02-28T20:23:17.567

@ValueInk, added, you don't need to install it though, it comes with python3 (at least it came by default for me). Why the other python answer doesn't need to do it? – Miguel – 2017-02-28T20:26:32.397

urllib2 is a native (pre-installed) Python library https://docs.python.org/2/library/urllib2.html so anyone downloading Python can immediately run their code. I can't run your code on my Python 3 without that library. – Value Ink – 2017-02-28T20:28:39.177

@ValueInk no problem, my first contribution here, I didn't know – Miguel – 2017-02-28T20:31:55.910

1

Perl, 66 bytes

perl -MLWP::Simple -pe'map$t+=length get"http://google.com",1..$_;$_=$t/$_'

51 bytes + 14 bytes for -MLWP::Simple<space> + 1 byte for -p.

Straightforward solution using LWP::Simple. The get function is exported by default and returns the response content on success.

Perl 5.14+, 94 93 bytes (core modules only)

perl -MHTTP::Tiny -pe'map$t+=length${+get{new HTTP::Tiny}"http://google.com"}{content},1..$_;$_=$t/$_'

79 bytes + 13 bytes for -MHTTP::Tiny<space> + 1 byte for -p.

Uses HTTP::Tiny, which has been in core since Perl 5.14.

How it works

This:

get{new HTTP::Tiny}"http://google.com"

is the indirect object syntax equivalent of this:

HTTP::Tiny->new->get("http://google.com")

and saves three bytes. The get method returns a hashref with the content stored under the content key.

To get the actual response content, we do:

${+get{new HTTP::Tiny}"http://google.com"}{content}

which is equivalent to:

(get{new HTTP::Tiny}"http://google.com")->{content}

but saves one byte when we add length:

length(foo)->{bar}  # wrong, equivalent to (length(foo))->{bar}
length+(foo)->{bar}
length${+foo}{bar}

ThisSuitIsBlackNot

Posted 2017-02-26T22:13:38.743

Reputation: 1 050

0

Rebol, 69 bytes

n: 0 loop i: do input[n: n + length? read http://www.google.com]n / i

draegtun

Posted 2017-02-26T22:13:38.743

Reputation: 1 592

0

Clojure, 70 bytes

#(/(reduce(fn[a _](+ a(count(slurp"http://google.com"))))0(range %))%)

A fold over a n long range. Sums the length of each request, then divides it by number of requests. Due to the way Clojure handles division, this returns a fraction, not a decimal. If this is unacceptable, I can fix it at the cost of a couple bytes.

(defn avg-request-len [n]
  (/
    (reduce (fn [acc _]
              (+ acc (count (slurp "http://google.com"))))
            0
            (range n))
    n))

Carcigenicate

Posted 2017-02-26T22:13:38.743

Reputation: 3 295

0

Ruby, 73 + 10 = 83 bytes

Uses the -rnet/http flag.

->n{s=0.0;n.times{s+=Net::HTTP.get(URI"http://www.google.com").size};s/n}

Value Ink

Posted 2017-02-26T22:13:38.743

Reputation: 10 608

0

Common Lisp + quicklisp/dexador, 23 + 72 = 95 bytes

If quicklisp is installed on the system it will download and install dexador as neccesary.

Prelude:

(ql:quickload :dexador)

Code

(lambda(n)(/(loop :repeat n :sum(length(dex:get"http://google.com")))n))

Ungolfed:

(lambda (n)
  (/ (loop :repeat n 
           :sum (length (dex:get "http://google.com")))
     n))

Explaination

(dex:get "http://google.com")

This performs the web request to google and returns five values:

  1. The web request itself as a string or byte array (depending on content type)
  2. The http status code
  3. A hash map of the http response headers
  4. A QURI object representing the final URI after resolving redirects
  5. The socket used to communicate with the web server (if it wasn't closed by the server or one of the optional args to the function)

(length (dex:get ...))

If you don't explicity request otherwise, Common Lisp will discard all the return values other than the first, so the length function only sees the http response itself and returns the length of this string.

(loop :repeat n :sum (length ...))

This calculates the response length n times and adds them.

(/ (loop ...) n)

This divides the summed lengths by n to compute the average.

(lambda (n) ...)

This wraps the body of code in an anonymous function which takes n as an argument and returns the average response length for n web requests to http://google.com.

djeis

Posted 2017-02-26T22:13:38.743

Reputation: 281