# Translation of Ruby Code

**URL:** <https://forum.crystal-lang.org/t/translation-of-ruby-code/4025>\
**Category:** Help & Support\
**Created:** [October 30, 2021, 4:41pm UTC](https://forum.crystal-lang.org/t/translation-of-ruby-code/4025 "2021-10-30T16:41:30Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jzakiya](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jzakiya/32/278_2.png) [@jzakiya](https://forum.crystal-lang.org/u/jzakiya)\
**Post date:** [October 30, 2021, 4:41pm UTC](https://forum.crystal-lang.org/t/translation-of-ruby-code/4025/1 "2021-10-30T16:41:30Z")

</div>

I tried to use the Iterator module for this, but I’m missing something.  
I assumed you had to make these iterators, but what’s the correct way to do this in Crystal?

```auto
squares = Enumerator.new{ |y| (0..).each{ |n| y << 2**n}}
squares5 = Enumerator.new{ |y| (0..).each{ |n| y << 2**n * 5}}
 
pyth_quad = Enumerator.new do |y|
  n = squares.next
  m = squares5.next
  loop do
    if n < m
      y << n
      n = squares.next
    else
      y << m
      m = squares5.next
    end
  end
end

# this takes less than a millisecond
puts pyth_quad.take_while{ |n| n <= 1000000000}.join(" ")

```

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [October 30, 2021, 6:44pm UTC](https://forum.crystal-lang.org/t/translation-of-ruby-code/4025/2 "2021-10-30T18:44:48Z")

</div>

This is what I came up with:

```crystal
squares = (0..).each.map { |n| 2_i64**n }
squares5 = (0..).each.map { |n| 2_i64**n * 5 }

n = squares.next.as(Int)
m = squares5.next.as(Int)
pyth_quad = Iterator.of do
  if n < m
    value = n
    n = squares.next.as(Int)
  else
    value = m
    m = squares5.next.as(Int)
  end
  value
end

puts pyth_quad.take_while { |n| n <= 1000000000 }.join(" ")

```

---

<div class="post-metadata">

**Author:** ![jzakiya](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jzakiya/32/278_2.png) [@jzakiya](https://forum.crystal-lang.org/u/jzakiya)\
**Post date:** [October 30, 2021, 9:54pm UTC](https://forum.crystal-lang.org/t/translation-of-ruby-code/4025/3 "2021-10-30T21:54:33Z")

</div>

Thank @asterite, as always.  
The only thing I changed was the `2_i64` to `2_u64`.

I got about 65-70% right, trying to following the examples in the docs.  
I didn’t have the `.map` on the ends of `(0..).each` or the `.as(Int)` on the end of `next`, or moved `m/n = squares/5...` outside `pyth_quad`, or the `.of` on the end of `Iterator`.

I’m going to study it more, with the docs, to really understand what/why is going on.

FYI, here are time comparisons with different Ruby versions.  
For Ruby ran as: `$ time ruby pythquads.rb`  
For Crystal, compiled as: `$ crystal build pythquads.cr --release`  
Ran as: `$ time ./pythquads`

```auto
Ruby 3.0.2 0.063 secs  
Ruby 2.7.4 0.057 secs
Truffleruby 21.2.0.1 0.037 secs
Crystal 1.1.1 0.007 secs
Crystal 1.2.1 0.002 secs

```

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [October 31, 2021, 9:31am UTC](https://forum.crystal-lang.org/t/translation-of-ruby-code/4025/4 "2021-10-31T09:31:06Z")

</div>

Ideally, the library or the compiler should be smarter about iterators that never finish, but that’s not the case right now. That’s why you need those `as(Int) `, because the return value of `next` could be `Iterator::Stop`.

I tried. To improve that but couldn’t. I’ll open an issue and see if someone can figure this out, or if it’s even worth it.
