A taste of crystal language by converting a Ruby method
I recent learned crystal language because it is relatively fast with Ruby-like syntax. Although Rust is recently popular, it is too much for me to master.
To begin with, I need a method to find longest common substring between two. Here is a good start point in Ruby from Wikibooks.
class String
def intersection(str)
return '' if [self, str].any?(&:empty?)
matrix = Array.new(self.length) { Array.new(str.length) { 0 } }
intersection_length = 0
intersection_end = 0
self.length.times do |x|
str.length.times do |y|
next unless self[x] == str[y]
matrix[x][y] = 1 + (([x, y].all?(&:zero?)) ? 0 : matrix[x-1][y-1])
next unless matrix[x][y] > intersection_length
intersection_length = matrix[x][y]
intersection_end = x
end
end
intersection_start = intersection_end - intersection_length + 1
slice(intersection_start..intersection_end)
end
end
How to translate this into crystal language ? Here is the result.
class String
def intersection(str)
return "" if [self, str].any?(&.empty?)
matrix = Array.new(self.size) { Array.new(str.size) { 0 } }
intersection_length = 0
intersection_end = 0
self.length.times do |x|
str.size.times do |y|
next unless self[x] == str[y]
matrix[x][y] = 1 + (([x, y].all?(&.zero?)) ? 0 : matrix[x-1][y-1])
next unless matrix[x][y] > intersection_length
intersection_length = matrix[x][y]
intersection_end = x
end
end
intersection_start = intersection_end - intersection_length + 1
self[intersection_start..intersection_end]
end
end
They looks almost the same !! Here are some difference.
First, empty string in Crystal must be ""
, not single quotation mark.
Second, instead of &:method
in Ruby, use &.method
in Crystal.
Third, instead of length
of string in Ruby, use size
in Crystal.
Last, instead of slice
in Ruby, use []
for substring in Crystal.
That’s it !! How easy it is.