I made it up

迷いの竹林   –  2 min

TWC score tool

Given

bas1+c=i1 bas2+c=i2 bas3+c=i3 c=i1bas1 b=i2cas2=i2i1as2as1 as3=i3cb(i2i1)as3+(i1i3)as2+(i3i2)as1=0

where i is iscore, s is in-game score, and a,b,c the three parameters.

import numpy as np
import scipy.optimize


"""
s1,s2,s3 and i1,i2,i3 have to be in _increasing_ order

            s1 < s2 < s3, i1 < i2 < i3
If solving fails, check if the provided points are convex.
            
Method can be 
'root_scalar': versatile, works for any scores
'polynomial': robust, but s3-s1 and s2-s1 have to be integers
"""
def getParam(s1,s2,s3,i1,i2,i3, method = 'root_scalar', a_range = [1.01,100]):
    d2 = s3-s1
    d1 = s2-s1
    if method == 'polynomial':
        coeff = []
        for c in range(d2, -1, -1):
            if c == d2:
                coeff.append(i2-i1)
            elif c == d1:
                coeff.append(i1-i3)
            elif c == 0:
                coeff.append(i3-i2)
            else:
                coeff.append(0)
        a = np.roots(coeff)
        b = (i2-i1)/(np.power(a,s2)-np.power(a,s1))
        c = i1-b*np.power(a,s1)
    elif method == 'root_scalar':
        f = lambda x: (i2-i1)*np.power(x,d2) + (i1-i3)*np.power(x,d1) + (i3-i2)
        print(f"{i2-i1}x^{d2}+{i1-i3}x^{d1}+{i3-i2}")
        a = scipy.optimize.root_scalar(f, bracket=a_range).root
        b = (i2-i1)/(np.power(a,s2)-np.power(a,s1))
        c = i1-b*np.power(a,s1)
    else:
        raise ValueError("Unknown root finding method.")
    return a,b,c
#sample data:e
score = np.array([[16.5, 17.1, 17.7],
                  [15.5, 16.1, 16.7],
                  [23,   24,   25]])
iscore = np.array([[56, 100, 180],
                   [56, 100, 180],
                   [56, 100, 180]])

def calcParam(score, iscore):
    a = np.empty(3)
    b = np.empty(3)
    c = np.empty(3)
    for i in range(len(score)):
        x,y,z = getParam(score[i][0], score[i][1], score[i][2], iscore[i][0], iscore[i][1], iscore[i][2])
        a[i] = x
        b[i] = y
        c[i] = z
    return a,b,c
        
a,b,c = calcParam(score, iscore)

print(a)
print(b)
print(c)

# ans = np.where(np.logical_and(np.isreal(a), a > 1))

44x^1.1999999999999993+-124x^0.6000000000000014+80
44x^1.1999999999999993+-124x^0.6000000000000014+80
44x^2.0+-124x^1.0+80
[2.70850007 2.70850007 1.81818182]
[3.89562203e-06 1.05512925e-05 5.74043377e-05]
[2.22222222 2.22222222 2.22222222]
import matplotlib as mpl
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
x = [np.linspace(3, 18, 200), np.linspace(3, 17, 200), np.linspace(3, 25, 200)]
for i in range(len(score)):
    y = b[i]*np.power(a[i],x[i])+c[i]
    ax.plot(x[i],y)
    ax.scatter(score.T[i], iscore.T[i], c='r')

graph