# coding: utf-8
require 'minitest/autorun'
F=->s{
l=s.split ?\n
m=l.size
n=l[0].size
# Make an array with lowercase letters and their coords (`b`)
# Make a hash that for each target (uppercase letter) holds
# its coordinates
b=[]
t={}
[*0...m].product([*0...n]).map{|y,x|
c=l[y][x]
c!=' '&&(c>?Z?b<<[c,y,x]:t[c.downcase]=[y,x])
}
# `l` is a function that, given an array of the form
# [lowercase_letter, y-coord, x-coord] will append to that array
# the number of steps required for the letter to reach its
# uppercase correspondent
l=->q{
c,y,x=q
u,i=t[c]
d=c.ord-97
(m*n).times{|w|
e=([u-y,i-x].map &:abs).max
e<=d&&q<<w+e
y=(y+1)%m
x=(x+1)%n
}
}
# apply function `l` to each of the lowercase letter...
b.map &l
# ...then sort accordingly and return the array
b.map{|x|[x[3],x[0]]}.select{|a,b|a}.sort.map{|a,b|b}
}
describe '#F' do
def test_case_1
assert_equal %w[d a], F[%q{
D
d Aa
}]
end
def test_case_2
assert_equal %w[w b], F[%q{
W B
A
b
a
w
}]
end
def test_case_3
assert_equal %w[a], F[%q{
A
a
}]
end
def test_case_4
assert_equal %w[i d f], F[%q{
i
f d
DI F }]
end
def test_case_5
assert_equal %w[g w j], F[%q{
g a
G W
j
w
A J
}]
end
end
IyBjb2Rpbmc6IHV0Zi04CnJlcXVpcmUgJ21pbml0ZXN0L2F1dG9ydW4nCgpGPS0+c3sKICBsPXMuc3BsaXQgP1xuCiAgbT1sLnNpemUKICBuPWxbMF0uc2l6ZQoKICAjIE1ha2UgYW4gYXJyYXkgd2l0aCBsb3dlcmNhc2UgbGV0dGVycyBhbmQgdGhlaXIgY29vcmRzIChgYmApCiAgIyBNYWtlIGEgaGFzaCB0aGF0IGZvciBlYWNoIHRhcmdldCAodXBwZXJjYXNlIGxldHRlcikgaG9sZHMKICAjIGl0cyBjb29yZGluYXRlcwogIGI9W10KICB0PXt9CiAgWyowLi4ubV0ucHJvZHVjdChbKjAuLi5uXSkubWFwe3x5LHh8IAogICAgYz1sW3ldW3hdCiAgICBjIT0nICcmJihjPj9aP2I8PFtjLHkseF06dFtjLmRvd25jYXNlXT1beSx4XSkKICB9CiAgCiAgIyBgbGAgaXMgYSBmdW5jdGlvbiB0aGF0LCBnaXZlbiBhbiBhcnJheSBvZiB0aGUgZm9ybQogICMgW2xvd2VyY2FzZV9sZXR0ZXIsIHktY29vcmQsIHgtY29vcmRdIHdpbGwgYXBwZW5kIHRvIHRoYXQgYXJyYXkKICAjIHRoZSBudW1iZXIgb2Ygc3RlcHMgcmVxdWlyZWQgZm9yIHRoZSBsZXR0ZXIgdG8gcmVhY2ggaXRzCiAgIyB1cHBlcmNhc2UgY29ycmVzcG9uZGVudAogIGw9LT5xewogICAgYyx5LHg9cQogICAgdSxpPXRbY10KICAgIGQ9Yy5vcmQtOTcKICAgIChtKm4pLnRpbWVze3x3fAogICAgICBlPShbdS15LGkteF0ubWFwICY6YWJzKS5tYXgKICAgICAgZTw9ZCYmcTw8dytlCiAgICAgIHk9KHkrMSklbQogICAgICB4PSh4KzEpJW4KICAgIH0KICB9CgogICMgYXBwbHkgZnVuY3Rpb24gYGxgIHRvIGVhY2ggb2YgdGhlIGxvd2VyY2FzZSBsZXR0ZXIuLi4KICBiLm1hcCAmbAoKICAjIC4uLnRoZW4gc29ydCBhY2NvcmRpbmdseSBhbmQgcmV0dXJuIHRoZSBhcnJheQogIGIubWFwe3x4fFt4WzNdLHhbMF1dfS5zZWxlY3R7fGEsYnxhfS5zb3J0Lm1hcHt8YSxifGJ9Cn0KCgpkZXNjcmliZSAnI0YnIGRvCiAgZGVmIHRlc3RfY2FzZV8xCiAgICBhc3NlcnRfZXF1YWwgJXdbZCBhXSwgRlslcXsgICAgICAKRCAgICAgCiAgZCBBYQogICAgICAKICAgICAgfV0KICBlbmQKCiAgZGVmIHRlc3RfY2FzZV8yCiAgICBhc3NlcnRfZXF1YWwgJXdbdyBiXSwgRlslcXsgICAgICAgIApXICAgICAgQgogICAgQSAgIAogIGIgICAgIAogICAgICAgIAogICAgICBhIAogIHcgICAgIAogICAgICAgIH1dCiAgZW5kCgogIGRlZiB0ZXN0X2Nhc2VfMwogICAgYXNzZXJ0X2VxdWFsICV3W2FdLCBGWyVxeyAgICAgICAgCiAgICAgICAgCiAgICAgQSAgCiAgICAgICAgCiAgICAgICAgCiAgICAgIGEgCiAgICAgICAgfV0KICBlbmQKCiAgZGVmIHRlc3RfY2FzZV80CiAgICBhc3NlcnRfZXF1YWwgJXdbaSBkIGZdLCBGWyVxeyAgICAgICAgICAKICAgICAgICAgIAogICBpICAgICAgCiAgZiAgICAgZCAKICAgICAgICAgIAogICAgICAgICAgCiAgICBESSAgRiB9XQogIGVuZAoKICBkZWYgdGVzdF9jYXNlXzUKICAgIGFzc2VydF9lcXVhbCAld1tnIHcgal0sIEZbJXF7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICBnICAgICAgICAgICAgICAgICBhICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICBHICAgICAgICAgICAgICAgVyAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICBqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgIHcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBICAgICAgSiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XQogIGVuZAplbmQKCgo=