Given a string, Return its Cumulative Delta
Python 3, 71 bytes
s=input();k=r=0
for c in s:r=ord(c)-r*k/(len(s)-k);k+=1
print(round(r))
Test it on Ideone.
Alternate version, 58 bytes (inexact)
If an approximate result is enough – e.g., -904.9999999999993 ≈ -905 for input helloworld – then the following solution works as well.
f=lambda s,k=1:len(s)and-~-len(s)*f(s[1:],k+1)/k+ord(s[0])
Test it on Ideone.
Background
Proposition Let f be a variadic function that maps the code points s0, ⋯, sn to their cumulative delta with sign (-1)n, i.e.,
Then
Proof The statement is clearly true when n = 0. Suppose that it holds for n - 1, where n > 0.
By the recursive definition of f and the hypothesis,
By induction, the statement holds for all non-negative values of n.
How it works
Since
we can rewrite the proposition as follows.
The iterative implementation does precisely this. Numerators are computed by incrementing k, denominators by subtracting k from the length of the input string s, i.e., n+1.
Unfortunately, not all fractions will evaluate to integers, so the result is computed using floating point arithmetic and finally rounded to the nearest integer.
The recursive implementation does roughly the same, but it keeps track of the denominator via the auxiliary variable k and computes the numerator by subtracting 1 from the length of the remaining string (~-len(s)
).
MATL, 5 bytes
`dtnq
Try it Online! or here is a slightly modified version for all test cases.
Explanation
% Implicitly grab the input as a string
` % Do....while loop
d % Compute the difference between all consecutive ASCII codes
tnq % Determine the current length and subtract 1
% Implicit end of do...while. Evaluate (and consume) stack element and break out
% of loop if it's 0.
% Implicit end of loop and display
Jelly, 6 4 bytes
-2 bytes thanks to @Dennis (implement a while loop)
OIṖ¿
TryItOnline
RunAllTestCases
How?
OIṖ¿ - Main link: s
O - cast to ordinals
Ṗ¿ - while, ¿, pop last value, Ṗ, evaluates to True:
I - find increments between consecutive values