VB.Net: 290 chars (320 bytes)
Requires Option Strict Off, Option Explicit Off
Function G(i,P)
i=i*2-1
F=0
M="-"
Q="="
Z=P.Split(Chr(10))
While E<Z.Length
L=(" "& Z(E))(i-1)
R=(Z(E)&" ")(i)
J=L & R=" "&" "
E-=(F=2Or J)
i+=If(F=1,2*((L=M)-(R=M)),If(F=2,2*((L=Q)-(R=Q)),If(J,0,2+4*(L=Q Or(L=M And R<>Q)))))
F=If(F=1,2,If(F=2,0,If(J,F,2+(L=Q Or R=Q))))
End While
G=(i-1)\2+1
End Function
Readable form:
Function G(ByVal i As Integer, ByVal P As String) As Integer
i = i * 2 - 1
Dim F As Integer = 0
Const M As String = "-"
Const Q As String = "="
Dim Z As String() = P.Split(Chr(10))
Dim E As Integer = 0
While E < Z.Length
Dim L As Char = (" " & Z(E))(i - 1)
Dim R As Char = (Z(E) & " ")(i)
Dim J As Boolean = L & R = " " & " "
E -= (F = 2 Or J)
i += If(F = 1, 2 * ((L = M) - (R = M)), _
If(F = 2, 2 * ((L = Q) - (R = Q)), _
If(J, 0, 2 + 4 * (L = Q Or (L = M And R <> Q)))))
F = If(F = 1, 2, If(F = 2, 0, If(J, F, 2 + (L = Q Or R = Q))))
End While
G = (i - 1) \ 2 + 1
End Function
Test cases
Sub Main()
Dim sb As New StringBuilder
Dim LF As Char = ControlChars.Lf
sb.Append("|-| |=|-|=|")
sb.Append(LF)
sb.Append("| |-| | |-|")
sb.Append(LF)
sb.Append("|=| |-| | |")
sb.Append(LF)
sb.Append("| | |-|=|-|")
Dim pattern As String = sb.ToString
For w As Integer = 1 To pattern.Split(LF)(0).Length \ 2 + 1
Console.WriteLine(w.ToString & " : " & G(w, pattern).ToString)
Next
Console.ReadKey()
End Sub
Edit:
(for those still reading this)
I tried a different approach. My idea was to map the different patterns expected and act accordingly. We first need to decide if we'll turn left or right and then determine the number of columns our little Amidar monkey will move (reversing the string if needed).
Presenting the full solution first:
Function GhostLeg(ByVal i As Integer, ByVal p As String) As Integer
i = i * 2 - 2
Dim LeftOrRight As New Dictionary(Of String, Integer)
LeftOrRight(" | ") = 0
LeftOrRight("-| ") = -1
LeftOrRight("=| ") = -1
LeftOrRight("=|-") = -1
LeftOrRight(" |-") = 1
LeftOrRight(" |=") = 1
LeftOrRight("-|=") = 1
Dim ColumnAdd As New Dictionary(Of String, Integer)
ColumnAdd("| | | ") = 0
ColumnAdd("| | |-") = 0
ColumnAdd("| |-| ") = 0
ColumnAdd("| | |=") = 0
ColumnAdd("| |=| ") = 0
ColumnAdd("| |-|=") = 0
ColumnAdd("| |=|-") = 0
ColumnAdd("|=| | ") = 0
ColumnAdd("|=| |-") = 0
ColumnAdd("|=| |=") = 0
ColumnAdd("|-| |-") = 1
ColumnAdd("|-| | ") = 1
ColumnAdd("|-| |=") = 1
ColumnAdd("|-|=|-") = 2
ColumnAdd("|-|=| ") = 2
ColumnAdd("|=|-| ") = 2
ColumnAdd("|=|-|=") = 3
Const TRIPLESPACE As String = " | | "
Dim direction As Integer
For Each line As String In p.Split(Chr(10))
line = TRIPLESPACE & line & TRIPLESPACE
direction = LeftOrRight(line.Substring(i + 4, 3))
If direction = 1 Then
line = line.Substring(i + 5, 6)
i += 2 * direction * ColumnAdd(line)
ElseIf direction = -1 Then
line = StrReverse(line.Substring(i, 6))
i += 2 * direction * ColumnAdd(line)
End If
Next
Return 1 + i \ 2
End Function
By removing the character-wise expensive Dictionary, as well as the unecessary |
's and after some more 'minification' we end up with:
Function G(i,p)
D="- 0= 0=-0 -2 =2-=2"
A="- -1- 1- =1-=-2-= 2=- 2=-=3"
For Each l In p.Replace("|","").Split(Chr(10))
l=" "& l &" "
w=InStr(D,Mid(l,i+2,2))
If w Then
w=Val(D(w+1))-1
s=InStr(A,If(w=1,Mid(l,i+3,3),StrReverse(Mid(l,i,3))))
i+=If(s,w*Val(A(s+2)),0)
End If
Next
G=i
End Function
Not much of a gain, compared to my previous effort (282 chars, 308 bytes), but maybe this approach will prove useful to others using a different programming language.
|=|-|
doesn't exist as well? – Iridescent|-|-|
and|=|=|
. Everything else is valid and has no ambiguity. The point is that we need to know every time how to turn (left or right). In the case of|=|-|
, the first column leads us to the third, the second leads to the same column and the third column leads to the first. – Mythomania=
represents two lines. – Mythomania4->5
and5->4
? – Exactly