Ruby, 217
->a{r=''
z=a.index ?@
a.tr!('<^>v',b='awds').scan(/\w/){c=0
e,n=[a[z,c+=1][?\n]?p: c,d=c*a[/.*
/].size,a[z-c,c][?\n]?p: -c,-d].zip(b.chars).reject{|i,k|!i||a[v=i+z]!=k||0>v}.max_by{|q|q&[a[z]]}until n
z+=e
r=n*c+r}
r}
Điều này bắt đầu tại @
và đi về phía sau, tìm kiếm hàng xóm chỉ đến vị trí hiện tại ( z
). Để chọn đúng đường tại ngã tư 4 chiều, nó ưu tiên hàng xóm chỉ theo cùng một hướng ( max_by{...}
). Nếu không có hàng xóm ngay lập tức được tìm thấy, nó giả định rằng phải có sự giao thoa và đạt đến một cấp độ tại một thời điểm cho đến khi tìm thấy một ( until n
và c+=1
). Quá trình này lặp lại cho số lượng các phân đoạn cơ thể (không bao gồm đầu) ( .scan(/\w/){...}
).
Trường hợp thử nghiệm mà tôi đã thêm vào câu đố khiến tôi vấp ngã, vì vậy tôi đã chuyển từ 182 char sang 218. Những nhân vật phụ đó đều đảm bảo rằng các bước di chuyển ngang của tôi không đi vào các dòng tiếp theo / trước. Tôi tự hỏi nếu tôi có thể đối phó với điều đó một cách tốt hơn.
Ung dung:
f=->a{
result=''
position=a.index ?@ # start at the @
a.tr!('<^>v',b='awds') # translate arrows to letters
a.scan(/\w/){ # for each letter found...
search_distance=0
until distance
search_distance+=1
neighbors = [
a[position,search_distance][?\n]?p: search_distance, # look right by search_distance unless there's a newline
width=search_distance*a[/.*\n/].size, # look down (+width)
a[position-search_distance,search_distance][?\n]?p: -search_distance, # look left unless there's a newline
-width # look up (-width)
]
distance,letter = neighbors.zip(b.chars).reject{ |distance, letter_to_find|
!distance || # eliminate nulls
a[new_position=distance+position]!=letter_to_find || # only look for the letter that "points" at me
0>new_position # and make sure we're not going into negative indices
}.max_by{ |q|
# if there are two valid neighbors, we're at a 4-way intersection
# this will make sure we prefer the neighbor who points in the same
# direction we're pointing in. E.g., when position is in the middle of
# the below, the non-rejected array includes both the top and left.
# v
# >>>
# v
# We want to prefer left.
q & [a[position]]
# ['>',x] & ['>'] == ['>']
# ['v',x] & ['>'] == []
# ['>'] > [], so we select '>'.
}
end
position+=distance
result=(letter*search_distance)+result # prepend result
}
result # if anyone has a better way of returning result, I'm all ears
}