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}
Ini dimulai pada @dan berjalan mundur, mencari tetangga yang menunjuk ke posisi saat ini ( z). Untuk memilih jalan yang benar di persimpangan 4 arah, ada baiknya tetangganya menunjuk ke arah yang sama ( max_by{...}). Jika tidak ada tetangga terdekat yang ditemukan, itu mengasumsikan bahwa pasti ada persimpangan dan menjangkau satu tingkat pada satu waktu sampai menemukan satu ( until ndan c+=1). Proses ini berulang untuk jumlah segmen tubuh (tidak termasuk kepala) ( .scan(/\w/){...}).
Kasing uji coba yang saya tambahkan ke puzzle terus membuat saya tersandung, jadi saya beralih dari 182 char ke 218. Semua karakter tambahan itu memastikan pergerakan horizontal saya tidak masuk ke baris berikutnya. Saya ingin tahu apakah saya bisa mengatasinya dengan cara yang lebih baik.
Tidak Disatukan:
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
}