24
\$\begingroup\$

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?

\$\endgroup\$
  • 1
    \$\begingroup\$ Strange, http://google.com always returns 261 bytes for me... https://google.com/ncr might return more though. \$\endgroup\$ – Neil Feb 26 '17 at 22:19
  • \$\begingroup\$ @Neil Odd, http://google.com always returns 10422 bytes for me... \$\endgroup\$ – LegionMammal978 Feb 26 '17 at 23:40
  • \$\begingroup\$ Can a ratio of integers (i.e., an exact fraction) be returned? \$\endgroup\$ – LegionMammal978 Feb 26 '17 at 23:43
  • 5
    \$\begingroup\$ @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. \$\endgroup\$ – seshoumara Feb 27 '17 at 6:39
  • 3
    \$\begingroup\$ @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. \$\endgroup\$ – Aaron Feb 27 '17 at 14:29

18 Answers 18

20
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ @DigitalTrauma Very nice, no need for xargs. Thanks, I updated the answer. \$\endgroup\$ – seshoumara Feb 27 '17 at 21:59
  • 2
    \$\begingroup\$ You don't need -s. Stray output to STDERR is allowed by default. \$\endgroup\$ – Dennis Feb 27 '17 at 23:17
  • \$\begingroup\$ @Dennis Thanks, answer updated. \$\endgroup\$ – seshoumara Feb 28 '17 at 19:17
17
\$\begingroup\$

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
\$\endgroup\$
12
\$\begingroup\$

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.
\$\endgroup\$
  • \$\begingroup\$ did not know |% A* was possible, i've always avoided measure because I thought you couldn't wildcard the property name... \$\endgroup\$ – colsw Feb 27 '17 at 10:43
  • 2
    \$\begingroup\$ @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. \$\endgroup\$ – briantist Feb 27 '17 at 15:00
  • \$\begingroup\$ @ConnorLSW added some detailed info on these usages in the tips page. \$\endgroup\$ – briantist Feb 27 '17 at 15:40
10
\$\begingroup\$

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ Possible improvements: 1. double -> float 2. google.com -> google.com 3. maybe specifying encoding is not necessary, there should be some deprecated method You should save some 20 bytes \$\endgroup\$ – kukis Feb 27 '17 at 14:01
  • \$\begingroup\$ @kukis thanks, that shaved off 13 bytes. \$\endgroup\$ – user18932 Feb 27 '17 at 14:42
  • \$\begingroup\$ 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 \$\endgroup\$ – Roman Gräf Feb 27 '17 at 20:38
  • \$\begingroup\$ @RomanGräf yes, that works. Thanks! \$\endgroup\$ – user18932 Feb 27 '17 at 21:04
  • \$\begingroup\$ for(;i<n;++i) can be changed to for(;i++<n;) for -1 byte. \$\endgroup\$ – Kevin Cruijssen Feb 28 '17 at 8:52
7
\$\begingroup\$

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.

\$\endgroup\$
7
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ Either you have a built-in for google.com or something else is going on! \$\endgroup\$ – Pureferret Feb 28 '17 at 7:59
  • \$\begingroup\$ @Pureferret It's actually a dictionary compressed string. You can try it out here :). \$\endgroup\$ – Adnan Feb 28 '17 at 8:01
  • \$\begingroup\$ 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 \$\endgroup\$ – kukis Feb 28 '17 at 14:41
  • \$\begingroup\$ @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. \$\endgroup\$ – Adnan Feb 28 '17 at 17:46
7
\$\begingroup\$

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
\$\endgroup\$
  • 2
    \$\begingroup\$ Wellcome to codegolf.se ! join(file()) instead of file_get_contents() saves you a few bytes. \$\endgroup\$ – Christoph Feb 27 '17 at 7:10
  • 2
    \$\begingroup\$ In 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. \$\endgroup\$ – user59178 Feb 27 '17 at 12:09
6
\$\begingroup\$

Mathematica, 58 bytes

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

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

\$\endgroup\$
  • \$\begingroup\$ Why do you need N@? You aren't printing it, so there's no reason to format it nicely. \$\endgroup\$ – Pavel Feb 27 '17 at 3:01
  • \$\begingroup\$ @Pavel OP specified that exact fractions aren't allowed. \$\endgroup\$ – LegionMammal978 Feb 27 '17 at 3:07
3
\$\begingroup\$

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
\$\endgroup\$
  • 1
    \$\begingroup\$ You 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. \$\endgroup\$ – mbomb007 Feb 27 '17 at 14:52
  • 1
    \$\begingroup\$ You also don't need the [] in the 2nd case - sum takes a generator \$\endgroup\$ – Bahrom Feb 27 '17 at 22:03
3
\$\begingroup\$

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.
\$\endgroup\$
1
\$\begingroup\$

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)
\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – Carcigenicate Feb 28 '17 at 20:07
1
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ 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 \$\endgroup\$ – Value Ink Feb 28 '17 at 20:23
  • \$\begingroup\$ @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? \$\endgroup\$ – Miguel Feb 28 '17 at 20:26
  • \$\begingroup\$ urllib2 is a native (pre-installed) Python library 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. \$\endgroup\$ – Value Ink Feb 28 '17 at 20:28
  • \$\begingroup\$ @ValueInk no problem, my first contribution here, I didn't know \$\endgroup\$ – Miguel Feb 28 '17 at 20:31
1
\$\begingroup\$

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}
\$\endgroup\$
0
\$\begingroup\$

Rebol, 69 bytes

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

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))
\$\endgroup\$
0
\$\begingroup\$

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}
\$\endgroup\$
0
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.