language-agnostic - psicologia - sindrome del miembro fantasma en perros
Código Golf: Pierna Fantasma (6)
La respuesta de Daniel en C # - 173 caracteres
Después de ver la solución de Daniel Vassallo, estaba demasiado avergonzada de la mía para publicarla. Pero aquí está la respuesta de Daniel portada a C # por el gusto de hacerlo. Una desventaja importante en C # era tener que hacer comprobaciones de límites, lo que costaba 20 caracteres.
int G(string s,int n){var l=s.Split(''/n'');n*=2;for(int i=0,j,c;i<l.Length;i++)
for(j=0;j<3;n+=n>2&&l[i][n-3]==c?-2:n<l[i].Length&&l[i][n-1]==c?2:0)c=j++==1?45
:61;return n/2;}
Formateado:
int G(string s, int n)
{
var l = s.Split(''/n'');
n *= 2;
for (int i = 0, j, c; i < l.Length; i++)
for (j = 0; j < 3; n += n > 2 && l[i][n - 3] == c ? -2 : n < l[i].Length && l[i][n - 1] == c ? 2 : 0)
c = j++ == 1 ? 45 : 61;
return n / 2;
}
El reto
El código más corto por conteo de caracteres que generará la solución numérica, dado un número y un patrón de cadena válido, utilizando el método Ghost Leg .
Ejemplos
Input: 3, "| | | | | | | | |-| |=| | | | | |-| | |-| |=| | | |-| |-| | |-|" Output: 2 Input: 2, "| | |=| | |-| |-| | | |-| | |" Output: 1
Aclaraciones
- No te molestes con la entrada. Considere los valores como dados en otro lugar.
- Ambos valores de entrada son válidos: el número de columna corresponde a una columna existente y el patrón solo contiene los símbolos
|
,-
,=
(y [espacio], [LF]). Además, dos columnas adyacentes no pueden contener guiones (en la misma línea). - Las dimensiones del patrón son desconocidas (mínimo 1x1).
Aclaraciones # 2
- Hay dos patrones inválidos:
|-|-|
y|=|=|
que crean ambigüedad La cadena de entrada dada nunca contendrá esos. - Las variables de entrada son las mismas para todos; un valor numérico y una cadena que representa el patrón.
- Los participantes deben producir una función.
Caso de prueba
Given pattern: "|-| |=|-|=|LF| |-| | |-|LF|=| |-| | |LF| | |-|=|-|" |-| |=|-|=| | |-| | |-| |=| |-| | | | | |-|=|-| Given value : Expected result 1 : 6 2 : 1 3 : 3 4 : 5 5 : 4 6 : 2
Editar: resultados esperados corregidos
Perl, 92 91 caracteres
sub g{for$s(pop=~/.+/g){map$_[0]-=1-abs(index substr(" $s",$_[0]*2-2,3),$_),qw[= - =]}pop}
Otro enfoque, 98 97 95 94 93 92 caracteres
sub g{map{for$s(qw[= - =]){pos=$_[0]*2-2;$_[0]+=//G((?<=$s)|.$s)/&&$&cmp$"}}pop=~/.+/g;pop}
Banco de pruebas
$s=<<''__PATTERN__'';
|-| |=|-|=|
| |-| | |-|
|=| |-| | |
| | |-|=|-|
__PATTERN__
for $n (1..6) {
print g($n,$s);
}
Ruby - 66 95 92 83 caracteres
(Alternar filas idea de la respuesta de Daniel)
def f s,m
m.each_line{|r|%w{= - =}.map{|i|s+=i==r[2*s-3]?-1:i==r[2*s-1]?1:0}}
s
end
92 caracteres
def f s,m
s=s*2-2
m.each_line{|r|%w{= - =}.each{|i|s+=i==r[s-1]?-2:i==r[s+1]?2:0}}
1+s/2
end
Uso
map="|-| |=|-|=|
| |-| | |-|
|=| |-| | |
| | |-|=|-|"
1.upto(6) do |i|
p f(i, map)
end
Salida
6
1
3
5
4
2
AWK - 68 77 79 caracteres
Prácticamente una traducción de la solución de Daniel (te amamos hombre;)
{for(i=0;i<3;){s=++i-2?"=":"-";if(s==$x)x--;else if(s!=$++x)x--}}END{print x}
Pero podemos eliminar if/else
y reemplazarlo por ?:
{for(i=0;i<3;){s=++i-2?"=":"-";s==$x?x--:s!=$++x?x--:x}}END{print x}
Ejecútelo con la posición de inicio definida como la variable x:
$ for x in `seq 6`; do echo $x/ ;awk -F/| -vx=$x -f ghost.awk<<__EOF__
|-| |=|-|=|
| |-| | |-|
|=| |-| | |
| | |-|=|-|
__EOF__
done
1 6
2 1
3 3
4 5
5 4
6 2
JavaScript: 169 158 148 141 127 125 123 122 Personajes
Minificado y Golfed:
function g(n,s){for(l=s.split(''/n''),n*=2;k=l.shift();)for(j=3;j;)n+=k[n-3]==(c=--j-1?''='':''-'')?-2:k[n-1]==c?2:0;return n/2}
Versión legible:
function g(n, str) {
var c, i, j;
var lines = str.split(''/n'');
n = (n * 2) - 2;
for (i = 0; i < lines.length; i++) {
for (j = 0; j < 3; j++) {
c = (j == 1) ? ''-'' : ''='';
if (lines[i].charAt(n-1) == c) n-=2; // Move left
else if (lines[i].charAt(n+1) == c) n+=2; // Move right
}
}
return 1+n/2;
}
Explicación:
-
str
se divide en una matriz de líneas. -
n
se escala para cubrir el número de caracteres en cada línea, comenzando desde 0. - Iterar tres veces sobre cada línea: una vez para cada capa. Imagine que cada línea está dividida en 3 capas: las capas superior e inferior son donde se unen las patas del signo de
=
. La capa intermedia es para las piernas de los signos. - Mueva
n
hacia la izquierda o hacia la derecha según los signos adyacentes. Solo hay un movimiento posible para cada capa de cada línea. Por lo tanto,n
podría moverse hasta 3 veces en una línea. - Devuelve
n
, normalizado para comenzar de 1 a la cantidad de líneas verticales.
Casos de prueba:
var ghostLegs = [];
ghostLegs[0] = "|-| |=|-|=|/n" +
"| |-| | |-|/n" +
"|=| |-| | |/n" +
"| | |-|=|-|";
ghostLegs[1] = "| | | | | | | |/n" +
"|-| |=| | | | |/n" +
"|-| | |-| |=| |/n" +
"| |-| |-| | |-|";
ghostLegs[2] = "| | |=| |/n" +
"|-| |-| |/n" +
"| |-| | |";
ghostLegs[3] = "|=|-|";
for (var m = 0; m < ghostLegs.length; m++) {
console.log(''/nTest: '' + (m + 1) + ''/n'');
for (var n = 1; n <= (ghostLegs[m].split(''/n'')[0].length / 2) + 1; n++) {
console.log(n + '':'' + g(n, ghostLegs[m]));
}
}
Resultados:
Test: 1
1:6
2:1
3:3
4:5
5:4
6:2
Test: 2
1:1
2:3
3:2
4:4
5:5
6:6
7:8
8:7
Test: 3
1:3
2:1
3:4
4:2
5:5
Test: 4
1:3
2:2
3:1
VB.Net: 290 caracteres (320 bytes)
Requiere opción estricta desactivada, opción explícita desactivada
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
Forma legible:
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
Casos de prueba
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
Editar:
(para aquellos que sigan leyendo esto)
Intenté un enfoque diferente. Mi idea era mapear los diferentes patrones esperados y actuar en consecuencia. Primero tenemos que decidir si daremos vuelta a la izquierda o a la derecha y luego determinaremos la cantidad de columnas que moverá nuestro pequeño mono Amidar (invirtiendo la cuerda si es necesario).
Presentando la solución completa primero:
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
Al eliminar el diccionario costoso, así como el innecesario |
''s y después de un poco más de'' minificación ''terminamos con:
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
No es una gran ganancia, en comparación con mi esfuerzo anterior (282 caracteres, 308 bytes), pero tal vez este enfoque sea útil para otros que usan un lenguaje de programación diferente.