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