Explanation: undefined
ends by d
.
Test:
" -> 0\r\n\
^^ -> 0\r\n\
^v -> -1\r\n\
^ -> 1\r\n\
v -> -1\r\n\
v^ -> 1\r\n\
vv -> 0\r\n\
^^^ -> 1\r\n\
vvv -> -1\r\n\
^^^^ -> 0\r\n\
vvvv -> 0\r\n\
^^^^^ -> 1\r\n\
vvvvv -> -1\r\n\
^^^^^^ -> 0\r\n\
vvvvvv -> 0\r\n\
^^v -> -1\r\n\
^v^ -> 1\r\n\
^vv -> 0\r\n\
vv^ -> 1\r\n\
v^v -> -1\r\n\
v^^ -> 0\r\n\
^vvv^^vv^vv^v^ -> 1\r\n\
^vvv^^vv^vv^v^^ -> 0\r\n\
^vvv^^vv^vv^v^^^ -> 1\r\n\
^vvv^^vv^vv^v^^v -> -1\r\n\
^vvv^^vv^vv^v^^vv -> 0\r\n\
^vvv^^vv^vv^v^^vvv -> -1\r\n\
^vvvvvvvvvvvv -> 0\r\n\
^^vvvvvvvvvvvv -> 0\r\n\
^^^vvvvvvvvvvvv -> 0\r\n\
vvv^^^^^^^^^^^^ -> 0\r\n\
vv^^^^^^^^^^^^ -> 0\r\n\
v^^^^^^^^^^^^ -> 0"
.split("\n").map(s => s.split(" -> "))
.every(([s,key]) => (s=>~~{'^':1,v:-1}[s.replace(/(.)\1/g).slice(-1)])(s)==key)
Answer history:
s=>({'':0,'^':1,v:-1}[s.replace(/^(.)\1(\1\1)*(?=.?$)|.*(.)(((?!\3).)\5)+/,"").substr(-1)])
s=>~~{'^':1,v:-1}[s.replace(/^(.)\1(\1\1)*(?=.?$)|.*(.)(((?!\3).)\5)+/,"").substr(-1)]
s=>~~{'^':1,v:-1}[s.replace(/^.*(.)(((?!\1).)\3)+|(.)\4(\4\4)*/,"").substr(-1)]
s=>~~{'^':1,v:-1}[s.replace(/^.*(.)(((?!\1).)\3)+|(.)\4(\4\4)*/,"").slice(-1)]
s=>~~{'^':1,v:-1}[s.replace(/.*(.)(((?!\1).)\3)+|(.)\4(\4\4)*/,"").slice(-1)]
s=>~~{'^':1,v:-1}[s.replace(/.*(.)(((?!\1).)\3)+|((.)\5)*/,"").slice(-1)]
s=>~~{'^':1,v:-1}[s.replace(/((.)\2)+/g,"!").slice(-1)]
s=>~~{'^':1,v:-1}[s.replace(/(.)\1/g,"!").slice(-1)]
s=>~~{'^':1,v:-1}[s.replace(/(.)\1/g,0).slice(-1)]
s=>~~{'^':1,v:-1}[s.replace(/(.)\1/g).slice(-1)]