| Bytes | Lang | Time | Link |
|---|---|---|---|
| 167 | Python 2 | 250111T013410Z | Lucenapo |
| 075 | JavaScript V8 | 250111T025253Z | Weird Gl |
| 124 | Gawk | 250303T040555Z | Braden C |
| 105 | AWK | 250303T154105Z | xrs |
| 694 | Bespoke | 250120T015252Z | Josiah W |
| 064 | Julia 1.0 | 250119T213120Z | MarcMush |
| 017 | Jelly | 250111T183610Z | lolad |
| 064 | JavaScript ES6 | 250111T192138Z | Arnauld |
| 023 | 05AB1E | 250113T134414Z | Kevin Cr |
| 017 | Jelly | 250112T221918Z | Jonathan |
| 036 | APLNARS | 250112T195108Z | Rosario |
| 5958 | Ruby | 250111T201541Z | Level 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)
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
-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
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Ä÷/
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:
- \$\gamma>0\$ (adding coffee), and state becomes \$(c+\gamma,w)\$
- \$\omega>0\$ (adding water), and state becomes \$(c,w+\omega)\$
- \$\delta>0\$ (drinking). Given current total liquid \$V=c+w\$, we calculate scale factor \$k=\frac{V-\delta}{V}=1-\frac{\delta}{V}\$. If \$V=0\$ or \$k\le0\$, set \$k=0\$ (so we never drink more than everything). Then, multiply, giving new state \$(kc,kw)\$.
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
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}
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.