Adds some of the code I generated while studying for a role transfer at Google using the fantastic resource, InterviewCake.com. This work predates the mono-repo. I should think of ways to DRY up this code and the code in crack_the_coding_interview, but I'm afraid I'm creating unnecessary work for myself that way.
		
			
				
	
	
		
			94 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			94 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from heapq import heappush, heappop
 | 
						|
from collections import deque
 | 
						|
from fixtures import weighted_graph, expanded_weights_graph
 | 
						|
 | 
						|
# UnweightedGraph(a) :: Map(a, Set(a))
 | 
						|
# WeightedGraph(a) :: Map(a, Set(a))
 | 
						|
 | 
						|
 | 
						|
# shortest_path_dijkstra :: Vertex -> Vertex -> WeightedGraph(Vertex)
 | 
						|
def shortest_path_dijkstra(a, b, g):
 | 
						|
    q = []
 | 
						|
    seen = set()
 | 
						|
 | 
						|
    heappush(q, (0, a, [a]))
 | 
						|
 | 
						|
    while q:
 | 
						|
        w0, v0, path = heappop(q)
 | 
						|
        if v0 in seen:
 | 
						|
            continue
 | 
						|
        elif v0 == b:
 | 
						|
            return w0, path
 | 
						|
        for w1, v1 in g.get(v0):
 | 
						|
            heappush(q, (w0 + w1, v1, path + [v1]))
 | 
						|
        seen.add(v0)
 | 
						|
    return 'weighted', 'pizza'
 | 
						|
 | 
						|
 | 
						|
# expand_edge :: Vertex -> (Weight, Vertex) -> Map(Vertex, [Vertex])
 | 
						|
def expand_edge(v0, wv):
 | 
						|
    w, v1 = wv
 | 
						|
    assert w > 1
 | 
						|
 | 
						|
    result = {v0: ['{}-{}'.format(v1, 1)]}
 | 
						|
    for x in range(w - 2):
 | 
						|
        result['{}-{}'.format(v1, x + 1)] = ['{}-{}'.format(v1, x + 2)]
 | 
						|
    result['{}-{}'.format(v1, w - 1)] = [v1]
 | 
						|
 | 
						|
    return result
 | 
						|
 | 
						|
 | 
						|
# expand_weights :: Vertex -> WeightedGraph(Vertex) -> UnweightedGraph(Vertex)
 | 
						|
def expand_weights(v, g):
 | 
						|
    result = {}
 | 
						|
    q = deque()
 | 
						|
    seen = set()
 | 
						|
 | 
						|
    q.append(v)
 | 
						|
    while q:
 | 
						|
        v = d.popleft()
 | 
						|
        if v in seen:
 | 
						|
            continue
 | 
						|
        x = expand_edge(v, g.get)
 | 
						|
        for w, v1 in g.get(v):
 | 
						|
            if w > 1:
 | 
						|
                ws = expand_edge(v, (w, v1))
 | 
						|
                result = {**result, **ws}
 | 
						|
            q.append(v)
 | 
						|
        pass
 | 
						|
 | 
						|
 | 
						|
# shortest_path_inject :: Vertex -> Vertex -> WeightedGraph(Vertex)
 | 
						|
def shortest_path_inject(a, b, g):
 | 
						|
    q = deque()
 | 
						|
    seen = set()
 | 
						|
 | 
						|
    q.append((a, [a]))
 | 
						|
 | 
						|
    while q:
 | 
						|
        v0, path = q.popleft()
 | 
						|
        if v0 == 'dummy':
 | 
						|
            continue
 | 
						|
        elif v0 in seen:
 | 
						|
            continue
 | 
						|
        elif v0 == b:
 | 
						|
            return len(path), path
 | 
						|
        for _, v1 in g.get(v0):
 | 
						|
            q.append((v1, path + [v1]))
 | 
						|
        seen.add(v0)
 | 
						|
        continue
 | 
						|
 | 
						|
    return None, None
 | 
						|
 | 
						|
 | 
						|
print(expand_edge('a', (4, 'b')))
 | 
						|
print(expand_edge('a', (5, 'e')))
 | 
						|
assert expand_weights('a', weighted_graph) == expanded_weights_graph
 | 
						|
# a = 'a'
 | 
						|
# b = 'd'
 | 
						|
# w, x = shortest_path_dijkstra(a, b, weighted_graph)
 | 
						|
# w1, x1 = shortest_path_inject(a, b, weighted_graph)
 | 
						|
# print("[dijkstra]  Shortest path from {} to {} is {} with weight {}".format(
 | 
						|
#     a, b, x, w))
 | 
						|
# print("[injection] Shortest path from {} to {} is {} with weight {}".format(
 | 
						|
#     a, b, x1, w1))
 |