diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b844b14 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +Gemfile.lock diff --git a/lib/possible_bipartition.rb b/lib/possible_bipartition.rb index 69507f1..7206ec2 100644 --- a/lib/possible_bipartition.rb +++ b/lib/possible_bipartition.rb @@ -1,4 +1,47 @@ +# PSEUDOCODE +# BFS --> queue +# Groupings array for each dog (size of input array) --> can be 0 or 1 (since bipartition) +# >> rule will be current_grouping = 1 - current_grouping +# If a dog / node hasn't been encountered yet (grouping of -1), then add to queue and set grouping +# If a node grouping ever violates (same as the current node's grouping), then return false + +# Time Complexity: O(N+E) -- visit every single node and every one of its edges +# >> Outer loop: O(n) where n is size of input array +# >> Inner loop: O(e) where e is the number of edges +# Space Complexity: O(N) +# >> Queue depends on size of input array +# >> groupings array will be size of input array def possible_bipartition(dislikes) - raise NotImplementedError, "possible_bipartition isn't implemented yet" + return true if dislikes.empty? + + dog_queue = Queue.new + dog_queue << 0 + dog_groupings = [-1] * dislikes.size + current_grouping = 0 + + until dog_queue.empty? + current_dog = dog_queue.pop + if dog_groupings[current_dog] == -1 + dog_groupings[current_dog] = 1 - current_grouping + current_grouping = 1 - current_grouping + else + current_grouping = dog_groupings[current_dog] + end + + disliked_dogs = dislikes[current_dog] + disliked_dogs&.each do |dog| + return false if dog_groupings[dog] == current_grouping + + if dog_groupings[dog] == -1 + dog_groupings[dog] = 1 - current_grouping + dog_queue << dog + end + end + + dog_queue << current_dog + 1 if current_dog + 1 < dislikes.size && dog_queue.empty? + end + + return true end + diff --git a/test/possible_bipartition_test.rb b/test/possible_bipartition_test.rb index 5274935..0c18842 100644 --- a/test/possible_bipartition_test.rb +++ b/test/possible_bipartition_test.rb @@ -1,9 +1,10 @@ -require_relative "test_helper" +require_relative 'test_helper' -describe "possible_bipartition" do - it "will work for example 1" do +describe 'possible_bipartition' do + it 'will work for example 1' do # Arrange - dislikes = [ [], + dislikes = [ + [], [2, 3], [1, 4], [1], @@ -17,9 +18,10 @@ expect(answer).must_equal true end - it "will work for example 2" do + it 'will work for example 2' do # Arrange - dislikes = [ [], + dislikes = [ + [], [2, 3], [1, 3], [1, 2] @@ -32,7 +34,7 @@ expect(answer).must_equal false end - it "will work for example 3" do + it 'will work for example 3' do # Arrange dislikes = [ [], [2, 5], @@ -49,9 +51,10 @@ expect(answer).must_equal false end - it "will return true for a graph which can be bipartitioned" do + it 'will return true for a graph which can be bipartitioned' do # Arrange - dislikes = [ [3, 6], + dislikes = [ + [3, 6], [2, 5], [1, 3], [0, 2], @@ -68,9 +71,10 @@ end - it "will return false for a graph which cannot be bipartitioned" do + it 'will return false for a graph which cannot be bipartitioned' do # Arrange - dislikes = [ [3, 6], + dislikes = [ + [3, 6], [2, 5], [1, 3], [0, 2, 4], @@ -86,11 +90,11 @@ expect(answer).must_equal false end - it "will work for an empty graph" do + it 'will work for an empty graph' do expect(possible_bipartition([])).must_equal true end - it "will return false for a graph which cannot be bipartitioned" do + it 'will return false for a graph which cannot be bipartitioned' do # Arrange dislikes = [ [3, 6], [2, 5],