LoginSignup
0
1

More than 5 years have passed since last update.

オフラインリアルタイムどう書く F03「トリオミノの分類」をRubyで解いてみた。

Last updated at Posted at 2017-04-02

問題

5✕5の二次元のマス目(a〜y)がある。
入力は、3箇所のマスが文字列で指定される。
出力は、入力がリンク先の6種類の図形に該当するときは図形の識別子を、しないときは - を返す。

考え方

a〜yの二次元のマス目、入力値、JLTRIBの図形のすべてを二次元配列に変換して扱う。
JLTRIBの3つのマスを、二次元配列のindexの若いマス順にx, y, zと定義する。
xを原点としてy, zxからの相対的な位置関係で正規化する。

入力値をソートし、xの座標を決定した後、JLTRIBの6種類の図形のx, y, zと入力値が一致するかどうかを調べる。

コード

triom.rb
require 'test/unit'
require 'matrix'

# NOTE: PATTERNSは、パターンJLTRIBの [y - x, z - x] の値を格納
PATTERNS = [
  [[-1,  1], [ 0,  1]], # J
  [[ 0,  1], [ 1,  1]], # L
  [[ 1,  0], [ 1,  1]], # T
  [[ 1,  0], [ 0,  1]], # R
  [[ 0,  1], [ 0,  2]], # I
  [[ 1,  0], [ 2,  0]], # B
].freeze
# NOTE: PATTERNS_CHARは、パターンのCHARの順序を格納
PATTERNS_CHAR = %w(J L T R I B).freeze

class String
  IDX_CAHRS = [*"a".."y"].freeze

  # NOTE: 入力値を二次元配列に変換
  def to_dimension
    idx = IDX_CAHRS.find_index(self)
    [idx % 5, idx / 5]
  end
end

# メイン関数
def triom_pattern input
  splited = input.split("").sort.uniq

  # NOTE: 入力の要素に重複があった場合はtriomは形成されないため、該当パターンなし
  return "-" if splited.count < 3

  x, y, z = splited.map(&:to_dimension)

  idx = PATTERNS.find_index do |diff|
    dy, dz = diff
    next if y != (Vector[*x] + Vector[*dy]).to_a
    next if z != (Vector[*x] + Vector[*dz]).to_a
    true
  end
  # NOTE: パターンに該当あり
  return PATTERNS_CHAR[idx] if idx

  # NOTE: パターンに該当なし
  return "-"
end

class TestTriom < Test::Unit::TestCase
  def test_triom_pattern
    assert_equal triom_pattern("cba"), "B"
    assert_equal triom_pattern("yam"), "-"
    assert_equal triom_pattern("aaa"), "-"
    assert_equal triom_pattern("def"), "-"
    assert_equal triom_pattern("gga"), "-"
    assert_equal triom_pattern("bbf"), "-"
    assert_equal triom_pattern("gmh"), "T"
    assert_equal triom_pattern("mhn"), "L"
    assert_equal triom_pattern("dea"), "-"
    assert_equal triom_pattern("mrn"), "R"
    assert_equal triom_pattern("hcm"), "I"
    assert_equal triom_pattern("mno"), "B"
    assert_equal triom_pattern("snr"), "J"
    assert_equal triom_pattern("xnn"), "-"
    assert_equal triom_pattern("nnl"), "-"
    assert_equal triom_pattern("kop"), "-"
    assert_equal triom_pattern("ejd"), "T"
    assert_equal triom_pattern("txy"), "J"
    assert_equal triom_pattern("pvu"), "L"
    assert_equal triom_pattern("baf"), "R"
    assert_equal triom_pattern("hhc"), "-"
    assert_equal triom_pattern("ono"), "-"
    assert_equal triom_pattern("wxv"), "B"
    assert_equal triom_pattern("bdc"), "B"
    assert_equal triom_pattern("ojt"), "I"
    assert_equal triom_pattern("fkp"), "I"
  end
end

実行結果

% ruby triom.rb
Loaded suite triom
Started
.

Finished in 0.001545 seconds.
--------------------------------------------------------------------------------------
1 tests, 26 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
--------------------------------------------------------------------------------------
647.25 tests/s, 16828.48 assertions/s
0
1
0

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
0
1