開始番号がxyz
のようになっているとします。つまり、最後の(10進)桁はz、最後から2番目の桁はy、残りはxです。あなたの例では、504で始まった場合、x = 5、y = 0、z = 4です。元の番号の値は100x + 10y + zです。
最後の数字は、(100x + 10y + z)、(10x + y)、およびxの合計です。これは111x + 11y + zです。
私たちの制約は、0≦y≦9かつ0≦z≦9であったことに注意してください。最大値でも、11y + z≤11(9)+ 9 < 111です。したがって、変換を逆転できます。111の最大倍数を引き出し、残りの11の最大倍数を引き出します。残っているもの。
def transform(n):
return n + (n/10) + (n/100)
def invert(m):
[x, y, z] = [m/111, (m%111)/11, (m%111)%11]
return 100*x + 10*y + z
assert transform(504) == 559
assert invert(559) == 504
(Pythonシェルに上記試しxは1桁の数字でない場合でも、これが動作することに注意してください:。transform(12345)
は13702を与え、そして予想通りinvert(13702)
は、12345を与える)
を編集する:Paul Hankin's answer(考えてみてください)の考え方に基づいて、m*100/111
を開始点として使用します。あなたは確かにその値を天性値として使って正確な答えを得るために1と2を加えようとするが、粗い答えから必要な "オフセット"をあらかじめ計算することもできる。
# Precomputation, to populate the "offset" dictionary
def sane_mod(a, m): return ((a % m) + m) % m
offset = {}
for y in range(10):
for z in range(10):
add = 10*y + 11*z
offset[sane_mod(-add, 111)] = add
# Actual function
def invert2(m):
rough = m * 100
return (rough + offset[rough % 111])/111
assert invert2(559) == 504
a + b + cが小さい場合(<= 10^6)、bruteforceを使用して1からa + b + cまでのすべての可能性を試すことができます。 – algojava