LoginSignup
1
1

More than 5 years have passed since last update.

オフラインリアルタイムどう書くE04 の yancya の解答

Last updated at Posted at 2016-06-04

Ruby で解きました

問題

方針

  • 全体の横道の数だけステップがある
  • 各ステップで、どの横道に入るかという情報のリストが石側、登山家側の両方で作れる
  • いずれかのステップで石の通る横道と被ってしまう登山家はアウト(意味深)
  • 石が全く横道に入らない場合、最初に石が落ち始めた方角にいる登山家はアウト(意味深)

コード

# coding: utf-8
LABELS = ("A".."H").to_a

def hoge(code)
  # code #=> "2512:C"

  sideways, start = code.split(":").tap { |a, b|
    break [
      a.chars.map(&:to_i).
        map { |n| [LABELS[n-1], LABELS[n % 8]].join },
      b
    ]
  }

  # sideways #=> ["BC", "EF", "AB", "BC"]
  # start    #=> "C"

  router = -> ((d, log), way) {
    if way.match(d)
      [way.gsub(d, ""), log + [way]]
    else
      [d, log + [nil]]
    end
  }

  routes = LABELS.map { |l| sideways.reverse.reduce([l, []], &router) }.to_h

  # 麓から登ったときのゴールが key、経路が value
  # routes #=> {
  #              "C" => [ nil, "AB",  nil, "BC"],
  #              "B" => ["BC",  nil,  nil, "BC"],
  #              "A" => ["BC", "AB",  nil,  nil],
  #              "D" => [ nil,  nil,  nil,  nil],
  #              "F" => [ nil,  nil, "EF",  nil],
  #              "E" => [ nil,  nil, "EF",  nil],
  #              "G" => [ nil,  nil,  nil,  nil],
  #              "H" => [ nil,  nil,  nil,  nil]
  #            }

  # 石のスタート方向がゴールになっている経路の逆順が石の経路
  danger_route = routes[start].reverse

  # danger_route #=> ["BC", nil, "AB", nil]

  routes.values.map { |route|
    route.
      zip(danger_route.reverse).
      map { |(a, b)| a && a == b ? "死" : "セーフ" }.
      index("死") ? "死" : "生"
  }.map.with_index { |judge, i| #=> ["死", "死", "死", "生", "生", "生", "生", "生"]
    LABELS[i] if judge == "生"
  }.         #=> [nil, nil, nil, "D", "E", "F", "G", "H"]
    compact. #=> ["D", "E", "F", "G", "H"]
    join.    #=> "DEFGH"
    gsub(danger_route.none? ? start : "", "") #=> "DEFGH"
end

require 'test-unit'
class MainTest < Test::Unit::TestCase
  data(
    "/*00*/" => ["2512:C", "DEFGH"],
    "/*01*/" => ["1:A", "CDEFGH"],
    "/*02*/" => [":C", "ABDEFGH"],
    "/*03*/" => ["2345:B", "AGH"],
    "/*04*/" => ["1256:E", "ABCDH"],
    "/*05*/" => ["1228:A", "ADEFG"],
    "/*06*/" => ["5623:B", "AEFGH"],
    "/*07*/" => ["8157:C", "ABDEFGH"],
    "/*08*/" => ["74767:E", "ABCFGH"],
    "/*09*/" => ["88717:D", "ABCEFGH"],
    "/*10*/" => ["148647:A", "ACDEFH"],
    "/*11*/" => ["374258:H", "BCDEFH"],
    "/*12*/" => ["6647768:F", "ABCDEH"],
    "/*13*/" => ["4786317:E", "ABFGH"],
    "/*14*/" => ["3456781:C", ""],
    "/*15*/" => ["225721686547123:C", "CEF"],
    "/*16*/" => ["2765356148824666:F", "ABCDEH"],
    "/*17*/" => ["42318287535641783:F", "BDE"],
    "/*18*/" => ["584423584751745261:D", "FGH"],
    "/*19*/" => ["8811873415472513884:D", "CFG"],
    "/*20*/" => ["74817442725737422451:H", "BCDEF"],
    "/*21*/" => ["223188865746766511566:C", "ABGH"],
    "/*22*/" => ["2763666483242552567747:F", "ABCG"],
    "/*23*/" => ["76724442325377753577138:E", "EG"],
    "/*24*/" => ["327328486656448784712618:B", ""],
    "/*25*/" => ["4884637666662548114774288:D", "DGH"],
    "/*26*/" => ["84226765313786654637511248:H", "DEF"],
    "/*27*/" => ["486142154163288126476238756:A", "CDF"],
    "/*28*/" => ["1836275732415226326155464567:F", "BCD"],
    "/*29*/" => ["62544434452376661746517374245:G", "G"],
    "/*30*/" => ["381352782758218463842725673473:B", "A"],
  )
  test "hoge" do |(actual, expected)|
    assert { hoge(actual) == expected }
  end
end
1
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
1
1