Incremental Betting

19

2

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:

  1. The first argument is an integer a which is the initial money we amount we have when we start the betting.
  2. 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.

Sample run

1st round - Loss: 15-1 = 14
2nd round - Loss: 14-2 = 12 (Bet doubles)
3rd round - Loss: 12-4 = 8
4th round - Win: 8 + 8 = 16
5th round - Loss:16-1 = 15 (Since the previous bet was a win, this bet has a value of 1 dollar)
6th round - Loss: 15-2 = 13
7th round - Loss: 13-4 = 9
8th round - Loss: 9-8 = 1

The function returns 1 in this case

The winner is determined by least number of characters INSIDE of the implied function definition. Cooperate by language if desired. I know mine can be improved!

TheSoftwareJedi

Posted 2014-04-24T05:08:43.350

Reputation: 1 275

All questions on this site must have an objective winning criterion. You didn't mention what determines the winner of the challenge.

– Howard – 2014-04-24T05:37:09.237

1Moreover, 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? – Howard – 2014-04-24T05:38:05.397

Also, if every tag you are using is one that you created just for the question, something is wrong. – Justin – 2014-04-24T05:59:43.753

1Judging 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. – Justin – 2014-04-24T06:08:39.907

@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. – TheSoftwareJedi – 2014-04-24T06:27:37.357

No problem. If you want a better reception, you can send your challenges through the sandbox first.

– Justin – 2014-04-24T06:29:01.560

What should happen if the function receives invalid input, e.g., f(-42,"LOL")? Can we assume that the initial amount of money will be positive? – Dennis – 2014-04-24T19:08:39.147

If after successive losses, I have 20 as an amount, and the value of the bet is 32. Now I win a bet. So, according to "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", should I stop and return 20 or add up 32(due to the win) to my account and continue with more losses/wins ? – Gaurang Tandon – 2014-04-25T04:25:01.787

@GaurangTandon You cannot play a round if you cannot afford to lose. If you have 20 and the bet is 32, you return 20. – TheSoftwareJedi – 2014-04-25T11:59:57.350

What you should really output, given a seed, is how many rounds it takes you to lose all your money =P. (i.e. Martingale betting doesn't work in the long run) – Claudiu – 2014-04-28T22:58:19.623

@TheSoftwareJedi so in the case of your sample output, the string parameter was "LLLWLLLL" correct? – WallyWest – 2014-06-05T23:35:18.527

@wallywest correct – TheSoftwareJedi – 2014-06-06T15:09:21.030

Answers

5

GolfScript, 33 characters

{
1\{2$2$<!{1&{+1}{:b-b.+}if.}*;}/;
}:g;

Examples (online):

> 13 'LLLWLLLL'
6
> 4 'LWWLWLWWWL'
9
> 5 'LLLWWWLLWLWW'
2
> 2 'LW'
1

Annotated code:

1\            # prepare stack a b r
{             # for each char in r
  2$2$<!{     #   if a>=b  
    1&        #     take last bit of character (i.e. 0 for L and 1 for W)
    {         #     if W
      +       #       a <- a+b
      1       #       b <- 1
    }{        #     else
      :b-     #       a <- a-b
      b.+     #       b <- 2*b
    }if       #     end if
    .         #     create dummy value
  }*          #   end if
  ;           #   drop (i.e. either the dummy or the character)
}/            # end for
;             # discard current bet value

Howard

Posted 2014-04-24T05:08:43.350

Reputation: 23 109

5

Python 2, 72 68 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)

Sample output:

g(0,'LLWWWWWWLWWWWW'): 0
g(1,'WLLWWWWWWWW'): 1
g(2,'WWWLLLWLLW'): 2
g(3,'LLLLWLWLWWWWLL'): 0
g(4,'LWWWWLWLWWW'): 12
g(5,'WWLWWLLWWW'): 12
g(6,'LLLWWWLLLLWLLWL'): 3
g(7,'WWLLWWLWLWLWLLL'): 7
g(8,'WLLLWWWWWLLWLL'): 2
g(9,'WWWLLWLLLLLWL'): 6
g(10,'LWWWWLLLWL'): 7
g(11,'WLLLLWLWWWW'): 5
g(12,'WLLWWLWWWL'): 17
g(13,'LLLWLLWLWLWLWW'): 6

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.

Justin

Posted 2014-04-24T05:08:43.350

Reputation: 19 757

Some minor savings: you may replace c=='L' with c<'W'=. You can also write b,n=((n,1),(-n,2*n))[c<'W'] which then saves you more chars (if a<-b:break,a+=b). – Howard – 2014-04-24T06:51:27.673

@Howard Hmm. I tried the b,n= trick (with [s on the outside), but python complained. Let's try again. – Justin – 2014-04-24T07:06:58.417

Strange, have a look here.

– Howard – 2014-04-24T07:34:14.137

@Howard Ah, that's what the c<'W' does. < is a strange python syntax for "is in" – Justin – 2014-04-24T07:43:20.313

I think your function yields the wrong result for 2 LW. It assumes you can place a bet for winning but you actually don't have enough money. – Howard – 2014-04-24T09:06:12.387

@Howard fixed, and it saves bytes :-) – Justin – 2014-04-24T17:50:42.760

1Wouldn't if n<=a and save you some char since you won't have to break then? – Danny – 2014-04-24T19:12:28.617

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. – isaacg – 2014-04-24T19:15:05.893

4

R, 95 characters

g=function(a,r){n=1;for(i in 1:nchar(r)){s=substr(r,i,i);if(s=='L'){a=a-n;n=n*2}else{a=a+n;n=1};if(n>a)break};a}

Indented:

g=function(a,r){
    n=1
    for(i in 1:nchar(r)){
        s=substr(r,i,i)
        if(s=='L'){
            a=a-n
            n=n*2
            }else{
                a=a+n
                n=1
                }
        if(n>a)break
        }
    a
    }

Usage:

> g(15,'LLWLLLL')
[1] 1
> g(20,'WLLW')
[1] 22
> g(13,'LLWLLLLWWLWWWLWLWW')
[1] 7

plannapus

Posted 2014-04-24T05:08:43.350

Reputation: 8 610

3

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.

;@('W'<@(2^i.@#);.1@,}:)*_1^=&'L'   NB. win/loss as sole argument
                         _1^=&'L'   NB. -1 for every L, +1 for W
      <@(      );.1                 NB. split vector into streaks:
   'W'              ,}:             NB.  cut on wins, shift right by 1
         2^i.@#                     NB. for each, make doubling run
;@(                    )*           NB. unsplit, multiply by signs

(+/\@,(0{<#[)_,~|@])   NB. money on left, above result on right
                |@]    NB. absolute value of bets 
             _,~       NB. append infinity to end
 +/\@,                 NB. partial sums with initial money
      (  <  )          NB. 1 whenever money in account < bet
          #[           NB. select those money values corresp. to 1s
       0{              NB. take first such item

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.

Usage:

   15 ((+/\@,(0{<#[)_,~|@]);@('W'<@(2^i.@#);.1@,}:)*_1^=&'L') 'LLLWLLLL'
1
   NB. naming for convenience
   f =: ((+/\@,(0{<#[)_,~|@]);@('W'<@(2^i.@#);.1@,}:)*_1^=&'L')
   20 f 'WLLW'
22
   2 f 'LW'
1
   13 f 'LLWLLLLWWLWWWLWLWW'
7
   12 13 14 15 28 29 30 31 (f"0 _) 'LLWLLLLWWLWWWLWLWW'  NB. for each left argument
6 7 0 1 14 15 39 40

algorithmshark

Posted 2014-04-24T05:08:43.350

Reputation: 8 144

2I tested your code and it also returns 3 for the test case 2 LW. Unfortunately after the first loss you don't have enough money to even bet for the second run. – Howard – 2014-04-24T09:51:45.833

With 14 f 'LLWLLLLWWLWWWLWLWW', we get this sequence: 14, 13, 11, 15, 14, 12, 8, 0,.. at the 0, we don't have enough money to bid, so the program should output 0. – Justin – 2014-04-24T17:48:34.977

Is this code is correct now? I need to designate a winner and don't have a J compiler (nor time to start the experience). – TheSoftwareJedi – 2014-04-25T12:01:40.733

@TheSoftwareJedi Yes, it is correct. There is actually an online Javascript version of the J interpreter, now, that you can try at tryj.tk.

– algorithmshark – 2014-04-25T12:21:22.600

Now the dilemma, does Golfscript count?! – TheSoftwareJedi – 2014-04-25T14:19:18.197

@TheSoftwareJedi Why wouldn't it? – algorithmshark – 2014-04-25T14:53:33.533

3

JavaScript (ECMAScript 6 Draft) - 62 51 50 Characters (in function body)

function g(a,r,t=0,b=1)
a>=b&&(c=r[t])?g((c=c>'L')?a+b:a-b,r,t+1,c||2*b):a

Defines a recursive function g with two arguments:

  • a - the current amount of money you have; and
  • r - the string of wins/losses.

And two optional arguments:

  • t - the index of the current round of betting (initially 0)
  • b - the amount of money for the current bet (again initially 1).

Ungolfed:

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) - 61 58 54 Characters (in function body)

function g(a,r)
(b=1,[b=b>a?b:x>'L'?(a+=b,1):(a-=b,b*2)for(x of r)],a)

Explanation:

(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.

Tests

console.log(g(0,'LLLLLWWLWWLW')) // 0
console.log(g(1,'WWWLLLWWWWLLWW')) //1
console.log(g(2,'LLWLWWWWWWWL')) //1
console.log(g(3,'WWWWWWWLLLWL')) //3
console.log(g(4,'LWWLWLWWWL')) //9
console.log(g(5,'LLLWWWLLWLWW')) //2
console.log(g(6,'LWLLLLWWLWWW')) //0
console.log(g(7,'WWLWWLLLWLWLW')) //4
console.log(g(8,'WWLWWLLWLWL')) //13
console.log(g(9,'WWWLLLWLLWLWWW')) //5
console.log(g(10,'WLWLLWWWWWWWL')) //18
console.log(g(11,'WLWLWLWLLLWLLW')) //17
console.log(g(12,'WWLWWWLLWL')) //17
console.log(g(13,'WWWWLWLWWW')) //21
console.log(g(15,'LLLW')) //16
console.log(g(15,'LLLL')) //0
console.log(g(14,'LLLL')) //7
console.log(g(2,'LW')) //1
console.log(g(2,'LL')) //1
console.log(g(2,'WLL')) //0

MT0

Posted 2014-04-24T05:08:43.350

Reputation: 3 373

You can save 3 bytes changing b=1,r.split('').map( to [b=1].map.call(r, – nderscore – 2014-04-24T21:02:19.530

Thanks, I'd not considered manipulating the String directly like that. – MT0 – 2014-04-24T22:54:42.947

Chop another 4 bytes using array comprehension :) (b=1,[b=b>a?b:x>'L'?(a+=b,1):(a-=b,b*2)for(x of r)],a) – nderscore – 2014-04-25T17:18:00.217

-1 byte: a>=b&&(c=r[t])?g((c=c>'L')?a+b:a-b,r,t+1,c||2*b):a – nderscore – 2014-04-27T18:00:54.643

1

Java, 95 bytes (inside function)

int b=1;for(int c:r.getBytes()){if(m-b<0)return m;if(c<87){m-=b;b*=2;}else{m+=b;b=1;}}return m;

Try it online!

Benjamin Urquhart

Posted 2014-04-24T05:08:43.350

Reputation: 1 262

1

C#, 123

return q.Aggregate(new{b=1,c=w,x=1},(l,o)=>l.x<0?l:o=='W'?new{b=1,c=l.c+l.b,x=1}:new{b=l.b*2,c=l.c-l.b,x=l.c-l.b-l.b*2}).c;

The .NET Fiddle

A blog post explaining

TheSoftwareJedi

Posted 2014-04-24T05:08:43.350

Reputation: 1 275

Instead of just posting those two links with the code, bring the explanations there over here. – Justin – 2014-04-24T06:12:55.263

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. :) – TheSoftwareJedi – 2014-04-24T06:41:03.140

According to your .NET Fiddle, you are taking your arguments backwards. Is this allowed? – Justin – 2014-04-24T07:41:24.047

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. – TheSoftwareJedi – 2014-04-24T13:55:24.953

1

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:

print g(20,"WLLW") # 22
print g(15,"LLLWLLLL") # 1

I think this can be golfed furthermore.

Guestar

Posted 2014-04-24T05:08:43.350

Reputation: 11

This is basically a duplicate of http://codegolf.stackexchange.com/a/26238/9498.

– Justin – 2014-04-24T07:07:51.617

1

C, 107 characters

f(int a,char*r,int n){return*r&&n<a?*r<77?f(a-n,r+1,n*2):f(a+n,r+1,1):a;}g(int a, char*r){return f(a,r,1);}

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.

ungolfed:

f(int a,char*r,int n){
    return *r&&n<a
                ?*r<77
                    ?f(a-n,r+1,n*2)
                    :f(a+n,r+1,1)
                :a;
}
g(int a,char*r){
    return f(a,r,1);
}

MarcDefiant

Posted 2014-04-24T05:08:43.350

Reputation: 996

1

Ruby, 76 64 (in function body) bytes

EDIT : improved the answer by removing 3 bytes :

n=1;r.each_char{|c|;c>'L'?(a+=n;n=1):(a-=n;n*=2);break if n>a};a



using func (82 bytes) :

def g(a,r);n=1;r.each_char{|c|;c>'L'?(a,n=a+n,1):(a,n=a-n,n*2);break if n>a};a;end

using lambda (76 bytes) :

g=->a,r{n=1;r.each_char{|c|;c>'L'?(a,n=a+n,1):(a,n=a-n,n*2);break if n>a};a}

the run :

p g.call(15, 'LLLWLLLL') # 1
p g.call(20, 'WLLW') # 22
p g.call(13, 'LLWLLLLWWLWWWLWLWW') # 7

onionpsy

Posted 2014-04-24T05:08:43.350

Reputation: 201

1

C, 90

g(int a,char*r){int c=1;while(*r){*r++%2?c=1,a++:(c*=2);if(c>a){c/=2;break;}}return++a-c;}

tia

Posted 2014-04-24T05:08:43.350

Reputation: 745

1

Javascript, 63

function g(a,s){x=1;for(i in s)if(x<=a)s[i]>'L'?(a+=x,x=1):(a-=x,x*=2);return a}

Sample runs:

console.log(g(15, 'LLLWLLLL'));  //1
console.log(g(20, 'WLLW'));  //22
console.log(g(13, 'LLWLLLLWWLWWWLWLWW')); //7

JSFiddle w/ logging

Ungolfed:

function g(a,s){
  x=1;                //bet starts at 1
  for(i in s)         //loop through win/lose string
    if(x<=a)          //check if we still have money to bet
      s[i]>'L'?
        (a+=x,x=1):   //win: add the bet amount to your total, and reset bet to 1
        (a-=x,x*=2);  //lose: subtract the bet amount from your total, and double your bet
  return a            //return your money
}

Danny

Posted 2014-04-24T05:08:43.350

Reputation: 1 563

1

Javascript (ES5) 69 64 60 bytes within function

function g(a,r){b=1;for(i in r)b=b>a?b:r[i]>'L'?(a+=b,1):(a-=b,b*2);return a}

Variation: (same length)

function g(a,r,b){for(i in r)b=b?b>a?b:r[i]>'L'?(a+=b,1):(a-=b,b*2):1;return a}

Test cases: (taken from plannapus's solution)

g(15,'LLWLLLL'); // 1
g(20,'WLLW'); // 22
g(13,'LLWLLLLWWLWWWLWLWW'); // 7

nderscore

Posted 2014-04-24T05:08:43.350

Reputation: 4 912

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. – MT0 – 2014-04-24T20:04:21.627

@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. – Danny – 2014-04-24T20:17:04.787

For some reason, it doesn't happen with a new tab: http://i.imgur.com/BgSUSIe.png

– nderscore – 2014-04-24T20:18:41.677

1

Golfscript, 51 41 36 35 bytes

Inner function

1\{@2$-@2*@(1&{@@+1@}*.3$3$<!*}do;;

This assumes that we start with a positive amount of money and that the win-loss string will be non-empty, so that at least one bet can be performed.

Example

{
  # Push initial bet amount.
  1\
  # STACK: Money Bet Outcomes
  {
    # Subtract bet amount from money.
    @2$-
    # STACK: Bet Outcomes Money
    # Double bet amount.
    @2*
    # STACK: Outcomes Money Bet
    # Remove first character from win-loss string and check if its ASCII code is odd.
    @(1&
    # STACK: Money Bet Outcomes Boolean
    # If it is, we've won, so add the doubled bet amount to the money and push 1 as the
    # new bet amont.
    {@@+1@}*
    # STACK: Money Bet Outcomes
    # Duplicate win-loss string, bet amonut and money.
    .3$3$
    # STACK: Money Bet Outcomes Outcomes Bet Money
    # If the next bet amount is less than our money and the win-loss string is not empty,
    # repeat the loop.
    <!*
    # STACK: Money Bet Outcomes Boolean
  }do
  # STACK: Money Bet Outcomes
  ;;
  # STACK: Money
}:f                                      # Define function.

];                                       # Clear stack.

20 'WLLW'               f
2  'LW'                 f
13 'LLWLLLLWWLWWWLWLWW' f
14 'LLWLLLLWWLWWWLWLWW' f

]p                                       # Print results as array.

gives

[22 1 7 0]

Try it online.

Dennis

Posted 2014-04-24T05:08:43.350

Reputation: 196 637

1

Haskell, 62

g a=fst.foldl(\(t,b)l->if l=='W'then(t+b,1)else(t-b,2*t))(a,1)

or with both arguments named (65 chars):

g a r=fst$foldl(\(t,b)l->if l=='W'then(t+b,1)else(t-b,2*t))(a,1)r

Note that g a r = 1 + a + the number of Ws in r + the number of trailing Ls in r (69):

g a r=a+1+l(filter(=='W')r)-2^l(takeWhile(/='W')(reverse r))
l=length

Zaq

Posted 2014-04-24T05:08:43.350

Reputation: 1 525

This is only a partial solution. It doesn't cover the case when the player runs out of money. – Petr Pudlák – 2014-04-26T17:54:50.930

There are a lot of solutions to this problem which allow the bettor to be in the negative. The problem never stated that you had to check whether this was the case. – Zaq – 2014-04-26T23:09:43.697

@zaq Actually yes, the question explicitly stated that was the case. – TheSoftwareJedi – 2014-06-06T16:02:50.293

1

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.

I also needed to change the order of the function arguments in order for the tuple unpacking into function arguments to work.

In case you wonder, r>"">a>=b is short for r and a>=b.

Wrzlprmft

Posted 2014-04-24T05:08:43.350

Reputation: 2 772

1

C#, 74 characters inside method

My very first attempt on this site...

int b=1;foreach(var c in r)if(b<=a){a+=c>'L'?b:-b;b=c>'L'?1:b*2;}return a;

Or, more readable:

int bet = 1;
foreach (var chr in r)
{                       // these brackets are left out in short version
   if (bet <= a)
   {
       a += chr > 'L' ? bet : -bet;
       bet = chr > 'L' ? 1 : bet * 2;
   }
}
return a;

Pretty naive, not that many tricks... mainly taking advantage of char being ordinal and string being enumerable. Saving a few characters by extraneous looping when player runs out of money.

JimmiTh

Posted 2014-04-24T05:08:43.350

Reputation: 441

0

Japt, 38 bytes

V¬r@Z=WX<Z?X:Y¶'L?W=ZÑX-Z:(W=1X+Z}UW=1

Try it

Probably needs some golfing :) But it seems to getting correct results.

NOTE This is a full program that is trivial to turn into a function by prepending UV{. The byte count inside the function will be the same.

Transpiled JS Explained:

// V: input string of W's and L's
V
  // split V into an array of characters
  .q()
  // reduce
  .r(function(X, Y, Z) {
    return
      // W contains the current bet,
      // save it to a temp variable Z
      Z = W,
      // do we have enough to bet?
      X < Z
        // not enough to bet, return the previous amount
        ? X
         // we can bet, did we lose this round
         : Y === "L"
           // we lost, increment bet and decrease holdings
           ? (W = Z * 2, X - Z)
           // we won, reset bet and increase holdings
           : (W = 1, X + Z)
   },
   // U: initial holdings
   U,
   // initialize bet to 1
   W = 1
 )

dana

Posted 2014-04-24T05:08:43.350

Reputation: 2 541

35 bytes? – Shaggy – 2019-03-25T11:56:27.707

This question has kind of a strange requirement that you must write a "function". I probably should translate my answer to a function, but I am thinking some of the extra bytes are needed. This would probably be ok though: https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&code=VqxyQD1XWDxVP1g6WbYnTD9XPVXRWC1VOihXPTFYK1V9VVc9MQ==&input=NQonTExMV1dXTExXTFdXJw==

– dana – 2019-03-25T13:22:28.353

0

PowerShell, 68 81 bytes

param($n,$s)$w=1;$s|% t*y|%{if($n-ge$w){$n+=(-$w,$w)[$_%2];$w/=(.5,$w)[$_%2]}};$n

Try it online!

This challenge needs some very awkward assignments meaning I couldn't chain together one big update. It does use the fact that 'W' is 87 in ASCII and 'L' is 76 so modding by 2 gives you access to easy true/false values. |% t*y is the standard toCharArray shortcut and updating the wager using division turned out to be the cheapest way I could find (divides it either by a half on a loss (doubling it), or divides it by itself on a win (setting it to 1)).

Plus many bytes because I missed constraint. Will work on golfing down the patch

Veskah

Posted 2014-04-24T05:08:43.350

Reputation: 3 580

0

05AB1E, 19 bytes

vDX@iy'WQiX+1UëXxU-

Port of @Howard's GolfScript answer, so make sure to upvote him as well!

Note that 05AB1E has no functions, so this is a full program instead.
Takes the string input first, and the integer input second (newline delimited in STDIN).

Try it online or verify some more test cases.

Explanation:

v               # Loop over each character `y` of the (implicit) input-string:
 D              #  Duplicate the current integer
                #  (which is the implicit input-integer in the first iteration)
  X@i           #  If the integer is larger than or equal to variable `X`:
                #  (NOTE: variable `X` is 1 by default)
     y'WQi     '#   If the current character `y` is a 'W':
          X+    #    Increase the integer by `X`
          1U    #    And reset variable `X` to 1
         ë      #   Else (the current character `y` is an 'L' instead):
          X  -  #    Decrease the integer by `X`
           xU   #    And set variable `X` to double its current value
                # (the integer at the top of the stack is implicitly output after the loop)

Kevin Cruijssen

Posted 2014-04-24T05:08:43.350

Reputation: 67 575

0

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.

MarcDefiant

Posted 2014-04-24T05:08:43.350

Reputation: 996

0

K, 76

g:{x+/-1_last'{(,1_*x),(("LW"!/:((2*;{1});(-:;::)))@\:**x)@\:x 1}\[(y;1;0)]}

.

k)g[15;"LLLWLLLL"]
1
k)g[20;"WLLW"]
22
k)g[50;"WLLLWLWLWLWLW"]
56

tmartin

Posted 2014-04-24T05:08:43.350

Reputation: 3 917

0

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!

f(int s,char*r){
    int a=1;
    for(;*r&&(*r++%2?s+=a,a=1:s<a?0:(s-=a,a*=2)););
    a=s;
}

Allbeert

Posted 2014-04-24T05:08:43.350

Reputation: 489

0

Python, 86

def y(a,s):
 for l in s.split('W'):
    a+=1;k=2**len(l)
    if k>a:return int(bin(a)[3:],2)
 return a-k

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.

isaacg

Posted 2014-04-24T05:08:43.350

Reputation: 39 268

0

Batch - 212

@echo off&setlocal enabledelayedexpansion&set r=%2&set a=%1&set c=1&powershell "&{'%2'.length-1}">f&set/pl=<f
for /l %%a in (0,1,%l%)do if "!r:~%%a,1!"=="L" (set/aa-=!c!&set/ac*=2) else set/aa+=!c!&set c=1
echo %a%

Expample -

H:\uprof>bet.bat 15 LLLWLLLL
1

unclemeat

Posted 2014-04-24T05:08:43.350

Reputation: 2 302