Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,55 @@
from functools import lru_cache
#%%
DIVS = {2, 3}
SUBS = {1}
class Minrec():
"Recursive, memoised minimised steps to 1"
def __init__(self, divs=DIVS, subs=SUBS):
self.divs, self.subs = divs, subs
@lru_cache(maxsize=None)
def _minrec(self, n):
"Recursive, memoised"
if n == 1:
return 0, ['=1']
possibles = {}
for d in self.divs:
if n % d == 0:
possibles[f'/{d}=>{n // d:2}'] = self._minrec(n // d)
for s in self.subs:
if n > s:
possibles[f'-{s}=>{n - s:2}'] = self._minrec(n - s)
thiskind, (count, otherkinds) = min(possibles.items(), key=lambda x: x[1])
ret = 1 + count, [thiskind] + otherkinds
return ret
def __call__(self, n):
"Recursive, memoised"
ans = self._minrec(n)[1][:-1]
return len(ans), ans
if __name__ == '__main__':
for DIVS, SUBS in [({2, 3}, {1}), ({2, 3}, {2})]:
minrec = Minrec(DIVS, SUBS)
print('\nMINIMUM STEPS TO 1: Recursive algorithm')
print(' Possible divisors: ', DIVS)
print(' Possible decrements:', SUBS)
for n in range(1, 11):
steps, how = minrec(n)
print(f' minrec({n:2}) in {steps:2} by: ', ', '.join(how))
upto = 2000
print(f'\n Those numbers up to {upto} that take the maximum, "minimal steps down to 1":')
stepn = sorted((minrec(n)[0], n) for n in range(upto, 0, -1))
mx = stepn[-1][0]
ans = [x[1] for x in stepn if x[0] == mx]
print(' Taking', mx, f'steps is/are the {len(ans)} numbers:',
', '.join(str(n) for n in sorted(ans)))
#print(minrec._minrec.cache_info())
print()

View file

@ -0,0 +1,58 @@
class Mintab():
"Tabulation, memoised minimised steps to 1"
def __init__(self, divs=DIVS, subs=SUBS):
self.divs, self.subs = divs, subs
self.table = None # Last tabulated table
self.hows = None # Last tabulated sample steps
def _mintab(self, n):
"Tabulation, memoised minimised steps to 1"
divs, subs = self.divs, self.subs
table = [n + 2] * (n + 1) # sentinels
table[1] = 0 # zero steps to 1 from 1
how = [[''] for _ in range(n + 2)] # What steps are taken
how[1] = ['=']
for t in range(1, n):
thisplus1 = table[t] + 1
for d in divs:
dt = d * t
if dt <= n and thisplus1 < table[dt]:
table[dt] = thisplus1
how[dt] = how[t] + [f'/{d}=>{t:2}']
for s in subs:
st = s + t
if st <= n and thisplus1 < table[st]:
table[st] = thisplus1
how[st] = how[t] + [f'-{s}=>{t:2}']
self.table = table
self.hows = [h[::-1][:-1] for h in how] # Order and trim
return self.table, self.hows
def __call__(self, n):
"Tabulation"
table, hows = self._mintab(n)
return table[n], hows[n]
if __name__ == '__main__':
for DIVS, SUBS in [({2, 3}, {1}), ({2, 3}, {2})]:
print('\nMINIMUM STEPS TO 1: Tabulation algorithm')
print(' Possible divisors: ', DIVS)
print(' Possible decrements:', SUBS)
mintab = Mintab(DIVS, SUBS)
mintab(10)
table, hows = mintab.table, mintab.hows
for n in range(1, 11):
steps, how = table[n], hows[n]
print(f' mintab({n:2}) in {steps:2} by: ', ', '.join(how))
for upto in [2000, 50_000]:
mintab(upto)
table = mintab.table
print(f'\n Those numbers up to {upto} that take the maximum, "minimal steps down to 1":')
mx = max(table[1:])
ans = [n for n, steps in enumerate(table) if steps == mx]
print(' Taking', mx, f'steps is/are the {len(ans)} numbers:',
', '.join(str(n) for n in ans))