Advertisement
tadejpetric

challenge 2

May 17th, 2018
665
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.59 KB | None | 0 0
  1. # zavzav, 17th of may 2018
  2. # the challenge nr. 2
  3. # Educated exhaustive search works I guess...
  4.  
  5. """
  6. terminology:
  7. string - ordered list of numbers, also a sequence
  8. substring - a list of numbers within another list of numbers, subsequence
  9. 234 is a substring of 1234, for example
  10. """
  11.  
  12. def root_check(num): #checks the given substring of numbers, if it has a cube root, when multiplying digits
  13.     two = 0
  14.     three = 0
  15.     five = 0
  16.     seven = 0 #sets the counters that chount the amount of 2,3,5,7
  17.     for i in num: #counts instances of the digits
  18.         if i == 2:
  19.             two += 1
  20.         elif i == 3:
  21.             three += 1
  22.         elif i == 5:
  23.             five += 1
  24.         elif i == 7:
  25.             seven += 1
  26.     return (two % 3 == 0) and (three % 3 == 0) and (five % 3 == 0) and (seven % 3 == 0)
  27.     #returns true if num is a perfect cube
  28.     #because a perfect cube is a number that has the count of each prime factor mod 3 equal to 0
  29.  
  30. def iterate_over(x):
  31.     i = 0 #start index of the substring
  32.     while i < len(x): #checks every possible substring of the number supplied
  33.         j = i+3 #end index of the substring
  34.         while j <= len(x):
  35.             if (root_check(x[i:j])):
  36.                 return True, i # x has a perfect cube in it, try the next value (since we're searching for the
  37.                 #first without a cube)
  38.                 #returns True -> That a cube is found and i, the position of that cube
  39.             j += 3 #+3 because the length of the substring must always be a multiple of 3
  40.         i+= 1
  41.     print ("no perfect cube for length of list n= ", len(x))
  42.     return False, 0  #prepend an element to the list. We found a combination of digits that doesn't have
  43.     #any perfect cubes (because if it had, the if statement would've activated and return stopped the function)
  44.  
  45. def end_check(x): #checks if we tried every possible number
  46.     for i in x[-3:]: #every number starting with 3 7s will automatically have a cube, no need to check if
  47.         if i != 7: #cont. every number starting with 777 has a cube - it automatically has it
  48.             return False #it's not all 7's yet
  49.     return True
  50.  
  51.  
  52. #values = [2, 3, 5, 7] only primes needed because we're looking for the biggest number.
  53. #when there would be a 6, we can turn it into 2*3, 4->2*2, 9->3*3
  54. #0, 1, 8 are automatically excluded since already cubes themselves
  55. #so we're only interested in checking numbers with those digits
  56.  
  57.  
  58. def increment_list(number, i): # uses the index of that number that forms a cube (returned in iterate_over(x))
  59.     #increments a value from that substring that forms a cube, so that it doesn't anymore. Therefore creating
  60.     #a number that doesn't have that same sequence of cubes anymore. Difficult to understand maybe, but huge
  61.     #performance boost.
  62.     #for example transforms 23335 into 23355
  63.     end = i
  64.     #print(number, i)
  65.     while number[i] == 7:
  66.         #if the number we're incrementing is 7, make sure about carry digits. Similar to how
  67.         #you have to carry digits from 999+1 -> 1000. Implementing this, with only numbers 2,3,5,7
  68.         i += 1
  69.     number[i] += 2 if number[i] != 2 else 1 # 2->3, 3->5, 5->7
  70.     while i > end: #if we carried digits, set all preceding to the lowest value possible (like 000 in 1000)
  71.         i -= 1
  72.         number[i] = 2
  73.  
  74. number = [2] #starting value
  75.  
  76. while not end_check(number): #while we've yet to try every possible combination
  77.     cond, pos = iterate_over(number)
  78.     #try the current number. If that number has a cube, change it so that it might not anymore.
  79.     #if it doesn't have a cube, prepend another digit to it
  80.     #since we're searching for the first number which always has a cube, the answer will be when
  81.     #we try all combinations, but not find any string which doesn't have a cube in it
  82.     if cond: #if it has a cube in it
  83.         increment_list(number, pos) #change the number
  84.     else: #if it doesn't have a cube
  85.         number.insert(0, 2) #prepend a 2 to list (to the lowest position, 4 in the number 1234)
  86.         #we are also continuing from the previously obtained sequence without a cube since previous
  87.         #sequences are substrings of the bigger one. If they already all have a cube, the bigger one
  88.         #with the same starting digits will have a cube too. So continue from a sequence without cubes
  89.         #a huge performance boost, compared to creating a new list of [2,2,...,2] a size 1 larger than before
  90. print(len(number))
  91. #since we've tried every combination (with optimizations to avoid factorial time complexity) and not found
  92. #a combination, this is the answer. This wasn't the case with previous, smaller, numbers, so it must be the
  93. #smallest such number
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement