Dada uma sequência de N, S, E e W, produza um rolamento (ângulo no sentido horário em relação ao norte em graus), corrija até 5 casas decimais.
Na notação tradicional da bússola , uma sequência é composta por apenas 2 desses caracteres (como NNW ou ESE). Aqui você também deve aceitar cadeias que contêm todas as 4 (como WNNNSE) . O uso de apenas 2 símbolos permite que os humanos compreendam intuitivamente o significado. Permitir 4 símbolos torna a leitura horrível, mas permite maneiras mais curtas de descrever um rolamento com uma determinada precisão.
(Como apontado nos comentários do usuário2357112 , verifica-se que você pode provar que, para qualquer rolamento, a sequência de 4 símbolos terá exatamente o mesmo comprimento que a sequência de 2 símbolos, portanto, baseei esse desafio em uma suposição falsa. Espero que essa falta de um objetivo prático não prejudique o seu prazer no desafio ...)
O método exato é descrito abaixo e é equivalente à notação tradicional (ela se expande em vez de alterá-la).
Entrada
- A entrada é uma única sequência que contém apenas os caracteres
NESW
. - A entrada pode ser uma sequência de caracteres, se você preferir, desde que isso não inclua nenhum pré-processamento. Por exemplo,
[N, [E, [S, [W]]]]
não é permitida uma lista aninhada para ajudar na ordem de processamento. - Não são permitidos caracteres diferentes. Você não pode usar uma sequência de caracteres em
1234
vez deNESW
.
Saída
- A saída deve ser um número decimal ou representação de sequência de um (não uma fração / racional).
- Zeros à direita não precisam ser exibidos. Se o rolamento for
9.00000
, a saída9
também conta como correta com 5 casas decimais. - A saída está no intervalo [0, 360). Ou seja, incluindo 0, mas excluindo 360.
- A correção é verificada arredondando a saída para 5 casas decimais. Se o rolamento for 0,000005, este arredondará para 0,00001. As saídas 0,00001 e 0,000005 estão corretas.
- A saída em notação científica para algumas entradas é aceitável. Por exemplo, em
1e-5
vez de0.00001
.
Conversão
- A pontos de caracteres único bússola
N
,E
,S
, eW
correspondem a 0, 90, 180, e 270 graus respectivamente. - Anexar um desses a uma sequência resulta no rolamento que corta o rolamento do caractere único e o rolamento da sequência original.
- O mais próximo dos dois possíveis rolamentos de bissecção é escolhido, de modo que NE representa 45 graus, não 225 graus.
- Isso é inequívoco, exceto onde o ângulo a ser dividido é 180 graus. Portanto
NS
,SN
,WE
, eEW
correspondem aos rolamentos indefinida, e a entrada nunca irá terminar em qualquer um destes. No entanto, eles podem aparecer em qualquer outro lugar na sequência de entrada, pois isso não causa ambiguidade. - Se os dois caracteres finais forem idênticos, o caractere final será redundante, pois a bissecção retornará o mesmo rumo. Como isso não adiciona nada à notação, seu código não precisa lidar com isso. Portanto
NN
,EE
,SS
, eWW
correspondem aos rolamentos indefinida, e a entrada nunca irá terminar em qualquer um destes. No entanto, eles podem aparecer em qualquer outro lugar na sequência de entrada.
Exemplos
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 teste
Um envio é válido apenas se fornecer saída correta para todos os casos de teste. Observe que os casos de teste ultrapassam os limites do que pode ser tratado com precisão dupla. Para idiomas que usam a precisão única como padrão, você provavelmente precisará gastar os bytes para especificar a precisão dupla, a fim de obter resultados corretos.
As saídas do caso de teste são mostradas arredondadas para 5 casas decimais e também com precisão arbitrária. Ambos são saídas 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
Pontuação
Isso é código-golfe . A pontuação é o comprimento do código-fonte em bytes e as vitórias mais curtas.
Pedantry
Cometi o erro de pensar que "North by North West" era uma direção válida da bússola. Um erro feliz, pois levou a uma idéia desafiadora, mas descobri na página da Wikipedia :
"O título do filme de Alfred Hitchcock 1959, North by Northwest, na verdade não é um ponto de direção na bússola de 32 ventos, mas o filme contém uma referência à Northwest Airlines ".
Acontece também que o método usado para esse desafio é consistente apenas com os pontos tradicionais da bússola, incluindo a bússola de 16 pontos. A bússola de 32 ventos descrita nessa página é sutilmente diferente e eu negligenciei convenientemente sua existência para esse desafio.
Finalmente, para quem pensa que eu deveria usar "Sudeste" em vez de "Sudeste",.
WNNNSE
<= qual seria a saída desse exemplo de entrada no início da sua postagem? parece inválido para mim, mas é difícil dizer.WNNNSE
a saída seria323.4375
. Consulte a seção de exemplo para obter uma explicação passo a passo que se aplicaria da mesma maneira a este caso.f(N,N,N,S,E)
boa?Respostas:
JavaScript (ES6),
8480787472 bytesGuardou um byte graças a @Titus, 1 graças a @Neil
Demorou um pouco, mas acho que finalmente aperfeiçoei a fórmula ...
Snippet de teste
Mostrar snippet de código
Explicação
Vamos começar com o caso mais simples: uma string de caractere único. O resultado é simplesmente sua posição (indexada 0) na cadeia de caracteres
NESW
, multiplicada por 90.Para uma sequência de dois caracteres, o resultado fica na metade do caminho entre o resultado do primeiro caractere e o resultado do segundo. No entanto, há um problema: se a diferença absoluta entre os dois for maior que 180 (por exemplo,
NW
ouWN
), devemos 180 no ângulo para que não aponte na direção oposta.Para qualquer sequência mais longa, o resultado fica na metade do caminho entre o resultado do primeiro caractere e o resultado do restante da sequência. Isso pode ser generalizado da seguinte maneira:
NESW
vezes 90.NESW
vezes 45, mais a metade do resultado do restante da cadeia; adicione 180 extras se a diferença absoluta entre os dois for maior que 90.fonte
search
em vez deindexOf
economizar um byte.C # 6,
226217207185 bytesEdit: -10 bytes por "emprestar" a ideia da submissão da ETHproductions
-22 bytes graças a @Titus
Ungolfed
fonte
b=(b+360)%360;
vez deb+=b>360?-360:b<0?360:0;
. Salve outros 12 bytes dividindo tudo por 90 ereturn b*90;
.b=(b+f(c)+(b-f(c)>2?4:f(c)-b>2?-4:0)+8)/2%4;
depois distribuir+8
aos resultados ternáriosb=(b+f(c)+(b-f(c)>2?12:f(c)-b>2?4:8))/2%4;
PHP,
958886100127104101 bytesN
(e mais, porque isso permite colocar a conversão na cabeça do loop:N
é verdade, mas é avaliada0
no cálculo.)strtr
por um dos meus malabarismos de bitsEsta é oficialmente a primeira vez que eu uso o operador coalescente nulo. Corra com
-r
.PHP 7.1
Os deslocamentos negativos de string na próxima versão do PHP economizarão 12 bytes:
Substitua
strlen($s=$argv[1])
por0
e$s
com$argv[1]
.Bytes livres para (quase) todos:
(a/2%6+2)%5
a<87?a/2&3^3:3
oua/2&3^3*(a<87)
a&1?a&2|a/4&1:0
a/.8-1&3
fonte
Python 3,
133113 bytesEstou melhorando a resposta do @ L3viathan porque acabei de fazer essa conta e, portanto, ainda não posso fazer comentários.
fonte
05AB1E ,
48.42.37.32 bytesEconomizou 6 bytes graças a Emigna. Economizou 5 bytes graças à idéia de Titus de trabalhar no intervalo [0,4 [e multiplicar por 90 no final. Economizou 5 bytes graças ao domínio de Adnan da antiga metamorfose xor / modulo.
Portanto, todos os ângulos são reduzidos do intervalo [0,360 [para o intervalo [0,4]] durante toda a execução. O resultado é então multiplicado por 90 e exibido.
Experimente online!
Eixos potenciais do golfe:
fonte
NNNNNNNNNNNNNNNNNNNNNNNE
eSNNNNNNNNNNNNNNNNNNNNNNNE
teste.v"NESW"yk90*})R¬U¦vXy+;DX-Ä89›180*+360%U}X
.89›
realmente significa que a parte inteira é maior que 89, o que equivale a dizer que o número completo é maior que ou igual a 90 (o que ainda funciona bem porque exatamente 90 nunca deve ocorrer). Atualmente o comentário no explicou código faz parecer que ele está verificando maior do que 89, enquanto que o seu código passa os casos de teste assim é claramente corretamente verificando maior do que 90.›
deve se comportar em relação a valores negativos de ponto flutuante. Não há nenhum problema aqui, pois funciona com o valor absoluto, mas prefiro não fazer suposições muito fortes sobre o operador.v"NESW"yk})
porÇ30^5%
:)Python 3,
14614511710797949392 bytesLigue
f
com a corda.fonte
...0else
que lançam SyntaxErrors.else
e-
também? (cân em 3.3.3)d.find
pode, eu tive a idéia exata um minuto atrás; veja resposta atualizada.C, 184 bytes
Ungolfed
fonte
d
)?R,
172146 bytesUngolfed
Explicado
c("N","E","S","W")
0:3*90
(em vez dec(0,90,180,270)
)z
p
com o grau equivalente ao último caractere na entradal
p
comoz
Experimente os casos de teste no R-fiddle (observe que esta é uma função devido ao
scan
não trabalho no R-fiddle)fonte
Outputs 0.00001 and 0.000005 are both correct.
Então você deve ser capaz de salvar alguns bytes por não arredondamentoc("N","N","E")
em vez de"NNE"
? Isso equivale a uma lista python não aninhada["N","N","E"]
.Haskell,
109 105103 bytesObrigado por -2 byte @xnor!
fonte
f
parece longa, mas estou tendo problemas para encontrar algo mais curto. O mais perto que fiquei foif c=90*until(\i->"NESW"!!i==c)(+1)0
(35). Eu acho que você pode substituir'W'
por_
._
!Dyalog APL ,
554538 bytesSolução
Requer
⎕IO←0
, que é padrão em muitos sistemas. Pede orientação.Explicação
Contorna o problema convertendo cada letra em um número complexo 1∠ θ ⇔ a + b · i e , em seguida, reduzindo a soma da direita para a esquerda (forte da APL) enquanto normaliza a cada etapa. O θ final é então convertido em graus e normalizado para ficar entre [0, 360):
'NES'⍳⍞
Os índices de cada letra de entrada em "NES"; N → 0, E → 1, S → 2, qualquer outra coisa → 3○2÷⍨
converter em ângulos em radianos; θ = π · x ∕ 2¯12○
converter em números complexos no círculo unitário; e i · θ(
...)/
reduza a lista com ... (ou seja, insira a função entre os elementos de ...)+÷(|+)
... a soma normalizada; x n - 1 + x n ∕ | x n - 1 + x n |12○
converter em ângulo; θ÷○÷180×
converter em graus; 1 / pi · 1 / 180 · x360|
restante da divisão quando dividido por 360TryAPL online!
Anedota
Se a entrada e a saída fossem unidades complexas ortogonais, toda a solução seria apenas:
O restante do código está analisando a entrada e a formatação da saída.
fonte
⎕FR←1287
utiliza flutuadores de 128 bits, mas o TryAPL não permite.Lisp comum,
347327 bytesAgradecemos a @Titus por tirar alguns
Provavelmente isso pode ser jogado mais, mas pelo menos funciona (eu acho):
Uso:
Função
d
leva um personagemN
,E
,W
, ouS
e retorna o grau adequado. Funçãom
obtém o grau combinado apropriado de duas direções dadas. A funçãof
percorre a sequência fornecida, calcula o grau apropriado e a imprime como um ponto flutuante.fonte
Befunge,
183181175 bytesExperimente online!
Explicação
Isso segue um algoritmo semelhante a muitas das outras respostas, apenas usando cálculos de ponto fixo emulados com números inteiros, já que o Befunge não suporta ponto flutuante.
Obrigado a @Titus pela rotina ASCII-para-int.
fonte
APL (Dyalog Classic) ,
3027 bytesExperimente online!
fonte