Rubyには標準添付でtsortが存在するがcrystalにはなかったので書いてみた。
namusyaka/crystal-tsort
Ruby版と比較してfull compatibleというわけではない。
使い方
空配列に対する型の宣言が必要な点とalias
がない点以外は、ほぼそのままRubyの例を使える。
tsort
require "tsort"
class Hash
include TSort
def tsort_each_node(&block)
each_key do |key|
yield key
end
end
def tsort_each_child(node, &block)
fetch(node).each do |value|
yield value
end
end
end
sorted = {1=>[2, 3], 2=>[3], 3=>[] of Int32, 4=>[] of Int32}.tsort
p sorted #=> [3, 2, 1, 4]
each_strongly_connected_component
require "tsort"
class Hash
include TSort
def tsort_each_node(&block)
each_key do |key|
yield key
end
end
def tsort_each_child(node, &block)
fetch(node).each do |value|
yield value
end
end
end
non_sort = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[] of Int32}
non_sort.each_strongly_connected_component { |nodes| p nodes } #=>
# [4]
# [2, 3]
# [1]
strongly_connected_components
require "tsort"
class Hash
include TSort
def tsort_each_node(&block)
each_key do |key|
yield key
end
end
def tsort_each_child(node, &block)
fetch(node).each do |value|
yield value
end
end
end
non_sort = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[] of Int32}
p non_sort.strongly_connected_components
#=> [[4], [2, 3], [1]]
tsort_each
require "tsort"
class Hash
include TSort
def tsort_each_node(&block)
each_key do |key|
yield key
end
end
def tsort_each_child(node, &block)
fetch(node).each do |value|
yield value
end
end
end
non_sort = {1=>[2, 3], 2=>[3], 3=>[] of Int32, 4=>[] of Int32}
non_sort.tsort_each do |node|
non_sort.tsort_each_child(node) do |child|
printf("%d -> %d\n", node, child)
end
end
# 出力
# 2 -> 3
# 1 -> 2
# 1 -> 3
所感
書いたっきりそのままになっていたので紹介してみた次第。
(Crystalに対して)まだまだエコシステムは未熟だし、開発に付随するシステム・ライブラリも足りない状況なので、投資先としてのハードルは低いと思う。やれることは多い。
まずは自分がこのコミュニティのコア開発者になってやる、くらいの気概で飛び込んでいくと良さそう。