Moderated Coin Flipper

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

The irony is so rich.

Still, if you have yet to figure it out, I am happy to explain it to you. Just ask. It is really simple. You may also notice my code does not count the number of tails. Should we discuss that, too?
 
Pfft! If you are going to get nostalgic then you need to use GWBasic:
Code:
10 RANDOMIZE TIMER
...

I knew there was something to seed the pseudorandom number generator. I just didn't remember what. Thanks for the reminder.
 
I have taken the criticism about my code not being a single line of code to heart. Therefore I present to you tosserlad.sh as a one-liner:
#!/opt/homebrew/bin/bash; if [ -z "$1" ]; then; TOSSES=10; else; TOSSES=$1; fi; TOSS=0; HEADS=0; TAILS=0; RAVG=0; for ((i=TOSSES; i>=1; i--)); do; echo -n "Tosses: $i | "; TOSS=$(echo $RANDOM); echo -n "Toss: $TOSS | "; if [ `expr $TOSS % 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​

The nice thing about the one-line version is that it also solves Leumas's portability problem with carriage returns.

This version is presented without warranty or support. Any bugs that may be present are entirely the user's problem to solve.

Funnily enough, I originally read Leumas's "not one line of code" criticism as a complaint that shell scripts don't really count as "code". Which, honestly, I think is fair.

Also I feel an affinity for Leumas's sense of humor. I just wish he wouldn't weaponize to such an extreme ALL THE TIME.
 
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.

Very cool, thanks! I'm going to drop this into my algorithm notes.
 
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.


I just finished virtually killing Hitler... seriously Sniper Elite 4 let me kill Hitler by sniping his head off.:D

So now off to virtually suck blood out of dead zombies in Bioshock 2.

But I thought about your suggestion.

It is excellent thanks.

If I just append another file to balance things out it will not afford ability to do more than up to 20,000 more flips at a time... and it takes a lot of effort to keep downloading a file until I am going to get exactly 20 more heads than tails to balance out.

So I had a thought, while watching the slow motion scene of the head exploding of one of the Nazi generals in Sniper Elite 4.

Can't it be much more practical to just cut out of the file the 20 offending Nazi bytes??

What do you think?

Also psion10... what do you think too??

Thanks again :thumbsup:
 
Last edited:
Can't it be much more practical to just cut out of the file the 20 offending Nazi bytes??

What do you think?

Also psion10... what do you think too??
Removing bytes from a 16K byte array sounds like a lot of work to me. Not to mention that if you don't choose the offending bytes randomly, your data will be tainted.

jt512's suggestion seems much simpler.
 
...
Can't it be much more practical to just cut out of the file the 20 offending Nazi bytes??

In all seriousness, I think you are focusing too much on the whole "true" random number generator thing. The pseudorandom number generator provided by the standard Javascript implementations is actually very good. Your attempts to introduce atmospheric noise data is problematic and not likely to produce a clean result. On the other hand, the PRNG function is well behaved and robust.
 
In all seriousness, I think you are focusing too much on the whole "true" random number generator thing. The pseudorandom number generator provided by the standard Javascript implementations is actually very good. Your attempts to introduce atmospheric noise data is problematic and not likely to produce a clean result. On the other hand, the PRNG function is well behaved and robust.


So now you admit all that CONCERN before was just red herrings altogether.

Thanks for admitting that... QED!!!
 
Last edited:
Removing bytes from a 16K byte array sounds like a lot of work to me. Not to mention that if you don't choose the offending bytes randomly, your data will be tainted.

jt512's suggestion seems much simpler.


I will not remove just any bytes... I will remove 20 bytes from the bytes that are <= 127...

So the total number of bytes <= 127 will then be the same as the ones >127.

The total number of bytes will be reduced by 20.... so instead of 16,384... it will be 16,364 bytes.

But now there will be 8,182 bytes of either side.

And it does not matter which bytes <= 127 I remove at all.

Because the algorithm selects heads (>127) or tails (<=127).... so it does not matter the values or which bytes are selected to be removed just so long as they are (<=127)... thus rendering the balance of bytes to be the same on either side.

No???

ETA: and yes I will be removing the offending <= 127 bytes randomly from the set of bytes that are <=127.... it is not at all a lot of work... it is a lot less work than keeping downloading files and checking them to see which one is going to have 20 bytes > 127. So far no luck.
 
Last edited:
No.

If you are familiar with data structures then you would be aware that when you remove an element from an array, you have to shift the remaining elements back 1 space to fill the gap. That's an O(n) running time right there. IE the time taken to remove 20 bytes from the array will be proportional to 20 x 16,384 which is a lot of time wasted before you have got your first number!

Secondly you have to choose the bytes to remove randomly (an average of 2 tries per hit). If you just remove the first 20 bytes <= 127 then you will leave the array starting with a run of >127 bytes (20 on average). That is what I mean by "tainted".
 
So now you admit all that CONCERN before was just red herrings altogether.

Thanks for admitting that... QED!!!

You seem compelled to be combative no matter what.

Your conclusions from what I said are unfounded.
 
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.


It's hazardous to attempt mindreading anyone else; and in this case, it is probably an impossibiity; but I'd guess that he started out with a hazy idea that this app idea would indeed provide evidence that coil flips are random. Then, when people started pointing out to him the circularity of it all, he did his usual kneejerk How-dare-you-attack-me-and-my-ideas thing. And then, after awhile, after more people pointed it out to him, I'm guessing the absurdity of it all did percolate down to his awareness; but by then he was far too committed to the position he'd dug himself in on, to admit to having been mistaken.

On the other hand, it is also possbile that all he wanted to do was to try to provide evidence that random numbers tend to a mean. I doubt it, because it would simply be reinventing a wheel that had already been put in place long back; but, while implausible, it is still possible. That is what I'd tried to ask him, gently enough, whether it was this last, or maybe something else altogether, that was the idea behind the app/s --- but, heh, I'll not make the mistake of attempting to ask him again!

In any case, and after having gone down a the rabbit hole far enough that retreat is no longer an option, at least for him, he's now trying to pretend that all this was about is simply playing with the coding. (All of which, I suppose, answers to Bulverism; but I don't see any other way to answering the question other than guessing, as best one can.)

As you say, playing with codes in and of itself is cool, and I'm actually enjoying reading this thread, and not just the comic portions of it.
 
You seem compelled to be combative no matter what.


I am still waiting for an apology and admittance of error for your persistent and doubled and tripled and quadrupled down on false slander of me.


Your conclusions from what I said are unfounded.


No it is not... as clearly demonstrated in the post below showing yet another Concern red herring about the Edge case.


At any rate, I did not libel you. I did accuse you of lying. That was because, contrary to your claim about modeling the "edge case", your code did not model the "edge case" in any way that could be described as legitimately actually modeling the "edge case". Your claim was false, and you would not discuss nor clarify nor amend it, so it was false and deliberate. I.e., a lie.
 
Last edited:
So am I. Wanna just move on?


Oh, and it is not slander. QED!!!!!


You're not doing it right. You also need to "code" in a mass of white space at the bottom, for it to be really effective, at being ...whatever it was meant to be.
 
No.

If you are familiar with data structures then you would be aware that when you remove an element from an array, you have to shift the remaining elements back 1 space to fill the gap. That's an O(n) running time right there. IE the time taken to remove 20 bytes from the array will be proportional to 20 x 16,384 which is a lot of time wasted before you have got your first number!


Yes... I am very familiar with it... I have a masters in Concrete Structures.:D

But... yes... if it were the case that I am removing the 20 bytes every single time the program is run.

I will be removing the 20 bytes once and for all time from the file.


Secondly you have to choose the bytes to remove randomly (an average of 2 tries per hit). If you just remove the first 20 bytes <= 127 then you will leave the array starting with a run of >127 bytes (20 on average). That is what I mean by "tainted".


Running the algorithm on the file one time to remove the 20 bytes once and for all insitu like concrete and then it sets and stays there.:D

And... you forgot that the data file before it is used in the flipping algorithm is
  • Shuffled
  • a chunk is used with a random offset within the file
  • and only 10 up to maximum of 10,000 bytes are used out of the 16,364 (after removing the 20 bytes)

So the order of the data is not at all of any import since it is not ordered but will be shuffled... and thus no tainting.

No?
 
Last edited:
I will not remove just any bytes... I will remove 20 bytes from the bytes that are <= 127...


That's the problem. You would be systematically altering a random set. Therefore, the remaining set would no longer be random. You would, thus, be defeating the purpose of having used a true random number generator in the first place.

But, more importantly, you defeated the purpose of using a TRNG as soon as you hard coded the set into your script for it to be reused. Because, from that point on, you were no longer sampling from a uniform distribution over the integers 0,1,...,255, but from a specific, finite, non-uniform distribution of integers. Moreover, you are using a PRNG to sample from that set. What could possibly have been the point of downloading a set generated by a TRNG, just to sample from it using a PRNG? Since you are using a PRNG anyway, you would have been better off just using the PRNG in the first place to sample from Uniform({0,1}), a distribution which actually has the characteristics of the flip of a fair coin, unlike the set you are currently sampling from.

Looking at the bigger picture, jsfisher was right: just to simulate the long-run behavior of coin flips, there was no reason to have used even a cryptographically secure PRNG, much less a TRNG. Furthermore, you have now experienced, first hand, the practical problems of using a TRNG, the reasons they are relatively rarely used in practice.
 
Last edited:
That's the problem. You would be systematically removing elements from a random set. Therefore, the remaining set will not be random. So you will be defeating the purpose of having used a true random number generator in the first place.


No I won't.

I would be randomly removing 20 elements from a random set of elements... the remaining set of elements is still random.


But, more importantly, you defeated the purpose of using a TRNG as soon as you hard coded the set into your script for it to be reused.


No I did not... because a random set of elements is still a random set of elements when used no matter how many number of time if it is shuffled up every time it is used.


Because then you were no longer sampling from a uniform distribution over the integers 0,1,...,253, but from a specific, finite, non-uniform distribution of integers.


The above is wrong... because it is a SUBSET of random integers obtained from a set of random elements.


Moreover, you are using a PRNG to sample from that set.


Not that red herring again... [imgw=50]http://www.internationalskeptics.com/forums/imagehosting/5128262c750038bf97.jpg[/imgw]


What could possibly have been the point of downloading a set generated by a TRNG, just to sample from it using a PRNG?


To nip at the gills off of all those CONCERNED red herrings that have been admitted to be red herrings all along.


Since you are using a PRNG anyway, you would


Utterly wrong... randomly selecting from a random set of elements is as random as the set of elements.

Don't be so CONCERNED about the PRNG [imgw=50]http://www.internationalskeptics.com/forums/imagehosting/5128262c750038bf97.jpg[/imgw] anymore because it has already been admitted to be a red herring.

In all seriousness, I think you are focusing too much on the whole "true" random number generator thing. The pseudorandom number generator provided by the standard Javascript implementations is actually very good. Your attempts to introduce atmospheric noise data is problematic and not likely to produce a clean result. On the other hand, the PRNG function is well behaved and robust.
 
Last edited:
Can't it be much more practical to just cut out of the file the 20 offending Nazi bytes??

What do you think?

Also psion10... what do you think too??

Thanks again :thumbsup:

I'm not an expert in random numbers, either generating them of validating them. But I don't think you're going to seriously change the randomness from whatever is now by taking out 20 bytes lower than 127.

But honestly, jt512's suggestion is easy to implement and solves the problem without messing with whatever the degree of randomness currently is.

And your PRNG solution works fine, and doesn't have that very tiny tails bias. I'd just go with that. It's clean and works. In my shop that's a win!
 

Back
Top Bottom