103
\$\begingroup\$

One nice property of a Turing-complete language is that it can be used to write any program, up to and including the simulation of the entire Universe.

Your job is to do exactly that: write a program which simulates the Universe.


Note: although I don't doubt you'll be able to accomplish this task, nowadays I don't have enough spare time to verify whether all 1090 of the particles in your simulation do what they really should do. Therefore, solely to simplify testing and evaluation, it is enough if your universe simulator only works with a single starting particle. To keep things interesting, let's assume this particle is the recently discovered Higgs Boson.

Your universe starts with nothing but a single Higgs Boson of approximately 120 GeV in the middle of it. To not make the output too long, let's make this universe tick at only 10-25 seconds instead of its "usual clock rate" of 5.4×10−44 seconds..

This Higgs boson will decay sooner or later as it has a half-life of 1.6×10−22 seconds, so at every tick of the simulation, it has a 0.0433% chance of decaying. You can check here what it will decay into. To have a central and simplified requirement, I list the branching ratios you should use:

Running the simulation

At each tick of the simulation, the Higgs boson has a 0.0433% chance of decaying. If that happens, it will decay into the following particles, with the listed probabilities (you should use these names in the output):

  • bottom quark + bottom antiquark (64.8%)
  • 2 W bosons (14.1%)
  • 2 gluons (8.82%)
  • tau lepton + antitau lepton (7.04%)
  • charm quark + charm antiquark (3.27%)
  • 2 Z bosons (1.59%)
  • 2 photons (0.223%)
  • 1 Z boson + 1 photon (0.111%)
  • muon + antimuon (0.0244%)
  • top quark + top antiquark (0.0216%)

For a total of 100%.

Some of these particles will decay further.

W boson: half-life of 10-25 seconds, this means a 50% chance to decay at every tick into one of the following, with equal probabilities:

  • positron + neutrino
  • antimuon + neutrino
  • antitau lepton + neutrino

Z boson: half-life of 10-25 seconds, this means a 50% chance to decay at every tick into one of the following:

  • neutrino + antineutrino (20.6%)
  • electron + positron (3.4%)
  • muon + antimuon (3.4%)
  • tau lepton + antitau lepton (3.4%)
  • down quark + down antiquark (15.2%)
  • strange quark + strange antiquark (15.2%)
  • bottom quark + bottom antiquark (15.2%)
  • up quark + up antiquark (11.8%)
  • charm quark + charm antiquark (11.8%)

top quark: half-life of 5×10-25 seconds, this means a 12.95% chance to decay at every tick into the following, with equal probabilities:

  • W boson + down quark
  • W boson + strange quark
  • W boson + bottom quark

Of course, the W boson will also soon decay...

The top antiquark behaves similarly to the top quark: it decay into a W boson and a d/s/b antiquark.

All other particles (so all except for the Z and W bosons and top quarks) have a half life many orders of magnitude longer, so to not clutter the output, they are all considered stable for our simulation.

As the universe is largely empty, all the particles will have enough space for themselves and will not interact with each other. Therefore all individual particles are independent from each other in every regard, including the probabilities of splitting.

Output:

Every tick of the simulation, you have to print the contents of the simulated universe into a new line. For example:

The universe contains 1 Higgs boson.
The universe contains 1 Higgs boson.
The universe contains 1 Higgs boson.
The universe contains 1 Higgs boson.
The universe contains 2 W bosons.
The universe contains 2 W bosons.
The universe contains 1 W boson, 1 positron and 1 neutrino.
The universe contains 1 positron, 1 antitau lepton and 2 neutrinos.
Simulation ended after 0.8 yoctoseconds.

The order of the particles in the line is not important. The formatting, however, must be exactly as in the example above, including punctuation and pluralization. If you simulate an entire (mini-) universe, it should look nice (And I wanted to eliminate the abusing of a not sufficiently strict output requirement)

Each line corresponds to 0.1 yoctoseconds, but you will be forgiven if it takes longer than that for your program to print the output.

The simulation ends when only "stable" particles remain.

Scoring

Standard code golf rules apply.

The random number generator can be pseudo-random, but you must seed it if the language doesn't seed it by default. The probability distribution of your RNG must be uniform.

  • You will get a bonus -10% to the code size if the program takes an integer as an input, and starts with that many Higgs bosons.

Exception for Turing machine enthusiasts.

For those who dare to try their luck with an actual Turing machine or a similar language (like Brainfuck), their task is made easier by the following rule changes (only applicable if the language is a Brainfuck-derivative or otherwise a very simplified Turing-machine, incapable of assignment, lacking an ALU, and values on the tape can only be incremented and decremented by one):

  • The particle names are simplified to d, s, b, t, u, c for the quarks, v for the neutrino, T for tau lepton, m for muon, g for gluon, p for photon, Z, W and H for the bosons, - for the electron and + for the positron. At each tick, an input with the value of 0 or 1 are provided from the standard input, indicated whether the first unstable particle in the list decays or not.

The example output will therefore become

H
H
H
H
W W
W W
W + n
+ !T n n
\$\endgroup\$
  • 76
    \$\begingroup\$ Does Mathematica have a SimulateUniverse built-in function? \$\endgroup\$ – Digital Trauma Nov 4 '15 at 21:32
  • 14
    \$\begingroup\$ So... This universe doesn't have a big bang... - just a little bang? \$\endgroup\$ – Level River St Nov 4 '15 at 23:53
  • 3
    \$\begingroup\$ If a top quark decays, shouldn't a top antiquark decay too? I guess it doesn't matter, rules are rules. But physics is physics (and my particle physics isn't very good, but it seems odd.) \$\endgroup\$ – Level River St Nov 5 '15 at 7:22
  • 23
    \$\begingroup\$ Our whole universe might be a code golf challenge. \$\endgroup\$ – coredump Nov 6 '15 at 13:41
  • 18
    \$\begingroup\$ I suppose I'd be best at this challenge... ;) \$\endgroup\$ – Beta Decay Nov 8 '15 at 10:35

16 Answers 16

1
+100
\$\begingroup\$

Pyth, 572 * 0.9 = 514.8 bytes

Jm?tld,hd,-1^.5c1shced\ sm*]<k2s>k2tced\ dcR\,cu:GhHtHc"A76 !B17 !C1 v!D_top !E00 !F bosR!GmuR_!Ineutrino_!Jtau leptR_!KQ_charm !LQ_strange !MQ_down !NQ_up !OQ_bottom !Panti!Qquark!Ron"\!"HiggsF,16Efg3240Ebb705Epp441Eqr352ER16350 cc7950 ss1115 cs555 tu122 de108_WF,CxCuCr1_ZF,Cw103 yxBtuBqrBjkAlmAfgAhi59 R59DQ,5 bj1 bl1 bf1DPOOPNNPMMPLLPKKPQ_gluR_JPJphotR_GPGIPIpositrR_electrR"\_L%"The universe contains %s.":j", "fT.e?bs[b\ h@Jk?tb\s"")0b",(?!.*,)"" and"K+Q*]Z24Ws<K4yK=+Z1Vs.em?>O1.0he@JkY,kOee@Jkb<K4IN XhNK_1 XRK1xLGeN;yK%"Simulation ended after %s yoctoseconds."cZT

Qualifies for the -10% bonus. Try it online here, or try it out with the Higgs boson half life reduced to 1ys here (makes for less repetition in the output, and a more exciting universe!).

I'm convinced this is far from optimal, especially the dictionary compression, but I've wasted more than enough time on this already, so improvement suggestions are welcome.

The program is split into three parts - dictionary preparation, output function definition, and simulation execution.

Dictionary preparation

Jm?tld,hd,-1^.5c1shced\ sm*]<k2s>k2tced\ dcR\,cu:GhHtHc"A76 !B17 !C1 v!D_top !E00 !F bosR!GmuR_!Ineutrino_!Jtau leptR_!KQ_charm !LQ_strange !MQ_down !NQ_up !OQ_bottom !Panti!Qquark!Ron"\!"HiggsF,16Efg3240Ebb705Epp441Eqr352ER16350 cc7950 ss1115 cs555 tu122 de108_WF,CxCuCr1_ZF,Cw103 yxBtuBqrBjkAlmAfgAhi59 R59DQ,5 bj1 bl1 bf1DPOOPNNPMMPLLPKKPQ_gluR_JPJphotR_GPGIPIpositrR_electrR"\_

This is the largest section of the finished code, taking up 381 bytes. The dictionary is built using the following string:

Higgs boson,1600 fg324000 bb70500 pp44100 qr35200 on16350 cc7950 ss1115 cs555 tu122 de108_W boson,1 vx1 vu1 vr1_Z boson,1 vw103 yx17 tu17 qr17 jk76 lm76 fg76 hi59 on59_top quark,5 bj1 bl1 bf1_top antiquark_bottom quark_bottom antiquark_up quark_up antiquark_down quark_down antiquark_strange quark_strange antiquark_charm quark_charm antiquark_gluon_tau lepton_antitau lepton_photon_muon_antimuon_neutrino_antineutrino_positron_electron

The string is an underscore separated list of the particles and, if the particle is unstable, its behaviour - a space separated list consisting of its half life in simulation ticks followed by what it decays into, along with the distinct probabilies of each. Each particle has a single-letter code associated with it, given by their position in the list indexed into the lower case alphabet - so the Higgs boson is a, the W boson is b, all the way up to the electron being y.

Rather than storing the decay probabilities, the half life is stored instead and the probability calculated when the dictionary is processed. The formula used is P=1-(1/2)^(1/h) where P is the probablity to decay per tick, and h is the half life of the particle measured in ticks.

The unstable particles are the first four in the list. As the number of these particles is what determines when the simulation ends, having these at the start of the list makes them easy to check later on.

The problem is that this string is huge - 436 bytes! - and using Pyth's built-in string compression actually increases the byte count, as it uses so many multi-byte characters. I've settled on a relatively simple iterative dictionary compression scheme. The snippet u:GhHtHc"xxx"\!"yyy" decompresses it, as follows:

u:GhHtHc"xxx"\!"yyy"   xxx -> dictionary, yyy -> encoded string
       c"xxx"\!        Chop the dictionary on !
u              "yyy"   Reduce the above, with initial state as encoded string, using:
 :G                      In the current string, replace...
   hH                    ... the first character of the dictionary entry...
     tH                  ... with the remainder of the dictionary entry

The dictionary entries I've chosen are based only on my intuition and some trial and error, so I'm sure there is plenty of room for improvement.

The decompressed dictionary string is then interpreted and stored as described below:

Jm?tld,hd,-1^.5c1shced\ sm*]<k2s>k2tced\ dcR\,cxxx\_   xxx -> decompressed dictionary
                                              cxxx\_   Split the string on underscores
                                          cR\,         Split each part on commas
 m                                                     Map each element (particle), d, using:
  ?tld                                   d               Is the element length >1? If not, no change, otherwise...
      ,hd                                                  Create a pair consisting of the particle's name and...
                   ced\                                      Split the decay data on spaces
                 sh                                          Parse 1st element (half life) as int
          -1^.5c1                                            Calculate per-tick decay probability
         ,                                                   Pair the above with...
                         m         tced\                       Map the rest of the decay data, k, using:
                           ]<k2                                  Take the 1st two characters
                               s>k2                              Parse the rest of the characters as a string
                          *                                      Repeat the characters that many times
                        s                                      Flatten the list
J                                                      Store the processed dictionary in J

The result is that J contains an ordered list of the particle names. If they decay, the name is paired with its decay probability and a set of the particles it could decay into, weighted by their relative probabilities.

Output function definition

L%"The universe contains %s.":j", "fT.e?bs[b\ h@Jk?tb\s"")0b",(?!.*,)"" and"

This defines a function y(b), which accepts the current state of the universe as its input. This is simply a list of the numbers of the particles, ordered by their type as defined in the dictionary string described in the previous section.

L%"x":j", "fT.e?bs[b\ h@Jk?tb\s"")0b",(?!.*,)"" and"   "x" -> format string, omitted for brevity
L                                                      Define a function, y(b)
             .e                     b                  Map each element of b with its index, k, using:
               ?b                 0                     Is b non zero? If not, 0, otherwise...
                   b                                      Particle count
                    \                                     Space
                      h@Jk                                Particle name (lookup in dictionary, then take 1st element)
                          ?tb\s""                        Trailing s if more than 1
                 s[              )                       Concatenate the above 4
           fT                                          Filter out the 0s
      j", "                                            Join on comma + space
     :                                                 Replace in the above...
                                    ",(?!.*,)"         ... the last comma...
                                              " and"   ... with "and"
 %"x"                                                  Insert the above into the format string

Simulation execution

K+Q*]Z24Ws<K4yK=+Z1Vs.em?>O1.0he@JkY,kOee@Jkb<K4IN XhNK_1 XRK1xLGeN;yK%"Simulation ended after %s yoctoseconds."cZT

With the prep done, the simulation can now be executed. This consits of a few steps:

Universe initialisation

As the particle at index 0 in the universe state is the Higgs boson, the initial state of the universe is an array of input number followed by 24 zeroes.

K+Q*]Z24   implicit: Q=eval(input())
  Q        Input number
   *]Z24   0 repeated 24 times
 +         Concatenate
K          Assign to K

Simulation loop

At each tick in the simulation, the current state of the universe needs to be displayed, a counter incremented, and each volatile particle needs to check if it should decay, applying the results to the universe state once each particle has been evaluated.

Ws<H4yK=+Z1Vs.em?>O1.0he@JkY,kOee@Jkb<K4IN XhNK_1 XRK1xLGeN;   
 s<K4                                                          Take the sum of the first 4 particle counts
W                                                          ;   Loop until the above is 0
     yK                                                        Output the current universe state
       =+Z1                                                    Increment variable Z (initially 0)
             .e                      <K4                       Map each particle count, b, with its index, k, using:
               m                    b                            Map over the particle count using:
                        @JK                                        Look up the particle data
                      he                                           Get the decay probability
                  O1.0                                             Generate random float between 0 and 1
                ?>         Y                                       Has particle failed to decay? Empty array if so, otherwise...
                               ee@Jk                                 Get the particle decay choices
                              O                                      Choose one of them at random
                            ,k                                       Create a pair with the current particle index and the above
            s                                                  Combine into single nested list
           V                                                   For N in the above:
                                        IN                       If N is not empty:
                                           X  K                    Add to element in K...
                                            hN                     ... at the correct particle's index...
                                               _1                  ... -1
                                                      xLGeN        Get the index of each particle to be added to the universe
                                                                     (lookup using index in G, lowercase alphabet)
                                                  XRK1             Add 1 to the element in K at each of the indexes

Final output

The simulation finishes when there are no unstable particles left. All that remains is to output the final state of the universe, and how long (how many ticks) the simulation took.

yK%"Simulation ended after %s yoctoseconds."cZT   
yK                                                Output final universe state
                                            cZT   Float divide ticks count by 10
  %"Simulation ended after %s yoctoseconds."      Format string, implicit print
\$\endgroup\$
23
\$\begingroup\$

C++ (2420,2243,2353,1860,1822*.9=1639.8)

Ok, so this is probably the worst ever code golf submission, but it's my first and I had fun. I think it even works. :)

#include <iostream>
#include <list>
#include <string>
#include <time.h>
#define D r=rand();d=((double)r/RAND_MAX)
using namespace std;class P{int n[25];public:int S;P(int N){for(S=0;S<24;S++)n[S]=0;n[24]=N;S=1;}void C(){string s[25]={"down quark","down antiquark","up quark","up antiquark","bottom quark","bottom antiquark","tau lepton","antitau lepton","charm quark","charm antiquark","strange quark","strange antiquark","neutrino","antineutrino","muon","antimuon","gluon","photon","electron","positron","top quark","top antiquark","Z boson","W boson","Higgs boson"};int r,i,j,w,f,F,x,y;double d;S=0;F=0;for(i=0;i<25;i++){w=0;for(j=0;j<n[i];j++){D;x=-1;y=-1;if(i==24){if(d<.000433){D;if(d<.648){x=4;y=5;}else if(d<.789){x=23;y=23;}else if(d<.8772){x=16;y=16;}else if(d<.9476){x=6;y=7;}else if(d<.9803){x=8;y=9;}else if(d<.9962){x=22;y=22;}else if(d<.99843){x=17;y=17;}else if(d<.99954){x=22;y=17;}else if(d<.999784){x=14;y=16;}else{x=21;y=20;}}}else if(i==23){if(d<.5){D;if(d<.33){x=19;y=12;}else if(d<.67){x=16;y=12;}else{x=17;y=12;}}}else if(i==22){if(d<.5){D;if(d<.206){x=12;y=13;}else if(d<.24){x=18;y=19;}else if(d<.274){x=14;y=16;}else if(d<.308){x=16;y=17;}else if(d<.46){x=0;y=1;}else if(d<.612){x=10;y=11;}else if(d<.764){x=4;y=5;}else if(d<.882){x=2;y=3;}else{x=8;y=9;}}}else if(i==21||i==20){if(d<.1295){D;x=23;if(d<.33){y=0;}else if(d<.67){y=10;}else{y=4;}if(i==21)y-=32;}}if(x>=0){++n[x];++n[y];w++;}if(x>19||y>19)S=1;}n[i]-=w;if(n[i]>0){F=i;if(i>19)S=1;}}cout<<"The universe contains";f=0;for(i=0;i<25;i++){if(n[i]>0){cout<<(f>0?(i<F?", ":" and "):" ")<<n[i]<<' '<<s[i]<<(n[i]>1?"s":"");f=1;}}cout<<'.'<<endl;}};int main(int c,char* v[]){int w=1,y=0;if(c>1){w=atoi(v[1]);}srand(time(0));rand();P p=P(w);int Time=time(0);while(p.S){p.C();y++;}cout<<"Simulation ended after "<<(double)y/10<<" yoctoseconds.";}

Fast Version

This one isn't as short (9 extra bytes), but it runs way faster for testing huge numbers. Since it's not short enough to compete, I also added a little code to clock real-world execution time and print it right after simulated time. My original version did n=100k in about 8 minutes. The version above does it in about 2 minutes. This fast version can do it in 9 seconds. n=1 million took 53 seconds.

#include <iostream>
#include <list>
#include <string>
#include <time.h>
#define D r=rand();d=((double)r/RAND_MAX)
using namespace std;class P{int n[25];public:int S;P(int N){for(S=0;S<24;S++)n[S]=0;n[24]=N;S=1;}void C(){string s[25]={"down quark","down antiquark","up quark","up antiquark","bottom quark","bottom antiquark","tau lepton","antitau lepton","charm quark","charm antiquark","strange quark","strange antiquark","neutrino","antineutrino","muon","antimuon","gluon","photon","electron","positron","top quark","top antiquark","Z boson","W boson","Higgs boson"};int r,i,j,w,f,F,x,y;double d;S=0;F=0;for(i=20;i<25;i++){w=0;for(j=0;j<n[i];j++){D;x=-1;y=-1;if(i==24){if(d<.000433){D;if(d<.648){x=4;y=5;}else if(d<.789){x=23;y=23;}else if(d<.8772){x=16;y=16;}else if(d<.9476){x=6;y=7;}else if(d<.9803){x=8;y=9;}else if(d<.9962){x=22;y=22;}else if(d<.99843){x=17;y=17;}else if(d<.99954){x=22;y=17;}else if(d<.999784){x=14;y=16;}else{x=21;y=20;}}}else if(i==23){if(d<.5){D;if(d<.33){x=19;y=12;}else if(d<.67){x=16;y=12;}else{x=17;y=12;}}}else if(i==22){if(d<.5){D;if(d<.206){x=12;y=13;}else if(d<.24){x=18;y=19;}else if(d<.274){x=14;y=16;}else if(d<.308){x=16;y=17;}else if(d<.46){x=0;y=1;}else if(d<.612){x=10;y=11;}else if(d<.764){x=4;y=5;}else if(d<.882){x=2;y=3;}else{x=8;y=9;}}}else if(i==21||i==20){if(d<.1295){D;x=23;if(d<.33){y=0;}else if(d<.67){y=10;}else{y=4;}if(i==21)y-=32;}}if(x>=0){++n[x];++n[y];w++;}if(x>19||y>19)S=1;}n[i]-=w;if(n[i]>0&&i>19)S=1;}for(i=0;i<25;i++){if(n[i]>0)F=i;}cout<<"The universe contains";f=0;for(i=0;i<25;i++){if(n[i]>0){cout<<(f>0?(i<F?", ":" and "):" ")<<n[i]<<' '<<s[i]<<(n[i]>1?"s":"");f=1;}}cout<<'.'<<endl;}};int main(int c,char* v[]){int w=1,y=0;if(c>1){w=atoi(v[1]);}srand(time(0));rand();P p=P(w);int Time=time(0);while(p.S){p.C();y++;}cout<<"Simulation ended after "<<(double)y/10<<" yoctoseconds.";cout<<endl<<"Time Taken: "<<(time(0)-Time)<<" seconds."<<endl;}

Sample output (no args)

The universe contains 1 Higgs boson.
... (many lines later)
The universe contains 1 Higgs boson.
The universe contains 1 bottom quark and 1 bottom antiquark.
Simulation ended after 339.4 yoctoseconds.

Sample output (universe.exe 10):

The universe contains 10 Higgs bosons.
The universe contains 1 bottom quark, 1 bottom antiquark and 9 Higgs bosons.
The universe contains 2 bottom quarks, 2 bottom antiquarks and 8 Higgs bosons.
The universe contains 3 bottom quarks, 3 bottom antiquarks and 7 Higgs bosons.
The universe contains 4 bottom quarks, 4 bottom antiquarks and 6 Higgs bosons.
The universe contains 4 bottom quarks, 4 bottom antiquarks, 1 charm quark, 1 charm antiquark and 5 Higgs bosons.
The universe contains 5 bottom quarks, 5 bottom antiquarks, 1 charm quark, 1 charm antiquark and 4 Higgs bosons.
The universe contains 5 bottom quarks, 5 bottom antiquarks, 1 charm quark, 1 charm antiquark, 2 Z bosons and 3 Higgs bosons.
The universe contains 5 bottom quarks, 5 bottom antiquarks, 1 charm quark, 1 charm antiquark, 1 neutrino, 1 antineutrino, 1 Z boson and 3 Higgs bosons.
The universe contains 5 bottom quarks, 5 bottom antiquarks, 1 charm quark, 1 charm antiquark, 2 neutrinos, 2 antineutrinos and 3 Higgs bosons.
The universe contains 6 bottom quarks, 6 bottom antiquarks, 1 charm quark, 1 charm antiquark, 2 neutrinos, 2 antineutrinos and 2 Higgs bosons.
The universe contains 7 bottom quarks, 7 bottom antiquarks, 1 charm quark, 1 charm antiquark, 2 neutrinos, 2 antineutrinos and 1 Higgs boson.
The universe contains 7 bottom quarks, 7 bottom antiquarks, 1 charm quark, 1 charm antiquark, 2 neutrinos, 2 antineutrinos and 2 W bosons.
The universe contains 7 bottom quarks, 7 bottom antiquarks, 1 charm quark, 1 charm antiquark, 2 neutrinos, 2 antineutrinos and 2 W bosons.
The universe contains 7 bottom quarks, 7 bottom antiquarks, 1 charm quark, 1 charm antiquark, 3 neutrinos, 2 antineutrinos, 1 photon and 1 W boson.
The universe contains 7 bottom quarks, 7 bottom antiquarks, 1 charm quark, 1 charm antiquark, 4 neutrinos, 2 antineutrinos, 1 gluon and 1 photon.
Simulation ended after 1160.5 yoctoseconds.

Sample Output (universe.exe 1000000)

(not quite 10^90, but we're getting there)

(about a minute, 14 MB and 33000 lines of output later)
The universe contains 5006 down quarks, 4945 down antiquarks, 3858 up quarks, 3858 up antiquarks, 653289 bottom quarks, 653190 bottom antiquarks, 70388 tau leptons, 70388 antitau leptons, 36449 charm quarks, 36449 charm antiquarks, 4956 strange quarks, 4873 strange antiquarks, 289364 neutrinos, 6764 antineutrinos, 1401 muons, 275514 gluons, 99433 photons, 1065 electrons and 94219 positrons.
Simulation ended after 3299.9 yoctoseconds.

Larger Outputs

If you're using console output from a command line, I would suggest something like universe.exe 100 > temp.txt so it will go much faster. With Notepad++, you can then open temp.txt, hit ctrl+H, enter ^(.*?)$\s+?^(?=.*^\1$) into the Find What field, enter nothing in the Replace With field, turn Search Mode to Regular Expression, turn In selection and . matches newline OFF, then hit Replace All. Now you just see where the changes occurred instead of 8000 lines of output (I do seem to get bugs doing more than 2000-3000 lines at a time though).

Fixes/Tweaks

v4 - complete overhaul, removed list, one character array, moved almost everything into the class functions. Fixed output error, was using "," instead of "and" for last item. Sped up execution a *lot* as an added bonus. :)
v3 - more fixes
v2 - more shorter
v1 - fixed numerous little issues, bug fixes
v0 - baseline
\$\endgroup\$
  • 1
    \$\begingroup\$ It seems in your first example you confused the tau lepton with the up quark. The tau lepton has a half-life on the order of 10^-13 seconds, so it is considered stable in this simulation, otherwise we would have many billions of lines until it decayed. The only things which decay in our simulation are the bosons, and the top quark/antiquark. \$\endgroup\$ – vsz Nov 5 '15 at 9:02
  • 2
    \$\begingroup\$ Can you shorten char t[N]={'d','D','u','U','b','B','l','L','c','C','s','S','n','N','m','M','g','G','p','e','E','T','t','Z','W','H' to char t[]="dDuUbBlLcCsSnNmMgGpeETtZWH"? Should work in c, not sure about c++ \$\endgroup\$ – Digital Trauma Nov 5 '15 at 18:11
12
\$\begingroup\$

Python 3, 1,247 * 0.9 = 1,122.3

Well, this is my longest entry by a long shot, but at least I'm shorter than C++.

Now with added bonus! It has to be called with a number as the first argument.

My universe didn't work with decaying particles other than Higgs Boson, but now it does. Also, I didn't have pluralization or punctuation correct, but I actually do now.

I'm getting so close to sub 1k!

import random,sys,numpy as h
H,M,G,N,P,K,L,n,s='photon,muon,gluon,neutrino,positron, quark,tau lepton, boson,The universe '.split(',')
c=random.choice
Z=' anti'+K[1:]
B='bottom'+K
A=B[:6]+Z
U='anti '+M
T=U[:4]+L
Q='charm'+K
C=Q[:5]+Z
S='strange'+K
R=S[:7]+Z
D='down'+K
O=D[:4]+Z
def w(c):v,t=zip(*c);t=h.array(t);return v[h.random.choice(len(v),p=t/t.sum())]
y=M,U
f=lambda p:{z:w([(c([('up'+K,'up'+Z),(Q,C)]),11.8),((N,U[:5]+N),20.6),(c([('electron',P),y,(L,T)]),3.4),(c([(S,R),(B,B),(D,O)]),15.2)]),E:(I,c([D,S,B])),F:(I,c([O,R,A])),I:c([(P,N),(U,N),(T,N)]),J:w([((B,A),64.8),((I,I),14.1),((G,G),8.82),((L,T),7.04),((Q,C),3.27),((z,z),1.59),((H,H),0.223),((z,H),0.111),(y,0.0244),((E,F),0.0246)])}[p]
z='Z'+n,50
E='top'+K,12.95
F='top'+Z,E[1]
I='W'+n,50
J='Higgs'+n,.0433
u=[J]*int(sys.argv[1])
b={z,E,F,I,J}
k=isinstance
d=lambda p:p if k(p,str)else w([(p,100-p[1]),(f(p),p[1])])
a=0
g=lambda x:[x[0],x][k(x,str)]
while b&set(u):
 n=[]
 for p in u:q=d(p);n+=([q],(q,[q])[q in b])[p in b]
 e=list(map(g,n));e=[(x,x+'s')[e.count(x)>1]for x in e];print(s+'contains %s'%', '.join(('%s %s'%(e.count(x),g(x))for x in set(e[:-1])))+('.',' and %s %s.'%(e.count(e[-1]),e[-1]))[len(set(e))>1]);a+=.1;u=n
print(s+'ended after %s yoctoseconds.'%round(a,1))
\$\endgroup\$
  • 11
    \$\begingroup\$ I think it's funny that a program that simulates the universe starts with import random. So much for determinism. \$\endgroup\$ – agtoever Nov 14 '15 at 21:01
  • \$\begingroup\$ This is python3 right? I guess you can use F-strings in the final print, that might save you 1 or 2 bytes :-). \$\endgroup\$ – Chromium Jun 21 '18 at 9:03
  • 1
    \$\begingroup\$ @Chromium Yeah, I probably could. They didn't exist when I wrote this answer, but I could definitely go back and add them. \$\endgroup\$ – Morgan Thrapp Jun 21 '18 at 17:05
11
\$\begingroup\$

Perl 6, (707 bytes -10%) Score 636.3

With some unneeded line breaks for a bit more readability:

{
 my%p;
 %p=<H H2309.469bB64.8WW14.1gg8.82lL7.04cC3.27ZZ1.59pp0.223Zp0.111mM0.0244tT0.0216 W W3pn1Mn1Ln1 Z Z100nN20.6ep3.4mM3.4lL3.4dD15.2sS15.2bB15.2uU11.8cC11.8 t t7.722Wd1Ws1Wb1 T T7.722WD1WS1WB1>;
 my&f=*.comb[0];

 my%h;
 %h{.&f}="$_ boson" for <Higgs W Z>;
 {
  %h{.&f}="$_ quark";
  %h{.&f.uc}="$_ antiquark"
 } for <bottom top charm up down strange>;
 %h{.&f}=$_~"on" for <glu phot electr positr>;
 %h{.&f.uc}="anti"~(%h{.&f}=$_) for <muon neutrino>;
 %h<L>="anti"~(%h<l>="tau lepton");

 my$t;
 ("H"x$^a),{
   $t+=.1;
   S:g/./{%((%p{$/}||$/~1).comb(/(\D+|<:!L>+)/)).Mix.roll}/
 }...{
   say "The universe contains {
      .comb.Bag.map({
         "{.value,%h{.key}~'s'x(.value>1)}"
      }).join(', ')
   }.";
   !/<[HWZtT]>/
 };
 say "Simulation ended after $t yoctoseconds."
}

Try it online!

The universe contains 4 Higgs bosons.
The universe contains 4 Higgs bosons.
The universe contains 4 Higgs bosons.
The universe contains 4 Higgs bosons.
The universe contains 3 Higgs bosons, 2 gluons.
The universe contains 3 Higgs bosons, 2 gluons.
The universe contains 3 Higgs bosons, 2 gluons.
The universe contains 3 Higgs bosons, 2 gluons.
The universe contains 3 Higgs bosons, 2 gluons.
The universe contains 3 Higgs bosons, 2 gluons.
The universe contains 3 Higgs bosons, 2 gluons.
The universe contains 3 Higgs bosons, 2 gluons.
The universe contains 1 tau lepton, 2 Higgs bosons, 2 gluons, 1 antitau lepton.
The universe contains 1 tau lepton, 2 Higgs bosons, 2 gluons, 1 antitau lepton.
The universe contains 1 tau lepton, 2 Higgs bosons, 2 gluons, 1 antitau lepton.
The universe contains 1 tau lepton, 2 Higgs bosons, 2 gluons, 1 antitau lepton.
The universe contains 1 tau lepton, 1 Higgs boson, 4 gluons, 1 antitau lepton.
The universe contains 1 tau lepton, 6 gluons, 1 antitau lepton.
Simulation ended after 1.7 yoctoseconds.

Some explanation: God and Man

There are 2 data structures holding the physics %p and the naming %h; god and man as it were. The physics hash gives a set of strings indexed by original unstable particle letter, which can be split, hashed and converted to a Mix:

say %((%p<H>).comb(/(\D+|<:!L>+)/)).Mix;
> Mix(H(2309.469), WW(14.1), ZZ(1.59), Zp(0.111), bB(64.8), cC(3.27), gg(8.82), lL(7.04), mM(0.0244), pp(0.223), tT(0.0216))

Each particle gets a letter, and thus each of these Mixes specifies a collection of particle decays. H decays to WW, with probability weighting 14.1. Particle-antiparticle pairs are coded with lower and uppercase letters, like c and C for charm quark and charm antiquark.

And man thought for a bit, and named it antitau lepton

The naming is all set up in %h, which just maps each letter to a particle name. It's golfed to a degree, but I suspect there's room for improvement given the amount of repetition there.

p => positron
g => gluon
Z => Z boson
B => bottom antiquark
e => electron
s => strange quark
d => down quark
W => W boson
m => muon
U => up antiquark
c => charm quark
H => Higgs boson
L => antitau lepton
N => antineutrino
n => neutrino
S => strange antiquark
D => down antiquark
T => top antiquark
u => up quark
t => top quark
b => bottom quark
M => antimuon
C => charm antiquark
l => tau lepton

Original string

With those two structures in place, the universe is simulated, of course, by string manipulation. So "H" is a universe with a single Higgs boson in it. The generator structure _,_..._ is used to create a loop, and separates evolving the state of the universe string (held in $_) from printing it out. The printing is done by Bagging the letters in the universe and mapping the resulting counts (with plurals!).

Sneezing particles into being

Evolving particles involves mapping them to a value picked from the Mix for that particle; so t, the top quark, evolves as

t=>7.722
Wd=>1
Ws=>1
Wb=>1

Perl6 permits us to randomly choose one of those keys with those given weightings via the flooringly simple .roll. So we roll for t and get, say Wb and substitute it into our universe "HtT"->"HWbT". Each unstable particle has itself as a possible roll, which permits us to simplify the structure vs having to check whether it decayed or not; most of the time you roll for "H", you just get "H" again.

Experimental string theory

You can watch the universe string evolve via this modified version.

 HHH
 HHH
 HHbB
 HHbB
 HHbB
 HHbB
 HHbB
 HHbB
 lLHbB
 lLHbB
 lLHbB
 lLHbB
 lLHbB
 lLbBbB

Performance

I've taken it as far as 100 H on TIO, inevitably if you wanted to go much further it would be better to make some changes, this is Grand Unified String Theory after all.

\$\endgroup\$
  • \$\begingroup\$ What made the man give that name, Phil? \$\endgroup\$ – Manoj Kumar Jul 6 '18 at 5:04
  • 1
    \$\begingroup\$ @ManojKumar: According to wikipedia: "The symbol τ was derived from the Greek τρίτον (triton, meaning "third" in English), since it was the third charged lepton discovered." ( en.wikipedia.org/wiki/Tau_(particle) ) \$\endgroup\$ – Phil H Jul 6 '18 at 15:24
7
\$\begingroup\$

Groovy, 1506 1454 - 10% = 1309 bytes

Assumes the number of starting Higgs boson particles is given as the first argument on the command line:

A='anti'
B='bottom '
C='charmed '
D='downward'
E='tau '
F='top '
L='lepton'
M='muon'
N='nutrino'
O=' boson'
P='upward '
Q='quark'
T='strange '
a=[n:'gluon']
b=[n:B+Q]
c=[n:B+A+Q]
d=[n:D+Q]
e=[n:D+A+Q]
f=[n:P+Q]
g=[n:P+A+Q]
h=[n:T+Q]
i=[n:T+A+Q]
j=[n:C+Q]
k=[n:C+A+Q]
l=[n:'positron']
m=[n:'electron']
n=[n:N]
o=[n:A+N]
p=[n:'photon']
q=[n:M]
r=[n:A+M]
s=[n:E+L]
t=[n:A+E+L]
u=[n:'W'+O,c:50,s:[[c:33,p:[l,n]],[c:33,p:[l,n]],[c:33,p:[l,n]]]]
v=[n:F+Q,c:12.95,s:[[c:33,p:[u,d]],[c:33,p:[u,h]],[c:33,p:[u,b]]]]
w=[n:F+A+Q]
x=[n:'Z'+O,c:50,s:[[c:20.6,p:[n,o]],[c:3.4,p:[m,l]],[c:3.4,p:[q,r]],[c:3.4,p:[s,t]],[c:15.2,p:[d,e]],[c:15.2,p:[h,i]],[c:15.2,p:[b,c]],[c:11.8,p:[f,g]],[c:11.8,p:[j,k]]]]
y=[n:'Higgs'+O,c:0.0433,s:[[c:64.8,p:[b,c]],[c:14.1,p:[u,u]],[c:8.82,p:[a,a]],[c:7.04,p:[s,t]],[c:3.27,p:[j,k]],[c:1.59,p:[x,x]],[c:0.223,p:[p,p]],[c:0.111,p:[x,l]],[c:0.0244,p:[q,r]],[c:0.0216,p:[v,w]]]]
O={new Random().nextInt(1000001)/10000}
S={s,c->for(Map p:s){c-=p.c;if(c<=0){return p.p}};S(s,O())}
P={r=[];it.collect{it.n}.groupBy{it}.each{k,v->c=v.count{it};r<<"${c} ${c>1?k+'s':k}"};r.join(', ').reverse().replaceFirst(',', 'dna ').reverse()}
U=[]
args[0].times{U<=O()){I.remove();S(J.s,O()).each{I.add(it)}}}
if(!Z){println "Simulation ended after $Y yoctoseconds.";break}}

\$\endgroup\$
  • \$\begingroup\$ 10% of 1454 is 145.4 \$\endgroup\$ – geokavel Nov 23 '15 at 16:19
  • \$\begingroup\$ With math like that its a wonder the simulation works at all :-) Thanks for pointing that out! \$\endgroup\$ – K. Klassen Nov 23 '15 at 23:10
7
\$\begingroup\$

PHP, 989 - 10% = 890.1 bytes

Sub 1K baby! Thanks vsz, this was a really fun challenge. So many ways to go about it and very hard to verify your output is correct.

The program can take a command line argument to specify the starting number of Higgs bosons, e.g. php universe_simulator.php 5

<?eval(gzinflate(base64_decode('bVNdb9Q6EH3nV4TVSEm0ozRpt/uBcRGlQLlw4QIFWqxQuYm7mza1s4mzdEH73+84WUqFyINzjn1mfMaaAcmltgWDC35hrDU3DDKeLWRN4JC2GqMZLPmylfU1g4Y3tpZ6rhhY7lvZeqWqrNE+A821am1daMMuTa1ktgjUbVWaXAU++jiAn3Jz0xqNIKFbLMKFR/9l96c127LMsdx81z3v0RJVqTJbU4J56dIcF/N548Eh9kk1VgtDTrAyTdHJoNnma7rsFq2p+p0OLLHd0rZjX1yur7QMQtnAKoRKZIs6GA6hGI5HYcphxSDn4g0/EFEcx6O9PRQiGo+mKI7weZqiiCbTGYpTPO3IdDLZRfEaX3dsNpqMUTzDjz2bxhT9Al/2bDYm5Rmebdl0RIfv8N2WzvZHjv46nU2mxJ/iv44nKE7wU0ofnjpj++Qp2aHwt/ifO991+Cm+3WqfOUT47Jc22o3J1mEviPb2qZhjfNWRfdK/xw8dHjuDv6tE8Rm/9EXOpvfq2CPVP/3F0Ww8vu+yq5zwJ3dzsju7M/qqf67O6Icek/y5Q4RP/pQf35O/v5Mf9fKUQctlXcv1+WVRlkFMfVbPVyJJnzxK8E3IYM1j9n1RlCp4CLfhT7jlCYMrLtK7pu3DM9Nqe76SZauaAFrXEtf8wLXFlUj5AFYe9Qdcp4MogNVB8sRv/Ee+HzKVLYxX1Wp+XquqlBk1/w4G4humwxB2aBA8qXNIaB5OFsprdbFSdaO8zGgrC914g+jKFJomxvMRrsJoED0YhHfeoPXISEFGbFhcBpALsGlXRcyI02TmQbgzV25G8xt5G4SPeS8SsdP94H+R/M7eK5OU7si6/D8oPOtC+1ep2saZwCiKaD9JQ3ZBodds0+pGWToRUNDmZgPrIY8StnHPMfhY3LSltIXRntK5yj15aVXtwdpbm8yaRlH1eUOFsv8B')));

Here's the same thing with line breaks for, uh... "readability"...

<?eval(gzinflate(base64_decode('bVNdb9Q6EH3nV4TVSEm0ozRpt/uBcRGlQLlw4QIFWqxQuYm7
mza1s4mzdEH73+84WUqFyINzjn1mfMaaAcmltgWDC35hrDU3DDKeLWRN4JC2GqMZLPmylfU1g4Y3tpZ6
rhhY7lvZeqWqrNE+A821am1daMMuTa1ktgjUbVWaXAU++jiAn3Jz0xqNIKFbLMKFR/9l96c127LMsdx8
1z3v0RJVqTJbU4J56dIcF/N548Eh9kk1VgtDTrAyTdHJoNnma7rsFq2p+p0OLLHd0rZjX1yur7QMQtnA
KoRKZIs6GA6hGI5HYcphxSDn4g0/EFEcx6O9PRQiGo+mKI7weZqiiCbTGYpTPO3IdDLZRfEaX3dsNpqM
UTzDjz2bxhT9Al/2bDYm5Rmebdl0RIfv8N2WzvZHjv46nU2mxJ/iv44nKE7wU0ofnjpj++Qp2aHwt/if
O991+Cm+3WqfOUT47Jc22o3J1mEviPb2qZhjfNWRfdK/xw8dHjuDv6tE8Rm/9EXOpvfq2CPVP/3F0Ww8
vu+yq5zwJ3dzsju7M/qqf67O6Icek/y5Q4RP/pQf35O/v5Mf9fKUQctlXcv1+WVRlkFMfVbPVyJJnzxK
8E3IYM1j9n1RlCp4CLfhT7jlCYMrLtK7pu3DM9Nqe76SZauaAFrXEtf8wLXFlUj5AFYe9Qdcp4MogNVB
8sRv/Ee+HzKVLYxX1Wp+XquqlBk1/w4G4humwxB2aBA8qXNIaB5OFsprdbFSdaO8zGgrC914g+jKFJom
xvMRrsJoED0YhHfeoPXISEFGbFhcBpALsGlXRcyI02TmQbgzV25G8xt5G4SPeS8SsdP94H+R/M7eK5OU
7si6/D8oPOtC+1ep2saZwCiKaD9JQ3ZBodds0+pGWToRUNDmZgPrIY8StnHPMfhY3LSltIXRntK5yj15
aVXtwdpbm8yaRlH1eUOFsv8B')));

Some output:

The universe contains 2 Higgs bosons.
[...]
The universe contains 1 Higgs boson, 2 neutrinos, 1 positron and 1 antimuon.
The universe contains 1 Higgs boson, 2 neutrinos, 1 positron and 1 antimuon.
The universe contains 1 Higgs boson, 2 neutrinos, 1 positron and 1 antimuon.
The universe contains 1 Higgs boson, 2 neutrinos, 1 positron and 1 antimuon.
The universe contains 1 Higgs boson, 2 neutrinos, 1 positron and 1 antimuon.
The universe contains 2 neutrinos, 1 positron, 1 antimuon, 1 bottom antiquark and 1 bottom quark.
Simulation ended after 153.2 yoctoseconds.
\$\endgroup\$
  • 5
    \$\begingroup\$ Could you also add the uncompressed version to the answer? \$\endgroup\$ – Ray Nov 16 '16 at 23:16
  • \$\begingroup\$ Is the "Readability!" the unzipped version? \$\endgroup\$ – Manoj Kumar Jul 6 '18 at 5:10
7
\$\begingroup\$

QBasic 2161 * .9 = 1945 2028 * .9 = 1825 1854 * .9 = 1669 bytes

Now that QBasic is the LOTM I thought I'd revise my very first answer on PPCG ever. Managed to knock off 140 bytes, not bad!

Based on feedback by @TaylorScott and @DLosc I've done a complete redesign:

  • Time keeping altered
  • Formatting now conforms to spec
  • Saved a ton of bytes by making an array into an indexed string

The code

SUB f(p$,c)
DIM e$(25)
q$=" quark
a$=" antiquark
e$(1)="HHiggs boson
e$(2)="bbottom"+q$
e$(3)="1bottom"+a$
e$(4)="WW boson
e$(5)="gGluon
e$(6)="TTau lepton
e$(7)="2Tau antilepton
e$(8)="ccharm"+q$
e$(9)="3charm"+a$
e$(10)="ZZ boson
e$(11)="pphoton
e$(12)="mmuon
e$(13)="4antimuon
e$(14)="0top"+q$
e$(15)="5top"+a$
e$(16)="+positron
e$(17)="nneutrino
e$(18)="6antineutrino
e$(19)="-electron
e$(20)="ddown"+q$
e$(21)="7down"+a$
e$(22)="sstrange"+q$
e$(23)="8strange"+a$
e$(24)="uup"+q$
e$(25)="9up"+a$
FOR i=1TO 25
IF LEFT$(e$(i),1)=p$THEN ?str$(c)" "MID$(e$(i),2);
NEXT
IF c>1THEN?"s";
END SUB
RANDOMIZE TIMER
z=100
INPUT x
p$=string$(x,"H")
1:b=0
REDIM m$(LEN(p$))
FOR i=1TO LEN(p$)
m$(i)=MID$(p$,i,1)
NEXT
p$=s$(m$())
t=t+1
?"The universe contains";
FOR i=1TO LEN(p$)
y$=MID$(p$,i,1)
z$=MID$(p$,i+1,1)
c=c+1
IF(y$=z$ AND i<LEN(p$))=0THEN f y$,c:c=0
NEXT
?
r$="
FOR i=1TO LEN(p$)
d&=(RND*z)*z
e&=(RND*z)*(z^2)
q$=MID$(p$,i,1)
IF INSTR("HWZ02",q$) THEN b=1
r$=r$+g$(d&,e&,q$)
NEXT
p$=r$
IF b GOTO 1
?"Simulation ended after"t/10"yoctoseconds.
FUNCTION g$(d&,p&,q$)
DIM e$(28)
FOR i=1TO 28
x$=Mid$("H00433099979405H004330999550m4H004330998440ZpH004330996210ppH004330980310ZZH004330947610c3H004330877210T2H004330789010ggH004330648010WWH004330000000b12012950666670W12012950333340W82012950000000W70012950666670Wb0012950333340Ws0012950000000WdW0500006666702nW0500003333404nW050000000000+nZ050000882010c3Z050000764010u9Z050000612010b1Z050000460010s8Z050000308010d7Z050000274010T2Z050000240010m4Z050000206010-+Z050000000000n6",15*i+1,15)
a&=VAL(MID$(x$,8,7))
g$=q$
IF LEFT$(x$,1)=q$ THEN
IF d&<VAL(MID$(x$,2,5)) THEN
IF(p&>a& OR a&=0) THEN
g$=RIGHT$(x$,2)
EXIT FUNCTION
ENDIF
ENDIF
ENDIF
NEXT
END FUNCTION
FUNCTION s$(n$())
x=UBOUND(n$)
FOR i=1TO x:FOR J=1TO x
IF n$(i)<n$(J)THEN SWAP n$(i),n$(J)
NEXT j,i
FOR i=1TO UBOUND(n$)
a$=a$+n$(i)
NEXT
s$=a$
END FUNCTION

Sample output

? 3
The universe contains 3 Higgs bosons
The universe contains 3 Higgs bosons
The universe contains 3 Higgs bosons
The universe contains 3 Higgs bosons
The universe contains 1 bottom antiquark 2 Higgs bosons 1 bottom quark
The universe contains 1 bottom antiquark 2 Higgs bosons 1 bottom quark
The universe contains 2 bottom antiquarks 1 Higgs boson 2 bottom quarks
The universe contains 2 bottom antiquarks 1 Higgs boson 2 bottom quarks
The universe contains 2 bottom antiquarks 1 Higgs boson 2 bottom quarks
The universe contains 2 bottom antiquarks 1 Higgs boson 2 bottom quarks
The universe contains 2 bottom antiquarks 1 Higgs boson 2 bottom quarks
The universe contains 2 bottom antiquarks 1 Higgs boson 2 bottom quarks
The universe contains 2 bottom antiquarks 1 Higgs boson 2 bottom quarks
The universe contains 2 bottom antiquarks 1 Higgs boson 2 bottom quarks
The universe contains 2 bottom antiquarks 1 Higgs boson 2 bottom quarks
The universe contains 2 bottom antiquarks 1 Higgs boson 2 bottom quarks
The universe contains 2 bottom antiquarks 1 Higgs boson 2 bottom quarks
The universe contains 2 bottom antiquarks 1 Higgs boson 2 bottom quarks
The universe contains 2 bottom antiquarks 1 Higgs boson 2 bottom quarks
The universe contains 2 bottom antiquarks 1 Higgs boson 2 bottom quarks
The universe contains 2 bottom antiquarks 1 Higgs boson 2 bottom quarks
The universe contains 2 bottom antiquarks 1 Higgs boson 2 bottom quarks
The universe contains 3 bottom antiquarks 3 bottom quarks
Simulation ended after 2.3 yoctoseconds.
\$\endgroup\$
  • \$\begingroup\$ Yay for years-later golfing... but the output formatting doesn't match the strict requirements in the question. ?? \$\endgroup\$ – DLosc Jul 2 '18 at 17:43
  • 1
    \$\begingroup\$ For -~200 bytes, use For i=0To 28 x$=Mid$("H00433099979405H004330999550m4H004330998440ZpH004330996210ppH004330980310ZZH004330947610c3H004330877210T2H004330789010ggH004330648010WWH004330000000b12012950666670W12012950333340W82012950000000W70012950666670Wb0012950333340Ws0012950000000WdW0500006666702nW0500003333404nW050000000000+nZ050000882010c3Z050000764010u9Z050000612010b1Z050000460010s8Z050000308010d7Z050000274010T2Z050000240010m4Z050000206010-+Z050000000000n6",15*i+1,15) ... Next in function f$() over array e$() \$\endgroup\$ – Taylor Scott Jul 5 '18 at 11:02
  • \$\begingroup\$ In function s$(), Next:Next can be Next j,i, and you should check to see if the ? statements need all of those ;s. But it also appears that your output does not meet the spec at present \$\endgroup\$ – Taylor Scott Jul 5 '18 at 11:04
  • \$\begingroup\$ @DLosc and Taylor I'll look at both of your suggestions in the coming weekend; I'm a bit busy before then... Thanks. \$\endgroup\$ – steenbergh Jul 5 '18 at 11:21
6
\$\begingroup\$

C#6, 3619 3617 3611 3586 - 10% = 3227.4 bytes

Program takes two optional arguments for the number of starting Higgs Bosons and the seed to use for the Random class.

using System;using System.Collections.Generic;class a{List<P>L;List<Q>S;double Y;static void Main(string[]a){a b;b=a.Length<1?new a():a.Length<2?new a(int.Parse(a[0])):new a(int.Parse(a[0]),int.Parse(a[1]));}a(int j=1,int e=1){Random r=new Random(e);L=new List<P>();S=new List<Q>();for(int i=0;i<j;i++)L.Add(new H());while(L.Count>0){List<P>l=new List<P>();foreach(P p in L){List<P>d=p.C(r);if(d!=null)foreach(P y in d){if(y.GetType()==typeof(Q))S.Add((Q)y);else l.Add((P)y);}else l.Add(p);}L=l;Y+=.1;W();}var s=$"Simulation ended after {Y} yoctosecond";if(Y!=1d)s+="s";Console.WriteLine(s+".");}void W(){var t="";Dictionary<string,int>N=new Dictionary<string,int>();int M=0;foreach(P x in L){t=x+"";if(N.ContainsKey(t))N[t]++;else{N.Add(t,1);M++;}}foreach(Q x in S){t=x+"";if(N.ContainsKey(t))N[t]++;else{N.Add(t,1);M++;}}var o="The universe contains ";int i=N.Keys.Count;foreach(var x in N.Keys){i--;if(M==1){o+=$"{N[x]} {x}";if(N[x]!=1)o+="s";}else if(M==2){o+=$"{N[x]} {x}";if(N[x]!=1)o+="s";if(i!=0)o+=" and ";}else{if(i<1){o+=$"and {N[x]} {x}";if(N[x]!=1)o+="s";}else{o+=$"{N[x]} {x}";if(N[x]!=1)o+="s";o+=", ";}}}Console.WriteLine(o+".");}}abstract class P{public static string[]Z=new string[]{"photon","gluon","positron","electron","quark","lepton","muon","neutrino"};public double l;public abstract List<P>D(Random r);public List<P>C(Random r){List<P>d=null;if(r.NextDouble()<l)d=D(r);return d;}}class H:P{public H(){l=.000433;}public override List<P>D(Random r){var d=new List<P>();Action<P>U=d.Add;var n=r.NextDouble();if(n<.648){U(new Q("bottom "+Z[4]));U(new Q("bottom anti"+Z[4]));}else if(n<.789){U(new W());U(new W());}else if(n<.8772){U(new Q(Z[1]));U(new Q(Z[1]));}else if(n<.9476){U(new Q("tau "+Z[5]));U(new Q("antitau "+Z[5]));}else if(n<.9803){U(new Q("charm "+Z[4]));U(new Q("charm anti"+Z[4]));}else if(n<.9962){U(new Z());U(new Z());}else if(n<.99843){U(new Q(Z[0]));U(new Q(Z[0]));}else if(n<.99954){U(new Z());U(new Q(Z[0]));}else if(n<.999784){U(new Q(Z[6]));U(new Q("anti"+Z[6]));}else{U(new T(0>1));U(new T(1>0));}return d;}public override string ToString(){return"Higgs Boson";}}class W:P{public W(){l=.5;}public override List<P> D(Random r){var d=new List<P>();var n=r.NextDouble();d.Add(new Q(Z[7]));if(n<1/3d)d.Add(new Q(Z[2]));else if(n<2/3d)d.Add(new Q("anti"+Z[6]));else d.Add(new Q("antitau "+Z[5]));return d;}public override string ToString(){return"W Boson";}}class Z:P{public Z(){l=.5;}public override List<P>D(Random r){var d=new List<P>();var n=r.NextDouble();Action<P>U=d.Add;var t=Z[4];if(n<.206){U(new Q(Z[7]));U(new Q("anti"+Z[7]));}else if(n<.24){U(new Q(Z[3]));U(new Q(Z[2]));}else if(n<.274){U(new Q(Z[6]));U(new Q("anti"+Z[6]));}else if(n<.308){U(new Q("tau "+Z[5]));U(new Q("antitau "+Z[5]));}else if(n<.46){U(new Q("down "+t));U(new Q("down anti"+t));}else if(n<.612){U(new Q("strange "+t));U(new Q("strange anti"+t));}else if(n<.764){U(new Q("bottom "+t));U(new Q("bottom anti"+t));}else if(n<.882){U(new Q("up "+t));U(new Q("up anti"+t));}else{U(new Q("charm "+t));U(new Q("charm anti"+t));}return d;}public override string ToString(){return"Z Boson";}}class T:P{bool A;public T(bool a){A=a;l=.1295;}public override List<P>D(Random r){var d=new List<P>();var n=r.NextDouble();d.Add(new W());if(n<1/3d)d.Add(new Q("down "+Z[4]));else if(n <2/3.0)d.Add(new Q("strange "+Z[4]));else d.Add(new Q("bottom "+Z[4]));return d;}public override string ToString(){var r=A?"top anti":"top ";return r+Z[4];}}class Q:P{string N;public Q(string n){N=n;}public override List<P>D(Random r){return null;}public override string ToString(){return N;}}

I should not have used objects for this, I'll probably try to do a second solution using arrays instead, but it'd probably be similar to the C++ solution posted already. The number of Higgs Bosons I can handle is severely limited as well, I think at least an hour for H=1,000,000. Smaller numbers run reasonably well though.

Sample output:

$ b
// Default h=1,seed=1
The universe contains 1 Higgs Boson.
...
The universe contains 1 bottom quark and 1 bottom antiquark.
Simulation ended after 65.5000000000006 yoctosecond.

$ b 10 12345
The universe contains 10 Higgs Bosons.
The universe contains 9 Higgs Bosons, 1 bottom quark, and 1 bottom antiquark.
The universe contains 8 Higgs Bosons, 2 W Bosons, 1 bottom quark, and 1 bottom antiquark.
The universe contains 8 Higgs Bosons, 1 bottom quark, 1 bottom antiquark, 2 neutrinos, and 2 antitau leptons.
The universe contains 7 Higgs Bosons, 2 bottom quarks, 2 bottom antiquarks, 2 neutrinos, and 2 antitau leptons.
The universe contains 6 Higgs Bosons, 3 bottom quarks, 3 bottom antiquarks, 2 neutrinos, and 2 antitau leptons.
The universe contains 5 Higgs Bosons, 4 bottom quarks, 4 bottom antiquarks, 2 neutrinos, and 2 antitau leptons.
The universe contains 2 W Bosons, 4 Higgs Bosons, 4 bottom quarks, 4 bottom antiquarks, 2 neutrinos, and 2 antitau leptons.
The universe contains 1 W Boson, 4 Higgs Bosons, 4 bottom quarks, 4 bottom antiquarks, 3 neutrinos, 2 antitau leptons, and 1 antimuon.
The universe contains 4 Higgs Bosons, 4 bottom quarks, 4 bottom antiquarks, 4 neutrinos, 2 antitau leptons, and 2 antimuons.
The universe contains 3 Higgs Bosons, 5 bottom quarks, 5 bottom antiquarks, 4 neutrinos, 2 antitau leptons, and 2 antimuons.
The universe contains 2 Higgs Bosons, 6 bottom quarks, 6 bottom antiquarks, 4 neutrinos, 2 antitau leptons, and 2 antimuons.
The universe contains 1 Higgs Boson, 2 W Bosons, 6 bottom quarks, 6 bottom antiquarks, 4 neutrinos, 2 antitau leptons, and 2 antimuons.
The universe contains 1 Higgs Boson, 1 W Boson, 6 bottom quarks, 6 bottom antiquarks, 5 neutrinos, 2 antitau leptons, and 3 antimuons.
The universe contains 1 Higgs Boson, 6 bottom quarks, 6 bottom antiquarks, 6 neutrinos, 2 antitau leptons, 3 antimuons, and 1 positron.
The universe contains 7 bottom quarks, 7 bottom antiquarks, 6 neutrinos, 2 antitau leptons, 3 antimuons, and 1 positron.
Simulation ended after 540.500000000054 yoctoseconds.

I'll post the last two lines for the h=1000000 run when it finishes, probably later today. As promised:

$ b 1000000
(a few hours, 35K lines, and 15MB later)
The universe contains 653391 bottom quarks, 653271 bottom antiquarks, 36336 charm quarks, 36336 charm antiquarks, 176724 gluons, 71397 tau leptons, 165604 antitau leptons, 5626 photons, 288869 neutrinos, 95047 positrons, 95556 antimuons, 5254 strange quarks, 5130 strange antiquarks, 1389 muons, 1081 electrons, 5240 down quarks, 5104 down antiquarks, 6529 antineutrinos, 3862 up quarks, and 3862 up antiquarks.
Simulation ended after 3599.29999999782 yoctoseconds.
\$\endgroup\$
  • \$\begingroup\$ From a quick look, there's an useless whitespace at else {U(new T(0>1)) and multiple at n < 2 / 3.0, and one at n <2/3.0. \$\endgroup\$ – Yytsi Sep 24 '16 at 14:50
  • \$\begingroup\$ @TuukkaX Thanks, missed those. Got to save another byte by replacing the 3.0 with 3d, must've added that line after changing the first one. \$\endgroup\$ – Yodle Sep 26 '16 at 15:05
  • \$\begingroup\$ One at if (a.Length, and another at if (N[x]!=1, third one at o+= $. Also, you're parsing a[0] to an integer twice, when the result could be saved to an integer. I think that Y==1.0 can be Y==1., but I'm not certain about that. i!=0 could be i. I don't know whether your variables can actually negate, but if not, you can replace ==0s with <1. The title should say C# 6, since you're using string interpolation. \$\endgroup\$ – Yytsi Sep 26 '16 at 15:15
  • \$\begingroup\$ @TuukkaX Unfortunately, C# doesn't allow if (integer), unless I'm doing something wrong. And I shortened my Main method a different way, but I don't think it's possible to assign a[0] to an integer beforehand anyway if there aren't any arguments (default is to run with h=1 and seed=1). Thanks for everything else though! \$\endgroup\$ – Yodle Sep 26 '16 at 15:50
5
\$\begingroup\$

Mathematica, 950bytes-10% = 855 bytes

Using expression compressing:

ToExpression[Uncompress["1:eJxdVG1v2jAQ7of9kMyVpna9pkkKLV0aROlW2AQVb1MqPGsKYCBaYtPEjFLgf+zn7vKGaD/kse/J+fz4zuePI9nr//twdOQ5ZTt0DHvkDLxRwGkTPGZHTs8TExnez6U/5nYvN3vcC+zAaXExU3P7l2Faz7T7m31xiEZuqwPZV5EvZrRLqcUYu62mdH/lq/E8IU3GoAmk6c9msVaXsRQEXoHUpVIy1LpLL/pDYLgn7oTynzPSBeIWKxpAGsEymQ1aQAbeUmvxhUrs3EzWBTk1BXI/96J99IfCPgiOOw6L4AsgnbnEpTGBNpB2us8aSOIepsYLbiIXRbynzDqI1sEIMvZVlDgLII98mWRFEhhnYcSe4EC+BXycua6AYPo8MePvDl6w+Y6o6qtciUMnmVO5xx2Qn28k1VMi+8uSqrlzTBBt83DEoy4dQXPrbofbl+0Tg/DsDK/CQ+ApxQU9yYt3jHX7PqU9ym4N3YSIbvSrUgV0s2SCXqlYoBvXRgnx0rpGNMs3iIZlXSaDaZrJYFilUjaaV7vz6mbzCsMdbFxwERvQQMSCtnCYwgPiMP29gEU67yC2YY34Ak+7HV4khsnZayonmjYdEOiwTrGFiG4uw/q+dTN0y7gCA8WW3qFZtt6jWckwVSxgjJH5gZhcsYQ24gpWiNmx6nCXnwRFDBmcYHZPD3Jo3WSSXZBpElYpvqI3g99wnJbp9NNFbcTs2Hm+qJ08yij0gtq9XAoV0xG70HvLgJ9XW36sTu0O3ihFyWDOtaXw//Io5tpYCuX5eJOxB9PG/CF9QYvSDvBWxQsZc7rJGh+1BbXYcXwoZiYQAkTD1icsIf2CAoIqNz6YgH54PvzSdtcJs1PluZw+9gxu50uhcTHhE82bKh69eSswFZ/D9KlYy7FCOah6EmOg/5kZdRM="]]

Uncompressed Code (1168 bytes-10% = 1051.2bytes):

a=5;m=0;b=Table[H,a];r=RandomChoice;R=RandomReal;l=Length;
q[Q_]:=" "<>ToString[Q[[2]]]<>" "<>Switch[Q[[1]],H,"Higgs Boson",z,"Bottom Quark",Z,"Bottom Antiquark",W,"W Boson",G,"Gluon",TL,"Tau Lepton",L,"Tau Antilepton",f,"Charm Quark",F,"Charm Antiquark",Z,"Z Boson",p,"Photons",M,"Muon",y,"Antimuon",x,"Top Quark",X,"Top Antiquark",P,"Positron",n,"Neutrino",c,"Antineutrino",e,"Electron",w,"Strange Antiquark",W,"Strange Quark",M,"Down Antiquark",o,"Down Quark",A,"Up Antiquark",B,"Up Quark"]
While[MemberQ[b,H|W|Z|x|X],m++;b=Flatten[(Switch[#,H,If[R[]<0.1,r[{.648,.141,.882,.0704,.0327,.0159,.00223,.00111,.000244,.000216}->{{z,Z},{W,W},{G,G},{TL,L},{f,F},{Z,Z},{p,p},{Z,P},{M,y},{x,X}}],H],W,If[R[]<0.5,r[{{P,n},{y,n},{L,n}}],W],Z,If[R[]<0.5,r[{0.206,0.034,0.034,0.034,0.152,0.152,0.152,0.118,0.118}->{{n,c},{e,P},{M,y},{TL,L},{o,M},{w,w},{z,Z},{B,A},{f,F}}],Z],(x|X),If[R[]<0.1295,r[{{W,o},{W,w},{W,z}}]],_,#]
)&/@b];s=q/@(Normal@Counts[b]/.Rule->List);Print["The universe contains"<>StringJoin[Flatten[Transpose[{Table[If[l@s==i,If[l@s==1,""," and"],If[i==1,"",","]],{i,1,l@s}],s}]]]<>"."];]
Print["Simulation ended after "<>ToString[0.1*m]<>" yoctoseconds."]

The startparameter can by choosen by altering the value for a.

I noticed i've used the wrong probability for the Higgs boson but cant currently change it (in some hours or so). So add 3 oder 4 bytes to the current solution. (It was a test-value)

\$\endgroup\$
  • 3
    \$\begingroup\$ For almost a year the previous best stood, and you posted yours just 10 hours after mine! That's cold, man. :) \$\endgroup\$ – Alex Howansky Sep 24 '16 at 14:43
  • 2
    \$\begingroup\$ Since you bumped the challenge i had to do it too. Im sorry. :D \$\endgroup\$ – Julien Kluge Sep 24 '16 at 19:53
5
\$\begingroup\$

Perl, 973 986 959 944 bytes -10% = 849.6 points

Indentation and newlines are not part of the code, and are provided solely so you aren't scrolling for 30 years to read it all.

There are a couple of 0-byte optimizations that I never bothered to undo.

%p=(H,Higgs.($o=$".Boson),W,W.$o,Z,Z.$o,B,Bottom.($Q=$".Quark),b,Bottom.($q=$".Antiquark),G,Gluon,A,Tau.($t=$".Lepton),a,Antitau.$t,P,Photon,M,Muon,w,Antimuon,T,Top.$Q,t,Top.$q,e,Positron,N,Neutrino,n,Antineutrino,E,Electron,D,Down.$Q,d,Down.$q,S,Strange.$Q,z,Strange.$q,U,Up.$Q,u,Up.$q,C,Charm.$Q,c,Charm.$q);
%d=(H,[433e-6,.648,Bb,.141,WW,.0882,GG,.0704,Aa,.0327,Cc,.0159,ZZ,.00223,PP,.00111,ZP,244e-6,Mw,216e-6,Tt],W,[.5,$x=1/3,eN,$x,wN,$x,tN],Z,[.5,.206,Nn,.034,Ee,.034,Mw,.034,Aa,.152,Dd,.152,Sz,.152,Bb,.152,Uu,.118,Uu,.118,Cc],T,[.1295,$x,WD,$x,WS,$x,WB],t,[.1295,$x,Wd,$x,Wz,$x,Wb]);
for(@a=(H)x<>;grep/[HWZTt]/,@a;$z++){
    for$m(@a){
        @b=(@b,$m),next if$d{$m}[0]<rand;
        $e=rand;
        ($e-=$d{$m}[($_*=2)+1])>0||($e=2,@b=(@b,split//,$d{$m}[$_+2]))for 0..9
    }
    (@a,@b,%u,$w)=@b;
    $u{$_}++for@a;
    $w.=" $u{$_} $p{$_}".($u{$_}>1?'s,':',')for keys%u;
    say"The universe contains",$w=~s/.$/./r=~s/,([^,]+)$/ and$1/r
}
$z/=10;say"Simulation ended after $z yoctoseconds."

Obviously, the bulk of the code is creating the initial hashes. %p contains the names of all of the particles, exploiting Perl's bareword feature. %r determines the decay rates. If it's not featured in here, then it doesn't decay at all. %d contains the decay particles.

Since the order of particles in the output doesn't matter, I don't bother changing it from the random way Perl accesses the keys in the hash, which leads to things like the following:

[snip]
The universe contains 1 Higgs Boson.
The universe contains 1 Higgs Boson.
The universe contains 2 W Bosons.
The universe contains 2 Neutrinos, 1 Positron and 1 Top Antiquark.
The universe contains 1 Top Antiquark, 1 Positron and 2 Neutrinos.
The universe contains 1 Top Antiquark, 1 Positron and 2 Neutrinos.
The universe contains 1 Top Antiquark, 1 Positron and 2 Neutrinos.
The universe contains 2 Neutrinos, 1 Positron and 1 Top Antiquark.
The universe contains 1 Positron, 1 Top Antiquark and 2 Neutrinos.
The universe contains 2 Neutrinos, 1 Top Antiquark and 1 Positron.
The universe contains 1 Positron, 1 Strange Antiquark, 2 Neutrinos, 1 Bottom Antiquark and 2 W Bosons.
The universe contains 1 W Boson, 1 Bottom Antiquark, 2 Neutrinos, 1 Positron and 1 Strange Antiquark.
The universe contains 2 Neutrinos, 1 Bottom Antiquark, 1 W Boson, 1 Strange Antiquark and 1 Positron.
The universe contains 1 W Boson, 1 Bottom Antiquark, 2 Neutrinos, 1 Strange Antiquark and 1 Positron.
The universe contains 1 Bottom Antiquark, 4 Neutrinos, 1 Antimuon, 2 Positrons and 1 Strange Antiquark.

This has truly been an exhilarating adventure. Wonderful puzzle, honestly, I had a lot of fun! :)

\$\endgroup\$
5
\$\begingroup\$

Python 3.6.1, 1183 1157 ... 905 889 * 0.9 = 800.1 bytes

First time submitting one of these but this challenge looked pretty fun so here we go...

Almost certainly not as golfed as it could be but I'm pretty inexperienced at this so any tips are welcome.

from random import*
w,z='WZ';b,q,v=' boson',' .quark',[1]*3;p,n,u,t={'H':[433e-6,['Bb',w*2,'GG','Xx','Cc',z*2,'PP','ZP','Mm','Tt'],[6480,1410,882,704,32.7,15.9,2.23,1.11,.244,.216]],w:[.5,['FN','mN','xN'],v],z:[.5,['Nn','EF','Mm','Xx','Dd','Ss','Bb','Uu','Cc'],[2060]+[340]*3+[152]*3+[118]*2],'T':[.1295,['WD','WS','WB'],v]},{'H':'Higgs'+b,'B':'bottom'+q,w:w+b,'G':'gluon','X':'.tau lepton','C':'charm'+q,z:z+b,'P':'photon','M':'.muon','T':'top'+q,'E':'electron','F':'positron','N':'.neutrino','D':'down'+q,'S':'strange'+q,'U':'up'+q},['H']*int(input()),0
while{*u}&{*p}:
    for x in[*u]:
        if x in p and random()<p[x][0]:u.remove(x);u+=choices(*p[x][1:])[0]
    print("The universe contains %s."%' and'.join((', '.join(str(u.count(x))+' '+n[x.upper()].replace('.',(x>x.upper())*'anti')+(1<u.count(x))*'s'for x in{*u})).rsplit(',',1)));t+=.1
print('Simulation ended after %.1f yoctoseconds.'%t)

Try it online!

Edit: In the interest of brevity, an abridged list of the edits I've made (thank you commenters for the help!):

  • Saved 25 bytes thanks to Cat Wizard (semicolons instead of newlines) and the other Python answer (saved a couple of bytes defining strings).
  • Figured out a few more things to save another 107(!) bytes, mostly just better arrangement of dicts and it's no longer a function.
  • Realised random.choices() is weighted probabilities, not percentages, so I could save a few bytes from shifting things up a few powers of ten - 28 bytes saved! Higgs decay probability was wrong - I read 0.43% instead of 0.043% so that cost two bytes.
  • Saved another 28 bytes from assorted fancy tricks - set intersection instead of any(), += instead of list.extend() and a different import statement.
  • Swapped the nested dicts for a dict of lists, used choices(*p[x][1:]) to save a couple and x and y or z to avoid if...else...or.
  • Slightly better assignment, LBYL works out better and replaced enumerate() by copying the universe and using list.remove() on the original (the enumerate method was broken anyway as it happens).
  • Fixed a couple of silly things that were missed, better print() statement and merged if statements. Removed some unneeded brackets.

More readable version:

from random import *
w,z='WZ'
b,q,v=' boson',' .quark',[1]*3
        # Decayable particle products/probabilities
p,n,u,t={'H':[433e-6,['Bb',w*2,'GG','Xx','Cc',z*2,'PP','ZP','Mm','Tt'],[6480,1410,882,704,32.7,15.9,2.23,1.11,.244,.216]],
            w:[.5,['FN','mN','xN'],v],z:[.5,['Nn','EF','Mm','Xx','Dd','Ss','Bb','Uu','Cc'],[2060]+[340]*3+[152]*3+[118]*2],
            'T':[.1295,['WD','WS','WB'],v]},
        # Particle names
        {'H':'Higgs'+b,'B':'bottom'+q,w:w+b,'G':'gluon','X':'.tau lepton','C':'charm'+q,z:z+b,
            'P':'photon','M':'.muon','T':'top'+q,'E':'electron','F':'positron','N':'.neutrino',
            'D':'down'+q,'S':'strange'+q,'U':'up'+q},
        # Universe
        ['H']*int(input()),
        # Time taken
        0
while {*u} & {*p}: # While any particles can still decay
    for x in[*u]: # Iterate through them
        if x in p and random()<p[x][0]: # Check if they should decay
            u.remove(x) # If they should, remove them
            u+=choices(*p[x][1:])[0] # And add in the products
    # Join particle names with their counts together, separated by ',', add 'anti' where
    # needed, add 's' where needed, replace last ',' with 'and', then print.
    a = ' and'.join((', '.join(str(u.count(x))
                    + ' '
                    + n[x.upper()].replace('.',(x>x.upper())*'anti')
                    + (1<u.count(x))*'s' for x in {*u})).rsplit(',',1))
    print("The universe contains %s." % a)
    t+=.1
print('Simulation ended after %.1f yoctoseconds.'%t)

Sample output with 5000 Higgs bosons - might do a bigger run later to see if any top quark decay makes it in:

The universe contains 1 up antiquark, 23 charm quarks, 1 electron, 23 charm antiquarks, 371 tau leptons, 1542 neutrinos, 500 antimuons, 16 antineutrinos, 505 positrons, 4 muons, 3 photons, 3373 bottom quarks, 3373 bottom antiquarks, 1 up quark, 916 gluons and 897 antitau leptons.
Simulation ended after 2410.5 yoctoseconds.

If I've done anything wrong then please let me know and I'll try to fix it!

\$\endgroup\$
4
\$\begingroup\$

Ruby, 997 995 bytes -10% = 895.5 points

edit: added 'and' as the last delimiter as noticed by breadbox

First time posting on PPCG, this is an old challenge but I had much fun doing it. Here is the code

s=%w(boson quark top bottom anti tau lepton charm muon neutrino down strange up)
t="Higgs 0;Z 0;W 0;2 1;2 41;3 1;3 41;gluon;5 6;45 6;7 1;7 41;photon;8;48;positron;9;49;electron;#a 1;#a 41;#b 1;#b 41;#c 1;#c 41"
h=[4.33e-2,50,50,12.95]
d=[[64.8,14.1,8.82,7.04,3.27,1.59,0.223,0.111,0.0244,0.0216],[20.6,*[3.4]*3,*[15.2]*3,*[11.8]*2],*[[33.3]*3]*3]
r=["fgcchhijklbbmmbmnode","qrspnoijtuvwfgxykl","pqoqjq","ctcvcf","ctcvcf"]
r=r.map{|a|a.chars.map{|e|e.ord-97}}
s.size.times{|i|c=i>9?"#"+(i+87).chr: i.to_s;t=t.gsub(c,s[i])}
t=t.split(';')
z=Random.new
p=[0]*25
p[0]=gets.to_i
o=0
f=->p{puts"The universe contains "+(*a,b=(0..24).map{|i|e=p[i];e>0?"#{e} "+t[i]+(e>1?"s":""):nil}.compact;a*", "+(a.size>0?" and ":"")+b)+"."}
while p[0..4].sum>0 do
    f[p]
    q=p.clone
    (0..4).map{|i|p[i].times{|j|a=z.rand(100.0);a<h[i]?(q[i]-=1;a=z.rand(100.0);d[i].size.times{|k|a<d[i][k]?(q[r[i][k]]+=1;q[r[i][k+1]]+=1):a-=d[i][k]}):0}}
    p=q.clone
    o+=1
end
f[p]
puts "Simulation ended after #{o/10.0} yoctoseconds."

The strings are compressed by factoring recurring words (vars s and t) Products of decay are store compactly as string (var r), each letter is a particle. A function f prints the state of the universe by mapping the particle array to strings. I feel like there are some bytes to cut off in the state update line, but I can't find anything better.

Sample Output

[snip]
The universe contains 1 Higgs boson.
The universe contains 1 Higgs boson.
The universe contains 3 W bosons, 4 gluons and 1 tau lepton.
The universe contains 3 W bosons, 4 gluons and 1 tau lepton.
The universe contains 2 W bosons, 4 gluons, 1 tau lepton, 1 antimuon and 1 neutrino.
The universe contains 2 W bosons, 4 gluons, 1 tau lepton, 1 antimuon and 1 neutrino.
The universe contains 1 W boson, 4 gluons, 1 tau lepton, 3 antimuons, 1 positron and 4 neutrinos.
The universe contains 4 gluons, 1 tau lepton, 4 antimuons, 1 positron and 5 neutrinos.
Simulation ended after 653.2 yoctoseconds.

Performance

It's not so bad! It computed 100000 Higgs boson in 25sec

The universe contains 64751 bottom quarks, 93044 bottom antiquarks, 170984 gluons, 59927 tau leptons, 33038 antitau leptons, 14718 charm quarks, 12419 charm antiquarks, 5250 muons, 261567 antimuons, 53148 positrons, 305169 neutrinos, 2142 antineutrinos, 1575 electrons, 14080 down quarks and 7926 down antiquarks.
Simulation ended after 3131.4 yoctoseconds.
\$\endgroup\$
  • \$\begingroup\$ Welcome to the site! Do you need the spaces around > in your while? It's been a while since I've done anything in Ruby. \$\endgroup\$ – Sriotchilism O'Zaic Jun 20 '18 at 22:44
  • \$\begingroup\$ One issue: In your particle list, the last comma needs to be replaced with ` and` to meet the challenge requirements. \$\endgroup\$ – breadbox Jun 21 '18 at 1:08
2
\$\begingroup\$

D, 1172 1101 bytes - 10% = 990.9 bytes

import std.random,std.conv,std.stdio,std.algorithm,std.range;alias I=int,V=void,S=string,F=float,U=uniform01!F,W=writef,J=join,X=split;V main(S[]v){I[26]c;c[0]=to!I(v[1]);S[84]s;s[65..$]="antiX bosonXcharm Xdown XelectronXZXgluonXHiggsXtop Xbottom Xup Xtau leptonXmuonXneutrinoXWXphotonXquarkXpositronXstrange ".X('X');S[]f="HBXOBXFBXKQXKAQXDQXDAQXIQXIAQXJQXJAQXSQXSAQXCQXCAQXLXALXEXRXGXPXMXAMXNXAN".X('X');V 
D(I i,F p,F[]d,S v){d~=200;if(c[i]&&U()<p){c[i]--;p=U();foreach(j,q; d){if(p<q/100){c[v[2*j]-65]++;c[v[2*j+1]-65]++;break;}}}}S
C(T)(T s){return(s.length>1)?s[0..$-1].J(", ")~" and "~s[$-1]:s.J(" and ");}I
y=0;while(1){W("The universe contains "~C(iota(0,c.length).filter!(i=>c[i]).map!(i=>to!S(c[i])~" "~f[i].map!(a=>s[a]).J~((c[i]>1)?"s":"")).array)~".\n");y++;if(c[0]+c[1]+c[7]+c[8]<1)break;F[]u=[100/3.0,200/3.0];D(0,.000433,[.0216,.0460,.157,.38,1.97,5.24,12.28,21.1,35.2],"HIVWCUUUCCNOPQTTBBJK");D(2,.5,[11.8,23.6,38.8,54.,69.2,72.6,76.,79.4],"XYRSVWPQFGLMJKDENO");D(1,.5,u,"SXWXQX");D(7,.1295,u,"BFBLBJ");D(8,.1295,u,"BGBMBK");}W("Simulation ended after %f yoctoseconds.\n",y/10.0);}

Ungolfed

import std.random,std.conv,std.stdio,std.algorithm,std.range;
alias I=int,V=void,S=string,F=float,U=uniform01!F;

//uppercase is antiparticle.  The enums are replaced with constants
//in the golfed version.
enum P{ 
    h, w, z, //bosons
    u,U, d,D, t,T, b,B, s,S, c,C,//quarks
    l,L, //tau lepton, antitau lepton
    e,E, //electron,positron
    g, //gluon
    p, //photon
    m,M, //muon, antimuon
    n, N, //neutrino, antineutrino
};

void main(string[] v) {
    int[26]c;//particle counts
    c[0]=to!int(v[1]);//mandatory argument

    string format_particle(ulong i) {
        string[84] strs;
        strs[65..$]=["anti"," boson","charm ","down ","electron",/*f*/"Z",
        "gluon","Higgs",/*i*/"top ",/*j*/"bottom ",/*k*/"up ","tau lepton","muon","neutrino",/*o*/"W","photon","quark",/*r*/"positron","strange "];
        string[] fmt = [
            "HB","OB","FB",//bosons
            "KQ","KAQ",//up
            "DQ","DAQ",//down
            "IQ","IAQ",//top
            "JQ","JAQ",//bottom
            "SQ","SAQ",//strange
            "CQ","CAQ",//charm
            "L","AL",//Tau leptons
            "E","R",//electron/positron
            "G", //gluon
            "P", //photon
            "M","AM", //muon, antimuon
            "N", "AN", //neutrino, antineutrino
        ];
        //In the golfed version, we instead use X to delimit strings and call split to convert to array.

        return to!string(c[i])
            ~ " " ~ fmt[i].map!(a=>strs[a]).join
            ~ ((c[i]>1) ? "s" : "");
    }

    /* if there exist any of particle `i`, 
       it decays with probability `p`.
       into the particles specified in `v[j]`
       where `j` is drawn from distribution `decay_probs` */
    void decay(int i, float p, float[] decay_probs, P[] v...) {
        decay_probs ~= 2;//1.0, but with a margin for error in case of floating point precision issues
        if (c[i] && U()<p){
            c[i]--;

            p=U();
            foreach(j,q; decay_probs) {
                if (p<q) {
                    c[v[2*j]]++;
                    c[v[2*j+1]]++;
                    /*writef("Decay %s, Add: %s, %s\n",
                        format_particle(i),
                        format_particle(v[2*j]), format_particle(v[2*j+1]));*/
                    break;
                }
            }
        }
    }

    int y=0;
    while(1) {
        string commas(T)(T s) {
            return (s.length > 1)
                ?  s[0..$-1].join(", ") ~ " and " ~ s[$-1]
                :  s.join(" and ");
        }

        //print line for particle `d`
        writef("The universe contains " 
            ~ commas(
                iota(0,c.length)
                    .filter!(i=>c[i])
                    .map!(i=>format_particle(i))
                    .array) ~ ".\n");

        y++;
        if(c[P.h]+c[P.w]+c[P.t]+c[P.T]<1)break;

        F[] u = [1/3.0,2/3.0];
        decay(P.h, .000433,
            [.000216,.000460,.00157,.0038,.0197,.0524,.1228,.211,.352],
            P.t,P.T, P.m,P.M, P.z,P.p, P.p,P.p, P.z,P.z, P.c,P.C, P.l,P.L, P.g,P.g, P.w,P.w, P.b,P.B); 
        decay(P.z, .5,
            [.118,.236,.388,.54,.692,.726,.76,.794],
            P.n,P.N, P.e,P.E, P.m,P.M, P.l,P.L, P.d,P.D, P.s,P.S, P.b,P.B, P.u,P.U, P.c,P.C);
        decay(P.w,    .5, u, P.E,P.n, P.M,P.n, P.L,P.n);
        decay(P.t, .1295, u, P.w,P.d, P.w,P.s, P.w,P.b);
        decay(P.T, .1295, u, P.w,P.D, P.w,P.S, P.w,P.B);
        //In the golfed version, the list of enums is replaced by a string: each char is 65 + the enum's value.  D() is adjusted to subtract it again.
    }

    writef("Simulation ended after %f yoctoseconds.\n", y/10.0);
}
\$\endgroup\$
2
\$\begingroup\$

Kotlin: 1330 - 10% = 1197 bytes

My first ever code golf submission; very inefficient due to lists being golfier than maps, but seemingly correct! Works on JVM or JS implementation, and takes an (optional) argument.

operator fun String.minus(p:Pair<String,String>)=replace(p.first,p.second)
operator fun<A,B>A.div(b:B)=to(b)
val l=1.0
val e=l/3
val t=l-e
enum class V(val c:Double=.0,vararg val v:Pair<Pair<V,V>,Double>){E,F,G,P,L,AL,M,AM,N,AN,_Q,_AQ,CQ,CAQ,DQ,DAQ,SQ,SAQ,UQ,UAQ,WB(.5,P/N/e,AM/N/t,AL/N/l),TQ(.1295,WB/DQ/e,WB/SQ/t,WB/_Q/l),TAQ(.1295,WB/DAQ/e,WB/SAQ/t,WB/_AQ/l),ZB(.5,N/AN/.206,E/P/.24,M/AM/.274,L/AL/.308,DQ/DAQ/.46,SQ/SAQ/.612,_Q/_AQ/.764,UQ/UAQ/.882,CQ/CAQ/l),HiggsB(.000433,_Q/_AQ/.648,WB/WB/.789,G/G/.8772,L/AL/.9476,CQ/CAQ/.9803,ZB/ZB/.9962,F/F/.99843,ZB/F/.99954,M/AM/.999784,TQ/TAQ/l);fun d()=if(Math.random()<c)with(Math.random()){v.first{this<it.second}.first.toList()}else listOf(this)
override fun toString()=name-"_"/"bottom "-"A"/"anti"-"B"/" boson"-"C"/"charm "-"D"/"down "-"E"/"electron"-"F"/"photon"-"G"/"gluon"-"L"/"tau lepton"-"N"/"neutrino"-"M"/"muon"-"P"/"positron"-"Q"/"quark"-"S"/"strange "-"T"/"top "-"U"/"up "}
fun main(vararg a:String){var t=.0
var l=List(a.lastOrNull()?.toInt()?:1){V.HiggsB}
while(true){++t
var s="The universe contains"
with(l.toSet()){forEachIndexed{i,p->l.count{it==p}.let{s+=(" $it $p")
if(it>1)s+='s'
s+=when(size){i+1->"."
i+2->" and"
else->","}}}}
println(s)
if(l.filter{it.c>0}.isEmpty())break
for(p in l){l-=p;l+=p.d()}}
t/=10
print("Simulation ended after $t yoctoseconds.")}

Less Golfed Version

operator fun String.minus(p:Pair<String,String>)=replace(p.first,p.second)
operator fun<A,B>A.div(b:B)=to(b)
val l=1.0
val e=l/3
val t=l-e
enum class V(val c:Double=.0,vararg val v:Pair<Pair<V,V>,Double>){
    E,F,G,P,L,AL,M,AM,N,AN,_Q,_AQ,CQ,CAQ,DQ,DAQ,SQ,SAQ,UQ,UAQ,
    WB(.5,P/N/e,AM/N/t,AL/N/l),
    TQ(.1295,WB/DQ/e,WB/SQ/t,WB/_Q/l),
    TAQ(.1295,WB/DAQ/e,WB/SAQ/t,WB/_AQ/l),
    ZB(.5,N/AN/.206,E/P/.24,M/AM/.274,L/AL/.308,DQ/DAQ/.46,SQ/SAQ/.612,_Q/_AQ/.764,UQ/UAQ/.882,CQ/CAQ/l),
    HiggsB(.000433,_Q/_AQ/.648,WB/WB/.789,G/G/.8772,L/AL/.9476,CQ/CAQ/.9803,ZB/ZB/.9962,F/F/.99843,ZB/F/.99954,M/AM/.999784,TQ/TAQ/l);
    override fun toString()=name-
        "_"/"bottom "-
        "A"/"anti"-
        "B"/" boson"-
        "C"/"charm "-
        "D"/"down "-
        "E"/"electron"-
        "F"/"photon"-
        "G"/"gluon"-
        "L"/"tau lepton"-
        "N"/"neutrino"-
        "M"/"muon"-
        "P"/"positron"-
        "Q"/"quark"-
        "S"/"strange "-
        "T"/"top "-
        "U"/"up "
    fun d()=if(Math.random()<c)
        with(Math.random()){
            v.first{this<it.second}.first.toList()
        }else listOf(this)
}
fun main(vararg a:String){
    var t=.0
    var l=List(a.lastOrNull()?.toInt()?:99){V.HiggsB}
    while(true){
        ++t
        var s="The universe contains"
        with(l.toSet()){
            forEachIndexed{i,p->
                l.count{it==p}.let{
                    s+=(" $it $p")
                    if(it>1)s+='s'
                    s+=when(size){
                        i+1->"."
                        i+2->" and"
                        else->","
                    }
                }
            }
        }
        println(s)
        if(l.filter{it.c>0}.isEmpty())break
        for(p in l){l-=p;l+=p.d()}
    }
    t/=10
    print("Simulation ended after $t yoctoseconds.")
}
\$\endgroup\$
1
\$\begingroup\$

Quite a long submission.

Not that much golfed but still shorter than the other python one.

Take initial amount of Higgs as input.

Python 3, 1134 1120 bytes - 10% = 1020.6 1008 points

from random import *
n=int(input())
M=random
seed()
def D(i):
 for a in i:d[a]=d[a]+1 if a in d else 1
def X(p,A,B):
 for l in d[s]*' ':
  n[0]=1
  if M()<=p:d[s]-=1;r=M();D(A[B.index(next(x for x in B if x>r))])
s=lambda x:x.replace(Z,'')
Z,C,e,i,k,m,p,t,v='anti, boson,electron,gluon,neutrino,muon,photon,tau lepton,positron'.split(',')
B=' '+Z+'quark'
a='bottom'+B
c='charm'+B
f='down'+B
h="Higgs"+C
o='top'+B
u=Z+k
w="W"+C
x=Z+m
y=Z+t
z='Z'+C
S='strange'+B
U='up'+B
b,g,j,q,Q,T=map(s,[a,f,c,o,S,u])
d={h:n,0:0}
I=0
A=[(a,b),(w,w),(i,i),(t,y),(c,j),(z,z),(p,p),(z,p),(m,x),(o,q)]
B=[.648,.789,.8772,.9476,.9803,.9962,.99843,.99954,.999784,1]
O=[[k,v],[k,x],[k,y]]
E=[1/3,2/3,1]
F=[(u,k),(e,v),A[8],A[3],(g,f),(S,Q),A[0],(T,U),(c,j)]
G=[.206,.24,.274,.308,.46,.612,.764,.882,1]
H=[[w,g],[w,Q],[w,a]]
n={1}
while n:
 I+=1
 n={}
 P=dict(d)
 for s in P:
  if s==h:X(.00433,A,B)
  if s==w:X(.5,O,E)
  if s==z:X(.5,F,G)
  if s in [q,o]:X(.1295,H,E)
 l='The universe contains '
 for s in d:l+= str(d[s])+' '+s+'s'*(d[s]>1)+', ' if d[s]>0 else ''
 print(l[:-2]+'.')
print('Simulation ended after '+str(I/10)+' yoctoseconds.')

Try it online!

\$\endgroup\$
1
\$\begingroup\$

F#, 1993 1908 bytes - 10% = 1718 bytes

open System
let r=new Random()
let p()=r.NextDouble()*100.0
type P=
 |A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
let q="quark"
let n=dict[(A,"Higgs boson");(B,"Bottom "+q);(C,"Bottom anti"+q);(D,"Top "+q);(E,"Top anti"+q);(F,"W boson");(G,"Gluon");(H,"Tau lepton");(I,"Anti-tau lepton");(J,"Charm "+q);(K,"Charm anti"+q);(L,"Z boson");(M,"Photon");(N,"Muon");(O,"Antimuon");(P,"Antiquark");(Q,"Positron");(R,"Neutrino");(S,"Antineutrino");(T,"Electron");(U,"Down"+q);(V,"Down anti"+q);(W,"Strange "+q);(X,"Strange anti"+q);(Y,"Up "+q);(Z,"Up anti"+q);]
let c(u:P seq)=Option.isSome(Seq.tryFind(fun p->Seq.contains p [A;F;L;D])u)
let w()=
 if r.Next(2)=0 then
  let p=r.Next(3)
  if p=0 then[Q;R]elif p=1 then[O;R]else[I;R]
 else[F]
let t a=
 if p()<12.95 then
  let p=r.Next(3)
  if p=0 then[F;U]elif p=1 then[F;W]else[F;B]
 else[a]
let h()=
 if p()<0.0433 then
  let p=p()
  if p<64.8 then[B;C]elif p<78.9 then[F;F]elif p<87.72 then[G;G]elif p<94.76 then[H;I]elif p<98.03 then[J;K]elif p<99.62 then[L;L]elif p<99.843 then[M;M]elif p<99.954 then[L;M]elif p<99.9784 then[N;O]else[D;E]
 else[A]
let z()=
 if r.Next(2)=0 then
  let p=p()
  if p<20.6 then[R;S]elif p<24.0 then[T;Q]elif p<27.4 then[N;O]elif p<30.8 then[H;I]elif p<46.0 then[U;V]elif p<61.2 then[W;X]elif p<76.4 then[B;C]elif p<88.2 then[Y;Z]else[J;K]
 else[F]
let d u=List.map(fun p->if p=A then h()elif p=F then w()elif p=L then z()elif p=D||p=E then t p else[p])u|>List.concat 
let b h=List.init h (fun x->id A)
let o u=
 let e=List.countBy id u|>List.map(fun t->n.[fst t],snd t)|>List.map(fun t->
   if snd t>1 then(snd t,(fst t)+"s")else snd t,fst t)
 String.Join(", ",(List.map(fun x->(string(fst x))+" "+(snd x))e))|>printfn"The universe contains %s."
let [<EntryPoint>]m a=
 let mutable u=int a.[0]|>b
 let mutable t=0
 while c u do
  o u
  u<-d u
  t<-t+1
 o u
 (float t)/10.0|>printfn"Simulation ended after %f yoctoseconds."
 0

Try it online!

Ungolfed it looks like this:

That's a lot of particles...

\$\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.