Improve Crystal's profile on Rosetta Code

Mon 2019/4/22

This was a little tricky to translate. The Ruby version used slick booleans for flow control (which I did both ways to verify). The real problem was having to explicitly initialize the arrays to false (unecessary in Ruby). I also applied the lesson learned from previously using slices, in the output. Man, I’m getting good at this. :smile:

Jaro distance
https://rosettacode.org/wiki/Jaro_distance#Crystal
https://rosettacode.org/wiki/Jaro_distance#Ruby

2 Likes

Tu 2019/4/23

Sierpinski carpet
https://rosettacode.org/wiki/Sierpinski_carpet#Crystal

1 Like

@jzakiya Great work! One small input valuable when translating from Ruby: when doing [a, b].max it’s better to do {a, b}.max. The tuple will be allocated in the stack and things could be optimized probably by llvm much better.

1 Like

Thanks for the feedback @bcardiff. I changed in https://rosettacode.org/wiki/Jaro_distance#Crystal [].max|min to {}.max|min.

Tu 2019/4/23

Jortsort
https://rosettacode.org/wiki/JortSort#Crystal

Josephus problem
https://rosettacode.org/wiki/Josephus_problem#Crystal

1 Like

Another small snippet I notice is when reading ARGV that happens a lot. All of the following lines return the same value.

ARGV.empty? ? 41 : ARGV[0].to_i
ARGV[0]?.try(&.to_i) || 41
ARGV.fetch(0, "41").to_i
ARGV.fetch(0, 41).to_i

Beauty is in the eyes of the beholder :slight_smile:.

2 Likes

Thanks again @bcardiff for these equivalents examples, which I didn’t know about. I think the 2nd one conforms closest to the Ruby snippet spirit.

I hope at some point documentation is created to extract from these code examples these explicit snippets alternatives, and put them in an easily searchable|accessible form.

Only by using a language (program or human), and doing real things with it, will these types of nuances and options be known, which can then be accessed for appropriate use.

I’m not only learning more of real world Crystal, but also Ruby too, doing these problems (which is exactly the point).

Keep the feedback coming. It’s useful to everyone who will ultimately view this thread.

1 Like

F 2019/4/26

A simple one.

Binary digits
https://rosettacode.org/wiki/Binary_digits#Crystal

A not so simple one.
Apparently someone posted a Ruby translation just before I posted my Python translation. I was going to do the Ruby version too, but couldn’t figure out how to use Iterators for it. If someone knows how to do (a short version) with iterators please post. I’d like to know, if it’spossible.

Bernoulli numbers
https://rosettacode.org/wiki/Bernoulli_numbers#Crystal

Addition: Sat 2019/4/27
Added Python version 2 Bernoulli number generator translation, which (at least to me) is much simpler and understandable than Ruby|Crystal enumerator inspired versions (and likely faster too).

2 Likes

Sun 2019/4/28

String manipulation in Crystal is far less elegant and concise than Ruby.
And I can’t splat a tuple in an output expression (?).

Ruby vs Crystal equivalents

  g is a hash

  k = g.sort_by { |k, v| v.length }.map { |k, v| k }         # Ruby
  k = g.to_a.sort_by { |h| h[1].size }.map { |h| h[0] }      # Crystal
  or
  k = g.to_a.sort_by { |(k, v)| v.size }.map { |(k, v)| k }

  new[p] = letters.slice! i                                  # Ruby
  new = new.sub(p, letters[i]); letters = letters.sub(i, "") # Crystal

%w(abracadabra seesaw elk grrrrrr up a).each do |word|
  # puts "%s, %s, (%d)" % [word, *best_shuffle(word)]       # Ruby
  new, score = best_shuffle(word)                           # Crystal
  puts "%s, %s, (%d)" % [word, new, score]
end

Crystal (currently) doesn’t have sort_by method for hashes.

Are there better|concise alternative phrases for Crystal?

Best shuffle
https://rosettacode.org/wiki/Best_shuffle#Crystal

1 Like

Ruby has Enumberale#sort and Enumerable#sort_by which first convert the Enumerable to an array, so there’s a hidden performance penalty. Crystal makes it more explicit by having you write to_a. I think that’s good.

For the hash thing you can do:

g.to_a.sort_by { |(k, v)| v.size }.map { |(k, v)| v }
# or
g.to_a.sort_by(&.[1].size).map(&.[0])

Crystal strings are immutable so yeah, Crystal string manipulation will always be a bit more boring than in Ruby.

F 2019/5/3

A key thing to remember using Arrays|Hashes in Crystal, you have to initialize all the container values because you can’t do control flow on nil|false|true like in Ruby with uninitialized values.

Generate random chess position
https://rosettacode.org/wiki/Generate_random_chess_position#Crystal

Pythagorean quadruples
https://rosettacode.org/wiki/Pythagorean_quadruples#Crystal

Pythagorean triples
https://rosettacode.org/wiki/Pythagorean_triples#Crystal

1 Like

Th 2019/5/9

Gamma function
https://rosettacode.org/wiki/Gamma_function#Crystal

M 2019/5/13
Added C# translation of Lanczos method.

1 Like

W 2019/5/22

Binary search
https://rosettacode.org/wiki/Binary_search#Crystal

1 Like

Hi, I am not a Crystal user, but I am a long-time contributor to the Rosetta code site.

I’ve only just seen this thread and would like to take the opportunity of welcoming you all :slight_smile:
I would just like to point out that it would be best if you could bring out what makes crystal a good language to program in when writing examples rather than plain translations of Ruby, as that is more the aim of the site. It is good to have large numbers of language examples too, but the aim of the site is for people to compare solutions and sometimes direct language translations look out of place.

But mainly, welcome :wink:

7 Likes

F 2020/3/6

Modular inverse
https://rosettacode.org/wiki/Modular_inverse#Crystal

1 Like

F 2020/3/13

Benford's law
https://rosettacode.org/wiki/Benford’s_law#Crystal

Sun 2020/3/29

Modular exponentiation
https://rosettacode.org/wiki/Modular_exponentiation#Crystal

2 Likes

W 2020/4/1

Luhn test of credit card numbers
https://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers#Crystal

Addition:
I added the Ruby version, which uses its digits method.
https://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers#Ruby

2 Likes

Sat 2020/4/4

Lucas-Lehmer test
https://rosettacode.org/wiki/Lucas-Lehmer_test#Crystal

Lychrel numbers
https://rosettacode.org/wiki/Lychrel_numbers#Crystal

Monte Carl methods
https://rosettacode.org/wiki/Monte_Carlo_methods#Crystal

1 Like

Mon 2020/4/6

Anagrams
https://rosettacode.org/wiki/Anagrams#Crystal

Anti-primes
https://rosettacode.org/wiki/Anti-primes#Crystal

Catalan numbers
https://rosettacode.org/wiki/Catalan_numbers#Crystal

4 Likes

Hey @krthr welcome to the club! :grin:
Excellent work.

I ran all three tasks on my system: i7-6700HQ, 3.5GHz

For catalan numbers here are typical times:

                     user     system      total        real
catalan_direct   0.000026   0.000052   0.000078 (  0.000074)
catalan_rec1     0.139766   0.001143   0.140909 (  0.141418)
catalan_rec2     0.000003   0.000000   0.000003 (  0.000003)

Also, maybe you weren’t aware, Crystal has a product method, so it’s more idiomatic to do:

def factorial(n : BigInt) : BigInt
  #(1..n).reduce(1.to_big_i) { |acc, i| acc * i }
  (1..n).product(1.to_big_i)
end

On my system though, anagrams threw an error (0.33)

Unhandled exception: HTTP::Client::Response#body_io cannot be nil (NilAssertionError)
  from ???
  from /home/jzakiya/crystal/share/crystal/src/hash.cr:896:11 in '__crystal_main'
  from /home/jzakiya/crystal/share/crystal/src/crystal/main.cr:106:5 in 'main'
  from __libc_start_main
  from ../sysdeps/x86_64/start.S:122:0 in '_start'
  from ???