This documentation is automatically generated by online-judge-tools/verification-helper
require "spec" require "../src/graph" describe DiGraph do it ".weighted?, .directed?" do DiGraph.weighted?.should be_true DiGraph.directed?.should be_true end it ".new(size)" do g = DiGraph(Int32).new(5) g.size.should eq 5 g.to_a.should eq [] of WeightedEdge2(Int32) expect_raises(ArgumentError) { DiGraph(Int32).new(-2) } end it ".new(n, edges)" do edges = [WeightedEdge2.new(0, 1, 10), WeightedEdge2.new(1, 0, 11)] g = DiGraph.new 2, edges g.to_a.should eq edges g = DiGraph.new 2, edges.values_at(0, 1) g.to_a.should eq edges g = DiGraph.new 2, [{0, 1, 10}, {1, 0, 11}] g.to_a.should eq edges expect_raises(IndexError) { DiGraph.new 1, [WeightedEdge2.new(0, 1, 10)] } end it "#<<, #add_edges" do g = DiGraph(Int32).new(5) edges = [ WeightedEdge2.new(0, 1, 10), WeightedEdge2.new(0, 1, 11), WeightedEdge2.new(1, 2, 12), WeightedEdge2.new(2, 3, 13), WeightedEdge2.new(3, 4, 14), ] (g << edges[0]).should be g g << {0, 1, 11} g << {1, 2, 12} g.add_edges(edges[3..4]).should be g expect_raises(IndexError) { g << {4, 5, -1} } g[0].should eq [WeightedEdge.new(1, 10), WeightedEdge.new(1, 11)] g[1].should eq [WeightedEdge.new(2, 12)] g.to_a.should eq edges end it "#reverse" do edges = [ WeightedEdge2.new(0, 1, 10), WeightedEdge2.new(0, 1, 11), WeightedEdge2.new(1, 2, 12), WeightedEdge2.new(2, 3, 13), WeightedEdge2.new(3, 4, 14), ] g = DiGraph(Int32).new(5, edges) g.reverse.to_a.should eq edges.map(&.reverse) end it "#to_undirected" do edges = [ WeightedEdge2.new(0, 1, 10), WeightedEdge2.new(0, 1, 11), WeightedEdge2.new(1, 2, 12), WeightedEdge2.new(2, 3, 13), WeightedEdge2.new(3, 4, 14), ] g = DiGraph(Int32).new(5, edges) g.to_undirected.to_set.should eq edges.flat_map { |e| [e, e.reverse] }.to_set end end describe UnGraph do it ".weighted?, .directed?" do UnGraph.weighted?.should be_true UnGraph.directed?.should be_false end it "#.new(size)" do g = UnGraph(Int32).new(5) g.size.should eq 5 g.to_a.should eq [] of WeightedEdge2(Int32) expect_raises(ArgumentError) { UnGraph(Int32).new(-2) } end it ".new(n, edges)" do edges = [WeightedEdge2.new(0, 1, 10), WeightedEdge2.new(0, 1, 11), WeightedEdge2.new(1, 0, 10), WeightedEdge2.new(1, 0, 11)] g = UnGraph.new 2, [edges[0], edges[3]] g.to_a.should eq edges g = UnGraph.new 2, edges.values_at(0, 3) g.to_a.should eq edges g = UnGraph.new 2, [{0, 1, 10}, {1, 0, 11}] g.to_a.should eq edges expect_raises(IndexError) { UnGraph.new 1, [WeightedEdge2.new(0, 1, 10)] } end it "#<<, #add_edges" do edges = [ [WeightedEdge.new(1, 10)], [WeightedEdge.new(0, 10), WeightedEdge.new(2, 11)], [WeightedEdge.new(1, 11), WeightedEdge.new(3, 12)], [WeightedEdge.new(2, 12)], ] all_edges = [ WeightedEdge2.new(0, 1, 10), WeightedEdge2.new(1, 0, 10), WeightedEdge2.new(1, 2, 11), WeightedEdge2.new(2, 1, 11), WeightedEdge2.new(2, 3, 12), WeightedEdge2.new(3, 2, 12), ] g = UnGraph(Int32).new(4) (g << {0, 1, 10}).should be g g << {1, 2, 11} g << WeightedEdge2.new(2, 3, 12) g[0].should eq edges[0] g[1].should eq edges[1] g[2].should eq edges[2] g[3].should eq edges[3] g.to_a.should eq all_edges g = UnGraph(Int32).new(4) g.add_edges([{0, 1, 10}]).should be g g.add_edges({WeightedEdge2.new(1, 2, 11), WeightedEdge2.new(2, 3, 12)}) g[0].should eq edges[0] g[1].should eq edges[1] g[2].should eq edges[2] g[3].should eq edges[3] g.to_a.should eq all_edges end it "#reverse" do all_edges = [ WeightedEdge2.new(0, 1, 10), WeightedEdge2.new(1, 0, 10), WeightedEdge2.new(1, 2, 11), WeightedEdge2.new(2, 1, 11), WeightedEdge2.new(2, 3, 12), WeightedEdge2.new(3, 2, 12), ] g = UnGraph(Int32).new(4) g << {0, 1, 10} << {1, 2, 11} << {2, 3, 12} g.reverse.to_set.should eq all_edges.map(&.reverse).to_set end it "#to_undirected" do all_edges = [ WeightedEdge2.new(0, 1, 10), WeightedEdge2.new(1, 0, 10), WeightedEdge2.new(1, 2, 11), WeightedEdge2.new(2, 1, 11), WeightedEdge2.new(2, 3, 12), WeightedEdge2.new(3, 2, 12), ] g = UnGraph(Int32).new(4) g << {0, 1, 10} << {1, 2, 11} << {2, 3, 12} g.to_undirected.to_set.should eq all_edges.map(&.reverse).to_set end it "#each_child" do g = UnGraph(Int32).new(6) g << {0, 1, 1} << {0, 2, 2} << {0, 3, 3} << {3, 4, 4} << {3, 5, 5} v = [] of Int32 g.each_child(0, nil) { |e| v << e.to } v.should eq [1, 2, 3] v.clear g.each_child(3, nil) { |e| v << e.to } v.should eq [0, 4, 5] v.clear g.each_child(3, 0) { |e| v << e.to } v.should eq [4, 5] g.each_child(0, nil).map(&.to).to_a.should eq [1, 2, 3] g.each_child(3, nil).map(&.to).to_a.should eq [0, 4, 5] g.each_child(3, 0).map(&.to).to_a.should eq [4, 5] end end describe UnweightedDiGraph do it ".weighted?, .directed?" do UnweightedDiGraph.weighted?.should be_false UnweightedDiGraph.directed?.should be_true end it ".new(size)" do g = UnweightedDiGraph.new(5) g.size.should eq 5 g.to_a.should eq [] of UnweightedEdge2 expect_raises(ArgumentError) { UnweightedDiGraph.new(-2) } end it ".new(n, edges)" do edges = [UnweightedEdge2.new(0, 1), UnweightedEdge2.new(1, 0)] g = UnweightedDiGraph.new 2, edges g.to_a.should eq edges g = UnweightedDiGraph.new 2, edges.values_at(0, 1) g.to_a.should eq edges g = UnweightedDiGraph.new 2, [{0, 1}, {1, 0}] g.to_a.should eq edges expect_raises(IndexError) { UnweightedDiGraph.new 1, [UnweightedEdge2.new(0, 1)] } end it "#<<, #add_edges" do g = UnweightedDiGraph.new(5) edges = [ UnweightedEdge2.new(0, 1), UnweightedEdge2.new(0, 1), UnweightedEdge2.new(1, 2), UnweightedEdge2.new(2, 3), UnweightedEdge2.new(3, 4), ] (g << edges[0]).should be g g << {0, 1} g << {1, 2} g.add_edges(edges[3..4]).should be g expect_raises(IndexError) { g << {4, 5} } g[0].should eq [UnweightedEdge.new(1), UnweightedEdge.new(1)] g[1].should eq [UnweightedEdge.new(2)] g.to_a.should eq edges end it "#reverse" do edges = [ UnweightedEdge2.new(0, 1), UnweightedEdge2.new(0, 1), UnweightedEdge2.new(1, 2), UnweightedEdge2.new(2, 3), UnweightedEdge2.new(3, 4), ] g = UnweightedDiGraph.new(5, edges) g.reverse.to_a.should eq edges.map(&.reverse) end it "#to_undirected" do edges = [ UnweightedEdge2.new(0, 1), UnweightedEdge2.new(0, 1), UnweightedEdge2.new(1, 2), UnweightedEdge2.new(2, 3), UnweightedEdge2.new(3, 4), ] g = UnweightedDiGraph.new(5, edges) g.to_undirected.to_set.should eq edges.flat_map { |e| [e, e.reverse] }.to_set end end describe UnweightedUnGraph do it ".weighted?, .directed?" do UnweightedUnGraph.weighted?.should be_false UnweightedUnGraph.directed?.should be_false end it "#.new(size)" do g = UnweightedUnGraph.new(5) g.size.should eq 5 g.to_a.should eq [] of UnweightedEdge2 expect_raises(ArgumentError) { UnweightedUnGraph.new(-2) } end it ".new(n, edges)" do edges = [UnweightedEdge2.new(0, 1), UnweightedEdge2.new(0, 1), UnweightedEdge2.new(1, 0), UnweightedEdge2.new(1, 0)] g = UnweightedUnGraph.new 2, [edges[0], edges[3]] g.to_a.should eq edges g = UnweightedUnGraph.new 2, edges.values_at(0, 3) g.to_a.should eq edges g = UnweightedUnGraph.new 2, [{0, 1}, {1, 0}] g.to_a.should eq edges expect_raises(IndexError) { UnweightedUnGraph.new 1, [UnweightedEdge2.new(0, 1)] } end it "#<<, #add_edges" do edges = [ [UnweightedEdge.new(1)], [UnweightedEdge.new(0), UnweightedEdge.new(2)], [UnweightedEdge.new(1), UnweightedEdge.new(3)], [UnweightedEdge.new(2)], ] all_edges = [ UnweightedEdge2.new(0, 1), UnweightedEdge2.new(1, 0), UnweightedEdge2.new(1, 2), UnweightedEdge2.new(2, 1), UnweightedEdge2.new(2, 3), UnweightedEdge2.new(3, 2), ] g = UnweightedUnGraph.new(4) (g << {0, 1}).should be g g << {1, 2} g << UnweightedEdge2.new(2, 3) g[0].should eq edges[0] g[1].should eq edges[1] g[2].should eq edges[2] g[3].should eq edges[3] g.to_a.should eq all_edges g = UnweightedUnGraph.new(4) g.add_edges([{0, 1}]).should be g g.add_edges({UnweightedEdge2.new(1, 2), UnweightedEdge2.new(2, 3)}) g[0].should eq edges[0] g[1].should eq edges[1] g[2].should eq edges[2] g[3].should eq edges[3] g.to_a.should eq all_edges end it "#reverse" do all_edges = [ UnweightedEdge2.new(0, 1), UnweightedEdge2.new(1, 0), UnweightedEdge2.new(1, 2), UnweightedEdge2.new(2, 1), UnweightedEdge2.new(2, 3), UnweightedEdge2.new(3, 2), ] g = UnweightedUnGraph.new(4) g << {0, 1} << {1, 2} << {2, 3} g.reverse.to_set.should eq all_edges.to_set end it "#to_undirected" do all_edges = [ UnweightedEdge2.new(0, 1), UnweightedEdge2.new(1, 0), UnweightedEdge2.new(1, 2), UnweightedEdge2.new(2, 1), UnweightedEdge2.new(2, 3), UnweightedEdge2.new(3, 2), ] g = UnweightedUnGraph.new(4) g << {0, 1} << {1, 2} << {2, 3} g.to_undirected.to_set.should eq all_edges.to_set end it "#each_child" do g = UnweightedUnGraph.new(6) g << {0, 1} << {0, 2} << {0, 3} << {3, 4} << {3, 5} v = [] of Int32 g.each_child(0, nil) { |e| v << e.to } v.should eq [1, 2, 3] v.clear g.each_child(3, nil) { |e| v << e.to } v.should eq [0, 4, 5] v.clear g.each_child(3, 0) { |e| v << e.to } v.should eq [4, 5] g.each_child(0, nil).map(&.to).to_a.should eq [1, 2, 3] g.each_child(3, nil).map(&.to).to_a.should eq [0, 4, 5] g.each_child(3, 0).map(&.to).to_a.should eq [4, 5] end end
require "spec" # require "../src/graph" # require "./graph/edge" struct WeightedEdge(T) include Comparable(WeightedEdge(T)) property to : Int32, cost : T def initialize(@to, @cost : T) end def <=>(other : WeightedEdge(T)) {cost, to} <=> {other.cost, other.to} end def to_s(io) : Nil io << '(' << to << ", " << cost << ')' end def inspect(io) : Nil io << "->" << to << '(' << cost << ')' end end struct WeightedEdge2(T) include Comparable(WeightedEdge2(T)) property from : Int32, to : Int32, cost : T def initialize(@from, @to, @cost : T) end def initialize(@from, edge : WeightedEdge(T)) @to, @cost = edge.to, edge.cost end def <=>(other : WeightedEdge2(T)) {cost, from, to} <=> {other.cost, other.from, other.to} end def reverse : self WeightedEdge2(T).new(to, from, cost) end def sort : self WeightedEdge2(T).new(*{to, from}.minmax, cost) end def to_s(io) : Nil io << '(' << from << ", " << to << ", " << cost << ')' end def inspect(io) : Nil io << from << "->" << to << '(' << cost << ')' end end struct UnweightedEdge property to : Int32 def initialize(@to) end def initialize(@to, cost) end def cost : Int32 1 end def to_s(io) : Nil io << to end def inspect(io) : Nil io << "->" << to end end struct UnweightedEdge2 property from : Int32, to : Int32 def initialize(@from, @to) end def initialize(@from, @to, cost) end def initialize(@from, edge : UnweightedEdge) @to = edge.to end def cost : Int32 1 end def reverse : self UnweightedEdge2.new(to, from) end def sort : self UnweightedEdge2.new(*{to, from}.minmax) end def to_s(io) : Nil io << '(' << from << ", " << to << ')' end def inspect(io) : Nil io << from << "->" << to end end module Graph(Edge, Edge2) include Enumerable(Edge2) getter graph : Array(Array(Edge)) def initialize(size : Int) @graph = Array(Array(Edge)).new(size) { [] of Edge } end def initialize(size : Int, edges : Enumerable) initialize(size) add_edges(edges) end # Add *edge*. abstract def <<(edge : Edge2) # :ditto: def <<(edge : Tuple) : self self << Edge2.new(*edge) end def add_edges(edges : Enumerable) : self edges.each { |edge| self << edge } self end delegate size, :[], to: @graph # Yields each edge of the graph, ans returns `nil`. def each(&) : Nil (0...size).each do |v| graph[v].each do |edge| yield Edge2.new(v, edge) end end end def each_child(vertex : Int, parent, &block) : Nil graph[vertex].each do |edge| yield edge if edge.to != parent end end def each_child(vertex : Int, parent) graph[vertex].each.reject(&.to.== parent) end def reverse : self if self.class.directed? each_with_object(self.class.new(size)) do |edge, reversed| reversed << edge.reverse end else dup end end def to_undirected : self if self.class.directed? each_with_object(self.class.new(size)) do |edge, graph| graph << edge << edge.reverse end else dup end end def to_s(io : IO) : Nil io << '[' join(", ", io) do |edge, io| edge.inspect io end io << ']' end def inspect(io : IO) : Nil io << "[\n" graph.each do |edges| io << " " << edges << ",\n" end io << ']' end end class DiGraph(T) include Graph(WeightedEdge(T), WeightedEdge2(T)) def self.weighted? true end def self.directed? true end def initialize(size : Int) super end def initialize(size : Int, edges : Enumerable(WeightedEdge2(T))) super end def initialize(size : Int, edges : Enumerable({Int32, Int32, T})) super end def <<(edge : WeightedEdge2(T)) : self raise IndexError.new unless 0 <= edge.from < size && 0 <= edge.to < size @graph[edge.from] << WeightedEdge.new(edge.to, edge.cost) self end end class UnGraph(T) include Graph(WeightedEdge(T), WeightedEdge2(T)) def self.weighted? true end def self.directed? false end def initialize(size : Int) super end def initialize(size : Int, edges : Enumerable(WeightedEdge2(T))) super end def initialize(size : Int, edges : Enumerable({Int32, Int32, T})) super end def <<(edge : WeightedEdge2(T)) : self raise IndexError.new unless 0 <= edge.from < size && 0 <= edge.to < size @graph[edge.from] << WeightedEdge.new(edge.to, edge.cost) @graph[edge.to] << WeightedEdge.new(edge.from, edge.cost) self end end class UnweightedDiGraph include Graph(UnweightedEdge, UnweightedEdge2) def self.weighted? false end def self.directed? true end def initialize(size : Int) super end def initialize(size : Int, edges : Enumerable) super end def <<(edge : UnweightedEdge2) : self raise IndexError.new unless 0 <= edge.from < size && 0 <= edge.to < size @graph[edge.from] << UnweightedEdge.new(edge.to) self end end class UnweightedUnGraph include Graph(UnweightedEdge, UnweightedEdge2) def self.weighted? false end def self.directed? false end def initialize(size : Int) super end def initialize(size : Int, edges : Enumerable) super end def <<(edge : UnweightedEdge2) : self raise IndexError.new unless 0 <= edge.from < size && 0 <= edge.to < size @graph[edge.from] << UnweightedEdge.new(edge.to) @graph[edge.to] << UnweightedEdge.new(edge.from) self end end describe DiGraph do it ".weighted?, .directed?" do DiGraph.weighted?.should be_true DiGraph.directed?.should be_true end it ".new(size)" do g = DiGraph(Int32).new(5) g.size.should eq 5 g.to_a.should eq [] of WeightedEdge2(Int32) expect_raises(ArgumentError) { DiGraph(Int32).new(-2) } end it ".new(n, edges)" do edges = [WeightedEdge2.new(0, 1, 10), WeightedEdge2.new(1, 0, 11)] g = DiGraph.new 2, edges g.to_a.should eq edges g = DiGraph.new 2, edges.values_at(0, 1) g.to_a.should eq edges g = DiGraph.new 2, [{0, 1, 10}, {1, 0, 11}] g.to_a.should eq edges expect_raises(IndexError) { DiGraph.new 1, [WeightedEdge2.new(0, 1, 10)] } end it "#<<, #add_edges" do g = DiGraph(Int32).new(5) edges = [ WeightedEdge2.new(0, 1, 10), WeightedEdge2.new(0, 1, 11), WeightedEdge2.new(1, 2, 12), WeightedEdge2.new(2, 3, 13), WeightedEdge2.new(3, 4, 14), ] (g << edges[0]).should be g g << {0, 1, 11} g << {1, 2, 12} g.add_edges(edges[3..4]).should be g expect_raises(IndexError) { g << {4, 5, -1} } g[0].should eq [WeightedEdge.new(1, 10), WeightedEdge.new(1, 11)] g[1].should eq [WeightedEdge.new(2, 12)] g.to_a.should eq edges end it "#reverse" do edges = [ WeightedEdge2.new(0, 1, 10), WeightedEdge2.new(0, 1, 11), WeightedEdge2.new(1, 2, 12), WeightedEdge2.new(2, 3, 13), WeightedEdge2.new(3, 4, 14), ] g = DiGraph(Int32).new(5, edges) g.reverse.to_a.should eq edges.map(&.reverse) end it "#to_undirected" do edges = [ WeightedEdge2.new(0, 1, 10), WeightedEdge2.new(0, 1, 11), WeightedEdge2.new(1, 2, 12), WeightedEdge2.new(2, 3, 13), WeightedEdge2.new(3, 4, 14), ] g = DiGraph(Int32).new(5, edges) g.to_undirected.to_set.should eq edges.flat_map { |e| [e, e.reverse] }.to_set end end describe UnGraph do it ".weighted?, .directed?" do UnGraph.weighted?.should be_true UnGraph.directed?.should be_false end it "#.new(size)" do g = UnGraph(Int32).new(5) g.size.should eq 5 g.to_a.should eq [] of WeightedEdge2(Int32) expect_raises(ArgumentError) { UnGraph(Int32).new(-2) } end it ".new(n, edges)" do edges = [WeightedEdge2.new(0, 1, 10), WeightedEdge2.new(0, 1, 11), WeightedEdge2.new(1, 0, 10), WeightedEdge2.new(1, 0, 11)] g = UnGraph.new 2, [edges[0], edges[3]] g.to_a.should eq edges g = UnGraph.new 2, edges.values_at(0, 3) g.to_a.should eq edges g = UnGraph.new 2, [{0, 1, 10}, {1, 0, 11}] g.to_a.should eq edges expect_raises(IndexError) { UnGraph.new 1, [WeightedEdge2.new(0, 1, 10)] } end it "#<<, #add_edges" do edges = [ [WeightedEdge.new(1, 10)], [WeightedEdge.new(0, 10), WeightedEdge.new(2, 11)], [WeightedEdge.new(1, 11), WeightedEdge.new(3, 12)], [WeightedEdge.new(2, 12)], ] all_edges = [ WeightedEdge2.new(0, 1, 10), WeightedEdge2.new(1, 0, 10), WeightedEdge2.new(1, 2, 11), WeightedEdge2.new(2, 1, 11), WeightedEdge2.new(2, 3, 12), WeightedEdge2.new(3, 2, 12), ] g = UnGraph(Int32).new(4) (g << {0, 1, 10}).should be g g << {1, 2, 11} g << WeightedEdge2.new(2, 3, 12) g[0].should eq edges[0] g[1].should eq edges[1] g[2].should eq edges[2] g[3].should eq edges[3] g.to_a.should eq all_edges g = UnGraph(Int32).new(4) g.add_edges([{0, 1, 10}]).should be g g.add_edges({WeightedEdge2.new(1, 2, 11), WeightedEdge2.new(2, 3, 12)}) g[0].should eq edges[0] g[1].should eq edges[1] g[2].should eq edges[2] g[3].should eq edges[3] g.to_a.should eq all_edges end it "#reverse" do all_edges = [ WeightedEdge2.new(0, 1, 10), WeightedEdge2.new(1, 0, 10), WeightedEdge2.new(1, 2, 11), WeightedEdge2.new(2, 1, 11), WeightedEdge2.new(2, 3, 12), WeightedEdge2.new(3, 2, 12), ] g = UnGraph(Int32).new(4) g << {0, 1, 10} << {1, 2, 11} << {2, 3, 12} g.reverse.to_set.should eq all_edges.map(&.reverse).to_set end it "#to_undirected" do all_edges = [ WeightedEdge2.new(0, 1, 10), WeightedEdge2.new(1, 0, 10), WeightedEdge2.new(1, 2, 11), WeightedEdge2.new(2, 1, 11), WeightedEdge2.new(2, 3, 12), WeightedEdge2.new(3, 2, 12), ] g = UnGraph(Int32).new(4) g << {0, 1, 10} << {1, 2, 11} << {2, 3, 12} g.to_undirected.to_set.should eq all_edges.map(&.reverse).to_set end it "#each_child" do g = UnGraph(Int32).new(6) g << {0, 1, 1} << {0, 2, 2} << {0, 3, 3} << {3, 4, 4} << {3, 5, 5} v = [] of Int32 g.each_child(0, nil) { |e| v << e.to } v.should eq [1, 2, 3] v.clear g.each_child(3, nil) { |e| v << e.to } v.should eq [0, 4, 5] v.clear g.each_child(3, 0) { |e| v << e.to } v.should eq [4, 5] g.each_child(0, nil).map(&.to).to_a.should eq [1, 2, 3] g.each_child(3, nil).map(&.to).to_a.should eq [0, 4, 5] g.each_child(3, 0).map(&.to).to_a.should eq [4, 5] end end describe UnweightedDiGraph do it ".weighted?, .directed?" do UnweightedDiGraph.weighted?.should be_false UnweightedDiGraph.directed?.should be_true end it ".new(size)" do g = UnweightedDiGraph.new(5) g.size.should eq 5 g.to_a.should eq [] of UnweightedEdge2 expect_raises(ArgumentError) { UnweightedDiGraph.new(-2) } end it ".new(n, edges)" do edges = [UnweightedEdge2.new(0, 1), UnweightedEdge2.new(1, 0)] g = UnweightedDiGraph.new 2, edges g.to_a.should eq edges g = UnweightedDiGraph.new 2, edges.values_at(0, 1) g.to_a.should eq edges g = UnweightedDiGraph.new 2, [{0, 1}, {1, 0}] g.to_a.should eq edges expect_raises(IndexError) { UnweightedDiGraph.new 1, [UnweightedEdge2.new(0, 1)] } end it "#<<, #add_edges" do g = UnweightedDiGraph.new(5) edges = [ UnweightedEdge2.new(0, 1), UnweightedEdge2.new(0, 1), UnweightedEdge2.new(1, 2), UnweightedEdge2.new(2, 3), UnweightedEdge2.new(3, 4), ] (g << edges[0]).should be g g << {0, 1} g << {1, 2} g.add_edges(edges[3..4]).should be g expect_raises(IndexError) { g << {4, 5} } g[0].should eq [UnweightedEdge.new(1), UnweightedEdge.new(1)] g[1].should eq [UnweightedEdge.new(2)] g.to_a.should eq edges end it "#reverse" do edges = [ UnweightedEdge2.new(0, 1), UnweightedEdge2.new(0, 1), UnweightedEdge2.new(1, 2), UnweightedEdge2.new(2, 3), UnweightedEdge2.new(3, 4), ] g = UnweightedDiGraph.new(5, edges) g.reverse.to_a.should eq edges.map(&.reverse) end it "#to_undirected" do edges = [ UnweightedEdge2.new(0, 1), UnweightedEdge2.new(0, 1), UnweightedEdge2.new(1, 2), UnweightedEdge2.new(2, 3), UnweightedEdge2.new(3, 4), ] g = UnweightedDiGraph.new(5, edges) g.to_undirected.to_set.should eq edges.flat_map { |e| [e, e.reverse] }.to_set end end describe UnweightedUnGraph do it ".weighted?, .directed?" do UnweightedUnGraph.weighted?.should be_false UnweightedUnGraph.directed?.should be_false end it "#.new(size)" do g = UnweightedUnGraph.new(5) g.size.should eq 5 g.to_a.should eq [] of UnweightedEdge2 expect_raises(ArgumentError) { UnweightedUnGraph.new(-2) } end it ".new(n, edges)" do edges = [UnweightedEdge2.new(0, 1), UnweightedEdge2.new(0, 1), UnweightedEdge2.new(1, 0), UnweightedEdge2.new(1, 0)] g = UnweightedUnGraph.new 2, [edges[0], edges[3]] g.to_a.should eq edges g = UnweightedUnGraph.new 2, edges.values_at(0, 3) g.to_a.should eq edges g = UnweightedUnGraph.new 2, [{0, 1}, {1, 0}] g.to_a.should eq edges expect_raises(IndexError) { UnweightedUnGraph.new 1, [UnweightedEdge2.new(0, 1)] } end it "#<<, #add_edges" do edges = [ [UnweightedEdge.new(1)], [UnweightedEdge.new(0), UnweightedEdge.new(2)], [UnweightedEdge.new(1), UnweightedEdge.new(3)], [UnweightedEdge.new(2)], ] all_edges = [ UnweightedEdge2.new(0, 1), UnweightedEdge2.new(1, 0), UnweightedEdge2.new(1, 2), UnweightedEdge2.new(2, 1), UnweightedEdge2.new(2, 3), UnweightedEdge2.new(3, 2), ] g = UnweightedUnGraph.new(4) (g << {0, 1}).should be g g << {1, 2} g << UnweightedEdge2.new(2, 3) g[0].should eq edges[0] g[1].should eq edges[1] g[2].should eq edges[2] g[3].should eq edges[3] g.to_a.should eq all_edges g = UnweightedUnGraph.new(4) g.add_edges([{0, 1}]).should be g g.add_edges({UnweightedEdge2.new(1, 2), UnweightedEdge2.new(2, 3)}) g[0].should eq edges[0] g[1].should eq edges[1] g[2].should eq edges[2] g[3].should eq edges[3] g.to_a.should eq all_edges end it "#reverse" do all_edges = [ UnweightedEdge2.new(0, 1), UnweightedEdge2.new(1, 0), UnweightedEdge2.new(1, 2), UnweightedEdge2.new(2, 1), UnweightedEdge2.new(2, 3), UnweightedEdge2.new(3, 2), ] g = UnweightedUnGraph.new(4) g << {0, 1} << {1, 2} << {2, 3} g.reverse.to_set.should eq all_edges.to_set end it "#to_undirected" do all_edges = [ UnweightedEdge2.new(0, 1), UnweightedEdge2.new(1, 0), UnweightedEdge2.new(1, 2), UnweightedEdge2.new(2, 1), UnweightedEdge2.new(2, 3), UnweightedEdge2.new(3, 2), ] g = UnweightedUnGraph.new(4) g << {0, 1} << {1, 2} << {2, 3} g.to_undirected.to_set.should eq all_edges.to_set end it "#each_child" do g = UnweightedUnGraph.new(6) g << {0, 1} << {0, 2} << {0, 3} << {3, 4} << {3, 5} v = [] of Int32 g.each_child(0, nil) { |e| v << e.to } v.should eq [1, 2, 3] v.clear g.each_child(3, nil) { |e| v << e.to } v.should eq [0, 4, 5] v.clear g.each_child(3, 0) { |e| v << e.to } v.should eq [4, 5] g.each_child(0, nil).map(&.to).to_a.should eq [1, 2, 3] g.each_child(3, nil).map(&.to).to_a.should eq [0, 4, 5] g.each_child(3, 0).map(&.to).to_a.should eq [4, 5] end end