2
\$\begingroup\$

A book on probability says that a sequence of heads and tails is generated by a fair coin asking what is the probability that the pattern T, H, H, H occurs before the pattern H, H, H, H. I have made a generator of such strings. Is it right (I have heard that return statement is not appreciated in Scala)?

def l(s: String): Boolean = {
    if (s.endsWith("hhhh")) return true; 
    if (s.endsWith("thhh")) return false; 
    l(s + (if (Math.random > .5) "h" else "t"))
}
\$\endgroup\$
  • \$\begingroup\$ I"m not sure what you're trying to do here. you need to toss the coin four times to get that sequence. if you do 4 x 1,000,000 attempts using a fair coin how many times will you get THHH and HHHH? Compare those two amounts. IF they are roughly similar then it's likely the coin is fair. if there is a great disparity between the two numbers, then its more likely than not that the coin is biased. \$\endgroup\$ – BKSpurgeon May 16 '17 at 13:13
  • \$\begingroup\$ @BKSpurgeon The function that I posted for review generates a single sequence, up to "hhhh" or "thhh". You do not need to review anymore. And, just for your information, the fair coin generates thhh 15 times more often than hhhh. Gambler's fallacy does not apply here. Try yourself (1 to 20) map (_ => l("")) and see how more often true comes out than false. But, it does not matter for review. \$\endgroup\$ – Val May 16 '17 at 16:40
  • \$\begingroup\$ that's very interesting. thanks for posting. \$\endgroup\$ – BKSpurgeon May 17 '17 at 0:28
1
\$\begingroup\$

To avoid return statements:

def l(s: String): Boolean = {
  if (s.endsWith("hhhh")) true
  else if (s.endsWith("thhh")) false
  else l(s + (if (Math.random > .5) "h" else "t"))
}

Although I don't like if - else if sequences, in this case it remains simple and readable, but it still can be simplified like this

def l(s: String): Boolean = {
  if (s.length > 3) s.endsWith("hhhh")
  else l(s + (if (Math.random > .5) "h" else "t"))
}

or even

def l(s: String): Boolean = {
  s.endsWith("hhhh") || l(s + (if (Math.random > .5) "h" else "t"))
}

Randomness

I think that there is a minor issue with random values distribution.

As per Scaladoc for Math.random:

Returns a Double value with a positive sign, greater than or equal to 0.0 and less than 1.0.

For the current condition, this means that 0.5 < h < 1.0 and 0 <= t <= 0.5.

0.5 is not included in the lower bound for generation of h values, which favors t very slightly.

The condition for equal distribution should be if (Math.random < 0.5) "t" else "h".

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