Trying out Ruby code again today for no specific reason other than to try out some different languages. Expanding on the previous example I decided to allow edge detection for multi-row matrix. This time we look for changes to the matrix with the left character and the row above.
Some comments on the syntax
- I found the for loop syntax a little weird “…” does not seem very intuitive.
- Reading from standard Input was really simple and felt good.
- Some of the syntax like ‘gsub’, ‘def’ (instead of 'function') would take a little getting used too, but Stack Overflow was a big help with that.
- RegEx was never my favourite technology, but Rubular website was very good; however did not work on Safari only Chrome.
- Closing ‘if' statements with ‘end’ felt like I was coding basic again.
Full code example is below.- Reading from standard Input was really simple and felt good.
- Some of the syntax like ‘gsub’, ‘def’ (instead of 'function') would take a little getting used too, but Stack Overflow was a big help with that.
- RegEx was never my favourite technology, but Rubular website was very good; however did not work on Safari only Chrome.
- Closing ‘if' statements with ‘end’ felt like I was coding basic again.
#!/usr/bin/env ruby
# Usage: cat <filename> | ./<edge.rb>
# Usage: cat <filename> | ./<edge.rb>
def CalculateEdge(arr)
result = "" # loop over each line of the array of text items
for lineIndex in 0 ... arr.size
topChar = "0" # start empty
prevChar = "0" # start empty
for charIndex in 0 ... arr[lineIndex].chomp.size
# consider <whitespace> as '0'
currentChar = arr[lineIndex][charIndex].gsub(/\s/,'0')
# validation checks
if lineIndex == 0 then
topChar = currentChar # assume current char if first row
elsif lineIndex > 0 && charIndex > arr[lineIndex-1].chomp.size
topChar = "0" # assume "0" if missing on row above
else
topChar = arr[lineIndex-1][charIndex].nil? ? "0" : arr[lineIndex-1][charIndex].gsub(/\s/,'0')
end
# XOR char against the previous char to the left of current
edgeLeft = prevChar.to_i(2) ^ currentChar.to_i(2)
# XOR char against the char above the current
edgeTop = currentChar.to_i(2) ^ topChar.to_i(2)
# if the left char has not changed use the top row
edge = edgeLeft == 1 ? edgeLeft : edgeTop
prevChar = currentChar
result = result+"#{edge}"
end result = "#{result}\n\t"
end
return result
end
result = "" # loop over each line of the array of text items
for lineIndex in 0 ... arr.size
topChar = "0" # start empty
prevChar = "0" # start empty
for charIndex in 0 ... arr[lineIndex].chomp.size
# consider <whitespace> as '0'
currentChar = arr[lineIndex][charIndex].gsub(/\s/,'0')
# validation checks
if lineIndex == 0 then
topChar = currentChar # assume current char if first row
elsif lineIndex > 0 && charIndex > arr[lineIndex-1].chomp.size
topChar = "0" # assume "0" if missing on row above
else
topChar = arr[lineIndex-1][charIndex].nil? ? "0" : arr[lineIndex-1][charIndex].gsub(/\s/,'0')
end
# XOR char against the previous char to the left of current
edgeLeft = prevChar.to_i(2) ^ currentChar.to_i(2)
# XOR char against the char above the current
edgeTop = currentChar.to_i(2) ^ topChar.to_i(2)
# if the left char has not changed use the top row
edge = edgeLeft == 1 ? edgeLeft : edgeTop
prevChar = currentChar
result = result+"#{edge}"
end result = "#{result}\n\t"
end
return result
end
# Place each line into an array
input = $stdin.read
if not (input =~ /[^0-1\W]/).nil? then
puts "Error: Only 0-1 values allowed. e.g. 0100001111"
puts " Whitespace will be considered '0'"
exit
end
arr = input.split(/\n/)
result = CalculateEdge(arr)
puts "Input :\t#{input}"
puts "Output:\t#{result}"
input = $stdin.read
if not (input =~ /[^0-1\W]/).nil? then
puts "Error: Only 0-1 values allowed. e.g. 0100001111"
puts " Whitespace will be considered '0'"
exit
end
arr = input.split(/\n/)
result = CalculateEdge(arr)
puts "Input :\t#{input}"
puts "Output:\t#{result}"