Dada una cadena de N, S, E y W, genera un rumbo (ángulo en sentido horario desde el Norte en grados), correcto a 5 decimales.
En la notación de brújula tradicional , una cadena se compone de solo 2 de estos caracteres (como NNW o ESE). Aquí también debe aceptar cadenas que contengan las 4 (como WNNNSE) . El uso de solo 2 símbolos permite a los humanos comprender intuitivamente el significado. Permitir 4 símbolos hace que sea horrible de leer, pero permite formas más cortas de describir un rumbo con una precisión dada.
(Como se señaló en los comentarios de user2357112 , resulta que puede probar que para cualquier demora dada, la cadena de 4 símbolos tendrá exactamente la misma longitud que la cadena de 2 símbolos, por lo que he basado este desafío en una suposición falsa. Con suerte, esta falta de un propósito práctico no le resta valor al disfrute del desafío ...)
El método exacto se describe a continuación y es equivalente a la notación tradicional (se expande en lugar de cambiarla).
Entrada
- La entrada es una sola cadena que contiene solo los caracteres
NESW
. - La entrada puede ser una secuencia de caracteres si lo prefiere, siempre que no incluya ningún preprocesamiento. Por ejemplo,
[N, [E, [S, [W]]]]
no está permitido tomar una lista anidada para ayudar con el orden de procesamiento. - Tomar diferentes personajes no está permitido. No puede tomar una cadena de en
1234
lugar deNESW
.
Salida
- La salida debe ser un número decimal o una representación de cadena de uno (no un racional / fracción).
- No es necesario mostrar los ceros finales. Si el rumbo es
9.00000
, entonces la salida9
también cuenta como correcta a 5 decimales. - La salida está en el rango [0, 360). Es decir, incluye 0 pero excluye 360.
- La corrección se verifica redondeando la salida a 5 decimales. Si el rodamiento es 0.000005, esto se redondea a 0.00001. Las salidas 0.00001 y 0.000005 son correctas.
- La producción en notación científica para algunas entradas es aceptable. Por ejemplo, en
1e-5
lugar de0.00001
.
Conversión
- Puntos El solo carácter brújula
N
,E
,S
, yW
corresponden a 0, 90, 180, y 270 grados, respectivamente. - Anteponer uno de estos a una cadena da como resultado el rumbo que divide el rumbo del carácter único y el rumbo de la cadena original.
- Se elige el más cercano de los dos posibles cojinetes de bisección, de modo que NE represente 45 grados, no 225 grados.
- Esto no es ambiguo, excepto donde el ángulo que se bisecará es de 180 grados. Por lo tanto
NS
,SN
,WE
, yEW
corresponden a los rodamientos no definida, y la entrada nunca terminarán en cualquiera de estos. Sin embargo, pueden aparecer en cualquier otro lugar de la cadena de entrada, ya que esto no causa ambigüedad. - Si los dos caracteres finales son idénticos, el carácter final será redundante ya que la bisección devolverá el mismo rumbo. Como esto no agrega nada a la notación, su código no necesita manejar esto. Por lo tanto
NN
,EE
,SS
, yWW
corresponden a los rodamientos no definida, y la entrada nunca terminarán en cualquiera de estos. Sin embargo, pueden aparecer en cualquier otro lugar de la cadena de entrada.
Ejemplos
N: 0
E: 90
S: 180
SE: halfway between S and E: 135
NSE: halfway between N and SE: 67.5
NNSE: halfway between N and NSE: 33.75
NNNSE: halfway between N and NNSE: 16.875
NNNNSE: halfway between N and NNNSE: 8.4375
Casos de prueba
Un envío solo es válido si proporciona la salida correcta para todos los casos de prueba. Tenga en cuenta que los casos de prueba llegan al límite de lo que se puede manejar con doble precisión. Para los idiomas que tienen por defecto la precisión simple, probablemente necesitará gastar los bytes para especificar la precisión doble para obtener resultados correctos.
Las salidas de casos de prueba se muestran redondeadas a 5 decimales, y también a precisión arbitraria. Ambas son salidas válidas.
WNE 337.5 337.5
WEN 337.5 337.5
WEWEWEWEWEWEWEWEWEWEWEN 330.00001 330.000007152557373046875
NESWNESWNESWNESWNESWNESWNESW 90 89.99999932944774627685546875
NNNNNNNNNNNNNNNNNNNNNNNE 0.00001 0.0000107288360595703125
NNNNNNNNNNNNNNNNNNNNNNNW 359.99999 359.9999892711639404296875
SNNNNNNNNNNNNNNNNNNNNNNNE 90.00001 90.00000536441802978515625
SNNNNNNNNNNNNNNNNNNNNNNNW 269.99999 269.99999463558197021484375
Tanteo
Este es el código de golf . La puntuación es la longitud del código fuente en bytes, y gana el más corto.
Pedantería
Cometí el error de pensar que "Norte por Noroeste" era una dirección válida de la brújula. Un error feliz, ya que condujo a una idea desafiante, pero luego descubrí en la página de Wikipedia :
"El título de la película de Alfred Hitchcock 1959, North by Northwest, en realidad no es un punto de dirección en la brújula de 32 vientos, pero el la película contiene una referencia a Northwest Airlines ".
También resulta que el método utilizado para este desafío solo es consistente con los puntos de brújula tradicionales hasta e incluyendo la brújula de 16 puntos. La brújula de 32 vientos descrita en esa página es sutilmente diferente y convenientemente he pasado por alto su existencia para este desafío.
Finalmente, para cualquiera que piense que debería usar "Sureste" en lugar de "Sureste",.
WNNNSE
<= ¿cuál sería la salida para esta entrada de ejemplo al comienzo de su publicación? me parece inválido, pero es difícil saberlo.WNNNSE
la salida sería323.4375
. Consulte la sección de ejemplos para ver un tutorial que se aplicaría de la misma manera a este caso.f(N,N,N,S,E)
está bien?Respuestas:
JavaScript (ES6),
8480787472 bytesAhorré un byte gracias a @Titus, 1 gracias a @Neil
Me llevó un tiempo, pero creo que finalmente he perfeccionado la fórmula ...
Fragmento de prueba
Mostrar fragmento de código
Explicación
Comencemos con el caso más simple: una cadena de un solo carácter. El resultado es simplemente su posición (indexada en 0) en la cadena
NESW
, multiplicada por 90.Para una cadena de dos caracteres, el resultado se encuentra a medio camino entre el resultado del primer carácter y el resultado del segundo. Sin embargo, hay un problema: si la diferencia absoluta entre los dos es mayor que 180 (por ejemplo,
NW
oWN
), debemos 180 al ángulo para que no apunte en la dirección opuesta.Para cualquier cadena más larga, el resultado se encuentra a medio camino entre el resultado del primer carácter y el resultado del resto de la cadena. Esto se puede generalizar de la siguiente manera:
NESW
multiplicada por 90.NESW
multiplicado por 45, más la mitad del resultado del resto de la cadena; agregue 180 adicionales si la diferencia absoluta entre los dos es mayor que 90.fuente
search
en lugar deindexOf
ahorrarte un byte.C # 6,
226217207185 bytesEditar: -10 bytes por la idea de "préstamo" de la presentación de ETHproductions
-22 bytes gracias a @Titus
Sin golf
fuente
b=(b+360)%360;
lugar deb+=b>360?-360:b<0?360:0;
. Ahorre otros 12 bytes dividiendo todo por 90 yreturn b*90;
.b=(b+f(c)+(b-f(c)>2?4:f(c)-b>2?-4:0)+8)/2%4;
luego distribúyalo+8
a los resultados ternariosb=(b+f(c)+(b-f(c)>2?12:f(c)-b>2?4:8))/2%4;
PHP,
958886100127104101 bytesN
(y más, porque eso permite poner la traducción al encabezado del bucle:N
es cierto, pero se evalúa0
en el cálculo).strtr
con uno de mis malabarismos de bitsEsta es oficialmente la primera vez que uso el operador de fusión nula. Corre con
-r
.PHP 7.1
Las compensaciones de cadena negativas en la próxima versión de PHP ahorrarán 12 bytes:
Reemplace
strlen($s=$argv[1])
con0
y$s
con$argv[1]
.Bytes gratuitos para (casi) todos:
(a/2%6+2)%5
a<87?a/2&3^3:3
oa/2&3^3*(a<87)
a&1?a&2|a/4&1:0
a/.8-1&3
fuente
Python 3,
133113 bytesSolo estoy mejorando la respuesta de @ L3viathan porque acabo de crear esta cuenta y, por lo tanto, aún no puedo hacer comentarios.
fuente
05AB1E ,
48423732 bytesGuardado 6 bytes gracias a Emigna. Ahorró 5 bytes gracias a la idea de Titus de trabajar en el rango [0,4 [y multiplicar por 90 al final. Ahorró 5 bytes gracias al dominio de Adnan de la antigua metamorfosis xor / módulo.
Por lo tanto, cada ángulo se reduce del rango [0,360 [al rango [0,4 [durante toda la ejecución. El resultado se multiplica por 90 y se muestra.
Pruébalo en línea!
Posibles ejes del golf:
fuente
NNNNNNNNNNNNNNNNNNNNNNNE
ySNNNNNNNNNNNNNNNNNNNNNNNE
las pruebas de los casos.v"NESW"yk90*})R¬U¦vXy+;DX-Ä89›180*+360%U}X
.89›
realidad significa que la parte entera es mayor que 89, lo que equivale a decir que el número completo es mayor o igual a 90 (que todavía funciona bien porque exactamente 90 nunca debería ocurrir). Actualmente el comentario en el código explicó hace que suene como que está comprobando durante más de 89, mientras que el código pasa a los casos de prueba también verificar claramente correctamente para mayor que 90.›
debe comportarse el operador con los valores negativos de coma flotante. No hay ningún problema aquí ya que funciona en el valor absoluto, pero prefiero no hacer suposiciones demasiado fuertes sobre el operador.v"NESW"yk})
conÇ30^5%
:)Python 3,
14614511710797949392 bytesLlama
f
con la cuerda.fuente
...0else
que arrojan SyntaxErrors.else
y-
también? (puede en 3.3.3)d.find
puede, tuve la idea exacta hace un minuto; ver respuesta actualizadaC, 184 bytes
Sin golf
fuente
d
)?R,
172146bytesSin golf
Explicado
c("N","E","S","W")
0:3*90
(en lugar dec(0,90,180,270)
)z
p
al grado equivalente al último carácter en la entradal
p
enz
Pruebe los casos de prueba en R-fiddle (tenga en cuenta que esta es una función debido a que
scan
no funciona en R-fiddle)fuente
Outputs 0.00001 and 0.000005 are both correct.
Entonces debería poder guardar algunos bytes sin redondearc("N","N","E")
en lugar de"NNE"
? Esto equivale a una lista de Python no anidada["N","N","E"]
.Haskell,
109105103bytesGracias por -2 byte @xnor!
fuente
f
parece larga, pero tengo problemas para encontrar algo más corto. Lo más cerca que estuve fuef c=90*until(\i->"NESW"!!i==c)(+1)0
(35). Creo que puedes reemplazarlo'W'
con_
._
!Dyalog APL ,
554538 bytesSolución
Requiere
⎕IO←0
, que es el predeterminado en muchos sistemas. Pide dirección.Explicación
Evita el problema convirtiendo cada letra en un número complejo 1∠ θ ⇔ a + b · i , luego haciendo una reducción de suma de derecha a izquierda (fuerte de APL) mientras se normaliza en cada paso. El θ final se convierte a grados y se normaliza para estar dentro de [0, 360)
'NES'⍳⍞
los índices de cada letra de entrada en "NES"; N → 0, E → 1, S → 2, cualquier otra cosa → 3○2÷⍨
convertir a ángulos en radianes; θ = π · x ∕ 2¯12○
convertir a números complejos en el círculo unitario; e i · θ(
...)/
reduzca la lista con ... (es decir, inserte la función entre los elementos de ...)+÷(|+)
... la suma normalizada; x n - 1 + x n ∕ | x n - 1 + x n |12○
convertir a ángulo; θ÷○÷180×
convertir a grados; 1 ∕ π · 1 ∕ 180 · x360|
resto de división cuando se divide por 360TryAPL en línea!
Anécdota
Si la entrada y la salida fueran unidades complejas ortogonales, la solución completa sería simplemente:
El resto del código está analizando la entrada y el formato de salida.
fuente
⎕FR←1287
utiliza flotantes de 128 bits, pero TryAPL no lo permite.Common Lisp,
347327 bytesGracias a @Titus por despegar algunas
Esto probablemente se pueda jugar más, pero al menos funciona (creo):
Uso:
La función
d
toma un carácterN
,E
,W
, oS
y vuelve el grado apropiado. La funciónm
obtiene el grado combinado apropiado de dos direcciones dadas. La funciónf
itera a través de la cadena provista, calcula el grado apropiado e imprime como un punto flotante.fuente
Befunge
183181175 bytesPruébalo en línea!
Explicación
Esto sigue un algoritmo similar a muchas de las otras respuestas, solo que está usando cálculos de punto fijo emulados con enteros ya que Befunge no admite punto flotante.
Gracias a @Titus por la rutina ASCII a int.
fuente
APL (Dyalog Classic) ,
3027 bytesPruébalo en línea!
fuente