def compute(): # Each die has (10 choose 6) arrangements, so we have at most 44100 arrangements to check ans = sum(1 for i in range(1 << 10) for j in range(i, 1 << 10) # Ensure i <= j to force the dice to be orderless # If both have Hamming weight of 6 if eulerlib.popcount(i) == eulerlib.popcount(j) == 6 and is_arrangement_valid(i, j)) return str(ans)
def compute(): # Each die has (10 choose 6) arrangements, so we have at most 44100 arrangements to check ans = sum(1 for i in range(1 << 10) for j in range( i, 1 << 10) # Ensure i <= j to force the dice to be orderless # If both have Hamming weight of 6 if eulerlib.popcount(i) == eulerlib.popcount(j) == 6 and is_arrangement_valid(i, j)) return str(ans)
def sam_transitions_minus_max_transitions(n): samtrans = 0 maxtrans = 0 segmentstate = 0 while True: newstate = number_to_segments(n) if newstate == segmentstate: break maxtrans += eulerlib.popcount(newstate ^ segmentstate) segmentstate = newstate samtrans += 2 * eulerlib.popcount(newstate) n = digit_sum(n) maxtrans += eulerlib.popcount(segmentstate) return samtrans - maxtrans
def list_all_states(): result = set() # Try all 2^11 ways for which cells (or ant) hold a seed for i in range(2**11): if eulerlib.popcount(i) != 5: continue # Invalid state if not 5 things hold a seed # For all 5*5 possible ant positions for y in range(5): for x in range(5): seed = [((i >> j) & 1) != 0 for j in range(11)] result.add(State(False, x, y, seed)) result.add(State.DONE_STATE) return result
def find_maximum_sum(startrow, setofcols): if startrow == ROWS: assert eulerlib.popcount(setofcols) == COLUMNS - ROWS return 0 if maxsum[startrow][setofcols] is None: result = 0 col = 0 bit = 1 while True: if bit > setofcols: break if setofcols & bit != 0: result = max(MATRIX[startrow][col] + find_maximum_sum(startrow + 1, setofcols ^ bit), result) col += 1 bit <<= 1 maxsum[startrow][setofcols] = result return maxsum[startrow][setofcols]
def find_maximum_sum(startrow, setofcols): if startrow == ROWS: assert eulerlib.popcount(setofcols) == COLUMNS - ROWS return 0 if maxsum[startrow][setofcols] is None: result = 0 col = 0 bit = 1 while True: if bit > setofcols: break if setofcols & bit != 0: result = max( MATRIX[startrow][col] + find_maximum_sum(startrow + 1, setofcols ^ bit), result) col += 1 bit <<= 1 maxsum[startrow][setofcols] = result return maxsum[startrow][setofcols]
def find_minimum_length(currentsphereindex, setofspheres): if setofspheres & (1 << currentsphereindex) == 0: raise ValueError() # Memoization if minlength[currentsphereindex][setofspheres] is None: if eulerlib.popcount(setofspheres) == 1: result = sphereradii[currentsphereindex] # This sphere is rightmost else: result = float("inf") newsetofspheres = setofspheres ^ (1 << currentsphereindex) for i in range(NUM_SPHERES): # i is the index of the next sphere if newsetofspheres & (1 << i) == 0: continue # The sqrt() here is what makes the entire computation not guaranteed to be accurate temp = math.sqrt((sphereradii[i] + sphereradii[currentsphereindex] - 50000) * 200000) temp += find_minimum_length(i, newsetofspheres) result = min(temp, result) minlength[currentsphereindex][setofspheres] = result return minlength[currentsphereindex][setofspheres]