Exemplo n.º 1
0
 def locs_connected_to(self, loc):
     """
 Returns a set of the locations on this proto board that are connected (
     internally or by wires) to |loc|.
 """
     connected_locs = set()
     queue = set(section_locs(loc))
     while queue:
         connected_loc = queue.pop()
         connected_locs.add(connected_loc)
         if connected_loc in self._wire_mappings:
             for wire_neighbor in section_locs(self._wire_mappings[connected_loc]):
                 if wire_neighbor not in connected_locs:
                     queue.add(wire_neighbor)
     return connected_locs
Exemplo n.º 2
0
 def locs_connected_to(self, loc):
   """
   Returns a set of the locations on this proto board that are connected (
       internally or by wires) to |loc|.
   """
   connected_locs = set()
   queue = set(section_locs(loc))
   while queue:
     connected_loc = queue.pop()
     connected_locs.add(connected_loc)
     if connected_loc in self._wire_mappings:
       for wire_neighbor in section_locs(self._wire_mappings[connected_loc]):
         if wire_neighbor not in connected_locs:
           queue.add(wire_neighbor)
   return connected_locs
Exemplo n.º 3
0
 def with_wire(self, new_wire):
   """
   Returns a new Proto_Board containing the |new_wire|. If the wire connects
       nodes that are already connected, this method returns this proto board.
       If the wire connects nodes that are meant not to be connected, as per
       |self._loc_disjoint_set_forest|, this method returns None. If the wire's
       locations don't match the wire's node, this method returns None.
   """
   # if locations are already connected, no need for the wire
   if self.connected(new_wire.loc_1, new_wire.loc_2):
     return self
   # if the wire results in a short, no new proto board
   new_wire_node_rep = self.rep_for(new_wire.node)
   group_1 = self.rep_for(new_wire.loc_1)
   if group_1 and group_1 is not new_wire_node_rep:
     return None
   group_2 = self.rep_for(new_wire.loc_2)
   if group_2 and group_2 is not new_wire_node_rep:
     return None
   if group_1 and group_2 and group_1 != group_2:
     return None
   new_wire_mappings = self._wire_mappings.copy()
   new_wire_mappings[new_wire.loc_1] = new_wire.loc_2
   new_wire_mappings[new_wire.loc_2] = new_wire.loc_1
   new_loc_disjoint_set_forest = self._loc_disjoint_set_forest.copy()
   # update to avoid shorts that may result via the new wire
   if bool(group_1) != bool(group_2):
     present_loc = new_wire.loc_1 if group_1 else new_wire.loc_2
     absent_loc = new_wire.loc_1 if present_loc == new_wire.loc_2 else (
         new_wire.loc_2)
     for loc in section_locs(absent_loc):
       new_loc_disjoint_set_forest.make_set(loc)
       new_loc_disjoint_set_forest.union(present_loc, loc)
   return Proto_Board(new_wire_mappings, self._wires + [new_wire],
       self._pieces, new_loc_disjoint_set_forest)
Exemplo n.º 4
0
 def with_wire(self, new_wire):
     """
 Returns a new Proto_Board containing the |new_wire|. If the wire connects
     nodes that are already connected, this method returns this proto board.
     If the wire connects nodes that are meant not to be connected, as per
     |self._loc_disjoint_set_forest|, this method returns None. If the wire's
     locations don't match the wire's node, this method returns None.
 """
     # if locations are already connected, no need for the wire
     if self.connected(new_wire.loc_1, new_wire.loc_2):
         return self
     # if the wire results in a short, no new proto board
     new_wire_node_rep = self.rep_for(new_wire.node)
     group_1 = self.rep_for(new_wire.loc_1)
     if group_1 and group_1 is not new_wire_node_rep:
         return None
     group_2 = self.rep_for(new_wire.loc_2)
     if group_2 and group_2 is not new_wire_node_rep:
         return None
     if group_1 and group_2 and group_1 != group_2:
         return None
     new_wire_mappings = self._wire_mappings.copy()
     new_wire_mappings[new_wire.loc_1] = new_wire.loc_2
     new_wire_mappings[new_wire.loc_2] = new_wire.loc_1
     new_loc_disjoint_set_forest = self._loc_disjoint_set_forest.copy()
     # update to avoid shorts that may result via the new wire
     if bool(group_1) != bool(group_2):
         present_loc = new_wire.loc_1 if group_1 else new_wire.loc_2
         absent_loc = new_wire.loc_1 if present_loc == new_wire.loc_2 else (new_wire.loc_2)
         for loc in section_locs(absent_loc):
             new_loc_disjoint_set_forest.make_set(loc)
             new_loc_disjoint_set_forest.union(present_loc, loc)
     return Proto_Board(new_wire_mappings, self._wires + [new_wire], self._pieces, new_loc_disjoint_set_forest)
Exemplo n.º 5
0
 def node_for(self, loc):
   """
   If |loc| is internally connected to one of the locations on the proto board
       occupied by this piece, returns the node for |loc|. Returns None
       otherwise.
   """
   for node in self.nodes:
     for node_loc in self.locs_for(node):
       if loc in section_locs(node_loc):
         return node
   return None
Exemplo n.º 6
0
 def _connected(self, loc_1, loc_2, visited):
   """
   Helper for self.connected, see below.
   """
   if loc_1 in visited:
     return False
   group = set(section_locs(loc_1))
   new_visited = visited | group
   return loc_2 in group or any(map(lambda new_loc_1: self._connected(
       new_loc_1, loc_2, new_visited), (self._wire_mappings[loc] for loc in
       group if loc in self._wire_mappings)))
Exemplo n.º 7
0
 def node_for(self, loc):
     """
 If |loc| is internally connected to one of the locations on the proto board
     occupied by this piece, returns the node for |loc|. Returns None
     otherwise.
 """
     for node in self.nodes:
         for node_loc in self.locs_for(node):
             if loc in section_locs(node_loc):
                 return node
     return None
Exemplo n.º 8
0
 def with_loc_repped(self, rep, loc):
   """
   Returns a new Proto_Board with the given |loc| and the locations internally
       connected to it being members of the group of locations represented by
       |rep|.
   """
   assert self.rep_for(rep)
   assert not self.rep_for(loc)
   new_loc_disjoint_set_forest = self._loc_disjoint_set_forest.copy()
   for section_loc in section_locs(loc):
     new_loc_disjoint_set_forest.make_set(section_loc)
     new_loc_disjoint_set_forest.union(rep, section_loc)
   return self.with_loc_disjoint_set_forest(new_loc_disjoint_set_forest)
Exemplo n.º 9
0
 def with_loc_repped(self, rep, loc):
     """
 Returns a new Proto_Board with the given |loc| and the locations internally
     connected to it being members of the group of locations represented by
     |rep|.
 """
     assert self.rep_for(rep)
     assert not self.rep_for(loc)
     new_loc_disjoint_set_forest = self._loc_disjoint_set_forest.copy()
     for section_loc in section_locs(loc):
         new_loc_disjoint_set_forest.make_set(section_loc)
         new_loc_disjoint_set_forest.union(rep, section_loc)
     return self.with_loc_disjoint_set_forest(new_loc_disjoint_set_forest)
Exemplo n.º 10
0
 def _connected(self, loc_1, loc_2, visited):
     """
 Helper for self.connected, see below.
 """
     if loc_1 in visited:
         return False
     group = set(section_locs(loc_1))
     new_visited = visited | group
     return loc_2 in group or any(
         map(
             lambda new_loc_1: self._connected(new_loc_1, loc_2, new_visited),
             (self._wire_mappings[loc] for loc in group if loc in self._wire_mappings),
         )
     )
Exemplo n.º 11
0
 def with_piece(self, piece):
   """
   Returns a new Proto_Board containing the given |piece|. If the piece
       collides with another object on the board, this method raises an
       Exception.
   """
   # check for intersections with current objects on the board
   if any(piece.crossed_by(wire) for wire in self._wires) or any(
       piece.overlaps_with(other_piece) for other_piece in self._pieces):
     raise Exception('new piece overlaps with existing piece')
   # add new piece to pieces
   new_pieces = self._pieces.copy()
   new_pieces.add(piece)
   # account for piece sacred locations, i.e. make sure these locations never
   #     get connected to another node in the circuit
   new_loc_disjoint_set_forest = self._loc_disjoint_set_forest.copy()
   for loc in piece.get_sacred_locs():
     new_loc_disjoint_set_forest.make_set(loc)
     for section_loc in section_locs(loc):
       new_loc_disjoint_set_forest.make_set(section_loc)
       new_loc_disjoint_set_forest.union(loc, section_loc)
   return Proto_Board(self._wire_mappings, self._wires, new_pieces,
       new_loc_disjoint_set_forest)
Exemplo n.º 12
0
 def with_piece(self, piece):
     """
 Returns a new Proto_Board containing the given |piece|. If the piece
     collides with another object on the board, this method raises an
     Exception.
 """
     # check for intersections with current objects on the board
     if any(piece.crossed_by(wire) for wire in self._wires) or any(
         piece.overlaps_with(other_piece) for other_piece in self._pieces
     ):
         raise Exception("new piece overlaps with existing piece")
     # add new piece to pieces
     new_pieces = self._pieces.copy()
     new_pieces.add(piece)
     # account for piece sacred locations, i.e. make sure these locations never
     #     get connected to another node in the circuit
     new_loc_disjoint_set_forest = self._loc_disjoint_set_forest.copy()
     for loc in piece.get_sacred_locs():
         new_loc_disjoint_set_forest.make_set(loc)
         for section_loc in section_locs(loc):
             new_loc_disjoint_set_forest.make_set(section_loc)
             new_loc_disjoint_set_forest.union(loc, section_loc)
     return Proto_Board(self._wire_mappings, self._wires, new_pieces, new_loc_disjoint_set_forest)