# Want elegant code version

**URL:** <https://forum.crystal-lang.org/t/want-elegant-code-version/3013>\
**Category:** Help & Support\
**Created:** [March 9, 2021, 7:13pm UTC](https://forum.crystal-lang.org/t/want-elegant-code-version/3013 "2021-03-09T19:13:07Z")\
**Posts on this page:** 9\
**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:** [March 9, 2021, 7:13pm UTC](https://forum.crystal-lang.org/t/want-elegant-code-version/3013/1 "2021-03-09T19:13:07Z")

</div>

I converted a Ruby method into Crystal, but it’s soooo inelegant compared to the Ruby version. Can some suggest a more Crystal elegant way to do it.

Ruby code

```auto
def zeckendorf
  return to_enum( __method__ ) unless block_given?
  x = 0
  loop do
    bin = x.to_s(2)
    yield bin unless bin.include?("11") 
    x += 1
  end
end
 
zeckendorf.take(21).each_with_index{|x,i| puts "%3d: %8s"% [i, x]}

```

My functional, but inelegant, Crystal translatioin.

```auto
def zeckendorf
  #return to_enum( __method__ ) unless block?
  x = 0
  i = 0 # added
  loop do
    bin = x.to_s(2)
    #yield bin unless bin.includes?("11")
    yield bin, i += 1 unless bin.includes?("11")
    x += 1
  end
end

#zeckendorf.take(21).each_with_index{|x,i| puts "%3d: %8s"% [i, x]}
zeckendorf{ |num, i| puts "%3d: %8s"% [i, num]; (break if i > 20) }

```

---

<div class="post-metadata">

**Author:** ![Exilor](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/exilor/32/780_2.png) [@Exilor](https://forum.crystal-lang.org/u/Exilor)\
**Post date:** [March 9, 2021, 7:29pm UTC](https://forum.crystal-lang.org/t/want-elegant-code-version/3013/2 "2021-03-09T19:29:28Z")

</div>

Here’s how the stdlib does this kind of thing. A method that yields and another that returns an iterator:

```crystal
def zeckendorf
  x = 0
  loop do
    bin = x.to_s(2)
    yield bin unless bin.includes?("11")
    x += 1
  end
end

class ZeckendorfIterator
  include Iterator(String)

  def initialize
    @x = 0
  end

  def next
    bin = @x.to_s(2)
    @x += 1
    while bin.includes?("11")
      bin = @x.to_s(2)
      @x += 1
    end
    bin
  end
end

def zeckendorf
  ZeckendorfIterator.new
end

zeckendorf.first(21).each_with_index{|x,i| puts "%3d: %8s"% [i, x]}

```

---

<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:** [March 10, 2021, 1:32am UTC](https://forum.crystal-lang.org/t/want-elegant-code-version/3013/3 "2021-03-10T01:32:10Z")

</div>

Thank you @Exilor this is exactly what I was looking for.  
Now I just have to remember what to do going forward. 🤔

```auto
class ZeckendorfIterator
  include Iterator(String)

  def initialize
    @x = 0
  end

  def next
    bin = @x.to_s(2)
    @x += 1
    while bin.includes?("11")
      bin = @x.to_s(2)
      @x += 1
    end
    bin
  end
end

def zeckendorf(n)
  ZeckendorfIterator.new.first(n)
end

zeckendorf(21).each_with_index{|x,i| puts "%3d: %8s"% [i, x]}

```

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [March 10, 2021, 1:43am UTC](https://forum.crystal-lang.org/t/want-elegant-code-version/3013/4 "2021-03-10T01:43:02Z")

</div>

You don’t necessarily need a custom iterator for this.

```auto
0.step(by: 1).map(&.to_s(2)).select{|bin| !bin.includes?("11")}.first(21)

```

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [March 10, 2021, 1:46am UTC](https://forum.crystal-lang.org/t/want-elegant-code-version/3013/5 "2021-03-10T01:46:32Z")

</div>

Alternatives:

```auto
# shorter:
0.step(by: 1).map(&.to_s(2)).reject(&.includes?("11")).first(21)
# faster:
0.step(by: 1).compact_map{|x| bin = x.to_s(2); bin unless bin.includes?("11")}.first(21)

```

---

<div class="post-metadata">

**Author:** ![wrq](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/wrq/32/761_2.png) [@wrq](https://forum.crystal-lang.org/u/wrq)\
**Post date:** [March 10, 2021, 1:49am UTC](https://forum.crystal-lang.org/t/want-elegant-code-version/3013/6 "2021-03-10T01:49:07Z")

</div>

So tasteful, I love this kind of code. It’s something that always drew me into ruby, the way it gives off those magical lisp-esque vibes.

---

<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:** [March 10, 2021, 1:56am UTC](https://forum.crystal-lang.org/t/want-elegant-code-version/3013/7 "2021-03-10T01:56:51Z")

</div>

> [@straight-shoota](#):
>
> ```auto
> # shorter:
> 0.step(by: 1).map(&.to_s(2)).reject(&.includes?("11")).first(21)
> # faster:
> 0.step(by: 1).compact_map{|x| bin = x.to_s(2); bin unless bin.includes?("11")}.first(21)
> 
> ```

How do you generate output?

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [March 10, 2021, 2:08am UTC](https://forum.crystal-lang.org/t/want-elegant-code-version/3013/8 "2021-03-10T02:08:15Z")

</div>

You can chain the same `each_with_index` call as in your example.

---

<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:** [March 10, 2021, 2:08am UTC](https://forum.crystal-lang.org/t/want-elegant-code-version/3013/9 "2021-03-10T02:08:48Z")

</div>

> [@jzakiya](#):
>
> `each_with_index{|x,i| puts "%3d: %8s"% [i, x]}`

Yeh, I figured it out after asking the question.

```auto
0.step(by: 1).map(&.to_s(2)).reject(&.includes?("11")).first(21).each_with_index{|x,i| puts "%3d: %8s"% [i, x]}

```

or better

```auto
def zeckendorf(n)
  0.step.map(&.to_s(2)).reject(&.includes?("11")).first(n)
end

zeckendorf(21).each_with_index{ |x,i| puts "%3d: %8s"% [i, x] }

```
