LoginSignup
2

More than 5 years have passed since last update.

オフラインリアルタイムどう書く E13 の ruby による実装例

Last updated at Posted at 2017-04-01

問題:http://nabetani.sakura.ne.jp/hena/orde13hextet/
実装リンク集:http://qiita.com/Nabetani/items/50cd05989b6e2812f879

なんかわかりにくい計算になってしまった。

def xy(ch)
  shift=[0,1,1,2,2]
  %w(a f j o s x).each_cons(2).with_index(0) do |(b, e),y|
    return shift[y]+ch.ord - b.ord+y*1i if (b...e)===ch
  end
  raise "unexpected"
end

def neis(a)
  me=xy("l")
  "gkpqmh".chars.map do |ch|
    xy(ch) - me + a
  end
end

def normalize(sig)
  Array.new(6){ |ix| sig.map{ |x| x.rotate(ix) }.sort }.min
end

def solve( src )
  poses = src.chars.map{ |x| xy(x) }
  neimap = poses.map{ |me|
    neis(me).each.with_index(0).inject([]){ |acc, (n,ix)|
      acc + [poses.include?(n) ? 1 : 0]
    }
  }
  case normalize( neimap ).join.to_i(2)
  when 288297; "B"
  when 308016; "D"
  when 295497; "I"
  when 280872; "J"
  when 279144; "L"
  when 271656; "N"
  when 845361; "O"
  when 283176; "S"
  when 279594; "Y"
  when 295569; "Z"
  else; "-"
  end
end

if $0==__FILE__
  DATA.all? do |line|
    num, src, expected = line.split(/\s+/)
    actual = solve( src )
    ok = actual==expected
    p [ ok ? "ok" : "**NG**", num, src, expected, actual ]
    ok
  end.tap{ |all_ok| puts( all_ok ? "everythin is okay" : "SOMETHING WRONG") }
end

__END__
0 glmq  B
1 fhoq  -
2 lmpr  N
3 glmp  Y

いつもどおり、テストケースの大半は省略。

casewhen がややマジカルだけど、現物合わせでこんな感じ。
マス目の近傍の情報を収集して正規化すれば行けるよね、という実装。

会場で示したものは配列を使っていたけど、複素数に変更してみた。スッキリするね。

この計算で本当に正しいの? 証明できる? と言われるとちょっと自信がないみたいなことを会場では言ったけど、証明可能だと思う。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2