#Starting with 69 produces a chain of five non-repeating terms, but the longest non-repeating chain with a starting number below one million is sixty terms. #How many chains, with a starting number below one million, contain exactly sixty non-repeating terms? #Answer: #402 from time import time t = time() from mathplus import factorial M = 1000000 MM = 2177282 L = 60 fact = [factorial(n) for n in range(10)] facts = [0] * MM facts[:10] = fact[:] for n in range(10, MM): facts[n] = facts[n // 10] + fact[n % 10] #print time()-t ss = 0 for n in range(M): m = n way = {} while m not in way: way[m] = 1 m = facts[m] if len(way) == 60: ss += 1
#!/usr/bin/python # -*- coding: utf-8 -*- #n! means n × (n − 1) × ... × 3 × 2 × 1 #For example, 10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800, #and the sum of the digits in the number 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27. #Find the sum of the digits in the number 100! #Answer: #648 from mathplus import factorial M = 100 print(sum(int(digit) for digit in str(factorial(M))))
#Starting with 69 produces a chain of five non-repeating terms, but the longest non-repeating chain with a starting number below one million is sixty terms. #How many chains, with a starting number below one million, contain exactly sixty non-repeating terms? #Answer: #402 from time import time; t=time() from mathplus import factorial M = 1000000 MM = 2177282 L = 60 fact = [factorial(n) for n in range(10)] facts = [0]*MM facts[:10] = fact[:] for n in range(10, MM): facts[n] = facts[n//10]+fact[n%10] #print time()-t ss = 0 for n in range(M): m = n way = {} while m not in way: way[m] = 1 m = facts[m] if len(way) == 60: ss += 1
#!/usr/bin/python # -*- coding: utf-8 -*- #145 is a curious number, as 1! + 4! + 5! = 1 + 24 + 120 = 145. #Find the sum of all numbers which are equal to the sum of the factorial of their digits. #Note: as 1! = 1 and 2! = 2 are not sums they are not included. #Answer: #40730 from time import time; t = time() from mathplus import factorial d = [factorial(i) for i in range(10)] M = d[9]*6 s = -3 def split_num(n, size): if size == 1: yield [n], n return if n == 0: yield [0]*size, 0 return j = 0 for i in range(n+1): for k, v in split_num(n-i, size-1): yield k+[i], j+v j += d[size-1]
def a_bit_thinking(n, size, choices=None): if choices is None: choices = range(size) if size == 1: return choices s = factorial(size - 1) m, n = choices[n // s], n % s return [m] + a_bit_thinking(n, size - 1, [i for i in choices if i != m])
#!/usr/bin/python # -*- coding: utf-8 -*- #A bag contains one red disc and one blue disc. In a game of chance a player takes a disc at random and its colour is noted. After each turn the disc is returned to the bag, an extra red disc is added, and another disc is taken at random. #The player pays £1 to play and wins if they have taken more blue discs than red discs at the end of the game. #If the game is played for four turns, the probability of a player winning is exactly 11/120, and so the maximum prize fund the banker should allocate for winning in this game would be £10 before they would expect to incur a loss. Note that any payout will be a whole number of pounds and also includes the original £1 paid to play the game, so in the example given the player actually wins £9. #Find the maximum prize fund that should be allocated to a single game in which fifteen turns are played. #Answer: #2269 from time import time; t=time() from mathplus import factorial, product, reduce, op N = 15 s = 0 for l in product(*([(0, 1)]*N)): if sum(l) * 2 > N: s += reduce(op.mul, ((i + 1) if v == 0 else 1 for i, v in enumerate(l)), 1) print(factorial(N+1)//s)#, time()-t)
def a_bit_thinking(n, size, choices=None): if choices is None: choices = range(size) if size == 1: return choices s = factorial(size-1) m, n = choices[n//s], n%s return [m]+a_bit_thinking(n, size-1, [i for i in choices if i != m])
#!/usr/bin/python # -*- coding: utf-8 -*- #A bag contains one red disc and one blue disc. In a game of chance a player takes a disc at random and its colour is noted. After each turn the disc is returned to the bag, an extra red disc is added, and another disc is taken at random. #The player pays £1 to play and wins if they have taken more blue discs than red discs at the end of the game. #If the game is played for four turns, the probability of a player winning is exactly 11/120, and so the maximum prize fund the banker should allocate for winning in this game would be £10 before they would expect to incur a loss. Note that any payout will be a whole number of pounds and also includes the original £1 paid to play the game, so in the example given the player actually wins £9. #Find the maximum prize fund that should be allocated to a single game in which fifteen turns are played. #Answer: #2269 from time import time t = time() from mathplus import factorial, product, reduce, op N = 15 s = 0 for l in product(*([(0, 1)] * N)): if sum(l) * 2 > N: s += reduce(op.mul, ((i + 1) if v == 0 else 1 for i, v in enumerate(l)), 1) print(factorial(N + 1) // s) #, time()-t)