Several months ago I had this question as a pre-screening puzzle for an interview. Recently when thinking about blog material, it popped in my head as a good example to use for solving a problem functionally. I'll post my solution to this as soon as I'm done writing my blog post.

NOTE: This question was asked on StackOverflow a year ago, and was downvoted after a few (incorrect) answers. I assume it was downvoted for being an obvious interview or homework question. Our answers here should be code golfed deep enough for someone not to think about using them!

In a race, you bet using the following strategy. Whenever you lose a bet, you double the value of the bet for the next round. Whenever you win, the bet for the next round will be one dollar. You start the round by betting one dollar.

For example, if you start with 20 dollars, and you win the bet in the first round, lose the bet in the next two rounds and then win the bet in the fourth round, you will end up with 20+1-1-2+4 = 22 dollars.

You are expected to complete the function, g, which takes two arguments:

The first argument is an integer a which is the initial money we amount we have when we start the betting.

The second argument is a string r. The ith character of outcome will be either 'W' (win) or 'L' (lose), denoting the result of the ith round.

Your function should return the amount of money you will have after all the rounds are played.

If at some point you don't have enough money in your account to cover the value of the bet, you must stop and return the sum you have at that point.

Moreover, you state that Your function should return the amount of money you will have after all the rounds are played. although you show a much more detailed information in the Expected output section. Which is the desired behavior of the function?
–
HowardApr 24 '14 at 5:38

Also, if every tag you are using is one that you created just for the question, something is wrong.
–
QuincunxApr 24 '14 at 5:59

1

Judging from "Our answers here should be code golfed deep enough for someone not to think about using them!", I think you wanted a [code-golf], so I tagged it as such. Also, I adjusted the "Example Output" to be a "Sample Run" to better match what it seems you wanted.
–
QuincunxApr 24 '14 at 6:08

@quincunx sorry, I've never posted here but interestingly posted many of the original questions that migrated here when it was created. In a way, I'm one of the reasons this stackexchange was made. I thought it was all code golf, and my laptop battery was dying so I was in a hurry to finish up. Sorry. Long night.
–
TheSoftwareJediApr 24 '14 at 6:27

Python 2, 7268 62 bytes

def g(a,s,n=1):
for c in s:
if a>=n:a,n=((a+n,1),(a-n,2*n))[c<'W']
return a

Call it like so: g(15,'LLLWLLLL').

This simply loops through the string, changing the value of the money that we have based on the character.

Here is a sample program that runs tests on this function:

import random
def g(a,s,n=1):
for c in s:
if a>=n:a,n=((a+n,1),(a-n,2*n))[c<'W']
return a
for i in range(14):
s=''.join(('L','W')[random.randint(0, 1)] for e in range(random.randint(10, 15)))
print'g(%i,%s):'%(i,`s`),
print g(i,s)

With a little change to the tester, we can get the average profit of many runs:

import random
def g(a,s,n=1):
for c in s:
if a>=n:a,n=((a+n,1),(a-n,2*n))[c<'W']
return a
r=[]
for i in range(5000):
for i in range(1000):
s=''.join(('L','W')[random.randint(0, 1)] for e in range(random.randint(10, 15)))
r+=[i-g(i,s)]
a=0
for n in r:
a+=n
print float(a)/len(r)

Sample output (took quite a while, since we are calling the function 5000000 times):

-0.0156148

Edit: Thanks to Howard and Danny for further golfing.

EDIT: now the program checks for whether there is enough money to make the bet. This actually saves bytes.

Wouldn't if n<=a and save you some char since you won't have to break then?
–
DannyApr 24 '14 at 19:12

1

@Quincinx: No, < just means less than. Strings are ordered lexicographically, so 'L'<'W' returns True, which is interpreted as 1, while 'W'<'W' returns False, which is interpreted as 0.
–
isaacgApr 24 '14 at 19:15

J - 63 55 char

Now with the added bonus of not being incorrect! It's even exactly as long as before.

((+/\@,(0{<#[)_,~|@]);@('W'<@(2^i.@#);.1@,}:)*_1^=&'L')

Takes the starting amount of money as the left argument and the win/loss streak on the right.

Explanation: The program splits evenly into something like a composition of two functions, both detailed below. The first turns the win/loss streak into the values of the bets, with corresponding sign, and then the second actually figures out the answer given the initial money and this transformed win/loss streak.

Note that we prepend the money to the bets before taking the partial sums, but we append the infinite bet to the end of the list of bet values. This is what shifts the value of the account overtop of the next bet, and using infinity allows us to always have the last element as a catch-all.

function g(a,r,t=0,b=1){ // declare a function g with arguments a,r,t,b where
// t defaults to 0 and b defaults to 1
c = r[t]; // get the character in the win/loss string for the current
// round.
if ( a>=b // check if we have enough money
&& c ) // and if the string has not ended
{
if ( c > 'L' ) // check if we've won the round
{
return g(a+b,r,t+1,1); // if so call g again adding the winnings and resetting the
// cost.
} else {
return g(a-b,r,t+1,2*b); // otherwise, subtract from the total money and double the
// cost.
}
} else {
return a; // If we've run out of money or got to the end then return
// the current total.
}}

JavaScript (ECMAScript 6) - 6158 54 Characters (in function body)

(b=1, // Initialise the cost to 1
[ // for each character x of r using array comprehension
b=
b>a?b // if we have run out of money do b=b
:x>'L'?(a+=b,1) // else if we've won collect the winnings and reset b=1
:(a-=b,2*b) // else subtract the cost from the total money and double
// the cost for next round.
for(x of r)] // Repeat for each character
// array.
,a) // Finally, return a.

Python, 74 bytes

def g(a,r,b=1):
for l in r:
if l>"L":a+=b;b=1
else:a-=b;b*=2
return a

I defined function g which takes a (the amount of money you have at start) and r (which is the results of the bets)
It initializes the amount of the first bet at 1.
Then for each result of the bets, if it is a win ("W" in r) you gain the money and bet comes back to 1. Else you lose the amount of the bet, and the amount for the next bet doubles.
Finally it returns the money you have.
You can use it like this:

C, 107 characters

I'm using a recursive function here, because most of the time the implementation is shorter. But I'm not quite sure if it is the case here, because I needed to make an additional wrapper function so my function does in fact only take 2 arguments. The third argument in function f is needed for the current bet (the accumulator).

Without the wrapper function this solution would only be 73 characters long, but you would need to pass an additional parameter with the value 1 (the inital bet) to get the proper result.

g(20,'WLLW') returns 25 in my FireFox console - the for...in loop picks up three extra properties in the string and iterates over them as well.
–
MT0Apr 24 '14 at 20:04

@MT0 same thing happens in my Firefox console. However if I open a new private browsing window I get 22 in my console. Thinking maybe some site that your on when you have the console open modified the String prototype. I know stackexchange does modify it and add three extra functions.
–
DannyApr 24 '14 at 20:17

Python 2 – 65 bytes

Now beaten by the current best Python solution, but I cannot not share it:

def g(r,a,b=1):
if r>"">a>=b:a=g(r[1:],*[(a+b,1),(a-b,b*2)][r[0]<"W"])
return a

As some other Python solutions, I use the function arguments for declaring b outside the function definition, but as the function is recursive, this actually serves some purpose other than golfing here.

Instead of just posting those two links with the code, bring the explanations there over here.
–
QuincunxApr 24 '14 at 6:12

I'd love to man, and will edit in the AM. It was a hurry up and finish ordeal. I've not been active on SO in a while, bear with me as I accept that it's not in it's infancy anymore. :)
–
TheSoftwareJediApr 24 '14 at 6:41

According to your .NET Fiddle, you are taking your arguments backwards. Is this allowed?
–
QuincunxApr 24 '14 at 7:41

I'd made the function definition irrelevant to the solution in the question. The fiddle isn't part of the answer, just a way to execute it.
–
TheSoftwareJediApr 24 '14 at 13:55

Ruby, 84 characters

def g(a,r,n=1)
return a if !r[0]||n>a
s=r[1..-1]
r[0]<?M?g(a-n,s,n*2):g(a+n,s,1)
end

Same approach as my other answer in C, but I wanted to try ruby for Code-Golfing. The advantage to the C version is that I don't need to create a wrapper function, I can simply use the default values for parameters.

Python, 86

I know this is nowhere near the shortest solution, but I wanted to demonstrate a different approach, that iterates over loss streaks rather than individual bets. int(bin(a)[3:],2) gives the integer with the most significant bit from the binary representation of a deleted, which is the amount of money the person will have after losing increasing powers of 2 until he or she can no longer bet, because a is currently 1 higher than his or her actual amount of money. This version assumes the initial capital is positive.

C - 64 59 (Inside function)

Yet another C answer. It takes advantage of the fact that the value of the variable stays on the stack. So this my fail with some compilers, but it did work properly wherever I tested. Also, I took the %2 from tia to save a character. Sorry!