Death By Shock Probe: That's a lot of dice

20

2

In the webcomic Darths & Droids, Pete, who plays R2-D2 in the fictional roleplaying campaign around which the comic is based, once claims (warning: potential spoilers in the linked comic) that, with the Lost Orb of Phanastacoria rigged up to his shock probe, he can now dish out a whopping 1048576d4 of damage. (The GM has neither confirmed nor denied this.) Since it should be reasonably obvious that almost no one will actually have the patience to roll that many dice, write a computer program to do it for him, outputting the total value rolled in some reasonable format. Entries will be ranked by program size (shortest program, by byte count, wins), both overall and per-language, with run time breaking ties. Answer may be either a full program or a function definition.

Scores Per-Language

Pyth

Maltysen - 8 bytes*

Jakube - 10 bytes

APL

Alex A - 10 bytes

CJam

Optimizer - 11 bytes

J

ɐɔıʇǝɥʇuʎs - 12 bytes **

Clip10

Ypnypn - 12 bytes **

K

JohnE - 13 bytes

Ti-84 BASIC

SuperJedi224 - 17 bytes*

R

MickyT - 23 bytes

OCTAVE/MATLAB

Oebele - 24 bytes

PARI/GP

Charles - 25 bytes **

Wolfram/Mathematica

LegionMammal978 - 27 bytes

Perl

Nutki - 29 bytes

AsciiThenAnsii - 34 bytes

Ruby

Haegin - 32 bytes **

ConfusedMr_C - 51 bytes **

Commodore Basic

Mark - 37 bytes **

PHP

Ismael Miguel - 38 bytes

VBA

Sean Cheshire - 40 bytes **

PowerShell

Nacht - 41 bytes **

Javascript

Ralph Marshall - 41 bytes

edc65 - 54 bytes (Requires ES6 functionality not available in all browsers.)

Lua

cryptych - 51 bytes

Java

RobAu - 52 bytes **

Geobits - 65 bytes

C

Functino - 57 bytes

Python

CarpetPython - 58 bytes

Postgre/SQL

Andrew - 59 bytes **

Swift

Skrundz - 69 bytes

GoatInTheMachine - 81 bytes

Haskell

Zeta - 73 bytes **

ActionScript

Brian - 75 bytes **

><>

ConfusedMr_C - 76 bytes

GO

Kristoffer Sall-Storgaard - 78 bytes

C#

Brandon - 91 bytes **

Andrew - 105 bytes

Ewan - 148 bytes

Scratch

SuperJedi224 - 102 bytes

C++

Michelfrancis Bustillos - 154 bytes

Polyglots

Ismael Miguel (Javascript/ActionScript2) - 67 bytes


Top 10 Overall

Maltysen
Alex A
Jakube
Optimizer
ɐɔıʇǝɥʇuʎs/Ypnypn (order uncertain)
JohnE
SuperJedi224
MickyT
Oebele

Warning- entries marked with a * are VERY SLOW.

Programmed marked ** I have not yet been able to properly test

SuperJedi224

Posted 2015-04-30T01:50:28.427

Reputation: 11 342

Wait, do I have to give the sum of the dice roll or just all the rolls in a list? – Maltysen – 2015-04-30T01:58:03.007

The sum of the dice roll. – SuperJedi224 – 2015-04-30T02:01:58.230

5Your question, as it stands, will likely be criticized for being unclear or being overly broad. It would be very helpful if you described in specific, objective terms how programs will be scored and what methods programs should have available to them. Also, the notation of 1048576d4 may be unclear to some users. It would be helpful to provide a description of precisely what should be computed, and any guidelines that must be followed. – BrainSteel – 2015-04-30T02:05:15.680

2This problem can be done too quickly to be a good time trial. – isaacg – 2015-04-30T02:57:44.990

I think you need to update your post: there have been several faster answers than the Perl answer by @AsciiThenAnsii. – ɐɔıʇǝɥʇuʎs – 2015-04-30T09:14:53.613

I'm working on updating it now. – SuperJedi224 – 2015-04-30T10:07:43.403

@isaacg yeah, I think you're right – SuperJedi224 – 2015-04-30T12:58:26.013

12

You could try your hand at making a stack snippet leaderboard to avoid having to manually keep the list of submissions up to date.

– Alex A. – 2015-04-30T14:32:08.367

1I absolutely love this title. – ASCIIThenANSI – 2015-04-30T22:19:26.350

How are you calculating your overall leaderboard ? – Optimizer – 2015-05-01T08:38:11.103

It's code size, with run time to break ties. I believe it says that in the current version of the question. – SuperJedi224 – 2015-05-01T09:54:04.293

Actually, the polyglot is in ActionScript2. The version is very important, since the var statement is required in version 3, but on version 2 it may be left behind in some situations. – Ismael Miguel – 2015-05-03T17:59:52.027

Since this question was asked, the party has lost the Lost Orb. Again. – SuperJedi224 – 2016-04-22T11:58:34.867

Answers

10

Pyth - 9 8 bytes

Uses obvious simple method of summation of randint. Took me minute to realize 1048576 was 2^20, now I feel really stupid. Thanks to @Jakube for saving me a byte by pointing out 2^20 = 4^10.

smhO4^4T

The runtime is horrible, it has yet to finish on my computer, so there is no point running it online so here is the 2^10 one: Try it online here.

s        Summation
 m       Map
  h      Incr (accounts for 0-indexed randint)
   O4    Randint 4
  ^4T    Four raised to ten

Maltysen

Posted 2015-04-30T01:50:28.427

Reputation: 25 023

48 bytes are possible. 2^20 = 4^10 – Jakube – 2015-04-30T09:34:30.747

@Jakube thanks for the tip :) – Maltysen – 2015-04-30T16:35:05.700

This finishes immediately for me. – Carcigenicate – 2015-05-02T00:16:11.347

@Carcigenicate are you talking about the link I gave? That's the modified one, only sums 1024d4. – Maltysen – 2015-05-02T00:35:23.380

@Maltysen Whoops, sorry. Ya, that's it. – Carcigenicate – 2015-05-02T00:36:34.193

9

Perl - 48 44 37 39 34 bytes

$-+=rand(4)+1for(1..2**20);print$-

Prints the sum without a trailing newline.
Saved 4 bytes by substituting for 2**20 (thanks Maltysen) and removing quotes around print.
Saved another 7 bytes by rearranging the code (thanks Thaylon!)
Lost 2 bytes because my old code generated 0-4 (it should be 1-4).
Once again, saved 5 bytes thanks to Caek and nutki.

Ungolfed, properly written code:

my $s = 0
$s += int( rand(4) + 1 ) for (1 .. 2**20);
print "$s";

ASCIIThenANSI

Posted 2015-04-30T01:50:28.427

Reputation: 1 935

It was a little hard to get a timer hooked up, but I eventually got it working. – SuperJedi224 – 2015-04-30T02:35:37.317

2Since we dont care about warnings ... $s+=int rand(5)for(1..2**20);print$s – Thaylon – 2015-04-30T14:11:45.190

3int(rand(5)) returns range 0 to 4 while d4 should be 1 to 4. – nutki – 2015-04-30T19:19:11.523

@nutki OK, thanks. I've edited that in now. – ASCIIThenANSI – 2015-04-30T20:05:17.860

$s+=int rand(4)+1for(1..2**20);print$s Removing the parenthesis for int also works for me, to save a stroke. – Caek – 2015-05-01T05:03:03.710

$=+=rand(4)+1for(1..2**20);print$= also worked for me to save more strokes. Assigning to the special var $= has the side affect of forcing int. – Caek – 2015-05-01T06:08:37.640

@Caek $= is initialized to 60 so it would be incorrect. $- has a similar behavior and starts at 0. – nutki – 2015-05-01T10:46:34.037

@nutki: I forgot it was += and not =.Thanks for that, I'll probably use $- from now on. – Caek – 2015-05-03T23:34:02.837

try for 1..2**20; instead of for(1..2**20); for another byte? – Caek – 2015-05-03T23:38:19.073

7

R, 32 24 23 21 bytes

Edit: Got rid of the as.integer and used integer division %/%. Speed it up slightly.

Thanks to Alex A for the sample tip ... and Giuseppe for removing the r=

sum(sample(4,2^20,T))

Tested with

i = s = 0
repeat {
i = i + 1
print(sum(sample(4,2^20,r=T)))
s = s + system.time(sum(sample(4,2^20,r=T)))[3]
if (i == 10) break
}
print (s/10)

Outputs

[1] 2621936
[1] 2620047
[1] 2621004
[1] 2621783
[1] 2621149
[1] 2619777
[1] 2620428
[1] 2621840
[1] 2621458
[1] 2620680
elapsed 
   0.029 

For pure speed the following completes in microseconds. However I'm not sure I've got my logic correct for it. The results appear consistent with the random method. Shame it's a longer length.

sum(rmultinom(1,2^20,rep(1,4))*1:4)

Here's a timing run I did on my machine

system.time(for(i in 1:1000000)sum(rmultinom(1,2^20,rep(1,4))*1:4))
                   user                  system                 elapsed 
7.330000000000040927262 0.000000000000000000000 7.370000000000345607987 

MickyT

Posted 2015-04-30T01:50:28.427

Reputation: 11 735

You can save a couple bytes by using sample() in place of runif(), i.e. sum(sample(4,2^20,r=T)). – Alex A. – 2015-04-30T04:09:05.217

Just did some benchmarking on my computer and sample() is actually faster too! – Alex A. – 2015-04-30T04:26:07.000

@AlexA. Thanks will test and change when I get close to a computer – MickyT – 2015-04-30T06:05:20.167

not to necro this or anything but you don't need r=T, just T is fine for replacement. – Giuseppe – 2017-06-12T21:12:12.323

1@Giuseppe, thanks .. this really was an old one – MickyT – 2017-06-12T21:33:35.130

7

APL, 11 10 bytes

+/?4⍴⍨2*20

This just takes the sum of an array of 220 = 1048576 random integers between 1 and 4.

+/           ⍝ Reduce by summing a
  ?          ⍝ random integer
   4⍴⍨       ⍝ array with values between 1 and 4
      2*20   ⍝ of length 2^20

You can benchmark this on TryAPL by printing the timestamp before and after. It takes about 0.02 seconds.

Saved a byte thanks to marinus and FUZxxl!

Alex A.

Posted 2015-04-30T01:50:28.427

Reputation: 23 761

One and 5??? A d4 can give 1, 2, 3 or 4. You can't get 5. – Loren Pechtel – 2015-04-30T03:59:53.197

@LorenPechtel: Sorry, my bad. Thanks for pointing that out. It's fixed now. I have tired brain. – Alex A. – 2015-04-30T04:02:44.110

Save a byte: +/?4⍴⍨2*20 – marinus – 2015-04-30T09:35:39.157

Small improvement: use +/?4⍴⍨2*20 instead. – FUZxxl – 2015-04-30T11:50:43.917

@marinus and FUZxxl: Thanks to both of you! Edited to use your suggestion. – Alex A. – 2015-04-30T14:19:30.957

1Incidtenally, this answer is not golfed in any way: It would be written exactly the same way in production APL code. – FUZxxl – 2015-07-11T21:13:49.813

7

Ti-84 Basic, 17 bytes

Total footprint - Size of program header = 17 bytes

Run Time: Unknown, estimated at 5-6 hours based on performance for smaller numbers of rolls (so, basically, not very good)

Σ(randInt(1,4),A,1,2^20

SuperJedi224

Posted 2015-04-30T01:50:28.427

Reputation: 11 342

1+1 for making it run on a TI-84. I guess time isn't a problem here, those are 30-40 year-old calculators by now. – ASCIIThenANSI – 2015-04-30T14:15:07.543

I presume there's a function for sampling a normal distribution rather than a uniform one? Should be much quicker. – Ben Voigt – 2015-04-30T18:25:38.867

@BenVoigt: Since this is meant to simulate the rolling of dice, a normal distribution is not appropriate; it would have to be uniform. – Alex A. – 2015-04-30T19:47:39.393

If this runs for 5-6 hours straight, I think your calculator battery would die before this finishes. – Alex A. – 2015-04-30T19:48:44.070

2@AlexA.: Central Limit Theorem provides that the sum of many uniform dice is indistinguishable from a normal distribution. So it depends on how pedantic we are about "simulating rolling". – Ben Voigt – 2015-04-30T20:34:47.583

@AlexA. the TI-84 series has a USB port for charging. – M. I. Wright – 2015-04-30T21:10:01.853

1@M.I.Wright, I thought it was just for communication. At least the one I've got uses AAA batteries. – Arturo Torres Sánchez – 2015-04-30T21:35:22.667

@ArturoTorresSánchez My apologies, you're actually partially right; it's only the C Silver Edition that uses the port for charging. The monochrome calcs don't really use it for anything. – M. I. Wright – 2015-05-04T18:39:49.707

To save a byte, the close-paren is unnecessary. – lirtosiast – 2015-05-17T18:13:18.530

6

Python 2, 58 bytes

We get 1048576 random characters from the operating system, take 2 bits of each, and add them up. Using the os library seems to save a few characters over using the random library.

import os
print sum(1+ord(c)%4 for c in os.urandom(1<<20))

This takes about 0.2 seconds on my PC.

Logic Knight

Posted 2015-04-30T01:50:28.427

Reputation: 6 622

6

CJam, 12 11 bytes

YK#_{4mr+}*

This is pretty straight foward:

YK                  e# Y is 2, K is 20
  #                 e# 2 to the power 20
   _                e# Copy this 2 to the power 20. The first one acts as a base value
    {    }*         e# Run this code block 2 to the power 20 times
     4mr            e# Get a random int from 0 to 3. 0 to 3 works because we already have
                    e# 2 to the power 20 as base value for summation.
        +           e# Add it to the current sum (initially 2 to the power 20)

But the beauty of this is that its really fast too! On my machine (and using the Java compiler) it takes on an average of 70 milliseconds.

The online version takes around 1.7 seconds on my machine.

Update: 1 byte saved thanks to DocMax

Optimizer

Posted 2015-04-30T01:50:28.427

Reputation: 25 836

The online version is taking about 6 seconds from the computers here, but that's probably just the network and/or the macbooks the school insists on using. I'll try again when I get home. – SuperJedi224 – 2015-04-30T15:47:16.107

@SuperJedi224 The online version is all in JavaScript, does not make any network calls. You can download the Java version and run it using the instructions on the website. – Optimizer – 2015-04-30T15:48:05.893

3Unless I am missing something (which is sadly too common with CJam and me), instead of seeding with 0 and adding 1 for 2^20 runs, seed with 2^20 to save 1 byte: YK#_{4mr+}* – DocMax – 2015-04-30T19:34:19.520

@DocMax You are right. Thanks! – Optimizer – 2015-04-30T19:36:15.357

+1; I was going to post this exact answer (except with 4A# instead of YK#), but you beat me to it. :) – Ilmari Karonen – 2015-04-30T21:00:16.943

6

JavaScript (ES6), 54 bytes

Average time < 100 msec. Run snippet to test (in Firefox)

// This is the answer
f=t=>(i=>{for(t=i;i--;)t+=Math.random()*4|0})(1<<20)|t

// This is the test
test();

function test(){
  var time = ~new Date;
  var tot = f();
  time -= ~new Date;
  
  Out.innerHTML = "Tot: " + tot + " in msec: " + time + "\n" + Out.innerHTML;
}
<button onclick="test()">Repeat test</button><br>
<pre id=Out></pre>

Explanation

With no statistical package built-in, in Javascript the shortest way to obtain the sum of 1 million random number is to call random() for a million times. So simply

f=()=>{
   var t = 0, r, i
   for (i=1<<20; i--; ) 
   {
      r = Math.random()*4 // random number between 0 and 3.9999999
      r = r + 1 // range 1 ... 4.999999
      r = r | 0 // truncate to int, so range 1 ... 4
      t = t+r
   }
   return t
}

Now, adding 1 for a million times is exactly the same than adding 1 million, or even better, start the sum with 1 million and then add the rest:

f=()=>{
   var t, r, i
   for (t = i = 1<<20; i--; ) 
   {
      r = Math.random()*4 // random number between 0 and 3.9999999
      r = r | 0 // truncate to int, so range 0 ... 3
      t = t+r
   }
   return t
}

Then golf, drop the temp variable r and drop the declaration of local variables. t is a parameter, as one is needed to shorten the declaration of f. i is global (bad thing)

f=t=>{
   for(t=i=1<<20;i--;) 
      t+=Math.random()*4|0
   return t
}

Then find a way to avoid 'return' using a nameless inner function. As a side effect, we gain another parameter so no globals used

f=t=>(
  (i=>{ // start inner function body
     for(t=i;i--;)t=t+Math.random()*4|0 // assign t without returning it
   })(1<<20) // value assigned to parameter i
  | t // the inner function returns 'undefined', binary ored with t gives t again
) // and these open/close bracket can be removed too

edc65

Posted 2015-04-30T01:50:28.427

Reputation: 31 086

Doesn't work in chrome. About to test in FF. – SuperJedi224 – 2015-04-30T21:31:13.227

Of course. Chrome is ES5 – edc65 – 2015-04-30T21:31:49.630

1It has some ES6 support (most of which is only available by enabling experimental javascript from chrome:\flags), but does not yet support arrow functions – SuperJedi224 – 2015-04-30T21:32:43.337

5

J (12 bytes, about 9.8 milliseconds)

+/>:?4$~2^20

I suspect this is mostly memory bandwith-limited: I can't even get it to max out a single core...

You can test this with the following code:

   timeit =: 13 : '(1000 * >./ ($/x) 6!:2"0 1 y)'
   4 20 timeit '+/>:?4$~2^20'
9.90059

This runs it in 4 groups of 20 trails, and returns the number of milliseconds of the avarage time in the quickest group. An interpreter can be found here.

ɐɔıʇǝɥʇuʎs

Posted 2015-04-30T01:50:28.427

Reputation: 4 449

5

Perl, 29

Generates a table of the required length.

print~~map{0..rand 4}1..2**20

nutki

Posted 2015-04-30T01:50:28.427

Reputation: 3 634

I'm getting a syntax error on this one. – SuperJedi224 – 2015-04-30T22:03:14.037

This needs a new enough version of Perl (the smartmatch operator was introduced in 5.10.1, and I think it wasn't made available by default until later). – Mark – 2015-04-30T23:31:33.770

~~ is not a smartmatch, just a double bit inversion to force scalar context. A one character longer way would be print$x=map.... Maybe on newer versions it warns because of ambiguity with smartmatch, but it does seem to work without warnings on my system and in here: http://ideone.com/LAIWzq – nutki – 2015-05-01T10:50:40.343

Yep, it works on IDEone. I'll give it to you. – SuperJedi224 – 2015-05-01T13:49:20.060

4

Pyth, 10 bytes

u+GhO4^4TZ

This has slightly more bytes than @Maltysen's Pyth solution. But it runs in 8.5 seconds on my laptop, while @Maltysen's solution produced no solution in 20 minutes running time.

But still a little bit too slow for the online compiler.

Explanation

u     ^4TZ   start with G = 0, for H in 0, ... 4^10-1:
                G = 
 +GhO4              G + (rand_int(4) + 1)
             result is printed implicitly 

Jakube

Posted 2015-04-30T01:50:28.427

Reputation: 21 462

Will test this this afternoon. – SuperJedi224 – 2015-04-30T13:51:11.327

4

Java, 65

Since we have scores listed by language, why not throw Java into the mix? There's not much to golf here, just a simple loop, but I was able to squeeze a couple out of my initial attempt:

int f(){int i=1<<20,s=i;while(i-->0)s+=Math.random()*4;return s;}

Geobits

Posted 2015-04-30T01:50:28.427

Reputation: 19 061

Will test this this afternoon. – SuperJedi224 – 2015-04-30T13:51:17.673

No problem. It takes around 80ms on this (slow) PC, but I don't know what you're using to time. – Geobits – 2015-04-30T13:55:05.413

I do not believe your program is a correct model. It can and does in my testing add 0 on some rolls. As I understand it most d4's are 1,2,3,4 (no 0 possible). – None – 2015-05-01T19:33:51.503

4@user39526 s (the total sum) starts at 1<<20 (the number of rolls). This is equivalent to adding one to each roll. When the randomizer throws 0, it's rolled a 1, etc. – Geobits – 2015-05-01T19:42:18.323

You should upgrade to Java 8 !http://codegolf.stackexchange.com/a/52919/7021

– RobAu – 2015-07-10T12:35:39.473

@RobAu I use it at home, but on the computer I did this on it's taboo. So I end up using 7 sometimes and 8 sometimes. No worse than people using python 2 or 3 :) – Geobits – 2015-07-10T12:39:04.987

4

Matlab, 24

First submission ever!

sum(randi([1,4],1,2^20))

I had hoped to make use of randi([1,4],1024), which gives a matrix of 1048576 elements, but then I needed a double sum, which takes more characters than this.

Regarding the running speed mentioned in the question, timeit tells me the runtime is about 0.031 seconds. So, pretty much instant.

Oebele

Posted 2015-04-30T01:50:28.427

Reputation: 311

I'm getting 0.04 to 0.05 seconds via octave online. – SuperJedi224 – 2015-04-30T13:48:35.017

4

PHP, 38 37 bytes

This uses a very simple idea: sum them all!

Also, I've noticed that 1048576 is 10000000000000000000 in binary, equivalent to 1<<20.

Here's the code:

while($i++<1<<20)$v+=rand(1,4);echo$v

Test in your browser (with VERY LITTLE changes):

$i=$v=0;while($i++<1<<20)$v+=rand(1,4);printf($v);

//'patch' to make a TRUE polyglot, to work in JS

if('\0'=="\0")//this will be false in PHP, true in JS
{
  //rand function, takes 2 parameters
  function rand($m,$n){
    return ((Math.random()*($n-$m+1))+$m)>>0;
    
    /*
     *returns an integer number between $m and $n
     *example run, with rand(4,9):
     *(Math.random()*(9-4+1))+4
     *
     *if you run Math.random()*(9-4+1),
     *it will returns numbers between 0 and 5 (9-4+1=6, but Math.random() never returns 1)
     *but the minimum is 4, so, we add it in the end
     *this results in numbers between 0+4 and 4+5
     *
     */
    
  }
  
  //for this purpose, this is enough
  function printf($s){
    document.write($s);
  }
}


/*
 *Changes:
 *
 *- instead of echo, use printf
 *    printf outputs a formatted string in php
 *    if I used echo instead, PHP would complain
 *- set an initial value on $i and $v
 *    this avoids errors in Javascript
 *
 */


$i=$v=0;while($i++<1<<20)$v+=rand(1,4);printf($v);

All the changes in the code are explained in comments.

Ismael Miguel

Posted 2015-04-30T01:50:28.427

Reputation: 6 797

You can remove the ; after echo$v – Martijn – 2015-05-01T13:24:18.560

@Martijn I left it there because most of the time PHP complains about it. But I have removed it now. It works on http://sandbox.onlinephpfunctions.com/ and that's enough.

– Ismael Miguel – 2015-05-01T18:20:27.597

4

Haskell, 73 bytes

import System.Random
f=fmap sum.(sequence.replicate(2^20))$randomRIO(1,4)

Usage:

$ ghci sourcefile.hs
ghci> f
2622130

Zeta

Posted 2015-04-30T01:50:28.427

Reputation: 681

4

C#: 105 bytes

using System.Linq;class C{int D(){var a=new System.Random();return new int[1<<20].Sum(i=>a.Next(1,5));}}

Andrew

Posted 2015-04-30T01:50:28.427

Reputation: 171

Nice, I like this even if it's two times wrong. It's 1<<20, not 2<<20. And the second parameter of Random.Next is The *exclusive* upper bound of the range so it should be 5 – edc65 – 2015-05-01T22:04:14.233

@edc65 Thanks for catching those errors. I have updated the answer. – Andrew – 2015-05-01T22:08:57.370

1You could save 9 chars by eliminating a and moving the new System.Random() inside of the Sum. Sure, it will create a new Random every time, but who cares as long as it gives a result? – LegionMammal978 – 2015-05-02T01:28:11.090

@LegionMammal978 if you create a new Random again and again, the result is mostly non-random – edc65 – 2015-05-03T20:24:15.420

@edc65 That is why I didn't go that route. I haven't had a chance to test what happens if I followed the suggestion. – Andrew – 2015-05-03T20:34:42.810

4

Mathematica, 30 27 bytes

Tr[RandomInteger[3,2^20]+1]

Mathematica has quite long function names...

LegionMammal978

Posted 2015-04-30T01:50:28.427

Reputation: 15 731

3

Ruby, 32 bytes

(1..2**20).inject{|x|x-~rand(4)}

In a more readable form:

(1..2**20).inject(0) do |x|
  x + rand(4) + 1
end

It creates a range from 1 to 1048576 and then iterates over the block that many times. Each time the block is executed the value from the previous iteration is passed in as x (initially 0, the default for inject). Each iteration it calculates a random number between 0 and 3 (inclusive), adds one so it simulates rolling a d4 and adds that to the total.

On my machine it's pretty fast to run (0.25 real, 0.22 user, 0.02 sys).

If you've got Ruby installed you can run it with ruby -e 'p (1..2**20).inject{|x|x+rand(4)+1}' (the p is necessary to see the output when run in this manner, omit it if you don't care for that or just run it inside IRB where the result is printed to the screen for you). I've tested it on Ruby 2.1.6.

Thanks to histocrat for the bit twiddling hack that replaces x + rand(4) + 1 with x-~rand(4).

Haegin

Posted 2015-04-30T01:50:28.427

Reputation: 141

1Could you explain how it works? – ASCIIThenANSI – 2015-04-30T16:41:05.470

The first online interpreter I could find that actually wants to load claims that the method rand() doesn't exist. I'll try to find another one. – SuperJedi224 – 2015-05-01T13:39:31.863

Okay, I found one that works. – SuperJedi224 – 2015-05-01T13:45:33.657

Bit twiddling hack: x-~rand(4) is equivalent to x+rand(4)+1. – histocrat – 2015-05-02T18:53:15.587

Also, you can replace 2**20 with 4e10. – histocrat – 2015-05-02T18:53:48.233

3

C, 57 bytes

main(a,b){for(b=a=1<<20;a--;b+=rand()%4);printf("%d",b);}

This code works... once. If you ever need to roll those dice again, you'll need to put srand(time(0)) in there, adding 14 bytes.

Functino

Posted 2015-04-30T01:50:28.427

Reputation: 417

Why would you need to add srand(time(0))? (Sorry, I don't use C.) – ASCIIThenANSI – 2015-04-30T16:27:41.993

@ASCIIThenANSI Many implementations of C's rand seed it to the same value every run. srand seeds the RNG, and time(0) gets the current time in seconds since 1970. – Functino – 2015-04-30T16:31:47.847

If you initialize a=b=1<<20 then you can skip 1+, this saves 4 bytes. – nutki – 2015-04-30T19:23:21.340

Also, int before main is not required. – nutki – 2015-04-30T19:45:19.293

Hint to anybody doing t=0, then t=t (...) +1 for 1048576 times: think again! (see my answer, eventually) – edc65 – 2015-04-30T20:38:14.227

@nutki Thanks for the help! – Functino – 2015-04-30T21:41:58.087

3

PARI/GP, 25 bytes

Really, no need for golfing here -- this is the straightforward way of doing the calculation in GP. It runs in 90 milliseconds on my machine. Hoisting the +1 saves about 20 milliseconds.

sum(i=1,2^20,random(4)+1)

Just for fun: if one were optimizing for performance in PARI,

inline long sum32d4(void) {
  long n = rand64();
  // Note: __builtin_popcountll could replace hamming_word if using gcc
  return hamming_word(n) + hamming_word(n & 0xAAAAAAAAAAAAAAAALL);
}

long sum1048576d4(void) {
  long total = 0;
  int i;
  for(i=0; i<32768; i++) total += sum32d4();
  return total;
}

has a very small total operation count -- if xorgens needs ~27 cycles per 64-bit word (can anyone verify this?), then a processor with POPCNT should take only about 0.5 cycle/bit, or a few hundred microseconds for the final number.

This should have close-to-optimal worst-case performance among methods using random numbers of similar or higher quality. It should be possible to greatly increase average speed by combining cases -- maybe a million rolls at a time -- and selecting with (essentially) arithmetic coding.

Charles

Posted 2015-04-30T01:50:28.427

Reputation: 2 435

3

PostgreSQL, 59 bytes

select sum(ceil(random()*4)) from generate_series(1,1<<20);

I'll admit to the slight problem that random() could, in theory, produce exactly zero, in which case the die roll would be zero.

Andrew

Posted 2015-04-30T01:50:28.427

Reputation: 171

You don't really need the ; to terminate the query since it is the only one – MickyT – 2015-05-03T21:18:40.523

3

Javascript, 55 53 50 47 41 bytes

for(a=i=1<<20;i--;)a+=(Math.random()*4)|0

I didn't realize that non-random numbers were a known irritant, so I figure that I ought to post a real solution. Meant no disrespect.

Commentary: as noted by others above you can skip the +1 to each roll by starting off with the number of rolls in your answer, and by not having to write a=0,i=1<<20 you save two bytes, and another 2 because you don't add +1 to each roll. The parseInt function does the same thing as Math.floor but is 2 characters shorter.

Ralph Marshall

Posted 2015-04-30T01:50:28.427

Reputation: 729

Note that this answer is completely different from the one originally commented on by SuperJedi224 and @Andrew – Ralph Marshall – 2015-05-02T19:15:48.000

You can remove both brackets and the last semicolon (and only the last one) to cut down a few further characters. Also, the current version is only 50 characters, not 52. – SuperJedi224 – 2015-05-02T19:49:31.673

SuperJedi - thanks for the suggestions. I thought I'd tried it without the brackets only to run into problems, but perhaps I had a different problem. In any case, I think this is about as good as it's going to get. – Ralph Marshall – 2015-05-03T01:31:35.037

a+=parseInt(Math.random()*4) may be shortened to a+=1+Math.random()*4&7. The 1+ is only if you care if it rolls 0 or not. – Ismael Miguel – 2015-05-03T17:45:36.613

You can golf it down to this: for(a=i=1<<20;i--;)a+=(Math.random()*4)|0, that's only 41 bytes – SuperJedi224 – 2015-05-30T18:18:56.157

for(a=i=1<<20;i--;)a+=Math.random()*4|0 works as well – Conor O'Brien – 2017-06-12T21:58:59.887

2

Clip 10, 12 bytes

r+`m[)r4}#WT

         #4T    .- 4^10 = 1048576             -.
   m[   }       .- that many...               -.
     )r4        .-          ...random numbers -.
r+`             .- sum                        -.

It takes approximately 0.6 seconds to run on my machine.

Ypnypn

Posted 2015-04-30T01:50:28.427

Reputation: 10 485

2

Go, 87 bytes

Naive solution

import"math/rand";func r(){o,n:=0,2<<19;for i:=0;i<n;i++{o+=rand.Intn(4)};println(o+n)}

Run online here: http://play.golang.org/p/gwP5Os7_Sq

Due to the way the Go playground works you have to manually change the seed (time is always the same)

Kristoffer Sall-Storgaard

Posted 2015-04-30T01:50:28.427

Reputation: 489

2

Go, 78 bytes

Golfed

import."math/rand";func r()(o int){for i:=2<<19;i>=0;i--{o+=Intn(4)+1};return}

Still working on it

Run online here http://play.golang.org/p/pCliUpu9Eq

Kristoffer Sall-Storgaard

Posted 2015-04-30T01:50:28.427

Reputation: 489

Unfortunately, the golang.org playground doesn't implement the time operations properly and the repl.it one doesn't want to load right now. I'll see what I can do about it this afternoon. – SuperJedi224 – 2015-04-30T14:12:22.097

2

Swift, 64 bytes

Nothing clever, golfing in Swift is hard...

func r()->Int{var x=0;for _ in 0..<(2<<19) {x+=Int(arc4random()%4)+1;};return x;}

Version 2 (too late)

var x=0;for _ in 0..<(2<<19){x+=Int(arc4random()%4)+1;};print(x)

GoatInTheMachine

Posted 2015-04-30T01:50:28.427

Reputation: 463

2

VBA, 40 Bytes

for i=1 to 2^20:q=q+int(rnd*4)+1:next:?q

SeanC

Posted 2015-04-30T01:50:28.427

Reputation: 1 117

How can I retrieve the output? – Ismael Miguel – 2015-04-30T20:57:42.660

1@IsmaelMiguel: Paste the line in an immedtiate VBA window. ? is the print statement. – edc65 – 2015-04-30T21:26:16.127

I plan on testing this one as soon as I can get visual studio to finish installing – SuperJedi224 – 2015-04-30T22:13:09.733

I should really warn you it's slow... But it's BASIC - what else would you expect? – SeanC – 2015-04-30T23:46:57.940

i reckon solutions that require Visual Studio should include the installation time in the running time! :P – Nacht - Reinstate Monica – 2015-05-01T12:46:49.620

1@SuperJedi224 Don't need Visual Studio. It's vbA and it's included in Office Applications. Excel for instance – edc65 – 2015-05-01T19:14:40.170

2using excel/word/powerpoint/access, ?timer:for i=1 to 2^20:q=q+int(rnd*4)+1:next:?q:?timer will test it. using a dell latitude E6440, the time was 0.16 secs – SeanC – 2015-05-01T21:31:13.747

you can lose 1 byte by changing this for i=1 to 2... to for i=1To 2 – Taylor Scott – 2017-03-25T20:36:28.280

2

Commodore Basic, 37 bytes

1F┌I=1TO2↑20:C=C+INT(R/(1)*4+1):N─:?C

PETSCII substitutions: = SHIFT+E, / = SHIFT+N, = SHIFT+O

Estimated runtime based on runs with lower dice counts: 4.25 hours.

It's tempting to try to golf off two bytes by making C an integer, getting implicit rounding of the random numbers. However, the range on integers in Commodore Basic is -32678 to 32767 -- not enough, when the median answer is 2621440.

Mark

Posted 2015-04-30T01:50:28.427

Reputation: 2 099

2

PowerShell, 41 37 bytes

1..1mb|%{(get-random)%4+1}|measure -s

Took my machine 2 minutes 40 seconds

Nacht - Reinstate Monica

Posted 2015-04-30T01:50:28.427

Reputation: 481

2

Ruby, 51 47 chars

x=[];(2**20).times{x<<rand(4)+1};p x.inject(:+)

I looked at all of the answers before I did this, and the sum(2**20 times {randInt(4)}) strategy really stuck out, so I used that.

><>, 76 chars

012a*&>2*&1v
|.!33&^?&:-<
3.v < >-:v >
   vxv1v^<;3
  1234    n+
  >>>> >?!^^

I'm not sure if this one works, because my browser crashed when I tried to test it, but here's the online interpreter.

clap

Posted 2015-04-30T01:50:28.427

Reputation: 834

I'll give you a +1 for the ><> answer. – SuperJedi224 – 2015-07-08T00:43:08.073

2

Java (Java 8) - 52

int f(){return new Random().ints(1<<20,1,5).sum();}

RobAu

Posted 2015-04-30T01:50:28.427

Reputation: 641

1

C#, 148 (console app)

using R=System.Random;using C=System.Console;class P{static void Main(){int o=0;R r=new R();for(int i=0;i<1048576;i++){o+=r.Next(1,4);}C.Write(o);}}

Ewan

Posted 2015-04-30T01:50:28.427

Reputation: 151

You can make your code shorter by removing all unnecessary whitespace, for example, int o = 0; to int o=0;. – ProgramFOX – 2015-05-01T09:59:15.097

You can also remove the space after C=, and then you'll have 148 chars (at the moment you have 149, not 150). – ProgramFOX – 2015-05-01T10:12:19.313

It's wrong (just try it: the sum is too low) Should be .Next(1,5), as the second parameter is the exclusive upper bound of the range – edc65 – 2015-05-01T22:10:07.247

1

Lua 5.1, 51 bytes :)

a=0 for _=1,2^20 do a=a+math.random(4) end print(a)

math.random(n) already returns a number between 1 and n, so I didn't use @edc65's optimization (clever though it is). Another 26 bytes is required to properly seed the RNG, however....

criptych stands with Monica

Posted 2015-04-30T01:50:28.427

Reputation: 181

1

K, 13 bytes

+/1+(_2^20)?4

Take the sum (+/) of one plus a vector of 2^20 (_2^20) numbers from [0,4) (?4).

The floor _ is necessary because ^ returns a float, which is slightly inconvenient for this problem.

Tested with Kona. On my machine, this runs in roughly 24 milliseconds.

edit:

To test timing, you can prefix the program with \t and get the runtime in milliseconds.

  \t +/1+(_2^20)?4
25

JohnE

Posted 2015-04-30T01:50:28.427

Reputation: 4 632

Okay, I'll test this later this afternoon – SuperJedi224 – 2015-05-11T16:43:50.737

1

Microscript, 7 bytes

First, a disclaimer: This is not actually a competing entry for this challenge, as this language is significantly too new.

Now, here's the program: 20ec1r4

SuperJedi224

Posted 2015-04-30T01:50:28.427

Reputation: 11 342

1

Scratch, 102 bytes

The consensus seems to be to convert it to the plaintext form used by the scratchblocks code on the scratch forums, so here we go.

when green flag clicked
set [a v] to [0]
repeat (1048576)
change [a v] by (pick random (1) to (4))
end

Result will be stored in the variable a.

SuperJedi224

Posted 2015-04-30T01:50:28.427

Reputation: 11 342

1

Swift, 69 bytes

var b={return[UInt32](0..<8<<17).reduce(0){$1*0+$0+arc4random()%4+1}}

$1*0 is required for the compiler to infer the type of the closure.

David Skrundz

Posted 2015-04-30T01:50:28.427

Reputation: 466

0

Perl 6, 26 bytes

{sum (1..4).pick xx 1+<20}

It's not fast...takes about nine seconds on my system.

Sean

Posted 2015-04-30T01:50:28.427

Reputation: 4 136

0

Actionscript 3, 81 77 75 bytes:

function r(){var a=0,i=1<<20;while(i--){a+=int(Math.random()*4+1)}return a}

Brian

Posted 2015-04-30T01:50:28.427

Reputation: 231

1I don't know Actionscript, but if you can write this as a full program rather than a function it will likely be shorter. And are the trailing semicolons on the final lines prior to the closing braces necessary? Also, you can express 1048576 as 2^20, which is much shorter. – Alex A. – 2015-04-30T19:53:57.297

@AlexA. As a full program, you have to write a class declaration in order to have it compile. – Brian – 2015-04-30T20:10:50.247

1048576 can be replaced with 1<<20. Also, int(Math.random()*4+1) may return 5. Use 1+Math.random()*3>>0 instead. Also, declare it as Actionscript 2 and you have this for you: r=function(){i=a=0;while(i++<1<<20)a+=1+Math.random()*3>>0;return a}. Only 68 bytes!. (or 69, if ; is required after the return) – Ismael Miguel – 2015-04-30T20:19:19.677

@IsmaelMiguel Math.random()*4+1 will never return 5. Math.random() returns 0 <= x < 1. See the Math asdocs for details.

– Brian – 2015-04-30T20:21:12.340

Hint to anybody doing t=0, then t=t (...) +1 for 1048576 times: think again! (see my answer, eventually) – edc65 – 2015-04-30T20:38:43.330

You are right, it won't return 1. Sorry for that. – Ismael Miguel – 2015-04-30T20:47:55.643

Since you haven't accepted my suggestion, I will take it and post it as a polyglot. – Ismael Miguel – 2015-05-02T15:27:43.043

@IsmaelMiguel I'd have taken your suggestion if I'd written actionscript 2, but since I wrote actionscript 3, your suggestion would break. – Brian – 2015-05-04T15:02:25.797

0

Javascript + ActionScript2, 67 bytes

According to the ActionScript3 documentation, it is only required to use the keyword var when setting a type.

Other than that, it pretty much looks like Javascript.
Since I'm a fan of polyglots, I did this one.

The code:

function r(){i=a=0;while(i++<1<<20)a+=1+Math.random()*4&7;return a}

The &7 has a function to convert the number to an integer value. I could use other methods, but the gain in size would be null.

Test it here:

function r(){i=a=0;while(i++<1<<20)a+=1+Math.random()*4&7;return a}

document.write(r());

This answer is based on Brian's answer in ActionScript3, based in a comment I left with a solution for him.

Ismael Miguel

Posted 2015-04-30T01:50:28.427

Reputation: 6 797

Er...you do need var in the variable declaration. Depending on settings, it's a compile or runtime error if you omit it. – Brian – 2015-05-03T16:34:40.927

@Brian According to the documentation, only if I define a datatype (E.g.: var i:Number;) or "type annotation" (as the documentation calls it). And since I'm providing a value to it, according to the documentation, it won't give me any error. – Ismael Miguel – 2015-05-03T16:37:58.910

" In ActionScript 3.0, use of the var statement is always required" Are you running as2 or 3? Your answer title says 2, but you cite as 3 documentation. Does your swf run successfully? – Brian – 2015-05-03T22:20:43.653

@Brian I'm aware of what I'm saying. Quoting: "In ActionScript 2.0, use of the var statement is only required if you use type annotations.". Therefore, the var statement isn't required. I'm reading from ActionScript3 but the code is for ActionScript2. I'm not inventing anything. And I haven't found a way to test it. But I surely will, if I had a way. – Ismael Miguel – 2015-05-03T22:36:01.437

Ah. Might I suggest adding a note to that effect? Mentioning both as2 and 3 in your answer confuses the issue. – Brian – 2015-05-04T14:58:33.887

@Brian You are free to edit the question with that footnote, Actually, I would thank if you did so. – Ismael Miguel – 2015-05-04T15:35:28.817

0

C# - 91

I went the function route for this

Func<int,int>G=s=>{int e=s=0;var r=new Random();for(;s<1<<20;s++)e+=r.Next(1,5);return e;};

Brandon

Posted 2015-04-30T01:50:28.427

Reputation: 257

0

C++, 154 bytes

Golfed:

#include<iostream>
#include <stdlib.h>
#include <time.h>
int main(){int c=0;srand(time(NULL));for(int x=0;x<=1048576;x++){c=c+(rand()%4+1);}std::cout<<c;}

Ungolfed:

#include<iostream>
#include <stdlib.h>
#include <time.h>

int main(){
    int c = 0;
    srand (time(NULL));
    for(int x = 0; x <= 1048576; x++){
        c = c + (rand() % 4 + 1);
    }

    std::cout<<c;
}

Michelfrancis Bustillos

Posted 2015-04-30T01:50:28.427

Reputation: 695

0

Python 2, 69 67 Bytes

import random
print sum([random.randint(1,4)for _ in range(4**10)])

11 9 bytes more that the existing Python 2 answer :( I'm sure I can find some places to shave off a few bytes though.

DoctorHeckle

Posted 2015-04-30T01:50:28.427

Reputation: 336

I don't think this version gets the distribution right. – SuperJedi224 – 2016-04-22T18:44:41.680

@SuperJedi224 you are 100% correct, this is purely uniform where it should be some flavor of normal. I have an idea that involves sum(), I'll see if I can make it work. – DoctorHeckle – 2016-04-25T13:14:11.133

You can remove the spaces between 4,) and for, and the space between range and (4**10). – Rɪᴋᴇʀ – 2016-04-25T20:58:57.467

Good eyes, @EasterlyIrk. Thanks! – DoctorHeckle – 2016-04-26T13:07:34.930