zholnin

Google Code Jam Helper file v1.1

May 3rd, 2014
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import multiprocessing
  2. import cPickle
  3. import time
  4. import bisect
  5. import math
  6. from files import *
  7.  
  8. """
  9. Things yet to do:
  10.  
  11. """
  12.  
  13. BABY = 0
  14. SMALL = 1
  15. LARGE = 2
  16. PSMALL = 3
  17. PLARGE = 4
  18.  
  19. def doit(preprocess, readinput, solve, MultiCore = True, Verify = False, Input  = None, Filename = None, Problem = "A", Attempt = 0, SingleCase = False):
  20.     start_time = time.time()
  21.  
  22.     if Input == None:
  23.         if Filename == None:
  24.             print "Input Filename Not specified."
  25.             return
  26.         INPUTNAME = Filename
  27.     else:
  28.         INPUTNAME = Problem + "_baby.in"
  29.         if Input == SMALL: INPUTNAME = Problem + "-small-attempt" + str(Attempt) + ".in"
  30.         if Input == LARGE: INPUTNAME = Problem + "-large.in"
  31.         if Input == PSMALL: INPUTNAME = Problem + "-small-practice.in"
  32.         if Input == PLARGE: INPUTNAME = Problem + "-large-practice.in"
  33.            
  34.        
  35.    
  36.     OUTPUTNAME = INPUTNAME[:INPUTNAME.find(".")] + ".out"
  37.    
  38.     Input = File(INPUTNAME, "r")
  39.     Correct = None
  40.    
  41.     if Verify == True:
  42.         try:
  43.             Output = File(OUTPUTNAME, "r")
  44.             Correct = Output.readall()
  45.         except IOError:
  46.             print "Verification not possible - output file does not exist. Fall back to normal mode."
  47.             Verify = False
  48.             Output = File(OUTPUTNAME, "w")
  49.     else:
  50.         Output = File(OUTPUTNAME, "wb")
  51.    
  52.     PREPNAME = Problem + ".prep"
  53.     try:
  54.         pfile = open(PREPNAME, "rb")
  55.         Prep = cPickle.load(pfile)
  56.         pfile.close()
  57.         print "Loaded preprocessed information from file"
  58.     except IOError:
  59.         Prep = preprocess()
  60.         if Prep <> None:
  61.             pfile = open(PREPNAME, "wb")
  62.             cPickle.dump(Prep, pfile, 2)
  63.             pfile.close()
  64.             print "Saved preprocessed information to file"            
  65.    
  66.     if SingleCase == True:
  67.         n_cases = 1
  68.     else:
  69.         n_cases = Input.readint()
  70.    
  71.     Problems = []
  72.    
  73.     # Just reading input
  74.     for _ in range(n_cases):
  75.         Problems.append(readinput(Input))
  76.        
  77.     AllCorrect = True
  78.    
  79.     if MultiCore:
  80.         pool = multiprocessing.Pool(processes = 4)
  81.         Result = [pool.apply_async(solve, [p, Prep]) for p in Problems]
  82.    
  83.     for n in range(n_cases):
  84.         if MultiCore:
  85.             Solution = Result[n].get()
  86.         else:
  87.             Solution = solve(Problems[n], Prep)
  88.            
  89.         sline = "Case #" + str(n+1) + ": " + str(Solution)
  90.        
  91.         print sline
  92.  
  93.         if not Verify:
  94.             Output.write(sline + "\n")
  95.         else:
  96.             for line in split(sline, "\n"):
  97.                 if len(Correct) == 0 or line.rstrip("\n") <> Correct[0].rstrip("\n"):
  98.                     print "MISMATCH: ", line,
  99.                     AllCorrect = False
  100.                     if len(Correct) > 0: print Correct[0]
  101.                     else: print ""
  102.                 if len(Correct) > 0: Correct.pop(0)
  103.    
  104.         TOT = (time.time() - start_time) / (n + 1) * n_cases
  105.         if TOT > 120:
  106.             print "Running over two minutes by:", int (TOT - 120), "seconds"
  107.    
  108.     print time.time() - start_time, "seconds"
  109.     if Verify and AllCorrect == False:
  110.         print "VERIFICATION FAILED - ERRORS WERE FOUND IN SOLUTION"
  111.    
  112.     return
  113.  
  114. Primes = None
  115. largestPrime = None
  116.  
  117. def frange(x, y, jump):
  118.     while x < y:
  119.         yield x
  120.         x += jump
  121.  
  122. def loadPrimes(N):
  123.     global Primes
  124.     global largestPrime
  125.     try:
  126.         pfile = open("Primes" + str(N) + ".prep", "rb")
  127.         Primes = cPickle.load(pfile)
  128.         largestPrime = N
  129.         pfile.close()
  130.     except IOError:
  131.         s = set(range(3, N + 1, 2))
  132.         Primes = [2]
  133.         for i in range(3, N + 1, 2):
  134.             if i not in s:
  135.                 continue
  136.    
  137.             Primes.append(i)
  138.            
  139.             k = 2
  140.             while k*i <= N:
  141.                 if k*i in s:
  142.                     s.remove(k*i)
  143.                 k += 1
  144.         pfile = open("Primes" + str(N) + ".prep", "wb")
  145.         cPickle.dump(Primes, pfile, 2)
  146.         largestPrime = N
  147.     return
  148.      
  149.  
  150. def getPrimes(A, B):
  151.     global Primes
  152.     global largestPrime
  153.     """get primes between A and B inclusive"""
  154.     if Primes == None:
  155.         print "Prime numbers are not initialized"
  156.         quit()
  157.    
  158.     if B > largestPrime:
  159.         print "Sorry, no data on primes so large"
  160.         quit()
  161.    
  162.     S = bisect.bisect_left(Primes, A)
  163.     E = bisect.bisect_left(Primes, B + 1)
  164.     return Primes[S:E]
  165.  
  166.  
  167. def ncr(n, r):
  168.     r = min(r, n-r)
  169.     if r == 0: return 1
  170.     if r < 0: return 0
  171.     num = reduce(mul, xrange(n, n-r, -1))
  172.     denom = reduce(mul, xrange(1, r+1))
  173.     return num/denom
  174.  
  175. def memoize(f):
  176.     cache= {}
  177.     def memf(*x):
  178.         if x not in cache:
  179.             cache[x] = f(*x)
  180.         return cache[x]
  181.     return memf
  182.  
  183. def Transpose(M):
  184.     X = len(M)
  185.     Y = len(M[0])
  186.     A = []
  187.     for y in range(Y):
  188.         B = [0] * X
  189.         for x in range(X):
  190.             B[x] = M[x][y]
  191.         A.append(B)
  192.     return A
  193.  
  194. def bin_search_max(function, search_from, search_to, *args):
  195.     """
  196.    function - function to test - must return True when result is OK.
  197.    search_from - search from where (integer!)
  198.    search_to - search to where (integer!)
  199.    """
  200.    
  201.     while search_from <> search_to:
  202.         guess = (search_from + search_to) / 2 + 1
  203.         if function(guess, *args):
  204.             search_from = guess
  205.         else:
  206.             search_to = guess - 1
  207.    
  208.     return search_from
  209.  
  210. def bin_search_max_float(function, search_from, search_to, precision, *args):
  211.     """
  212.    function - function to test - must return True when result is OK.
  213.    search_from - search from where (integer!)
  214.    search_to - search to where (integer!)
  215.    """
  216.    
  217.     while abs(search_from - search_to) > precision:
  218.         guess = (search_from + search_to) / 2.0
  219.         if function(guess, *args):
  220.             search_from = guess
  221.         else:
  222.             search_to = guess
  223.    
  224.     return search_from
  225.  
  226. def bin_search_min_float(function, search_from, search_to, precision, *args):
  227.     """
  228.    function - function to test - must return True when result is OK.
  229.    search_from - search from where (integer!)
  230.    search_to - search to where (integer!)
  231.    """
  232.    
  233.     while abs(search_from - search_to) > precision:
  234.         guess = (search_from + search_to) / 2.0
  235.         if function(guess, *args):
  236.             search_to = guess
  237.         else:
  238.             search_from = guess
  239.    
  240.     return search_from
  241.  
  242. def bin_search_min(function, search_from, search_to, *args):
  243.     """
  244.    function - function to test - must return True when result is OK.
  245.    search_from - search from where (integer!)
  246.    search_to - search to where (integer!)
  247.    """
  248.    
  249.     while search_from <> search_to:
  250.         guess = (search_from + search_to) / 2
  251.         if function(guess, *args):
  252.             search_to = guess
  253.         else:
  254.             search_from = guess + 1
  255.    
  256.     return search_from
  257.  
  258.  
  259. def bin_search(function, search_result, search_from, search_to, precision, *args):
  260.     """
  261.    function - function to test
  262.    search_result - what to look for (which number)
  263.    search_from - search from where
  264.    search_to - search to where
  265.    precision - precision for comparison to test result
  266.    """
  267.     W = search_to - search_from
  268.     step =  W / 4.0
  269.     initial = W / 2.0 + search_from
  270.     s = function(initial, *args)
  271.    
  272.     while abs(step) > precision:
  273.         if s > search_result and step > 0:
  274.             step = - step / 2
  275.         if s < search_result and step < 0:
  276.             step = - step / 2
  277.         initial = initial + step
  278.         s = function(initial, *args)
  279.     return initial
  280.  
  281. def square_matrix_multiply(a, b):
  282.     s = len(a)
  283.     r = []
  284.    
  285.     for x in range(s):
  286.         r.append([0] * s)
  287.         for y in range(s):
  288.             for t in range(s):
  289.                 r[x][y] += (a[x][t] * b[t][y])
  290.                 r[x][y] = r[x][y]
  291.    
  292.     return r
  293.  
  294. def fastpower(m, x, p):
  295.     """return a**b % q"""
  296.     val = x
  297.     mult = x
  298.     p -= 1
  299.    
  300.     while p > 0:
  301.         odd = p & 1 # bitwise and
  302.         if odd == 1:
  303.             val = m(val, mult)
  304.             p -= 1
  305.         if p == 0:
  306.             break
  307.         mult = m(mult, mult)
  308.         p = p >> 1 # bitwise divide by 2
  309.     return val
  310.  
  311. def feq(a, b):
  312.     return fabs(a-b) < 1e-8
  313.  
  314. def next_permutation(L):
  315.     B = len(L) - 1
  316.     while L[B] <= L[B-1]:
  317.         B = B - 1
  318.         if (B == 0):
  319.             return sorted(L)
  320.    
  321.     b = B
  322.     for x in range(B, len(L)):
  323.         if L[b] > L[x] and L[x] > L[B-1]:
  324.             b = x
  325.    
  326.     (L[b], L[B - 1]) = (L[B - 1], L[b])
  327.     L = L[:B] + sorted(L[B:])
  328.     return L
  329.  
  330. def semi_circle_segment(x0, x1, R):
  331.     def integral(x, R):
  332.         h = R - x
  333.         return (R**2*acos((R-h)/R) - (R-h)*sqrt(2*R*h-h**2))/2
  334.    
  335.     return - integral(x1, R) + integral(x0, R)
  336.  
  337. def isqrt(x):
  338.     if x < 0:
  339.         raise ValueError('square root not defined for negative numbers')
  340.     n = int(x)
  341.     if n == 0:
  342.         return 0
  343.     a, b = divmod(n.bit_length(), 2)
  344.     x = 2**(a+b)
  345.     while True:
  346.         y = (x + n//x)//2
  347.         if y >= x:
  348.             return x
  349.         x = y  
  350.  
  351. def ilog(x, b):
  352.     if b == 1:
  353.         raise "Log base 1 fail"
  354.     a = -1
  355.     bb = 1
  356.     while bb <= x:
  357.         bb *= b
  358.         a += 1
  359.     return a
  360.  
  361. class File:
  362.     def __init__(self, filename, mode):
  363.         self.handle = open(filename, mode)
  364.         self.cursor = 0
  365.         self.filename = filename
  366.         self.mode = mode
  367.         if mode == "r":
  368.             self.lines = self.handle.readlines()
  369.    
  370.     def __del__(self):
  371.         self.handle.close()
  372.        
  373.     def readint(self):
  374.         a = int(self.lines[self.cursor])
  375.         self.cursor += 1
  376.         return a
  377.    
  378.     def readall(self):
  379.         return self.lines
  380.    
  381.     def readbinary(self):
  382.         self.handle.close()
  383.         self.handle = open(self.filename, "rb")
  384.         return self.handle.read()
  385.  
  386.     def readints(self):
  387.         ints = self.lines[self.cursor]
  388.         ints = strip(ints, "\n")
  389.         ints = strip(ints, " ")
  390.         while "  " in ints:
  391.             ints = ints.replace("  ", " ")
  392.         ints = ints.split(" ")
  393.         for a in range(len(ints)):
  394.             ints[a] = int(ints[a])
  395.         self.cursor += 1
  396.         return ints
  397.  
  398.     def readfloats(self):
  399.         ints = self.lines[self.cursor]
  400.         ints = strip(ints, "\n")
  401.         ints = ints.split(" ")
  402.         for a in range(len(ints)):
  403.             ints[a] = float(ints[a])
  404.         self.cursor += 1
  405.         return ints
  406.  
  407.     def readstring(self):
  408.         a = self.lines[self.cursor]
  409.         a = strip(a, "\n")
  410.         self.cursor += 1
  411.         return a
  412.    
  413.     def readstrings(self):
  414.         a = self.lines[self.cursor]
  415.         a = strip(a, "\n")
  416.         a = a.split(" ")
  417.         self.cursor += 1
  418.         return a
  419.    
  420.     def write(self, line):
  421.         self.handle.write(line)
  422.         return
  423.  
  424.     def writeint(self, number):
  425.         self.handle.write(str(number))
  426.         return
  427.        
  428.     def writefloat(self, fl, after):
  429.         self.handle.write(("%." + str(after) + "f") % fl)
  430.         return
  431.        
  432.     def nextline(self):
  433.         self.handle.write("\n")
  434.         return
  435.        
  436.        
  437.     """Matrix = numpy.array(Matrix, dtype = numpy.int64)"""
  438.    
  439.    
  440. class UnionFind:
  441.     def __init__(self):
  442.         '''\
  443. Create an empty union find data structure.'''
  444.         self.num_weights = {}
  445.         self.parent_pointers = {}
  446.         self.num_to_objects = {}
  447.         self.objects_to_num = {}
  448.         self.unique = 0
  449.        
  450.     def insert_objects(self, objects):
  451.         '''\
  452. Insert a sequence of objects into the structure.  All must be Python hashable.'''
  453.         for object in objects:
  454.             self.find(object);
  455.            
  456.     def find(self, object):
  457.         '''\
  458. Find the root of the set that an object is in.
  459. If the object was not known, will make it known, and it becomes its own set.
  460. Object must be Python hashable.'''
  461.         if not object in self.objects_to_num:
  462.             obj_num = len(self.objects_to_num)
  463.             self.num_weights[obj_num] = 1
  464.             self.objects_to_num[object] = obj_num
  465.             self.num_to_objects[obj_num] = object
  466.             self.parent_pointers[obj_num] = obj_num
  467.             self.unique += 1
  468.             return object
  469.         stk = [self.objects_to_num[object]]
  470.         par = self.parent_pointers[stk[-1]]
  471.         while par != stk[-1]:
  472.             stk.append(par)
  473.             par = self.parent_pointers[par]
  474.         for i in stk:
  475.             self.parent_pointers[i] = par
  476.         return self.num_to_objects[par]
  477.    
  478.     def union(self, object1, object2):
  479.         '''\
  480. Combine the sets that contain the two objects given.
  481. Both objects must be Python hashable.
  482. If either or both objects are unknown, will make them known, and combine them.'''
  483.         o1p = self.find(object1)
  484.         o2p = self.find(object2)
  485.         if o1p != o2p:
  486.             on1 = self.objects_to_num[o1p]
  487.             on2 = self.objects_to_num[o2p]
  488.             w1 = self.num_weights[on1]
  489.             w2 = self.num_weights[on2]
  490.             if w1 < w2:
  491.                 o1p, o2p, on1, on2, w1, w2 = o2p, o1p, on2, on1, w2, w1
  492.             self.num_weights[on1] = w1+w2
  493.             del self.num_weights[on2]
  494.             self.parent_pointers[on2] = on1
  495.             self.unique -= 1
  496.     def getUnique(self):
  497.         return self.unique
  498.  
  499.  
  500. class mod_calc:
  501.     def __init__(self, m):
  502.         self.m = m
  503.         self.fact_table = None
  504.        
  505.         self.pre_fact(m)
  506.    
  507.     def pre_fact(self, m):
  508.         f = 1
  509.         res = [1]
  510.         for n in range(1, m):
  511.             f = (f*n)%m
  512.             res.append(f)
  513.         return res
  514.  
  515.     def factorial(self, n):
  516.         if self.fact_table == None:
  517.             self.fact_table = self.pre_fact(self.m)
  518.         if n==0:
  519.             return 1
  520.         r = n%self.m
  521.         k = n//self.m
  522.         kk = 1
  523.         if k%2==1:
  524.             kk = -1
  525.         return (self.fact_table[r]*self.factorial(k)*kk)%self.m
  526.  
  527.     def fact_ord(self, n):
  528.         r = n%self.m
  529.         k = n//self.m
  530.         if k==0:
  531.             return 0
  532.         return k+self.fact_ord(k)
  533.  
  534.     def gcd(self, a, b):
  535.         if b==0:
  536.             return [1,0]
  537.         k = a//b
  538.         r = a-b*k
  539.         g = self.gcd(b, r)
  540.         return [g[1], g[0]-g[1]*k]
  541.  
  542.     def inv(self, x):
  543.         g = self.gcd(self.m, x)
  544.         return g[1]%self.m
  545.    
  546.     def ncr(self, n, r):
  547.         if self.fact_ord(n)>self.fact_ord(r)+self.fact_ord(n-r):
  548.             return 0
  549.         return (self.factorial(n)*self.inv((self.factorial(r)*self.factorial(n-r))%self.m))%self.m    
  550.  
  551. def rotate_coordinates_clockwise(xr, yr, alpha):
  552.     """point stays still, coordinate axis rotate clockwise by angle alpha"""
  553.     y = yr * math.cos(alpha) + xr * math.sin(alpha)
  554.     x = xr * math.cos(alpha) - yr * math.sin(alpha)
  555.     return x, y
  556.    
  557. def point_left_line(a, b, c):
  558.     """a and b are two points of line, showing direction. c is point to be determined"""
  559.     r = (b[0] - a[0])*(c[1] - a[1]) - (b[1] - a[1])*(c[0] - a[0])
  560.  
  561.     if r > 1e-15:
  562.         return True
  563.    
  564.     elif r < -1e-15:
  565.         return False
  566.    
  567.     return None
  568.    
  569. def convex_hull(points):
  570.     points = sorted(set(points))
  571.     if len(points) <= 1:
  572.         return points
  573.     def cross(o, a, b):
  574.         return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0])
  575.     lower = []
  576.     for p in points:
  577.         while len(lower) >= 2 and cross(lower[-2], lower[-1], p) <= 0:
  578.             lower.pop()
  579.         lower.append(p)
  580.     upper = []
  581.     for p in reversed(points):
  582.         while len(upper) >= 2 and cross(upper[-2], upper[-1], p) <= 0:
  583.             upper.pop()
  584.         upper.append(p)
  585.     return lower[:-1] + upper[:-1]
  586.  
  587. def findSCCs(Graph, n = None):
  588.     """Graph with vertices numbered from 1...n, represented as Dictionary"""
  589.        
  590.     if n == None:
  591.         n = len(Graph)
  592.        
  593.     po={}
  594.     ll={}
  595.     sf={}
  596.     sq = []
  597.     sl=[]
  598.     i=0
  599.     for s in xrange(1, n+1):
  600.         if s not in sf:
  601.             queue=[s]
  602.             while queue:
  603.                 v=queue[-1]
  604.                 if v not in po:
  605.                     i=i+1
  606.                     po[v]=i
  607.                 done=1
  608.                 v_nbrs=Graph.get(v, [])
  609.                 for w in v_nbrs:
  610.                     if w not in po:
  611.                         queue.append(w)
  612.                         done=0
  613.                         break
  614.                 if done==1:
  615.                     ll[v]=po[v]
  616.                     for w in v_nbrs:
  617.                         if w not in sf:
  618.                             if po[w]>po[v]:
  619.                                 ll[v]=min([ll[v],ll[w]])
  620.                             else:
  621.                                 ll[v]=min([ll[v],po[w]])
  622.                     queue.pop()
  623.                     if ll[v]==po[v]:
  624.                         sf[v]=True
  625.                         scc=[v]
  626.                         while sq and po[sq[-1]]>po[v]:
  627.                             k=sq.pop()
  628.                             sf[k]=True
  629.                             scc.append(k)
  630.                         sl.append(scc)
  631.                     else:
  632.                         sq.append(v)
  633.     return sl
Add Comment
Please, Sign In to add comment