require 'pp'
require 'minitest/autorun'
F=
# 198
->g,w,h{m=->y,x,d,v=[]{q=y,x
r=->s{([""]*h+g)[y+h,h].map{|l|(?x*w+l)[x+w,w]}.join.count s}
z=k=r[?v]-r[?^],j=r[?>]-r[?<]
q[d=[d,1,0][j*j<=>k*k]]+=z[d]<=>0
v&[q<<d]!=[]?q!=v[-1]:m[*q,v<<q]}
m[0,0,1]}
# Debug version
# ->g,w,h{m=->y,x,d,v=[]{r=->s{g[[0,y].max...y+h].map{|l|l[[0,x].max...x+w]}.join.count s}
# j=r[?>]-r[?<]
# k=r[?v]-r[?^]
# q=y,x
# z=g.map{|l|l.dup}
# z[[0,y].max...y+h].map!{|l|
# r=[0,x].max...x+w
# n = l
# n[r]=?#*r.size
# n
# }
# puts z
# p [*q,d]
# q[d=[d,1,0][j*j<=>k*k]]+=[k,j][d]<=>0
# q<<d
# p q
# puts
# v&[q]!=[]?q!=v[-1]:m[q[0],q[1],d,v<<q]}
# m[0,0,1]}
describe :X do
describe 'Grid 1 (2x2)' do
before do
@g = [
'>v',
'^<' ]
end
it 'detects loop for 1x1' do assert F[@g, 1, 1] end
it 'detects loop for 1x2' do assert F[@g, 1, 2] end
it 'detects loop for 2x1' do assert F[@g, 2, 1] end
it 'detects rest for 2x2' do refute F[@g, 2, 2] end
end
describe 'Grid 2 (3x3)' do
before do
@g = [
'> v',
' ',
'^ <' ]
end
it 'detects rest for 1x1' do refute F[@g, 1, 1] end
it 'detects rest for 1x2' do refute F[@g, 1, 2] end
it 'detects rest for 1x3' do refute F[@g, 1, 3] end
it 'detects rest for 2x1' do refute F[@g, 2, 1] end
it 'detects loop for 2x2' do assert F[@g, 2, 2] end
it 'detects loop for 2x3' do assert F[@g, 2, 3] end
it 'detects rest for 3x1' do refute F[@g, 3, 1] end
it 'detects loop for 3x2' do assert F[@g, 3, 2] end
it 'detects rest for 3x3' do refute F[@g, 3, 3] end
end
describe 'Grid 3 (4x3)' do
before do
@g = [
'>^>v',
'v^v ',
'^ <<',
]
end
it 'detects rest for 2x2' do refute F[@g, 2, 2] end
end
describe 'Grid 4 (6x5)' do
before do
@g = [
'>v>v>v',
'^v^v^v',
'^v^v^v',
'^>^>^v',
'^<<<<<']
end
it 'detects loop for 1x1' do assert F[@g, 1, 1] end
it 'detects rest for 1x2' do refute F[@g, 1, 2] end
it 'detects loop for 2x1' do assert F[@g, 2, 1] end
it 'detects loop for 2x2' do assert F[@g, 2, 2] end
it 'detects loop for 2x4' do assert F[@g, 2, 4] end
it 'detects rest for 2x5' do refute F[@g, 2, 5] end
it 'detects rest for 3x1' do refute F[@g, 3, 1] end
it 'detects loop for 3x2' do assert F[@g, 3, 2] end
it 'detects loop for 3x3' do assert F[@g, 3, 3] end
it 'detects loop for 3x5' do assert F[@g, 3, 5] end
it 'detects rest for 6x2' do refute F[@g, 6, 2] end
it 'detects loop for 6x3' do assert F[@g, 6, 3] end
it 'detects rest for 6x5' do refute F[@g, 6, 5] end
end
describe 'Grid 5 (10x6)' do
before do
@g = [
'> <vv <',
' v ^ >v v ',
' >v^^>vv^',
' ^>^ v ',
'> v<v >>',
' >v v<^ ']
end
it 'detects rest for 1x1' do refute F[@g, 1, 1] end
it 'detects rest for 2x3' do refute F[@g, 2, 3] end
it 'detects rest for 2x6' do refute F[@g, 2, 6] end
it 'detects loop for 3x2' do assert F[@g, 3, 2] end
it 'detects rest for 5x4' do refute F[@g, 5, 4] end
it 'detects loop for 6x1' do assert F[@g, 6, 1] end
it 'detects rest for 10x6' do refute F[@g, 10, 6] end
end
describe 'Incorrect cycle detection' do
before do
@g = [
'>>v ',
' >v ',
'>> >',
'^ v',
'^ v ',
' <<'
]
end
it 'detects rest for 2x2' do refute F[@g, 2, 2] end
end
end
cmVxdWlyZSAncHAnCnJlcXVpcmUgJ21pbml0ZXN0L2F1dG9ydW4nCgpGPQojIDE5OAotPmcsdyxoe209LT55LHgsZCx2PVtde3E9eSx4CnI9LT5zeyhbIiJdKmgrZylbeStoLGhdLm1hcHt8bHwoP3gqdytsKVt4K3csd119LmpvaW4uY291bnQgc30Kej1rPXJbP3ZdLXJbP15dLGo9cls/Pl0tcls/PF0KcVtkPVtkLDEsMF1baipqPD0+ayprXV0rPXpbZF08PT4wCnYmW3E8PGRdIT1bXT9xIT12Wy0xXTptWypxLHY8PHFdfQptWzAsMCwxXX0KCiMgRGVidWcgdmVyc2lvbgojIC0+Zyx3LGh7bT0tPnkseCxkLHY9W117cj0tPnN7Z1tbMCx5XS5tYXguLi55K2hdLm1hcHt8bHxsW1swLHhdLm1heC4uLngrd119LmpvaW4uY291bnQgc30KIyBqPXJbPz5dLXJbPzxdCiMgaz1yWz92XS1yWz9eXQojIHE9eSx4CiMgICB6PWcubWFwe3xsfGwuZHVwfQojICAgeltbMCx5XS5tYXguLi55K2hdLm1hcCF7fGx8CiMgICAgIHI9WzAseF0ubWF4Li4ueCt3CiMgICAgIG4gPSBsCiMgICAgIG5bcl09PyMqci5zaXplCiMgICAgIG4KIyAgIH0KIyAgIHB1dHMgegojICAgcCBbKnEsZF0KIyBxW2Q9W2QsMSwwXVtqKmo8PT5rKmtdXSs9W2ssal1bZF08PT4wCiMgcTw8ZAojICAgcCBxCiMgcHV0cwojIHYmW3FdIT1bXT9xIT12Wy0xXTptW3FbMF0scVsxXSxkLHY8PHFdfQojIG1bMCwwLDFdfQoKZGVzY3JpYmUgOlggZG8KICBkZXNjcmliZSAnR3JpZCAxICgyeDIpJyBkbwogICAgYmVmb3JlIGRvCiAgICAgIEBnID0gWwogICAgICAgICc+dicsCiAgICAgICAgJ148JyBdCiAgICBlbmQKCiAgICBpdCAnZGV0ZWN0cyBsb29wIGZvciAxeDEnIGRvIGFzc2VydCBGW0BnLCAxLCAxXSBlbmQKICAgIGl0ICdkZXRlY3RzIGxvb3AgZm9yIDF4MicgZG8gYXNzZXJ0IEZbQGcsIDEsIDJdIGVuZAogICAgaXQgJ2RldGVjdHMgbG9vcCBmb3IgMngxJyBkbyBhc3NlcnQgRltAZywgMiwgMV0gZW5kCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciAyeDInIGRvIHJlZnV0ZSBGW0BnLCAyLCAyXSBlbmQKICBlbmQKCiAgZGVzY3JpYmUgJ0dyaWQgMiAoM3gzKScgZG8KICAgIGJlZm9yZSBkbwogICAgICBAZyA9IFsKICAgICAgICAnPiB2JywKICAgICAgICAnICAgJywKICAgICAgICAnXiA8JyBdCiAgICBlbmQKCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciAxeDEnIGRvIHJlZnV0ZSBGW0BnLCAxLCAxXSBlbmQKICAgIGl0ICdkZXRlY3RzIHJlc3QgZm9yIDF4MicgZG8gcmVmdXRlIEZbQGcsIDEsIDJdIGVuZAogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgMXgzJyBkbyByZWZ1dGUgRltAZywgMSwgM10gZW5kCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciAyeDEnIGRvIHJlZnV0ZSBGW0BnLCAyLCAxXSBlbmQKICAgIGl0ICdkZXRlY3RzIGxvb3AgZm9yIDJ4MicgZG8gYXNzZXJ0IEZbQGcsIDIsIDJdIGVuZAogICAgaXQgJ2RldGVjdHMgbG9vcCBmb3IgMngzJyBkbyBhc3NlcnQgRltAZywgMiwgM10gZW5kCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciAzeDEnIGRvIHJlZnV0ZSBGW0BnLCAzLCAxXSBlbmQKICAgIGl0ICdkZXRlY3RzIGxvb3AgZm9yIDN4MicgZG8gYXNzZXJ0IEZbQGcsIDMsIDJdIGVuZAogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgM3gzJyBkbyByZWZ1dGUgRltAZywgMywgM10gZW5kCiAgZW5kCgogIGRlc2NyaWJlICdHcmlkIDMgKDR4MyknIGRvCiAgICBiZWZvcmUgZG8KICAgICAgQGcgPSBbCiAgICAgICAgJz5ePnYnLAogICAgICAgICd2XnYgJywKICAgICAgICAnXiA8PCcsCiAgICAgIF0KICAgIGVuZAoKICAgIGl0ICdkZXRlY3RzIHJlc3QgZm9yIDJ4MicgZG8gcmVmdXRlIEZbQGcsIDIsIDJdIGVuZAogIGVuZAoKICBkZXNjcmliZSAnR3JpZCA0ICg2eDUpJyBkbwogICAgYmVmb3JlIGRvCiAgICAgIEBnID0gWwogICAgICAgICc+dj52PnYnLAogICAgICAgICdedl52XnYnLAogICAgICAgICdedl52XnYnLAogICAgICAgICdePl4+XnYnLAogICAgICAgICdePDw8PDwnXQogICAgZW5kCgogICAgaXQgJ2RldGVjdHMgbG9vcCBmb3IgMXgxJyBkbyBhc3NlcnQgRltAZywgMSwgMV0gZW5kCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciAxeDInIGRvIHJlZnV0ZSBGW0BnLCAxLCAyXSBlbmQKICAgIGl0ICdkZXRlY3RzIGxvb3AgZm9yIDJ4MScgZG8gYXNzZXJ0IEZbQGcsIDIsIDFdIGVuZAogICAgaXQgJ2RldGVjdHMgbG9vcCBmb3IgMngyJyBkbyBhc3NlcnQgRltAZywgMiwgMl0gZW5kCiAgICBpdCAnZGV0ZWN0cyBsb29wIGZvciAyeDQnIGRvIGFzc2VydCBGW0BnLCAyLCA0XSBlbmQKICAgIGl0ICdkZXRlY3RzIHJlc3QgZm9yIDJ4NScgZG8gcmVmdXRlIEZbQGcsIDIsIDVdIGVuZAogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgM3gxJyBkbyByZWZ1dGUgRltAZywgMywgMV0gZW5kCiAgICBpdCAnZGV0ZWN0cyBsb29wIGZvciAzeDInIGRvIGFzc2VydCBGW0BnLCAzLCAyXSBlbmQKICAgIGl0ICdkZXRlY3RzIGxvb3AgZm9yIDN4MycgZG8gYXNzZXJ0IEZbQGcsIDMsIDNdIGVuZAogICAgaXQgJ2RldGVjdHMgbG9vcCBmb3IgM3g1JyBkbyBhc3NlcnQgRltAZywgMywgNV0gZW5kCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciA2eDInIGRvIHJlZnV0ZSBGW0BnLCA2LCAyXSBlbmQKICAgIGl0ICdkZXRlY3RzIGxvb3AgZm9yIDZ4MycgZG8gYXNzZXJ0IEZbQGcsIDYsIDNdIGVuZAogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgNng1JyBkbyByZWZ1dGUgRltAZywgNiwgNV0gZW5kCiAgZW5kCgogIGRlc2NyaWJlICdHcmlkIDUgKDEweDYpJyBkbwogICAgYmVmb3JlIGRvCiAgICAgIEBnID0gWwogICAgICAgICc+IDx2diAgICA8JywKICAgICAgICAnIHYgXiA+diB2ICcsCiAgICAgICAgJyAgPnZeXj52dl4nLAogICAgICAgICcgICAgXj5eIHYgJywKICAgICAgICAnPiAgdjx2ICA+PicsCiAgICAgICAgJyAgPnYgdjxeICAnXQogICAgZW5kCgogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgMXgxJyBkbyByZWZ1dGUgRltAZywgMSwgMV0gZW5kCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciAyeDMnIGRvIHJlZnV0ZSBGW0BnLCAyLCAzXSBlbmQKICAgIGl0ICdkZXRlY3RzIHJlc3QgZm9yIDJ4NicgZG8gcmVmdXRlIEZbQGcsIDIsIDZdIGVuZAogICAgaXQgJ2RldGVjdHMgbG9vcCBmb3IgM3gyJyBkbyBhc3NlcnQgRltAZywgMywgMl0gZW5kCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciA1eDQnIGRvIHJlZnV0ZSBGW0BnLCA1LCA0XSBlbmQKICAgIGl0ICdkZXRlY3RzIGxvb3AgZm9yIDZ4MScgZG8gYXNzZXJ0IEZbQGcsIDYsIDFdIGVuZAogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgMTB4NicgZG8gcmVmdXRlIEZbQGcsIDEwLCA2XSBlbmQKICBlbmQKCiAgZGVzY3JpYmUgJ0luY29ycmVjdCBjeWNsZSBkZXRlY3Rpb24nIGRvCiAgICBiZWZvcmUgZG8KICAgICAgQGcgPSBbCiAgICAgICAgJz4+diAnLAogICAgICAgICcgPnYgJywKICAgICAgICAnPj4gPicsCiAgICAgICAgJ14gIHYnLAogICAgICAgICdeIHYgJywKICAgICAgICAnICA8PCcKICAgICAgXQogICAgZW5kCgogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgMngyJyBkbyByZWZ1dGUgRltAZywgMiwgMl0gZW5kCiAgZW5kCmVuZAo=