Advertisement
Vermiculus

so much python

Mar 20th, 2012
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 15.08 KB | None | 0 0
  1. #Proj2.py
  2. #Implementation of COSC 251 Project 2
  3. #Spring 2012
  4. #Last Revision - 2/21/2012
  5. #Sean Allred and David Rice
  6.  
  7. ############### QUESTION 1 ###############
  8. def d(s):
  9.     raw_input("----DEBUG----{0}".format(s))
  10.  
  11. class City:
  12.     # parses the intersections from a string s
  13.     def __init__(self, s):
  14.         nums = s.split()
  15.         self.juncs = set(map(int,nums))
  16.         self.roads = dict()
  17.         self.inf = list()
  18.        
  19.         # create the dictionary of outgoing roads from junctions
  20.         for i in range(0, len(nums), 2):
  21.             if int(nums[i]) in self.roads:
  22.                 self.roads[int(nums[i])].append(int(nums[i+1]))
  23.             else:
  24.                 self.roads[int(nums[i])] = [int(nums[i+1])]
  25.        
  26.         # Determine two way streets (as tuples of junctions)
  27.         for j in self.juncs:
  28.             if self.roads.has_key(j):
  29.                 for out in self.roads[j]:
  30.                     if self.roads.has_key(out):
  31.                         if j in self.roads[out]:
  32.                             self.inf.append((j,out))
  33.        
  34.         # remove duplicates
  35.         for twoway in self.inf:
  36.             if (twoway[1], twoway[0]) in self.inf:
  37.                 self.inf.remove(twoway)
  38.        
  39.         # convert tuples to sets
  40.         for i in range(len(self.inf)):
  41.             self.inf[i] = set([self.inf[i][0],self.inf[i][1]])
  42.        
  43.         #print "  inf = {i}\njuncs = {j}\nroads = {r}".format(i=self.inf,j=self.juncs,r=self.roads)
  44.    
  45.     def __str__(self):
  46.         return str(self.roads)
  47.    
  48.     def isInf(self, paths):
  49.     # Go through list of paths
  50.     # if there is any junction that leads to a previous junction, it is infinite
  51.         for path in paths:
  52.             for start in path:
  53.                 for end in path:
  54.                     # if we've gone through all previous junctions
  55.                     if start == end or not self.roads.has_key(start):
  56.                         break
  57.                     if end in self.roads[start]:
  58.                         return True
  59.         return False
  60.    
  61.     def paths(self, a, b, current_path=[]):
  62.         # IF
  63.         #   the start point and end point are the same at the beginning,
  64.         #   junction 'a' does not exist
  65.         #   junction 'b' does not exist
  66.         # return nothing
  67.         if (current_path == [] and a == b) or not (a in self.juncs and b in self.juncs):
  68.             return []
  69.        
  70.         # add the starting junction to the path
  71.         current_path = current_path + [a]
  72.        
  73.         # If we've reached the endpoint, (because the endpoint need not any outgoing roads)
  74.         if a == b:
  75.             return [current_path]
  76.            
  77.         if not self.roads.has_key(a):
  78.             return []
  79.        
  80.         # prepare the return
  81.         thispath = []
  82.        
  83.         # for every junction reachable from a
  84.         for junction in self.roads[a]:
  85.        
  86.             # if we haven't already visited this junction,
  87.             if junction not in current_path:
  88.            
  89.                 # send out a probe finding all paths from this junction to the ending point
  90.                 probe = self.paths(junction, b, current_path)
  91.                
  92.                 # add all the paths found
  93.                 for potential_path in probe:
  94.                     thispath.append(potential_path)
  95.        
  96.         # return the paths found from junction a to junction b
  97.         return thispath
  98.    
  99.     def isCyclic(self, j):
  100.         for pair in self.inf:
  101.             if j in pair:
  102.                 return True
  103.         return False
  104.    
  105.     # returns the number of paths from a to b, -1 if infinite
  106.     def numPaths(self, a, b):
  107.         if self.isCyclic(a):
  108.             return -1
  109.         p = self.paths(a, b)
  110.         if self.isInf(p):
  111.             return -1
  112.         else:
  113.             return len(p)
  114.  
  115. # takes an input list of characters and returns a list of Cities
  116. def parse(s):
  117.     nums = map(int, s)
  118.     ret = list()
  119.    
  120.     i = 0
  121.     while i < len(nums):
  122.         citystring = ""
  123.         for j in range(i + 1, i + 2*nums[i] + 1):
  124.             citystring += " {}".format(nums[j])
  125.         i += 2*nums[i] + 1
  126.        
  127.         ret.append(citystring)
  128.    
  129.     ret = map(City,ret)
  130.     return ret
  131.  
  132. # recieves input and returns a list of characters
  133. def problem1_input():
  134.     print "Input:"
  135.     out = list()
  136.     while(True):
  137.         _in = raw_input().split()
  138.         for char in _in:
  139.             if char != '-1':
  140.                 out.append(char)
  141.             else:
  142.                 return out
  143.     #return "7 0 1 0 2 0 4 2 4 2 3 3 1 4 3".split()
  144.  
  145. def Problem1():
  146.     #tester = "7 0 1 0 2 0 4 2 4 2 3 3 1 4 3\n5\n0 2\n0 1 1 5 2 5 2 1\n9\n0 1 0 2 0 3\n0 4 1 4 2 1\n2 0\n3 0\n3 1 -1"
  147.  
  148.     cities = parse(problem1_input())
  149.     for city in cities:
  150.         print "matrix for city {}".format(cities.index(city))
  151.         citymatrix = ""
  152.         for r in range(max(city.juncs) + 1):
  153.             for c in range(max(city.juncs) + 1):
  154.                 citymatrix += "{} ".format(city.numPaths(r,c))
  155.             citymatrix += '\n'
  156.         print citymatrix
  157.  
  158.  
  159. ############### QUESTION 2 ###############
  160.  
  161.  
  162. #import string
  163.  
  164. alph = [' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
  165.  
  166. def clean(s):
  167.     return s.rjust(5, ' ').lower()
  168.  
  169. def nxt(s):
  170.  
  171.     TERM = ['v','w','x','y','z']
  172.    
  173.     start = 4
  174.  
  175.     if(s[start] != TERM[start]): # If the index doesn't need to roll over,
  176.         s[start] = alph[alph.index(s[start]) + 1] # Increment the last letter
  177.     else: # We need to do le count!
  178.  
  179.         # find where we should start the count
  180.         while(s[start] == TERM[start]):
  181.             start = start - 1
  182.  
  183.         # count it! :D
  184.         s[start] = alph[alph.index(s[start]) + 1]
  185.         t = start + 1
  186.  
  187.         # make necessary trailing incrementations
  188.         while(t < 5):
  189.             s[t] = alph[alph.index(s[t-1])+1]
  190.             t = t + 1
  191.  
  192.     return s
  193.  
  194. def brute_gen():
  195.     l = list()
  196.    
  197.     e = ['v','w','x','y','z']
  198.     s = [' ',' ',' ',' ','a']
  199.  
  200.     while(s != e):
  201.         l.append(str(s))
  202.         s = nxt(s)
  203.     l.append(str(e))
  204.  
  205.     return l
  206.  
  207. def p2r(s):
  208.     l = brute_gen()
  209.     s = clean(s)
  210.     m = [' ',' ',' ',' ',' ']
  211.     for x in range(5):
  212.         m[x] = s[x]
  213.     m = str(m)
  214.    
  215.     if (l.count(m) != 0):
  216.         return l.index(m) + 1
  217.     else:
  218.         return 0
  219.  
  220. def valid(s):
  221.     if(len(s) != 5):
  222.         return False
  223.  
  224.     for c in s:
  225.         if(alph.count(c) == 0):
  226.             return False
  227.  
  228.     for c in s:
  229.         if(alph.index(c) == -1):
  230.             return False
  231.  
  232.     for i in range(4):
  233.         if(alph.index(s[i]) >= alph.index(s[i+1])):
  234.             return False
  235.     return True
  236.  
  237. def Problem2(s):
  238.     for ans in map(p2r,s.split()):
  239.         print ans
  240.  
  241.  
  242. ############### QUESTION 3 ###############
  243.  
  244.  
  245. def pl(l):
  246.     for n in l:
  247.         d(n)
  248.  
  249. # Class Molecule:
  250. #   elements: a dictionary of elements and their subscripts
  251. #   count: the coefficient on the molecule
  252. class Molecule:
  253.     class Atomic: # Represents a {Element}_{Subscript} structure (no coefficient)
  254.         def __init__(self, el, sub):
  255.             self.element = el
  256.             self.subscript = sub
  257.         def getElement(self):
  258.             return self.element
  259.         def getSubscript(self):
  260.             return self.subscript
  261.  
  262.     def __init__(self):
  263.         self.elements = dict()
  264.         self.count = 1
  265.  
  266.     def __str__(self):
  267.         ret = "{"+str(self.count)+"}"
  268.         for el in self.elements:
  269.             ret += "[{0}_{1}]".format(el,self.elements[el])
  270.         return ret
  271.  
  272.     def getElementTotals(self):
  273.         ret = dict()
  274.         for el in self.elements.keys():
  275.             ret[el] = self.elements[el] * self.count
  276.         return ret
  277.  
  278.     def add(self, atomic):
  279.         self.add(atomic.getElement(), atomic.getSubscript())
  280.  
  281.     def add(self, element, subscript):
  282.         # if the molecule already contains this element, just increase the subscript
  283.         if element in self.elements:
  284.             self.elements[element] += subscript
  285.         else: # otherwise, add the element and its subscript
  286.             self.elements[element] = subscript
  287.    
  288.     def fold(self, mol):
  289.         self.elements = self.getElementTotals()
  290.         self.count = 1
  291.         for el in mol.elements.keys():
  292.             self.add(el, mol.elements[el] * mol.count)
  293.  
  294. def getWord(s,i): # Returns a [isElem, token, lastIndex] list from a string s starting at index i
  295.     if i >= len(s) or i < 0:
  296.         return Nothing
  297.    
  298.     ret = s[i]
  299.     isElem = ret.isalpha()
  300.     i += 1
  301.     while i < len(s):
  302.         #d(str((isDigit, s[i], i, ret)))
  303.         if not isElem:
  304.             if s[i].isdigit():
  305.                 ret += s[i]
  306.             else:
  307.                 return [isElem,ret,i]
  308.         else:
  309.             if s[i].isupper() or s[i].isdigit():
  310.                 return [isElem,ret,i]
  311.             else:
  312.                 ret += s[i]
  313.         i = i + 1
  314.     return [isElem,ret,i]
  315.  
  316. def tokenize(s):
  317.     l = list()
  318.     i = 0
  319.     while i < len(s):
  320.         newi = getWord(s, i)
  321.         i = newi[2]
  322.         l.append(newi)
  323.     return l
  324.  
  325. def standardize(tokens): # inserts implicit subscripts and puts them into ints
  326.     if tokens[0][0]:
  327.         tokens.insert(0,[False,1,0])
  328.     i = 0
  329.     while i < len(tokens):
  330.         if tokens[i][0]: # if this is an element
  331.             if i+1 == len(tokens):
  332.                 tokens.append([False,1,tokens[i][2]])
  333.             elif tokens[i+1][0]: # if the next is also an element (ie not a subscript)
  334.                 tokens.insert(i+1,[False,1,tokens[i][2]])
  335.         else: # if this was a subscript
  336.             tokens[i][1] = int(tokens[i][1])
  337.         i = i + 1
  338.    
  339.     return tokens
  340.  
  341. def molecularize(tokens):
  342.     mol = Molecule()
  343.     mol.count = tokens[0][1]
  344.     for i in range(1,len(tokens),2):
  345.         mol.add(tokens[i][1], tokens[i+1][1])
  346.     return mol
  347.  
  348. def getmol(s): # returns a Molecule from a string
  349.     tok = tokenize(s)
  350.     standardize(tok)
  351.     mol = molecularize(tok)
  352.     return mol
  353.  
  354. def fission(s): # splits a string 'A=B' up into molecular components [[A1,A2,...],[B1,B2,...]
  355.     lnr = s.split('=')
  356.     if len(lnr) != 2:
  357.         print 'error'
  358.         return Nothing
  359.     left = lnr[0].split('+')
  360.     right = lnr[1].split('+')
  361.    
  362.     lmols = list()
  363.     for m in left:
  364.         lmols.append(getmol(m))
  365.    
  366.     rmols = list()
  367.     for m in right:
  368.         rmols.append(getmol(m))
  369.    
  370.     return [lmols,rmols]
  371.  
  372. def fusion(lnr): # takes the output of fission and folds them for balancing
  373.     if len(lnr) != 2:
  374.         print 'error'
  375.         return Nothing
  376.    
  377.     for side in lnr:
  378.         for i in range(1,len(side)):
  379.             side[0].fold(side[i])
  380.    
  381.     return [lnr[0][0], lnr[1][0]]
  382.    
  383. def balance(s):
  384.     # split up the string into lists of left and right molecules
  385.     # add the sides together element-wise, taking coefficients into consideration
  386.     f = fusion(fission(s))
  387.    
  388.     # get element totals
  389.     l = f[0].getElementTotals()
  390.     r = f[1].getElementTotals()
  391.    
  392.     if l == r:
  393.         print "{} balances".format(s)
  394.     else:
  395.         print "{} does not balance".format(s)
  396.  
  397. def Problem3(s):
  398.     map(balance, s.split())
  399.  
  400. #print ""
  401. #print ""
  402. #print ""
  403.  
  404. #Problem3("6H2O+6CO2=6O2+C6H12O6 \n2Na+2H2O=2NaOH+H2 C6H12O6=3C2H2+3O")
  405.  
  406. # EXTRA CREDIT:
  407. # Balance the equation
  408.  
  409. # add the set-subtract from each to the other.
  410.  
  411.  
  412. ############### QUESTION 4 ###############
  413.  
  414.  
  415. class Time:
  416.     def __init__(self, h, m):
  417.         self.hour = h
  418.         self.minute = m
  419.    
  420.     def __str__(self):
  421.         #return "{h}:{m}".format(h=self.hour, m=self.minute)
  422.         return '%(hour)02d:%(minute)02d' % {"hour":self.hour, "minute":self.minute}
  423.    
  424.     def add(self, time):
  425.         r = Time(self.hour, self.minute)
  426.         r.hour += time.hour
  427.         r.minute += time.minute
  428.        
  429.         if r.minute > 59:
  430.             r.minute -= 60
  431.             r.hour += 1
  432.        
  433.         # Do we need to roll over the hour to a day?
  434.         # Is a concept of a day even necessary?
  435.        
  436.         return r
  437.    
  438.     def sub(self, time):
  439.         r = Time(self.hour, self.minute)
  440.         r.hour -= time.hour
  441.         r.minute -= time.minute
  442.        
  443.         if r.minute < 0:
  444.             r.minute += 60
  445.             r.hour -= 1
  446.        
  447.         return r
  448.    
  449.     def isLaterThan(self, time):
  450.         if self.hour > time.hour:
  451.             return True
  452.         elif self.hour == time.hour and self.minute > time.minute:
  453.             return True
  454.         return False
  455.    
  456.     def nextSec(self):
  457.         return self.add(Time(0,1))
  458.    
  459.     def prevSec(self):
  460.         return self.sub(Time(0,1))
  461.    
  462.     def nonNeg(self):
  463.         return self.hour >= 0 and self.minute >= 0
  464.    
  465.     def hasLen(self):
  466.         return self.hour > 0 or self.minute > 0
  467.  
  468. def eventCompare(event1,event2):
  469.     deltah = event1.start.hour - event2.start.hour
  470.     if deltah == 0:
  471.         return event1.start.minute - event2.start.minute
  472.     else:
  473.         return deltah
  474.  
  475. #Class for Events
  476. class Event:
  477.     #intialization
  478.     def __init__(self, timeStart, timeEnd):
  479.         self.start = timeStart
  480.         self.end = timeEnd
  481.    
  482.     #toString function
  483.     def __str__(self):
  484.         return "{}-{}".format(str(self.start), str(self.end))
  485.    
  486.     #finds out how long the event is
  487.     def getLength(self):
  488.         return self.end.sub(self.start)
  489.    
  490.     #checks to see if two events overlap at all
  491.     def overlaps(self, event):
  492.         return self.end.isLaterThan(event.start)
  493.    
  494.     def isOvernight(self):
  495.         return self.start.isLaterThan(self.end)
  496.        
  497.     def isLongerThan(self, event):
  498.         return self.getLength().sub(event.getLength()).nonNeg()
  499.    
  500.     def joinOvernight(self, other):
  501.         if self.hour == 0 and self.minute == 0 and other.hour == 23 and other.minute == 59:
  502.             return Event(other.start, self.end)
  503.         if self.hour == 23 and self.minute == 59 or other.hour == 0 and other.minute == 0:
  504.             return Event(self.start, other.end)
  505.         return None
  506.  
  507. # returns a single Event from a string 'HH:MM-HH:MM'
  508. def getEvent(s):
  509.     times = s.split('-') # splits it up into [HH:MM,HH:MM]
  510.     events = [times[0].split(':'),times[1].split(':')] # splits it up into [[HH,MM],[HH,MM]]
  511.    
  512.     # it seems to like the stupid way
  513.     for i in range(2):
  514.         for j in range(2):
  515.             events[i][j] = int(events[i][j])
  516.            
  517.     return Event(Time(events[0][0],events[0][1]), Time(events[1][0],events[1][1]))
  518.  
  519. # returns a tuple of (minSleep, maxAwake, [Events])
  520. # also does most of the work
  521. def input():
  522.     (minSleep, maxAwake) = inputMinMax()
  523.     events = list()
  524.     imp = raw_input()
  525.     while len(imp) != 0:
  526.         events.append(getEvent(imp))
  527.         imp = raw_input()
  528.        
  529.     for e in events:
  530.         print e
  531.    
  532.    
  533.     events.sort(eventCompare)
  534.     events = overnight(events)
  535.     events.sort(eventCompare)
  536.     print "overnight done"
  537.     for e in events:
  538.         print e
  539.     freetime = complement(events)
  540.     freetime.sort(eventCompare)
  541.     print "freetime"
  542.     for e in freetime:
  543.         print e
  544.     freetime = checkA(freetime, minSleep)
  545.     freetime.sort(eventCompare)
  546.     print "A checked"
  547.     for e in freetime:
  548.         print e
  549.    
  550.     events = complement(freetime)
  551.     events.sort(eventCompare)
  552.    
  553.    
  554.     return ((minSleep, maxAwake), "A", freetime, "B", events)
  555.    
  556.    
  557. #checks for events that go over midnight
  558. def overnight(events):
  559.     x = events.pop()
  560.     if x.isOvernight():
  561.         y = Event(Time(x.start.hour, x.start.minute), Time(23, 59))
  562.         z = Event(Time(00, 00), Time(x.end.hour, x.end.minute))
  563.         events.append(y)
  564.         events.append(z)
  565.     else:
  566.         events.append(x)
  567.     return events
  568.  
  569.  
  570. #Gets A and B
  571. def inputMinMax():
  572.     s = raw_input("'min max' := ")
  573.     minmax = s.split()
  574.     min = int(minmax[0])
  575.     max = int(minmax[1])
  576.     return (min,max)
  577.    
  578. #returns a maximized list of valid times for sleep
  579. # takes the complement of events needed to attend
  580. def checkA(events, A):
  581.     A = Event(Time(0, 0), Time(A, 0))
  582.     eventsA = list()
  583.     for e in events:
  584.         if e.isLongerThan(A) or e.getLength() == A.getLength():
  585.             eventsA.append(e)
  586.    
  587.     if events[0].start.hour == 0 and events[0].start.minute == 0 and events[len(events)-1].end.hour == 23 and events[len(events)-1].end.minute == 59:
  588.         # given overnight 23:00-01:00 (00:00-01:00 23:00-23-59)
  589.         # create a new event from 23:00-25:00
  590.         overn = Event(events[len(events)-1].start, events[0].end.add(Time(24,0)))
  591.         if overn.isLongerThan(A):
  592.             eventsA.append(events[0])
  593.             eventsA.append(events[len(events)-1])
  594.     return eventsA
  595.    
  596. #returns a list of events that force the cat to be awake too long
  597. def checkB(events, B):
  598.     for e in events:
  599.         if e.getLength().sub(B).hasLen():
  600.             events.remove(e)
  601.     return events
  602.    
  603. def complement(events):
  604.     comp = list()
  605.     if events[0].start.hasLen():
  606.         x = Event(Time(0,0), events[0].start.prevSec())
  607.         if not x.start.isLaterThan(x.end):
  608.             comp.append(x)
  609.     for i in range(len(events)-1):
  610.         y = Event(events[i].end.nextSec(), events[i+1].start.prevSec())
  611.         if y.getLength().hasLen():
  612.             comp.append(y)
  613.     if  events[len(events)-1] != Time(23, 59):
  614.         z = Event(events[len(events)-1].end.nextSec(), Time(23,59))
  615.         if not z.start.isLaterThan(z.end):
  616.             comp.append(z)
  617.     return comp
  618.    
  619.    
  620. #################################
  621. t = input()
  622. print "","input done"
  623. #for e in t[1]:
  624. #   print e
  625. for m in t:
  626.     for n in m:
  627.         print n
  628.  
  629. # A = Event(Time(0,0),Time(2,0))
  630. # B = Event(Time(0,0),Time(3,0))
  631. #
  632. # print A,B
  633. # print B.isLongerThan(A)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement