読者です 読者をやめる 読者になる 読者になる

人権真骨頂

とくがたかいことでゆうめい

exercismをCrystalでやった

exercismってなに

exercism.io

これ.いくつか問題があって,投稿してフィードバックもらえますよみたいなやつ.

色々な言語で問題とテストケースが用意されていてCrystalもあったのでやってみた.

適当にやるとだんだんCrystalに慣れてくるかなという感じで.

リポジトリ

github.com

1 Hello World

HelloWorld クラスを定義して helloメソッドを定義して引数を指定したときはその名前を利用して Hello, NAME! ,指定されていないときは Hello, World! とする.

ポイントは

  • クラスメソッドは def self.hello
  • デフォルト引数は name = "World" という感じ
  • String Interpolationは "Hello, #{name}" という感じ

2 hamming

ハミング距離求めよってやつ

def self.compute(a, b)
    a.chars.zip(b.chars).count { |l,r| l!=r }
end

で終わりだと思っていたけどこれでは無理.... (ver. 0.20.1)

Crystalではこう

https://carc.in/#/r/1i5n

Rubyではこう

http://melpon.org/wandbox/permlink/BqnausztCf9N8nrf

これでハマった.今もよく分からん.

3. Gigasecond

109秒を与えられた Time に足せば良い.

ポイントは

  • TImeクラスに +でSpanクラスを足すことができるということ
    • Time:::Span.new(0, 0, 10**9)

4 Rna Transcription

ある文字を別の文字にするやつ.

【Ruby】gsubで複数文字を置換したかった話 | カイトズズキ日記

ここを参考にした.

class RnaComplement
  CONVERTION_TABLE = {
    "G" => "C",
    "C" => "G",
    "T" => "A",
    "A" => "U"
  }
  def self.of_dna(dna)
    dna.gsub(/#{CONVERTION_TABLE.keys.join("|")}/, CONVERTION_TABLE)
  end
end

5 Bob

与えられた入力に対して決められた文を返すやつ. case-when でやっただけ.

6 Raindrop

FizzBuzz的なやつ. このScala のやつでやってみた.

Tuple は {} こう.

    case {i % 3 == 0, i % 5 == 0, i % 7 == 0}
    when {true, false, false}
      out = "Pling"
    when {false, true, false}
      out = "Plang"
    when {false, false, true}
      out = "Plong"
    end

こんな雰囲気.

7 Leap

うるう年判定. Timeleap_year? が生えているのでそれを利用する.

https://crystal-lang.org/api/0.20.3/Time.html#leap_year%3F%28year%29%3ABool-class-method

8 Difference Of Squares

Range を利用した. to_a で配列にできるのでよしなにできる. reduce ではなくて, reduce(0) にしないと配列が空で渡ってきたときに例外が発生するので注意.

https://crystal-lang.org/api/0.20.3/Enumerable.html#reduce%28memo%2C%26block%29-instance-method

9 Pangram

与えられた文字列中で 'a'~'z' までのアルファベットが少なくとも1回出てくるか判定するやつ.

さっきみたいに Range 使って, all? 使えばよい.

10 Largest Series Product

ウォー,Scalaの sliding みたいなのほしい.....

ポイントは - slidingみたいなのを実装 - BigIntで処理する - 引数が不正のときは例外を出す

例外で new を忘れがち

# NG
# raise ArgumentError

# OK
raise ArgumentError.new("hogehoge~")

11 Bracket Push

case-when になぜかハマった. if-elsif にしたら何故か通った.謎.

以下は良くて,

https://play.crystal-lang.org/#/r/1ig8

これはダメ

https://play.crystal-lang.org/#/r/1ig6

https://play.crystal-lang.org/#/r/1iga

これもダメ

12 Sieve

エラトステネスのふるいじゃない... まぁいいや

    while !num.empty?
      prime << num.shift
      num = num.reject { |i| i % prime[prime.size - 1] == 0 }
    end

13 Roman Numerals

ローマ数字化はここを参考にした.

http://codereview.stackexchange.com/a/7939

モンキーパッチやる.

14 Atbash Cipher

最初普通に変換しただけでやったら結果が微妙に違くてよく読んだら,そのまま出すんじゃなかった.

each_slice というべんりなやつがあって.べんり.

15 Anagram

next を覚えた. https://crystal-lang.org/docs/syntax_and_semantics/next.html

16 React

これは写経する感じでやった.なんかもっと上手く書けそうなきがする.

https://crystal-lang.org/api/0.20.3/Proc.html

17 Acronym

糞ゴミ正規表現でゴリ押しした.どうするのが正解なんだろう...?

str.split(/-|\s|(?<=[A-Z])(?=[A-Z][a-z])|(?<=[a-z])(?=[A-Z])/).map(&.[0].upcase).join

18 Binary

baseを2にして to_i すれば終わり.

19 Run Length Encoding

ランレングス符号化やるやつ.

エンコーディングはスッとできたけど,

  def self.encode(str : String)
    str.chars.chunks { |c| c }.map { |l, r|
      next l.to_s if r.size == 1
      r.size.to_s + l.to_s
    }.join
  end

デコーディングがなんか頑張る感じになってしまった.

  def self.decode(encoded_str : String)
    str = ""

    cnt = ""
    encoded_str.chars.each { |i|
      if i.ascii_number?
        cnt += i
      else
        cnt = "1" if cnt.empty?
        str += i.to_s * cnt.to_i
        cnt = ""
      end
    }

    str
  end

20 Pascals Triangle

パスカルの三角形作るやつ.

引数が不正なときは例外を出すようにする.

21 Forth

割りとダルそうなので例を見ながら写経した.

https://github.com/exercism/xcrystal/blob/master/exercises/forth/src/example.cr

property マクロは gettersetter を提供してくれる.

Char::Reader っていうべんりなやつもある. https://crystal-lang.org/api/0.20.3/Char/Reader.html

pop_once , pop_twice で使ってる yield はここらへんの話.

ブロックと Proc | プログラミング言語 Crystal

delegate マクロで処理を委譲できる

https://crystal-lang.org/api/0.20.0/Class.html#delegate%28%2Amethods%2Ctoobject%29-macro

22 Binary Search Tree

これも例を写経する感じにした. Java, Scala以来のジェネリクス,..

include を利用すると module に定義されたメソッドをインスタンスメソッドとして利用できるようになる.

モジュール | プログラミング言語 Crystal

まとめ

Rubyやんけ〜〜〜〜!!!

次はパフォーマンスとかのあたりを読んでおきたい.

Performance · GitBook