Moderated Coin Flipper

I wanna play, too.

I am glad my useless pointless nothing but bloated window dressing app and the OP have inspired you to play.

Although... you are playing with an ages old toy that very few people can join in on the play... so you are only playing by yourself unfortunately.

I had to rummage through my pile of old hard drives and plug it into an old computer to be able to find a working version of a BASIC from 13 years ago that is 1000 times better than QBasic (aahh the halcyon days) and runs on CURRENT Windows 10.

And I had to modify your code just a tad to fit the syntax of this better BASIC interpreter/compiler.... and I fixed a spelling error.

Notice it is 9 lines of code now... so jt512 still has you beat 8 times over.

And the Bash version of theprestive has you beat 1000 times over in that at least one can run it on a modern Linux machine.

Here is the modified less ancient BASIC code...
Code:
flips = 10 \ heads = 0\ mark = 1
For cntr = 1 To flips
    If random(1) >= .5 then heads++
    If cntr == mark
        Print "Iterations =", cntr, " and heads are at ", 100 * heads / cntr, "%"
        mark++
    endif
Next
Print "All done at ", flips, " and heads are at ", 100 * heads / flips, "%"


And I ran it and here is the result....

Code:
Iterations =1 and heads are at 100%
Iterations =2 and heads are at 100%
Iterations =3 and heads are at 100%
Iterations =4 and heads are at 100%
Iterations =5 and heads are at 80%
Iterations =6 and heads are at 83%
Iterations =7 and heads are at 71%
Iterations =8 and heads are at 62%
Iterations =9 and heads are at 66%
Iterations =10 and heads are at 70%
All done at 10 and heads are at 70%
================

Iterations =1 and heads are at 0%
Iterations =2 and heads are at 50%
Iterations =3 and heads are at 66%
Iterations =4 and heads are at 50%
Iterations =5 and heads are at 40%
Iterations =6 and heads are at 33%
Iterations =7 and heads are at 42%
Iterations =8 and heads are at 37%
Iterations =9 and heads are at 44%
Iterations =10 and heads are at 50%
All done at 10 and heads are at 50%
================

Iterations =1 and heads are at 0%
Iterations =2 and heads are at 0%
Iterations =3 and heads are at 33%
Iterations =4 and heads are at 50%
Iterations =5 and heads are at 60%
Iterations =6 and heads are at 66%
Iterations =7 and heads are at 71%
Iterations =8 and heads are at 62%
Iterations =9 and heads are at 66%
Iterations =10 and heads are at 60%
All done at 10 and heads are at 60%
 
Last edited:
I wanna play, too.


The logic of your code is a little silly.... why on earth do you have that mark stuff.... here is a correction

Code:
flips = 10 \ heads = 0
For cntr = 1 To flips
    If random(1) >= .5 then heads++
    Print "Iterations =", cntr, " and heads are at ", 100 * heads / cntr, "%"
Next
Print "All done at ", flips, " and heads are at ", 100 * heads / flips, "%"

And here are a couple of runs
Code:
Iterations =1 and heads are at 0%
All done at 10 and heads are at 70%
Iterations =1 and heads are at 100%
Iterations =2 and heads are at 100%
Iterations =3 and heads are at 100%
Iterations =4 and heads are at 100%
Iterations =5 and heads are at 100%
Iterations =6 and heads are at 100%
Iterations =7 and heads are at 85%
Iterations =8 and heads are at 75%
Iterations =9 and heads are at 77%
Iterations =10 and heads are at 80%
All done at 10 and heads are at 80%
==================

Iterations =1 and heads are at 0%
Iterations =2 and heads are at 0%
Iterations =3 and heads are at 0%
Iterations =4 and heads are at 0%
Iterations =5 and heads are at 20%
Iterations =6 and heads are at 16%
Iterations =7 and heads are at 14%
Iterations =8 and heads are at 12%
Iterations =9 and heads are at 22%
Iterations =10 and heads are at 20%
All done at 10 and heads are at 20%
 
Last edited:
Coming back to the OP and the post that prompted it


Sure. But we are talking about the words random and deterministic. There is a distinct difference if one of us is using the definition that includes a conscious choice and the other is defining them as only predictable/unpredictable.

An individual atom decays unpredictably. Yet we can predict the decay of a large set of atoms. A single coin toss produces an unpredictable result. But we can predict the approximate results of ten thousand coin tosses. Now, is this random?

The above post led me to write a little WebApp to play with to see the result of coin tosses varying from 10 at a time to 10,000,000 at a time

So you can set the number of coin tosses you would like to see the results for and then tell the app to flip the coin that many times.... it will give you a table of the % of heads and tails for each round you go... and also a running average for the rounds.

Use it to see how even if you go up to 10,000,000 tosses you still are not going to get a precise 50% and even the running average still is not 50%.

If you try 10,000,000 it might take some time depending on the computer you are using... on a good computer should not take more than 0.5 secs for each try... on my computer takes much less and it is a 5 years old computer.... on my iPhone 6plus it takes fraction of a second and on my iPad6 it takes much less than a second.


If you have a random process and you understand the probabilities, if it's not nonlinear, then you can predict the outcome to within a specific percentage at an arbitrary confidence with sufficient events.

If the process is nonlinear, then I would say that this is no longer the case and with reference to the next post:

The main point isn't the overall percentage it is that you can't predict what the next flip will be, regardless of your knowledge of the previous flips. With evolution however the past state does affect any future change caused by a "random" mutation or one of the other non-random ways organisms change between generations. And I use the word random in quotes because it is a constrained possibility of where a mutation happens and what it is and if it persists to the next generation.

I would say that this is not the case even in pretty simple ecological systems, for example the Long Term Evolution Experiment based on colonies of e.coli from a single recent ancestor.

I'd say that the reason for this is that on occasion, a mutation in one offspring alters the whole fitness landscape and thus the course of evolution for both it's descendants and the other organisms in its ecosystem. And depending on what the mutation us, it could close off other potential optimisations. For example, whilst humans exist, there is no possible niche for, say the descendants of other great apes to develop a technological civilisation.

You then have the impact of catastrophes - would a different set of wind conditions or a nasty pathogen at the time of the Toba eruption about 70k yr ago have been able to wipe out Homo Sapiens? And would those have been random? I'd say quite possibly as, even if climate is predictable, weather, being a chaotic system would get perturbed by random events. Not just things like radioactive decay causing subtly different cloud seedings but even silly things like DNA damage causing a cancer and affecting whether an animal dies in a certain position and that impact on the local airflow.

Similarly with what actually survived the K-Pg event. A lot of the large, warm-blooded and thus fast-metabolism dinosaurs were doomed, but I'd argue that some of the smaller ones would have been simply unlucky and that could have made the whole subsequent course of evolution quite different.
 
The logic of your code is a little silly....

Says the guy whose one script unnecessarily adds together four perfectly good random numbers, and whose other script picks a random starting point in a vector after having already randomized the vector.
 
Says the guy whose one script unnecessarily adds together four perfectly good random numbers, and whose other script picks a random starting point in a vector after having already randomized the vector.


The above comment is a vivid demonstration of this post and an exquisite illustration of this one.
 
I wanna play, too.

QBasic:
Code:
Input "Number of interations:"; count
heads = 0
mark = 1
For ctr = 1 To count
    If Rnd >= .5 Then
        heads = heads + 1
    End If
    If ctr = mark Then
        Print "Interations ="; ctr; " and heads are at "; 100 * heads / ctr; "%"
        mark = mark + mark
    End If
Next ctr
Print "All done at "; count; " and heads are at "; 100 * heads / count; "%"
Pfft! If you are going to get nostalgic then you need to use GWBasic:
Code:
10 RANDOMIZE TIMER
20 INPUT "Number of iterations"; IT
30 H = 0:M = 1
40 FOR C = 1 TO IT
50 IF RND >= .5 THEN H = H+1
60 IF C <> M THEN 90
70 PRINT "Iterations =";C; " and heads are at"; 100 * H / C;"%"
80 M = 2 * M
90 NEXT C
100 PRINT "All done at"; IT; "and heads are at"; 100 * H / IT;"%"

And here is one run:
Code:
RUN
Number of iterations? 10
Iterations = 1  and heads are at 100 %
Iterations = 2  and heads are at 50 %
Iterations = 4  and heads are at 25 %
Iterations = 8  and heads are at 37.5 %
All done at 10 and heads are at 40 %
Ok
 
Last edited:
If you have a random process and you understand the probabilities, if it's not nonlinear, then you can predictguesstimate the outcome to within a specific percentage at an arbitrary confidence with sufficient events.


Yes... and your guess will have a random probability of being right.... but it is still a random process.


If the process is nonlinear, then I would say that this is no longer the case


Yes... a random process that is not easy to guesstimate.


and with reference to the next post:

I would say that this is not the case even in pretty simple ecological systems, for example the Long Term Evolution Experiment based on colonies of e.coli from a single recent ancestor.

I'd say that the reason for this is that on occasion, a mutation in one offspring alters the whole fitness landscape and thus the course of evolution for both it's descendants and the other organisms in its ecosystem. And depending on what the mutation us, it could close off other potential optimisations. For example, whilst humans exist, there is no possible niche for, say the descendants of other great apes to develop a technological civilisation.

You then have the impact of catastrophes - would a different set of wind conditions or a nasty pathogen at the time of the Toba eruption about 70k yr ago have been able to wipe out Homo Sapiens? And would those have been random? I'd say quite possibly as, even if climate is predictable, weather, being a chaotic system would get perturbed by random events. Not just things like radioactive decay causing subtly different cloud seedings but even silly things like DNA damage causing a cancer and affecting whether an animal dies in a certain position and that impact on the local airflow.

Similarly with what actually survived the K-Pg event. A lot of the large, warm-blooded and thus fast-metabolism dinosaurs were doomed, but I'd argue that some of the smaller ones would have been simply unlucky and that could have made the whole subsequent course of evolution quite different.


Yes.
 
Aah... the good old days...

But I still don't see the point of the M stuff...
It makes a difference when you are doing a long run:
Code:
RUN
Number of iterations? 1000000
Iterations = 1  and heads are at 100 %
Iterations = 2  and heads are at 50 %
Iterations = 4  and heads are at 75 %
Iterations = 8  and heads are at 50 %
Iterations = 16  and heads are at 43.75 %
Iterations = 32  and heads are at 46.875 %
Iterations = 64  and heads are at 50 %
Iterations = 128  and heads are at 53.90625 %
Iterations = 256  and heads are at 53.51563 %
Iterations = 512  and heads are at 51.75782 %
Iterations = 1024  and heads are at 53.125 %
Iterations = 2048  and heads are at 49.95117 %
Iterations = 4096  and heads are at 50.26856 %
Iterations = 8192  and heads are at 50.93994 %
Iterations = 16384  and heads are at 50.38452 %
Iterations = 32768  and heads are at 49.96033 %
Iterations = 65536  and heads are at 49.92523 %
Iterations = 131072  and heads are at 49.97864 %
Iterations = 262144  and heads are at 49.85962 %
Iterations = 524288  and heads are at 49.94011 %
All done at 1000000 and heads are at 49.9274 %
Ok*
Most of the intermediate prints would scroll off the screen if you only went in steps of 1.

Notice that 1,000,000 tosses results in 499,274 heads which is more than the 499,180 necessary to reject the null hypothesis.
Therefore, we can conclude that this is a fair result.

doesn't GWBasic have a modulus operator?
It does but I don't see where you would use it in this program.
 
Last edited:
It makes a difference when you are doing a long run:

Most of the intermediate prints would scroll off the screen if you only went in steps of 1.


I see... ok... I guess in the old days one could not scroll back to see the scrolled off lines.

Never mind... I like that way better than mine...:thumbsup:
 
Last edited:
It makes a difference when you are doing a long run:
Code:
RUN
Number of iterations? 1000000
Iterations = 1  and heads are at 100 %
Iterations = 2  and heads are at 50 %
Iterations = 4  and heads are at 75 %
Iterations = 8  and heads are at 50 %
Iterations = 16  and heads are at 43.75 %
Iterations = 32  and heads are at 46.875 %
Iterations = 64  and heads are at 50 %
Iterations = 128  and heads are at 53.90625 %
Iterations = 256  and heads are at 53.51563 %
Iterations = 512  and heads are at 51.75782 %
Iterations = 1024  and heads are at 53.125 %
Iterations = 2048  and heads are at 49.95117 %
Iterations = 4096  and heads are at 50.26856 %
Iterations = 8192  and heads are at 50.93994 %
Iterations = 16384  and heads are at 50.38452 %
Iterations = 32768  and heads are at 49.96033 %
Iterations = 65536  and heads are at 49.92523 %
Iterations = 131072  and heads are at 49.97864 %
Iterations = 262144  and heads are at 49.85962 %
Iterations = 524288  and heads are at 49.94011 %
All done at 1000000 and heads are at 49.9274 %
Ok*
Most of the intermediate prints would scroll off the screen if you only went in steps of 1.

Notice that 1,000,000 tosses results in 499,274 heads which is more than the 499,180 necessary to reject the null hypothesis.
Therefore, we can conclude that this is a fair result.


The only statement you can make is that you failed to reject the null hypothesis. That does not imply that the null is true.
 
After going to bed last night a simple fix for the bias toward tails occurred to me.

Just download more random number sequences from your source site (I think you said you could download a thousand a day without incurring any cost?) until you get one that has 20 more values above 127 than below. Append that sequence to the end of your random array.

Your set of numbers will now be evenly distributed with respect to the only subset that matters, big numbers and little numbers.

As a bonus you could also now allow more than 10,000 tries per run if you wanted.


That is a very good idea... thanks:thumbsup:

I will try it when I finish Sniper Elite 2 :p
 
:bigclap


WOW... I am so glad my app was not so pointless and worthless so as to inspire you to such a good effort.

And in Bash no less.... WELL DONE.

I had to modify it just a tad to make it run on standard Debian-Linux bash...

And just copying and pasting it from your code above did not work because of the damned Windows cr/lf and EOF stuff... I tried to strip all of that but in the end I just typed the code by hand. (see below)

Only one comment.... it is not ONE LINE OF CODE THOUGH... hmmm.... I guess it is bloated Linux dressing then... no??:rolleyes:;)

But seriously :thumbsup::thumbsup:

Ah... another comment.... it is a very standard PSEUDO-RNG and not a real dynamics of a real coin toss... so it has nothing to do with a real world randomness... does it now??;)




Here is the Debian-Linux bash version (tosser.sh)

Code:
#! /bin/bash

if [ -z "$1" ]
  then
    tosses=10
  else
    tosses=$1
fi

echo $tosses

flip=0
heads=0
tails=0
ravg=0

for((i=tosses; i>=1; i--));
do
  echo -n "Tosses: $i | "
  flip=$(echo $RANDOM)
  echo -n "Toss: $toss | "
  if [ $(($flip%2)) == 0 ]
      then
    heads=$((heads+1))
      else
    tails=$((tails+1))
  fi
  total=$(($heads+$tails))
  ravg=$(printf %.2f%% "$((10**3 * 100 * $heads/$total))e-3")
  echo -n "Heads: $heads | "
  echo -n "Tails: $tails | "
  echo -n "Running Average (Heads): $ravg "
  echo ""
done


And here is the output from three runs.... notice the second run....

Code:
10
Tosses: 10 | Toss:  | Heads: 1 | Tails: 0 | Running Average (Heads): 100.00%
Tosses: 9 | Toss:  | Heads: 1 | Tails: 1 | Running Average (Heads): 50.00%
Tosses: 8 | Toss:  | Heads: 1 | Tails: 2 | Running Average (Heads): 33.33%
Tosses: 7 | Toss:  | Heads: 2 | Tails: 2 | Running Average (Heads): 50.00%
Tosses: 6 | Toss:  | Heads: 3 | Tails: 2 | Running Average (Heads): 60.00%
Tosses: 5 | Toss:  | Heads: 4 | Tails: 2 | Running Average (Heads): 66.67%
Tosses: 4 | Toss:  | Heads: 4 | Tails: 3 | Running Average (Heads): 57.14%
Tosses: 3 | Toss:  | Heads: 5 | Tails: 3 | Running Average (Heads): 62.50%
Tosses: 2 | Toss:  | Heads: 6 | Tails: 3 | Running Average (Heads): 66.67%
Tosses: 1 | Toss:  | Heads: 6 | Tails: 4 | Running Average (Heads): 60.00%
===========

10
Tosses: 10 | Toss:  | Heads: 1 | Tails: 0 | Running Average (Heads): 100.00%
Tosses: 9 | Toss:  | Heads: 1 | Tails: 1 | Running Average (Heads): 50.00%
Tosses: 8 | Toss:  | Heads: 1 | Tails: 2 | Running Average (Heads): 33.33%
Tosses: 7 | Toss:  | Heads: 1 | Tails: 3 | Running Average (Heads): 25.00%
Tosses: 6 | Toss:  | Heads: 1 | Tails: 4 | Running Average (Heads): 20.00%
Tosses: 5 | Toss:  | Heads: 1 | Tails: 5 | Running Average (Heads): 16.67%
Tosses: 4 | Toss:  | Heads: 1 | Tails: 6 | Running Average (Heads): 14.29%
Tosses: 3 | Toss:  | Heads: 1 | Tails: 7 | Running Average (Heads): 12.50%
Tosses: 2 | Toss:  | Heads: 1 | Tails: 8 | Running Average (Heads): 11.11%
Tosses: 1 | Toss:  | Heads: 1 | Tails: 9 | Running Average (Heads): 10.00%
===========

10
Tosses: 10 | Toss:  | Heads: 0 | Tails: 1 | Running Average (Heads): 0.00%
Tosses: 9 | Toss:  | Heads: 0 | Tails: 2 | Running Average (Heads): 0.00%
Tosses: 8 | Toss:  | Heads: 0 | Tails: 3 | Running Average (Heads): 0.00%
Tosses: 7 | Toss:  | Heads: 0 | Tails: 4 | Running Average (Heads): 0.00%
Tosses: 6 | Toss:  | Heads: 1 | Tails: 4 | Running Average (Heads): 20.00%
Tosses: 5 | Toss:  | Heads: 2 | Tails: 4 | Running Average (Heads): 33.33%
Tosses: 4 | Toss:  | Heads: 3 | Tails: 4 | Running Average (Heads): 42.86%
Tosses: 3 | Toss:  | Heads: 4 | Tails: 4 | Running Average (Heads): 50.00%
Tosses: 2 | Toss:  | Heads: 5 | Tails: 4 | Running Average (Heads): 55.55%
Tosses: 1 | Toss:  | Heads: 5 | Tails: 5 | Running Average (Heads): 50.00%

I'm glad you got it working.

There appears to be a minor bug in your output.
 
After going to bed last night a simple fix for the bias toward tails occurred to me.

Just download more random number sequences from your source site (I think you said you could download a thousand a day without incurring any cost?) until you get one that has 20 more values above 127 than below. Append that sequence to the end of your random array.

Your set of numbers will now be evenly distributed with respect to the only subset that matters, big numbers and little numbers.

As a bonus you could also now allow more than 10,000 tries per run if you wanted.

There is actually a simpler way to force P(H)=P(T), even if the set they are drawn from is biased. It is analogous to a method used to unbias hardware RNGs. You would do the following:

1. Randomly sample two outcomes, (X1, X2), from the set.
2. If they are either both heads or both tails, return them to the set and go back to Step 1.
3. If they are either (H, T) or (T, H), then accept X1.
4. Return both to the set.
5. Repeat Steps 1–4 until the desired number of draws is obtained.

This works for the following reason. For any P(H)=p and P(T)=1–p=q,
P(HH) = p^2,
P(TT) = q^2, and
P(HT) = pq = qp = P(TH).

From the last line above, we can see that H's and T's will each be accepted with probability pq. Hence the sampling is unbiased.
 
Last edited:
I'm glad you got it working.

There appears to be a minor bug in your output.


Yes... I see it
echo -n "Toss: $toss | "​

should say
echo -n "Toss: $flip | "​

Code:
10
Tosses: 10 | Toss: 20104 | Heads: 1 | Tails: 0 | Running Average (Heads): 100.00%
Tosses: 9 | Toss: 9189 | Heads: 1 | Tails: 1 | Running Average (Heads): 50.00%
Tosses: 8 | Toss: 4922 | Heads: 2 | Tails: 1 | Running Average (Heads): 66.67%
Tosses: 7 | Toss: 2478 | Heads: 3 | Tails: 1 | Running Average (Heads): 75.00%
Tosses: 6 | Toss: 7578 | Heads: 4 | Tails: 1 | Running Average (Heads): 80.00%
Tosses: 5 | Toss: 10054 | Heads: 5 | Tails: 1 | Running Average (Heads): 83.33%
Tosses: 4 | Toss: 18375 | Heads: 5 | Tails: 2 | Running Average (Heads): 71.43%
Tosses: 3 | Toss: 18014 | Heads: 6 | Tails: 2 | Running Average (Heads): 75.00%
Tosses: 2 | Toss: 9356 | Heads: 7 | Tails: 2 | Running Average (Heads): 77.78%
Tosses: 1 | Toss: 7477 | Heads: 7 | Tails: 3 | Running Average (Heads): 70.00%
 
Last edited:
There is actually a simpler way to force P(H)=P(T), even if the set they are drawn from is biased. It is analogous to a method used to unbias hardware RNGs. You would do the following:

1. Randomly sample two outcomes, (X1, X2), from the set.
2. If they are either both heads or both tails, return them to the set and go back to Step 1.
3. If they are either (H, T) or (T, H), then accept X1.
4. Return both to the set.
5. Repeat Steps 1–4 until the desired number of draws is obtained.

This works for the following reason. For any P(H)=p and P(T)=1–p=q,
P(HH) = p^2,
P(TT) = q^2, and
P(HT) = pq = qp = P(TH).

From the last line above, we can see that H's and T's will each be accepted with probability pq. Hence the sampling is unbiased.
Today I learned something. That seems like a neat and useful trick!
 
I am glad my useless pointless nothing but bloated window dressing app and the OP have inspired you to play.

Dude, seriously, if you just said up front that you wanted to fool around with coding, that would have taken care of all the pages of arguments right up front. Instead, you made zany predictions and bounced all over the place between religion and natural randomness and CONCERN and slander and all the rest.

Why didn't you just say that exploring code writing was your interest? It was not mentioned in the OP or for many pages, and in fact you refused to talk about the code at all till jfischer ctr-u'ed it.
 
Last edited:
I wanna play, too...

Why? I thought

...trials speak to the quality of the generator he is using and [ B][ HILITE]nothing at all to how coins behave[ /HILITE][ /B].

Your reading comprehension skills are poor. Those two statements are not in conflict.

And all you are doing is using the ages old PSEUDO-RNG of the ages old QBasic?

You meant "age-old", and yes, the age of QBasic was part of its charm for this exercise. Is there a particular defect in the QBasic or its RND function you care to cite, or are you just being negative without basis?

And where is the accounting for Edge cases??? Or do you command perfection only from others but not yourself???

Never claimed it did. On the other hand, were I to have claimed it did, but it didn't or was otherwise defecting in doing it or I was unwilling to have an intelligent discussion about the code that did it, then you could take me to task.

And I noticed it is not 1 line of code.... I guesss...

No need to guess. It is not just one line of code, obviously.
 

Back
Top Bottom