15
\$\begingroup\$

You have played \$N\$ matches in some game where each match can only result in one of the two outcomes: win or loss. Currently, you have \$W\$ wins. You want to have a win percentage of \$P\$ or more, playing as few matches as possible. Output the minimum win streak that you need. Assume the current win streak is at \$0\$.

For example: If \$N=10, W=2, P=50\$, then you can win \$6\$ matches in a row, bringing your win percentage to \$\frac{2+6}{10+6} = \frac{8}{16} = 50\%\$. You cannot have a win percentage of \$50\$ or more earlier than this. So the answer for this case is \$6\$.

Examples

W, N, P ->
2, 10, 50%      -> 6
3, 15, 50%      -> 9
35, 48, 0.75    -> 4
19, 21, 0.91    -> 2
9, 10, 50%      -> 0
0, 1, 1/100     -> 1
43, 281, 24/100 -> 33
0, 6, 52%       -> 7

Rules

  • \$N\$ and \$W\$ will be integers with \$0 \le W < N\$.
  • The percentage \$P\$ will be an integer between \$1\$ and \$100\$ inclusive. You can also choose to take a decimal value between \$0\$ and \$1\$ inclusive instead, which will contain no more than \$2\$ decimal places, or take it as a fraction.
  • You can take the inputs in any convenient format.
  • Standard loopholes are forbidden.
  • This is , so the shortest code in bytes wins.
\$\endgroup\$
1

21 Answers 21

9
\$\begingroup\$

Python 3, 35 bytes

lambda w,n,p:-min(0,(w-p*n)//(1-p))

Try it online!

-4 bytes thanks to pajonk

Some simple math: if \$X\$ is the number of wins we need, then we have:

\$\frac{W+X}{N+X}\geq P\$

\$W+X\geq PN+PX\$

\$X-PX\geq PN-W\$

\$X(1-P)\geq PN-W\$

Since \$P<1\$, then \$1-P>0\$, so we can divide from both sides without division by zero or flipping the sign.

\$X\geq\frac{PN-W}{1-P}\$

\$\endgroup\$
4
  • \$\begingroup\$ Since \$P<1\$ it would IMHO be clearer to write \$X\geq\frac{PN-W}{1-P}\$. \$\endgroup\$
    – Neil
    Apr 25, 2021 at 8:36
  • \$\begingroup\$ @Neil Ah, that's true. I think this is a bit clearer now. Thanks :) \$\endgroup\$
    – hyper-neutrino
    Apr 25, 2021 at 8:40
  • 2
    \$\begingroup\$ Shouldn't this work? Try it online! \$\endgroup\$
    – pajonk
    Apr 25, 2021 at 19:31
  • \$\begingroup\$ @pajonk It does seem to. Well spotted; thanks! \$\endgroup\$
    – hyper-neutrino
    Apr 25, 2021 at 19:35
4
\$\begingroup\$

05AB1E, 13 15 11 bytes

∞<.Δ¹+.«/²@

Try it online!

Why aren't I using Vyxal? Because I'm leaving the chance for others so they can claim the bounty.

+2 due to bug fix :(

but -4 thanks to @ovs

Explained (old)

∞0š.ΔD²+s¹+s/³@
∞0š.Δ            # get the first integer n where:
     D²+s¹+s/    #     (wins + n) / (matches + n)
             ³@  #     >= percentage 
\$\endgroup\$
2
  • \$\begingroup\$ Instead of prepending a 0 you can decrement every integer with <. \$\endgroup\$
    – ovs
    Apr 25, 2021 at 8:19
  • \$\begingroup\$ 11 bytes with a slightly different input format. \$\endgroup\$
    – ovs
    Apr 25, 2021 at 8:22
4
\$\begingroup\$

Jelly, 10 bytes

Ḣ_Ḣ×$÷’Ċ»0

Try it online!

Explanation

This uses the same formula as my Python answer: \$X\geq\frac{W-PN}{P-1}\$

Takes the input as a list of three numbers, \$W,N,P\$.

Ḣ_Ḣ×$÷’Ċ»0  Main Link
Ḣ           W (pops from the list)
 _          minus
  Ḣ×$       N (pops from the list) times the list (now only has P)
     ÷’     divided by (P - 1)
       Ċ    ceiling
        »0  maximum of that and 0

In-depth explanation

This is an even more in-depth explanation of this answer. If you are familiar with Jelly, you should probably skip this. I won't do these often.

Since this link is called with one argument each time, it is a monadic chain. Hence, as we walk down the chain, the following patterns are matched in this order: dyad-monad, dyad-nilad, nilad-dyad, dyad, and monad (nilads take 0 arguments; you can think of them as constants) (monads take 1 argument) (dyads take 2 arguments).

Since the link doesn't start with a nilad, the evaluation value starts equal to the argument, [W, N, P].

First, we see , a monad meaning "pop and return the first element". This matches the last rule, so it applies as a monad to the current value, which is [W, N, P]. Thus, the current value is now W, and this also modifies the left argument object itself to [N, P].

Here, it is important to note the function of $ - it takes the last two links and groups them into a monadic link. Here, the two links are and ×. We'll get back to this.

Next, we see _, a dyad (subtraction). It is followed by a monad, namely the one formed by the $ grouping two links, thus matching the first pattern. The dyad-monad pattern, if we have some dyad + and some monad F, computes v + F(a) where v is the current value and a is the right argument. Thus, this computes W - F([N, P]). Here, F(a) computes Ḣ× as a monadic chain whose argument is a = [N, P]. The value starts at v = [N, P] as well.

The first link is a monad and thus the value becomes N. Also, since "pop" mutates, the argument (to both the sub-link and the main link) is now [P]. Then, the second link is a dyad and nothing else follows, so the value becomes N × [P] which is [NP]. This is a singleton list, not a value, but that's fine because everything else vectorizes.

Now, the value is W - [NP] which vectorizes to [W - NP], and the argumnt is [P] since it was mutated within the sub-link.

÷’ is a dyad-monad chain, which computes [W - NP] ÷ P÷’. decrements, so this computes [W - NP] ÷ (P - 1), which vectorizes to [(W - NP) / (P - 1)].

Penultimately, Ċ is a monad meaning "ceiling", which just rounds all of these values up. Finally, »0 is a dyad-nilad chain which takes the maximum of this value and 0, thus preventing negative outputs.

Here's a shitty hand-drawn visualization of how chaining works out here:

enter image description here

\$\endgroup\$
3
  • \$\begingroup\$ And you're sure that a "find first n where" approach wouldn't be shorter? \$\endgroup\$
    – lyxal
    Apr 25, 2021 at 8:43
  • \$\begingroup\$ @Lyxal I can't say for sure that a solution of that form wouldn't be shorter, but I haven't found one yet. \$\endgroup\$
    – hyper-neutrino
    Apr 25, 2021 at 8:52
  • 1
    \$\begingroup\$ @Lyxal it's shorter \$\endgroup\$ Apr 25, 2021 at 17:20
4
\$\begingroup\$

R, 45 43 42 38 bytes

Edit: simultaneous discovery of -1 byte by Kirill L., and then -4 bytes thanks to pajonk

function(W,N,P)-min((W-P*N)%/%(1-P),0)

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ @KirilL Ha! I was just editing this in while you commented. You get half the credit! Thanks anyway! \$\endgroup\$ Apr 25, 2021 at 9:08
  • 1
    \$\begingroup\$ Shouldn't this work in principle? Try it online! \$\endgroup\$
    – pajonk
    Apr 25, 2021 at 19:27
  • \$\begingroup\$ @pajonk - Er, rather embarassing that I didn't spot that. Thanks. Do you want to just post it & be the winner? I feel rather ashamed... \$\endgroup\$ Apr 25, 2021 at 19:45
  • \$\begingroup\$ Nah, thanks - let's treat it the same as with the python answer :) \$\endgroup\$
    – pajonk
    Apr 26, 2021 at 6:08
3
\$\begingroup\$

PowerShell, 44 bytes

Every answer of Wasif inspires me to make the right one. Thanks.

param($w,$n,$p)for(;$w++/$n++-lt$p){$k++}+$k

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Clojure, 39 bytes

#(max(Math/ceil(/(-(* %2%)%3)(- 1%)))0)

Try it online!

Takes arguments in reverse order compared to the provided test cases (\$P, N, W\$).

\$\endgroup\$
3
\$\begingroup\$

Jelly, 9 bytes

0+÷/:⁴ʋ1#

Try it online!

Full program that takes [w, n] on the left and P on the right.

How it works

0+÷/:⁴ʋ1# - Main link. Takes [w, n] on the left and P on the right
      ʋ   - Previous 4 links as a dyad f(x, [w, n]):
 +        -   Yield [w+x, n+x]
  ÷/      -   Yield (w+x)÷(n+x)
     ⁴    -   Yield P
    :     -   Floor divide (w+x)÷(n+x) by P,
               returning 0 if P < (w+x)÷(n+x), and 1 otherwise
0      1# - Count up x = 0, 1, 2, ..., and find the first x such that f(x, [w, n]) is 1
\$\endgroup\$
2
\$\begingroup\$

PowerShell, 51 bytes

param($w,$n,$p)while(($w+$k)/($n+$k)-lt$p){$k+=1}$k

Try it online!

What? It beat my python answer? oO

\$\endgroup\$
2
\$\begingroup\$

Ruby, 34 bytes

->w,n,p{[0,-(w-p*n).div(1-p)].max}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Retina 0.8.2, 68 bytes

\d+
$*
\G1
100$*
1(?=1*,(1*)%)
$1
+`^(1*,)(1+\1(1+))
100$*1$1$3$2_
_

Try it online! Link includes test cases. Takes P as a percentage (including % sign). Explanation:

\d+
$*

Convert W, N and P to unary.

\G1
100$*

Multiply W by 100.

1(?=1*,(1*)%)
$1

Multiply N by P.

+`^(1*,)(1+\1(1+))

While 100W<NP...

100$*1$1$3$2_

increment W and N, i.e. add 100 to 100W and P to NP.

_

Count the number of increments made.

\$\endgroup\$
2
\$\begingroup\$

JavaScript, 44 40 34 bytes

f=(w,n,p)=>w/n>=p?0:f(w+1,n+1,p)+1

Takes all three parameters as integers except p which is a decimal.

-4 bytes, thanks to @DominicvanEssen -6 bytes, thanks to @Arnauld

Try it online

\$\endgroup\$
5
  • \$\begingroup\$ You can save 4 bytes by taking p as a fraction instead of a percentage... \$\endgroup\$ Apr 25, 2021 at 8:48
  • \$\begingroup\$ @DominicvanEssen Oh yeah that's right \$\endgroup\$
    – user100690
    Apr 25, 2021 at 8:49
  • \$\begingroup\$ 33 bytes, or 32 bytes if you don't mind returning false instead of 0. \$\endgroup\$
    – Arnauld
    Apr 25, 2021 at 9:13
  • \$\begingroup\$ 31 bytes by taking (p)(w,n). \$\endgroup\$
    – Arnauld
    Apr 25, 2021 at 9:21
  • \$\begingroup\$ @Arnauld I'll go with your 33 byte suggestion because I prefer its I/O formats. \$\endgroup\$
    – user100690
    Apr 25, 2021 at 10:18
2
\$\begingroup\$

Haskell, 37 bytes

(n,w)#p|100*w<p*n=1+(n+1,w+1)#p|1>0=0

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Pari/GP, 31 bytes

f(W,N,P)=-min(-(P*N-W)\(1-P),0)

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Python 3, 55 bytes

f=lambda w,n,p,c=0:(w+c)/(n+c)>=p and c or f(w,n,p,c+1)

Try it online!

Simple recursion, I am beaten by few minutes....

\$\endgroup\$
1
\$\begingroup\$

Charcoal, 24 bytes

NθNηNζ≔⁰εW‹⁺θε×ζ⁺ηε≦⊕εIε

Try it online! Link is to verbose version of code. Explanation:

NθNηNζ

Input W, N and P.

≔⁰ε

Start with X=0.

W‹⁺θε×ζ⁺ηε

Until we reach the desired win percentage...

≦⊕ε

... increment X.

Iε

Output X.

A port of @hyper-neutrino's solutions is of course much shorter at 13 bytes:

I⌈⟦⁰±÷⁻×NNN⊖θ

Try it online! Link is to verbose version of code. Takes input in the order P, N, W. Explanation:

        N       `P` as a number
       ×        Multiplied by
         N      `N` as a number
      ⁻         Subtract
          N     `W` as a number
     ÷          Floor divided by
           ⊖θ   `P` decremented
    ±           Negated
 ⌈⟦⁰            Maximum of that and 0
I               Cast to string
                Implicitly print
\$\endgroup\$
1
\$\begingroup\$

Japt, 11 bytes

@°*L¨V°*W}a

Try it

\$\endgroup\$
1
\$\begingroup\$

CSASM v2.4.0.1, 123 bytes

A function which pops three values from the stack ([N, W, P]) and pushes the result as an f64.
The function expects the types of all three values to be f64.

.include <stdmath>
func a:
pop $3
pop $2
pop $1
push $3
dup
push $2
swap
push $1
mul
sub
neg
swap
push 1.0
sub
div
neg
push 0.0
call max
ret
end

Explanation + Full Program:

.include <stdmath>

func main:
    ; Get the three inputs
    in "N: "
    conv f64

    in "W: "
    conv f64

    in "P: "
    conv f64

    call a

    ; Truncate the result and print it
    conv i32
    push "Wins needed: "
    swap
    add
    print.n

    ret
end

func a:
    pop $3 ; P
    pop $2 ; W
    pop $1 ; N

    push $3
    ; [ P ]
    dup
    ; [ P, P ]

    push $2
    ; [ P, P, W ]
    swap
    ; [ P, W, P ]
    push $1
    ; [ P, W, P, N ]
    mul
    ; [ P, W, P*N ]
    sub
    ; [ P, W-P*N ]
    neg
    ; [ P, P*N-W ]
    swap
    ; [ P*N-W, P ]
    push 1.0
    ; [ P*N-W, P, 1 ]
    sub
    ; [ P*N-W, P-1 ]
    div
    ; [ (P*N-W)/(P-1) ]
    neg
    ; [ -(P*N-W)/(P-1) ]
    push 0.0
    call max

    ret
end
```
\$\endgroup\$
1
\$\begingroup\$

Wolfram Language (Mathematica), 25 bytes

0//.x_/;x+#-##2<x#3:>x+1&

Try it online!

We can also directly compute the number of needed wins:

Wolfram Language (Mathematica), 25 bytes

⌈Min[#-##2,0]/--+#3⌉&

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Japt, 9 bytes

Takes P as a decimal.

@°/V°<W}f

Try it

\$\endgroup\$
1
\$\begingroup\$

JavaScript, 28 bytes

Takes P as a decimal and outputs false for 0.

w=>n=>g=p=>w++/n++<p&&g(p)+1

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Vyxal 2.4.1, 8 bytes

λ¹+ɖ⁰≥;ṅ

Try it Online! Here's what I managed to come up with. It doesn't seem like anyone else is going to give this a go using Vyxal, so here's my solution.

Explained

λ¹+ɖ⁰≥;ṅ
λ        # start a lambda that, given a single argument "n":
 ¹+      #     adds n to the list [wins, matches]
   ɖ     #     reduces that list by division
    ⁰≥;  #    and returns whether that number is greater than the percentage
       ṅ # take that lambda, and find the first integer (starting at 0) where it evaluates as truthy
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.