Created
March 21, 2018 21:50
-
-
Save StevenJL/42cf442e66b52cd10e0d143597384c84 to your computer and use it in GitHub Desktop.
Two colorable
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def alternate(color) | |
if color == :red | |
return :blue | |
else | |
return :red | |
end | |
end | |
class SameNeighborColorError < StandardError; end | |
class GraphNode | |
attr_accessor :color | |
attr_reader :neighbors | |
def initialize | |
@neighbors = [] | |
end | |
def add_neighbor(node) | |
@neighbors << node | |
end | |
end | |
def two_colorable?(node) | |
begin | |
color_node_and_neighbors(node, :red) | |
rescue SameNeighborColorError | |
return false | |
end | |
true | |
end | |
def color_node_and_neighbors(node, color) | |
# raise error if any of its neighbors already has this color | |
if node.neighbors.any? { |neighbor| neighbor.color == color } | |
raise SameNeighborColorError | |
end | |
# color the node | |
node.color = color | |
# check if it has any un-colored neighbors | |
return unless node.neighbors.any? { |neighbor| neighbor.color.nil? } | |
# attempt to color neighbors | |
next_color = alternate(color) | |
node.neighbors.each do |neighbor| | |
color_node_and_neighbors(neighbor, next_color) | |
end | |
end | |
# Test Cases | |
# Good Case (nodes in a row) | |
good_graph = GraphNode.new | |
node1 = GraphNode.new | |
node2 = GraphNode.new | |
node3 = GraphNode.new | |
node4 = GraphNode.new | |
good_graph.add_neighbor(node1) | |
node1.add_neighbor(node2) | |
node3.add_neighbor(node2) | |
node4.add_neighbor(node4) | |
unless two_colorable?(good_graph) | |
raise "Graph is 2-colorable but returned false" | |
end | |
# Bad Case (a triangle) | |
bad_graph = GraphNode.new | |
node1 = GraphNode.new | |
node2 = GraphNode.new | |
bad_graph.add_neighbor(node1) | |
node1.add_neighbor(node2) | |
node2.add_neighbor(bad_graph) | |
if two_colorable?(bad_graph) | |
raise "Graph is not 2-colorable but returned true" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment