I’m working on the Collatz exercise. Tests pass with a looping solution:
module CollatzConjecture
def self.steps(input : Number) : Number
raise ArgumentError.new if input <= 0
step = 0
until input == 1
input = input.even? ? (input // 2) : (3 * input + 1)
step += 1
end
step
end
end
$ crystal spec
......
Finished in 319 microseconds
6 examples, 0 failures, 0 errors, 0 pending
But trying it recursively:
module CollatzConjecture
def self.steps(input : Number, count = 0) : Number
raise ArgumentError.new if input <= 0
case
when input == 1 then count
when input.even? then steps(input // 2, count + 1)
else steps(3 * input + 1, count + 1)
end
end
end
and crystal fails with
$ crystal spec
Showing last frame. Use --error-trace for full trace.
There was a problem expanding macro 'macro_140506330720336'
Code in /usr/share/crystal/src/int.cr:185:5
185 | {% begin %}
^
Called macro defined in /usr/share/crystal/src/int.cr:185:5
185 | {% begin %}
Which expanded to:
> 2 | if other == 0
> 3 | raise DivisionByZeroError.new
> 4 | elsif self < 0 && self == Int::MIN && other == -1
^-------
Error: undefined constant Int::MIN
I was able to make it pass by altering the method signature, specifying a specific int type:
def self.steps(input : Int32, count = 0) : Int32
Any thoughts?