require 'pp'
require 'minitest/autorun'
F=
->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]}
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 (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 4 (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
end
cmVxdWlyZSAncHAnCnJlcXVpcmUgJ21pbml0ZXN0L2F1dG9ydW4nCgpGPQotPmcsdyxoe209LT55LHgsZCx2PVtde3E9eSx4CnI9LT5zeyhbIiJdKmgrZylbeStoLGhdLm1hcHt8bHwoP3gqdytsKVt4K3csd119LmpvaW4uY291bnQgc30Kej1rPXJbP3ZdLXJbP15dLGo9cls/Pl0tcls/PF0KcVtkPVtkLDEsMF1baipqPD0+ayprXV0rPXpbZF08PT4wCnYmW3E8PGRdIT1bXT9xIT12Wy0xXTptWypxLHY8PHFdfQptWzAsMCwxXX0KCmRlc2NyaWJlIDpYIGRvCiAgZGVzY3JpYmUgJ0dyaWQgMSAoMngyKScgZG8KICAgIGJlZm9yZSBkbwogICAgICBAZyA9IFsKICAgICAgICAnPnYnLAogICAgICAgICdePCcgXQogICAgZW5kCgogICAgaXQgJ2RldGVjdHMgbG9vcCBmb3IgMXgxJyBkbyBhc3NlcnQgRltAZywgMSwgMV0gZW5kCiAgICBpdCAnZGV0ZWN0cyBsb29wIGZvciAxeDInIGRvIGFzc2VydCBGW0BnLCAxLCAyXSBlbmQKICAgIGl0ICdkZXRlY3RzIGxvb3AgZm9yIDJ4MScgZG8gYXNzZXJ0IEZbQGcsIDIsIDFdIGVuZAogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgMngyJyBkbyByZWZ1dGUgRltAZywgMiwgMl0gZW5kCiAgZW5kCgogIGRlc2NyaWJlICdHcmlkIDIgKDN4MyknIGRvCiAgICBiZWZvcmUgZG8KICAgICAgQGcgPSBbCiAgICAgICAgJz4gdicsCiAgICAgICAgJyAgICcsCiAgICAgICAgJ14gPCcgXQogICAgZW5kCgogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgMXgxJyBkbyByZWZ1dGUgRltAZywgMSwgMV0gZW5kCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciAxeDInIGRvIHJlZnV0ZSBGW0BnLCAxLCAyXSBlbmQKICAgIGl0ICdkZXRlY3RzIHJlc3QgZm9yIDF4MycgZG8gcmVmdXRlIEZbQGcsIDEsIDNdIGVuZAogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgMngxJyBkbyByZWZ1dGUgRltAZywgMiwgMV0gZW5kCiAgICBpdCAnZGV0ZWN0cyBsb29wIGZvciAyeDInIGRvIGFzc2VydCBGW0BnLCAyLCAyXSBlbmQKICAgIGl0ICdkZXRlY3RzIGxvb3AgZm9yIDJ4MycgZG8gYXNzZXJ0IEZbQGcsIDIsIDNdIGVuZAogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgM3gxJyBkbyByZWZ1dGUgRltAZywgMywgMV0gZW5kCiAgICBpdCAnZGV0ZWN0cyBsb29wIGZvciAzeDInIGRvIGFzc2VydCBGW0BnLCAzLCAyXSBlbmQKICAgIGl0ICdkZXRlY3RzIHJlc3QgZm9yIDN4MycgZG8gcmVmdXRlIEZbQGcsIDMsIDNdIGVuZAogIGVuZAoKICBkZXNjcmliZSAnR3JpZCAzICg2eDUpJyBkbwogICAgYmVmb3JlIGRvCiAgICAgIEBnID0gWwogICAgICAgICc+dj52PnYnLAogICAgICAgICdedl52XnYnLAogICAgICAgICdedl52XnYnLAogICAgICAgICdePl4+XnYnLAogICAgICAgICdePDw8PDwnXQogICAgZW5kCgogICAgaXQgJ2RldGVjdHMgbG9vcCBmb3IgMXgxJyBkbyBhc3NlcnQgRltAZywgMSwgMV0gZW5kCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciAxeDInIGRvIHJlZnV0ZSBGW0BnLCAxLCAyXSBlbmQKICAgIGl0ICdkZXRlY3RzIGxvb3AgZm9yIDJ4MScgZG8gYXNzZXJ0IEZbQGcsIDIsIDFdIGVuZAogICAgaXQgJ2RldGVjdHMgbG9vcCBmb3IgMngyJyBkbyBhc3NlcnQgRltAZywgMiwgMl0gZW5kCiAgICBpdCAnZGV0ZWN0cyBsb29wIGZvciAyeDQnIGRvIGFzc2VydCBGW0BnLCAyLCA0XSBlbmQKICAgIGl0ICdkZXRlY3RzIHJlc3QgZm9yIDJ4NScgZG8gcmVmdXRlIEZbQGcsIDIsIDVdIGVuZAogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgM3gxJyBkbyByZWZ1dGUgRltAZywgMywgMV0gZW5kCiAgICBpdCAnZGV0ZWN0cyBsb29wIGZvciAzeDInIGRvIGFzc2VydCBGW0BnLCAzLCAyXSBlbmQKICAgIGl0ICdkZXRlY3RzIGxvb3AgZm9yIDN4MycgZG8gYXNzZXJ0IEZbQGcsIDMsIDNdIGVuZAogICAgaXQgJ2RldGVjdHMgbG9vcCBmb3IgM3g1JyBkbyBhc3NlcnQgRltAZywgMywgNV0gZW5kCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciA2eDInIGRvIHJlZnV0ZSBGW0BnLCA2LCAyXSBlbmQKICAgIGl0ICdkZXRlY3RzIGxvb3AgZm9yIDZ4MycgZG8gYXNzZXJ0IEZbQGcsIDYsIDNdIGVuZAogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgNng1JyBkbyByZWZ1dGUgRltAZywgNiwgNV0gZW5kCiAgZW5kCgogIGRlc2NyaWJlICdHcmlkIDQgKDEweDYpJyBkbwogICAgYmVmb3JlIGRvCiAgICAgIEBnID0gWwogICAgICAgICc+IDx2diAgICA8JywKICAgICAgICAnIHYgXiA+diB2ICcsCiAgICAgICAgJyAgPnZeXj52dl4nLAogICAgICAgICcgICAgXj5eIHYgJywKICAgICAgICAnPiAgdjx2ICA+PicsCiAgICAgICAgJyAgPnYgdjxeICAnXQogICAgZW5kCgogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgMXgxJyBkbyByZWZ1dGUgRltAZywgMSwgMV0gZW5kCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciAyeDMnIGRvIHJlZnV0ZSBGW0BnLCAyLCAzXSBlbmQKICAgIGl0ICdkZXRlY3RzIHJlc3QgZm9yIDJ4NicgZG8gcmVmdXRlIEZbQGcsIDIsIDZdIGVuZAogICAgaXQgJ2RldGVjdHMgbG9vcCBmb3IgM3gyJyBkbyBhc3NlcnQgRltAZywgMywgMl0gZW5kCiAgICBpdCAnZGV0ZWN0cyByZXN0IGZvciA1eDQnIGRvIHJlZnV0ZSBGW0BnLCA1LCA0XSBlbmQKICAgIGl0ICdkZXRlY3RzIGxvb3AgZm9yIDZ4MScgZG8gYXNzZXJ0IEZbQGcsIDYsIDFdIGVuZAogICAgaXQgJ2RldGVjdHMgcmVzdCBmb3IgMTB4NicgZG8gcmVmdXRlIEZbQGcsIDEwLCA2XSBlbmQKICBlbmQKZW5kCg==