g | x | w | all
Bytes Lang Time Link
167Python 2250111T013410ZLucenapo
075JavaScript V8250111T025253ZWeird Gl
124Gawk250303T040555ZBraden C
105AWK250303T154105Zxrs
694Bespoke250120T015252ZJosiah W
064Julia 1.0250119T213120ZMarcMush
017Jelly250111T183610Zlolad
064JavaScript ES6250111T192138ZArnauld
02305AB1E250113T134414ZKevin Cr
017Jelly250112T221918ZJonathan
036APLNARS250112T195108ZRosario
5958Ruby250111T201541ZLevel Ri

Python 2, 170 169 167 bytes

Q=[0,0]
from fractions import*
def w(s):Q[0]+=s
def c(s):Q[1]+=s
def d(s):
 t=sum(Q)
 if s<t:r=Fraction(t-s,t);Q[0]*=r;Q[1]*=r
 else:Q[:]=0,0
input()
print Q[1]/sum(Q)

Try it online!

JavaScript (V8), 83 80 77 76 75 bytes

(s,T,d=i=>i<T?w(-i,C-=C/T*i):C=T=0)=>!d(w=i=>T+=i,c=i=>w(i,C+=i))/eval(s)*C

Try it online!

-2 bytes thanks to l4m2

This is probably not perfect, but I'm satisfied with it.

Gawk, 219, 124 Bytes

-95 thanks to @manatwork

{for(i=1;n=$i;i++){gsub(/[^0-9]/,"",n);if($i~/w/)P=P*T/(T+=n);else if($i~/c/)P=(P*T+n)/(T+=n);else T>=+n?T-=n:T=P=0}print P}

Takes input almost as specified in the statement of the problem, except that the operations should be separated by spaces. For example: w(10) c(10) d(5).

An easier to read version is

{
        for(i=1;n=$i;i++) {
                gsub(/[^0-9]/,"",n);
                if($i~/w/)
                        P=P*T/(T+=n);
                else if($i~/c/)
                        P=(P*T+n)/(T+=n);
                else T>=+n?T-=n:T=P=0
        }
        print P
}

AWK, 105 bytes

{for(;i++<NF;t=c+w){y=$(i+1);$i~/c/&&c+=y;$i~/w/&&w+=y;if($i~/d/){y>t&&c=w=0;c-=c*y/t;w-=w*y/t}}}1,$0=c/t

To test:

awk -F FS=",|\\\(|\\\)" '{for(;i++<NF;t=c+w){y=$(i+1);$i~/c/&&c+=y;$i~/w/&&w+=y;if($i~/d/){y>t&&c=w=0;c-=c*y/t;w-=w*y/t}}}1,$0=c/t' <<< "c(10),d(5),w(5),d(5),w(5),d(5),w(5),d(5)"

Bespoke, 694 bytes

PUSH I
CONTROL DOWHILE
DO COPY
INPUT N
STACKTOP PRODUCTOF
PUSH I H V
STACKTOP PLUS
PUSH I H SV
DO COPY
INPUT N
STACKTOP PRODUCTOF
PUSH BI H V
STACKTOP PLUS
DO COPY
PUSH BI H SV
PUSH I H V
STACKTOP PLUS
DO COPY
PUSH TRI DO COPYN
INPUT N
STACKTOP PRODUCTOF
STACKTOP MINUS
DO COPY
PUSH TRI H V
STACKTOP LT
CONTROL IF
STACKTOP F
CONTROL END
DO COPY
PUSH I H V
STACKTOP PRODUCTOF
PUSH I H SV
PUSH BI H V
STACKTOP PRODUCTOF
PUSH BI H SV
DO COPY
PUSH I STACKTOP LT
CONTROL IF
STACKTOP F
CONTROL END
STACKTOP PRODUCTOF
PUSH TRI H V
INPUT CH
STACKTOP LT
CONTROL END
PUSH BI H V
PUSH I H V
DO COPY
OUTPUT N
PUT XX:TRI BI;OUTPUT CH
STACKTOP PLUS
OUTPUT N

(I didn't have time to turn this into a poem.)

This was interesting to figure out in Bespoke, because the only datatype is the signed arbitrary-precision integer. So I basically juggle around numerators and denominators to make this work.

Input is in the form of groups of 3 space-delimited numbers, in the order \$c, w, d\$ (e.g. c(7),w(1),d(7),w(1) = 7 0 0 0 1 0 0 0 7 0 1 0). Output is in the form n d, where n is the numerator of the result, and d is the denominator.

Julia 1.0, 64 bytes

!s=s[1]+s[2]
>(s,l,L...)=s+l-min(1,1/!s*l[3])s>L...
>(s)=s[2]/!s

Try it online!

takes input as triplets [water,coffee,drink] with false as default, eg:

w(1),c(2),d(3) => [1,false,false],[false,2,false],[false,false,3]

it is needed for 1/0*false == 0

Jelly, 24 23 17 bytes

Ṫ÷S}C0»×+⁸µ@ƒ0Ä÷/

Try it online!

Thanks to Jonathan Allan for -6 bytes, and for the TIO auto-formatting footer

Input is a list of lists, where each row is a 3-tuple [coffee, water, drink]. The index corresponding to the action contains its parameter, while the others are zero. For example,

w(10),c(15) -> [[0,10,0],[15,0,0]]

State is stored as \$(c,w)\$, where \$c\$ is coffee and \$w\$ is water. Given an input row \$(\gamma, \omega, \delta)\$, where only one of \$\gamma\omega\delta\$ is nonzero, there are three possiblities:

Note that \$\delta=0\implies k=1\$, and \$\gamma,\omega\$ work independently of each other. So we can apply all 3 operations at once, calculating new state \$(kc+\gamma,kw+\omega)\$.

Ṫ÷S}C0»×+⁸µ@ƒ0Ä÷/             Main monadic link taking
                               input matrix and returning
                               coffee %

Ṫ÷S}C0»×+⁸                    Dyadic chain taking (𝛾,𝜔,𝛿) and (c,w),
                               calculating state update:
Ṫ                              𝛿
 ÷S}                            ÷the sum c+w = V
    C                          1-𝛿÷V = k
     0»                        k=max(k,0)
       ×                       calculate (kc,kw)
        +⁸                     and add (𝛾,𝜔), giving (kc+𝛾,kw+𝜔)
                               - 𝛿 was implicitly popped earlier

          µ                   Monadic chain on input:
           @ƒ0                Loop through instructions:
           @ƒ                  Reduce through input
                               with args reversed,
                               calling previous chain
             0                 and using [0,0] as initial state

              Ä÷/             Calculate final coffee %
                               from (c,w):
              Ä                Cumulative sum giving (c,w+c)
               @/              reduce by division
                               giving c/(w+c)

JavaScript (ES6), 64 bytes

Expects a list of actions as pairs: [0,n] for adding water, [1,n] for adding coffee, [-1,n] for drinking.

a=>a.map(([t,n])=>(c+=~t?t*n:(n=n<s?-n:-s)*c/s,s+=n),s=c=0)&&c/s

Try it online!

Commented

a =>                // a[] = input list of actions
a.map(              // for each action in a[] ...
([t, n]) =>         // ... with type t and quantity n:
  (                 //
    c +=            //   update the coffee quantity:
      ~t ?          //     if we're not drinking:
        t * n       //       add n if t = 1, 0 otherwise
      :             //     else:
        (           //
          n =       //       update n:
            n < s ? //         if n is less than s:
              -n    //           use -n
            :       //         else:
              -s    //           use -s
        ) * c / s,  //       multiply by the current coffee ratio
    s += n          //   update the total quantity
  ),                //
  s = c = 0         //   start with s = 0 and c = 0
)                   // end of map()
&& c / s            // return the final coffee ratio

05AB1E, 23 bytes

Îvy+ćUÐO/X*-Dd*0š}DO/Ås

Input as a list of triplets in the order \$[d,c,w]\$.

Try it online or verify all test cases.

Explanation:

Î            # Push 0 and the input-list of triplets
 v           # Pop and loop over each triplet
             #   STACK first iteration:  0
             #   STACK later iterations: [0,C,W]
  y+         #  Add the current triplet [d,c,w] to this triplet:
             #   STACK first iteration:  [0+d,0+c,0+w] → [d,c,w]
             #   STACK later iterations: [0+d,C+c,W+w] → [d,C+c,W+w]
    ć        #  Extract head; push first item and remainder-list separately
             #   STACK: d,[C,W]
     U       #  Pop and store this d in variable `X`
             #   STACK: [C,W]
      Ð      #  Triplicate pair [C,W]
             #   STACK: [C,W],[C,W],[C,W]
       O     #  Pop one copy, and sum it
             #   STACK: C+W,[C,W],[C,W]
        /    #  Pop another copy and this sum, and divide each
             #   STACK: [C/(C+W),W/(C+W)],[C,W]
         X*  #  Multiply each by `X` (extracted value `d`)
             #   [C/(C+W)*d,W/(C+W)*d],[C,W]
           - #  Subtract
             #   STACK: [C-C/(C+W)*d,W-W/(C+W)*d]
  Dd*        #  Make negative values 0:
  D          #   Duplicate the pair
             #    STACK: [C-C/(C+W)*d,W-W/(C+W)*d],[C-C/(C+W)*d,W-W/(C+W)*d]
   d         #   Pop the copy, and do an >=0 check for both
             #    STACK: [C-C/(C+W)*d>=0,W-W/(C+W)*d>=0],[C-C/(C+W)*d,W-W/(C+W)*d]
    *        #   Multiply
             #    STACK: [(C-C/(C+W)*d)*(C-C/(C+W)*d>=0),(W-W/(C+W)*d)*(W-W/(C+W)*d>=0)]
     0š      #  Prepend 0 to this pair, for the d of the next iteration
             #   STACK: [0,(C-C/(C+W)*d)*(C-C/(C+W)*d>=0),(W-W/(C+W)*d)*(W-W/(C+W)*d>=0)]
 }D          # After the loop: duplicate the resulting triplet
             #  STACK: [0,C,W],[0,C,W]
   O         # Sum this copy
             #  STACK: C+W,[0,C,W]
    /        # Divide all three values by this
             #  STACK: [0/(C+W),C/(C+W),W/(C+W)]
     Ås      # Pop and leave just the middle value
             #  STACK: W/(C+W)
             # (which is output implicitly as the result)

Jelly,  19  17 bytes

-2 golfing to an inline version after finding golfs to lolad's Jelly answer.

S⁹÷ṪC0»×⁸+Ṗµƒ0Ä÷/

A monadic Link that accepts a list of instructions and yields the ratio. Each instruction is a list of three non-negative integers, [Coffee, Water, Drink] of which two are zero.

Try it online! Or see the test-suite (translates from the format of the examples and shows input and output).

How?

S⁹÷ṪC0»×⁸+Ṗµƒ0Ä÷/ - Link: Instructions
           µƒ0    - starting with CurrentState=zero reduce {Instructions} with:
S                 -   sum {CurrentState}
                      -> TotalLiquid
 ⁹÷               -   {Instruction} divided by {TotalLiquid} (vectorises)
   Ṫ              -   tail {that}
                      -> DrinkVolume/TotalLiquid
    C             -   complement {that}
                      -> 1-DrinkVolume/TotalLiquid
     0»           -   zero max {that}
                      -> max(0, 1-DrinkVolume/TotalLiquid)
       ×⁸         -   multiply {that} by {CurrentState} (vectorises)
                      -> [CoffeePostDinking, WaterPostDrinking]
         +        -   {that} add {Instruction}
                      -> [TotalCoffee, TotalWater, DrinkVolume]
          Ṗ       -   pop {that}
                      -> NewState = [TotalCoffee, TotalWater]
              Ä   - cumulative sums
                    -> [TotalCoffee, TotalLiquid]
               ÷/ - reduce by division
                    -> TotalCoffee/TotalLiquid

APL(NARS), 36 chars

w←c←0

d h
(w c)×←0⌈1-h÷w+c

w+←
c+←
c÷w+c

// 5+4+16+3+3+5 It use the global varibles w and c the function d and the function sum to w and sum to c, and the calculus for show the result c÷w+c.

The bottle is rapresented from 2 variables, the one I put the coffee c and the one I put the water w so c÷w+c would be the concentration of coffee in the bottle. It is easy add water in the bottle or add coffee, just increment the rispettive variable c or w by some number. The problem is the function drink from the bottle... This is the function before all semplifications was as:

(w_new c_new)←(h-⍨w+c)×(w c)÷w+c

what I thought was one way to make proportion of w and c each other not change before the drink, and after the drink for new quantities in c_new and w_new where c_new+w_new=(h-⍨w+c). This last speech is not for sure...

test:

  w←c←0⋄w+←10⋄c÷w+c
0
  w←c←0⋄w+←10⋄c+←20⋄d 50⋄w+←10⋄c÷w+c
0
  w←c←0⋄c+←10⋄d 5⋄w+←5⋄d 5⋄w+←5⋄d 5⋄w+←5⋄d 5⋄c÷w+c
0.125
  w←c←0⋄c+←7⋄w+←1⋄d 7⋄w+←1⋄c÷w+c
0.4375
  w←c←0⋄w+←10⋄c+←15⋄c÷w+c
0.6
  w←c←0⋄c+←10⋄c÷w+c
1
  w←c←0⋄w+←10⋄c+←10⋄d 10⋄c÷w+c
0.5
  w←c←0⋄w+←10⋄c+←10⋄d 10⋄c+←10⋄c÷w+c
0.75

Ruby, 61 59 (or 58) bytes

->z{v=c=0.0
z.map{|a,q|a<2?c=(c*v+a*q)/v+=q:v-=q>v ?v:q}
c}

Try it online!

This is the floating point version. It can be edited to a fractional version by changing the initialization of volume and concentration to v=c=0r for one less byte.

Function which takes an array of arrays, with each element of the form [action,quantity] and returns concentration.

Actions are: 0 add water 1 add coffee 2 drink.

The heart of the code is a conditional, which reduces the volume if action is 2 (or above) and updates both volume and and concentration if action is below 2. Putting the conditional this way round saves 1 byte of whitespace (which would otherwise be required to avoid a syntax error I don't fully understand.)

The concentration is updated as

((concentration * existing volume)+(concentration of new liquid * volume added)) 
divided by (new volume)   

Note that as the action code 0 or 1 is equal to the corresponding concentration (water = 0, coffee = 1) it can be used directly in the formula. This means it is also possible to add noninteger concentrations of coffee (an example of adding a mixture of concentration 0.5 is given in the TIO as an additional testcase.