require 'pp'
require 'minitest/autorun'
F=
# 200
->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}
j=r[?>]-r[?<]
k=r[?v]-r[?^]
q[d=[d,1,0][j*j<=>k*k]]+=[k,j][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
cmVxdWlyZSAncHAnCnJlcXVpcmUgJ21pbml0ZXN0L2F1dG9ydW4nCgpGPQojIDIwMAotPmcsdyxoe209LT55LHgsZCx2PVtde3E9eSx4CnI9LT5zeyhbIiJdKmgrZylbeStoLGhdLm1hcHt8bHwoP3gqdytsKVt4K3csd119LmpvaW4uY291bnQgc30Kaj1yWz8+XS1yWz88XQprPXJbP3ZdLXJbP15dCnFbZD1bZCwxLDBdW2oqajw9Pmsqa11dKz1bayxqXVtkXTw9PjAKdiZbcTw8ZF0hPVtdP3EhPXZbLTFdOm1bKnEsdjw8cV19Cm1bMCwwLDFdfQoKIyBEZWJ1ZyB2ZXJzaW9uCiMgLT5nLHcsaHttPS0+eSx4LGQsdj1bXXtyPS0+c3tnW1swLHldLm1heC4uLnkraF0ubWFwe3xsfGxbWzAseF0ubWF4Li4ueCt3XX0uam9pbi5jb3VudCBzfQojIGo9cls/Pl0tcls/PF0KIyBrPXJbP3ZdLXJbP15dCiMgcT15LHgKIyAgIHo9Zy5tYXB7fGx8bC5kdXB9CiMgICB6W1swLHldLm1heC4uLnkraF0ubWFwIXt8bHwKIyAgICAgcj1bMCx4XS5tYXguLi54K3cKIyAgICAgbiA9IGwKIyAgICAgbltyXT0/IypyLnNpemUKIyAgICAgbgojICAgfQojICAgcHV0cyB6CiMgICBwIFsqcSxkXQojIHFbZD1bZCwxLDBdW2oqajw9Pmsqa11dKz1bayxqXVtkXTw9PjAKIyBxPDxkCiMgICBwIHEKIyBwdXRzCiMgdiZbcV0hPVtdP3EhPXZbLTFdOm1bcVswXSxxWzFdLGQsdjw8cV19CiMgbVswLDAsMV19CgpkZXNjcmliZSA6WCBkbwogIGRlc2NyaWJlICdHcmlkIDEgKDJ4MiknIGRvCiAgICBiZWZvcmUgZG8KICAgICAgQGcgPSBbCiAgICAgICAgJz52JywKICAgICAgICAnXjwnIF0KICAgIGVuZAoKICAgIGl0ICdkZXRlY3RzIGxvb3AgZm9yIDF4MScgZG8gYXNzZXJ0IEZbQGcsIDEsIDFdIGVuZAogICAgaXQgJ2RldGVjdHMgbG9vcCBmb3IgMXgyJyBkbyBhc3NlcnQgRltAZywgMSwgMl0gZW5kCiAgICBpdCAnZGV0ZWN0cyBsb29wIGZvciAyeDEnIGRvIGFzc2VydCBGW0BnLCAyLCAxXSBlbmQKICAgIGl0ICdkZXRlY3RzIHJlc3QgZm9yIDJ4MicgZG8gcmVmdXRlIEZbQGcsIDIsIDJdIGVuZAogIGVuZAoKICBkZXNjcmliZSAnR3JpZCAyICgzeDMpJyBkbwogICAgYmVmb3JlIGRvCiAgICAgIEBnID0gWwogICAgICAgICc+IHYnLAogICAgICAgICcgICAnLAogICAgICAgICdeIDwnIF0KICAgIGVuZAoKICAgIGl0ICdkZXRlY3RzIHJlc3QgZm9yIDF4MScgZG8gcmVmdXRlIEZbQGcsIDEsIDFdIGVuZAogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgMXgyJyBkbyByZWZ1dGUgRltAZywgMSwgMl0gZW5kCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciAxeDMnIGRvIHJlZnV0ZSBGW0BnLCAxLCAzXSBlbmQKICAgIGl0ICdkZXRlY3RzIHJlc3QgZm9yIDJ4MScgZG8gcmVmdXRlIEZbQGcsIDIsIDFdIGVuZAogICAgaXQgJ2RldGVjdHMgbG9vcCBmb3IgMngyJyBkbyBhc3NlcnQgRltAZywgMiwgMl0gZW5kCiAgICBpdCAnZGV0ZWN0cyBsb29wIGZvciAyeDMnIGRvIGFzc2VydCBGW0BnLCAyLCAzXSBlbmQKICAgIGl0ICdkZXRlY3RzIHJlc3QgZm9yIDN4MScgZG8gcmVmdXRlIEZbQGcsIDMsIDFdIGVuZAogICAgaXQgJ2RldGVjdHMgbG9vcCBmb3IgM3gyJyBkbyBhc3NlcnQgRltAZywgMywgMl0gZW5kCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciAzeDMnIGRvIHJlZnV0ZSBGW0BnLCAzLCAzXSBlbmQKICBlbmQKCiAgZGVzY3JpYmUgJ0dyaWQgMyAoNHgzKScgZG8KICAgIGJlZm9yZSBkbwogICAgICBAZyA9IFsKICAgICAgICAnPl4+dicsCiAgICAgICAgJ3ZediAnLAogICAgICAgICdeIDw8JywKICAgICAgXQogICAgZW5kCgogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgMngyJyBkbyByZWZ1dGUgRltAZywgMiwgMl0gZW5kCiAgZW5kCgogIGRlc2NyaWJlICdHcmlkIDQgKDZ4NSknIGRvCiAgICBiZWZvcmUgZG8KICAgICAgQGcgPSBbCiAgICAgICAgJz52PnY+dicsCiAgICAgICAgJ152XnZedicsCiAgICAgICAgJ152XnZedicsCiAgICAgICAgJ14+Xj5edicsCiAgICAgICAgJ148PDw8PCddCiAgICBlbmQKCiAgICBpdCAnZGV0ZWN0cyBsb29wIGZvciAxeDEnIGRvIGFzc2VydCBGW0BnLCAxLCAxXSBlbmQKICAgIGl0ICdkZXRlY3RzIHJlc3QgZm9yIDF4MicgZG8gcmVmdXRlIEZbQGcsIDEsIDJdIGVuZAogICAgaXQgJ2RldGVjdHMgbG9vcCBmb3IgMngxJyBkbyBhc3NlcnQgRltAZywgMiwgMV0gZW5kCiAgICBpdCAnZGV0ZWN0cyBsb29wIGZvciAyeDInIGRvIGFzc2VydCBGW0BnLCAyLCAyXSBlbmQKICAgIGl0ICdkZXRlY3RzIGxvb3AgZm9yIDJ4NCcgZG8gYXNzZXJ0IEZbQGcsIDIsIDRdIGVuZAogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgMng1JyBkbyByZWZ1dGUgRltAZywgMiwgNV0gZW5kCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciAzeDEnIGRvIHJlZnV0ZSBGW0BnLCAzLCAxXSBlbmQKICAgIGl0ICdkZXRlY3RzIGxvb3AgZm9yIDN4MicgZG8gYXNzZXJ0IEZbQGcsIDMsIDJdIGVuZAogICAgaXQgJ2RldGVjdHMgbG9vcCBmb3IgM3gzJyBkbyBhc3NlcnQgRltAZywgMywgM10gZW5kCiAgICBpdCAnZGV0ZWN0cyBsb29wIGZvciAzeDUnIGRvIGFzc2VydCBGW0BnLCAzLCA1XSBlbmQKICAgIGl0ICdkZXRlY3RzIHJlc3QgZm9yIDZ4MicgZG8gcmVmdXRlIEZbQGcsIDYsIDJdIGVuZAogICAgaXQgJ2RldGVjdHMgbG9vcCBmb3IgNngzJyBkbyBhc3NlcnQgRltAZywgNiwgM10gZW5kCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciA2eDUnIGRvIHJlZnV0ZSBGW0BnLCA2LCA1XSBlbmQKICBlbmQKCiAgZGVzY3JpYmUgJ0dyaWQgNSAoMTB4NiknIGRvCiAgICBiZWZvcmUgZG8KICAgICAgQGcgPSBbCiAgICAgICAgJz4gPHZ2ICAgIDwnLAogICAgICAgICcgdiBeID52IHYgJywKICAgICAgICAnICA+dl5ePnZ2XicsCiAgICAgICAgJyAgICBePl4gdiAnLAogICAgICAgICc+ICB2PHYgID4+JywKICAgICAgICAnICA+diB2PF4gICddCiAgICBlbmQKCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciAxeDEnIGRvIHJlZnV0ZSBGW0BnLCAxLCAxXSBlbmQKICAgIGl0ICdkZXRlY3RzIHJlc3QgZm9yIDJ4MycgZG8gcmVmdXRlIEZbQGcsIDIsIDNdIGVuZAogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgMng2JyBkbyByZWZ1dGUgRltAZywgMiwgNl0gZW5kCiAgICBpdCAnZGV0ZWN0cyBsb29wIGZvciAzeDInIGRvIGFzc2VydCBGW0BnLCAzLCAyXSBlbmQKICAgIGl0ICdkZXRlY3RzIHJlc3QgZm9yIDV4NCcgZG8gcmVmdXRlIEZbQGcsIDUsIDRdIGVuZAogICAgaXQgJ2RldGVjdHMgbG9vcCBmb3IgNngxJyBkbyBhc3NlcnQgRltAZywgNiwgMV0gZW5kCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciAxMHg2JyBkbyByZWZ1dGUgRltAZywgMTAsIDZdIGVuZAogIGVuZAoKICBkZXNjcmliZSAnSW5jb3JyZWN0IGN5Y2xlIGRldGVjdGlvbicgZG8KICAgIGJlZm9yZSBkbwogICAgICBAZyA9IFsKICAgICAgICAnPj52ICcsCiAgICAgICAgJyA+diAnLAogICAgICAgICc+PiA+JywKICAgICAgICAnXiAgdicsCiAgICAgICAgJ14gdiAnLAogICAgICAgICcgIDw8JwogICAgICBdCiAgICBlbmQKCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciAyeDInIGRvIHJlZnV0ZSBGW0BnLCAyLCAyXSBlbmQKICBlbmQKZW5kCg==