Thar ella sopla!

21

Arrr ... ¡Hola, mami! ¡Despliega la vela mayor! Lleno a estribor! ¡Ah, siente el viento en tu cabello!

Bien, sinceros ... ¡Necesito un poco de tus habilidades de codificación! Mi tripulación es un poco más modernizada que yo ... Todavía prefiero los puntos de la brújula (ver aquí para más información, Arrr ...) mientras mi tripulación siempre usa una cabeza ... ¡Quiero una forma fácil de convertir este tonto que llaman cabeza a lo que puedo entender, Arrr!

¡Lo que necesito es un código que esté ingresando un número (los decimales están bien) como ese 0 <= the headin' < 360y se escupe la respuesta como el punto de compás más cercano! Arrr!

Aquí hay algunos ejemplos:

> heading 0.1

North

> heading 11.25

North by East

> heading 22.7

North Northeast

> heading 44.99

Northeast

> heading 91

East

Ahora, si te estás dando la cabeza de tal manera que caiga exactamente en el medio de dos puntos cardinales, no te preocupes, mi corazón ... Espero que el código salga a la luz. Between <point 1> and <point 2>, por ejemplo heading 5.625, dirá Between North and North by East Esto solo sucederá para un encabezado que satisfaga la ecuación H = 5.625 + 11.25(N)donde H sea el encabezado y N sea un número entero entre 0 y 31 inclusive ...

Dos restricciones aunque ...

1) No quiero que use matrices para almacenar sus datos para los puntos o la cabeza ... Eso lo engañará, señor, y me probará travesuras ... Esto tiene ¡Se calculará, como en los viejos tiempos! Arrr!

2) El código más corto gana, o te haré caminar por la tabla ... ¡Arrr!

WallyWest
fuente
10
50 '(Apostrophe) en una sola pregunta. ¡Felicitaciones! : D
Wasi
¿Está usando un objeto en javascript con teclas numéricas haciendo trampa? Me refiero a yaarrr! ya sea trampa, ya landlubber?
Tim Seguine
1
¿No debería ser "N ser un número entero entre 0 y 31 inclusive"?
nwellnhof
@nwellnhof Tienes razón! Actualizado ... :)
WallyWest
1
¡Creo que debería lanzar un código de golf donde el objetivo es traducir su pregunta al inglés ortográficamente correcto!
sergiol

Respuestas:

6

Perl 5.10 usando sustitución, 231 228 226 224

@c=(north,east,south,west);
@q=qw(P PbR P-Q QbP Q QbR R-Q RbP);
sub p{$j=$_[0]>>3&3;$_=$q[7&pop];s/P/$c[$j]/;s/Q/$c[$j+1&2]$c[$j|1]/;s/R/$c[$j+1&3]/;s/b/ by /;ucfirst}
$a=<>/11.25+.5;
say$a==int$a&&'Between '.p($a-1).' and ',p$a

Cuatro nuevas líneas agregadas para facilitar la lectura.

Editar: Golfed 2 bytes más usando pop. Gracias @Dom Hastings

Editar: 2 bytes menos usandoqw()

nwellnhof
fuente
22

Estoy pasando demasiado tiempo en esta búsqueda del tesoro, pero aquí hay una solución en Java :

public class Aaaaarrrr {

    public static void main(String[] aaarrrgs) {

        float heading = Float.parseFloat(aaarrrgs[0]);

        final List<String> points = Arrays.asList("North",
                "North by east", "North-northeast", "Northeast by north",
                "Northeast", "Northeast by east", "East-northeast",
                "East by north", "East", "East by south", "East-southeast",
                "Southeast by east", "Southeast", "Southeast by south",
                "South-southeast", "South by east", "South", "South by west",
                "South-southwest", "Southwest by south", "Southwest",
                "Southwest by west", "West-southwest", "West by south", "West",
                "West by north", "West-northwest", "Northwest by west",
                "Northwest", "Northwest by north", "North-northwest",
                "North by west");


        float cp = heading / 360.0f * 32.0f;
        if (cp % 1 == 0.5f)
             System.out.print("Between " + points.get((int)Math.floor(cp)) + " and ");

         System.out.println(points.get(Math.round(cp)));

    }
}

editar Si minimizo el código anterior y lo hago realmente feo, se convertiría en esto:

Java, 770 caracteres

import java.util.*;class A{public static void main(String[] r){List<String> l=Arrays.asList("North","North by east","North-northeast","Northeast by north","Northeast","Northeast by east","East-northeast","East by north","East","East by south","East-southeast","Southeast by east","Southeast","Southeast by south","South-southeast","South by east","South","South by west","South-southwest","Southwest by south","Southwest","Southwest by west","West-southwest","West by south", "West","West by north","West-northwest","Northwest by west","Northwest","Northwest by north","North-northwest","North by west");float c=Float.parseFloat(r[0])/360.0f*32.0f;if (c%1==0.5f) System.out.print("Between "+l.get((int)Math.floor(c))+" and ");System.out.println(l.get(Math.round(c)));}}
Jeen Broekstra
fuente
24
+1 paraaaarrrgs
Danko Durbić
3
Estoy seguro de que eso no me ayudó en la regla de "el código más corto gana", pero como uso Java de todos modos ...
Jeen Broekstra
Admiro el enfoque, aunque estás usando el Arrays.asListcomando, perdóname por mi ignorancia de Java, pero ¿no es eso usar una matriz de almacenamiento? ¿O es esta una forma furtiva de introducir la matriz en forma de lista? ;)
WallyWest
@Jeen, ¿puedes mostrarme qué podrías obtener si realmente tocas la bocina y reduces el código allí?
WallyWest
2
@ Eliseod'Annunzio escribió la matriz, pensé que solo querías decir que no podía usarla para almacenar una asignación entre nombres e intervalos de encabezado. Esta matriz (lista) solo almacena los nombres reales. Pero si eso está más allá de las reglas, imagino que podría cambiarse para usar una switchdeclaración en su lugar (con algunos caracteres adicionales, desafortunadamente). Ah, y se agregó una versión condensada del mismo código. Pensaré en reducirlo aún más cambiando realmente cómo funciona.
Jeen Broekstra
6

Pitón, 264

n='north'
e='east'
s='south'
w='west'
b=' by '
def f(H):x,y,z=(n,e,s,w,e,s,w,n,n+e,s+e,s+w,n+w)[int(H%360/90)::4];return(x,x+b+y,x+'-'+z,z+b+x,z,z+b+y,y+'-'+z,y+b+x)[int(H%90*4/45)].capitalize()
h=input()+5.625
print h%11.25and f(h)or'Between '+f(h-1)+' and '+f(h)

Esto usa mayúsculas según la página de wikipedia y debería funcionar para cualquier número.

grc
fuente
1
Arrr, que sea un uso inteligente de una función allí ...
WallyWest
4

Arrr Python, 336

A,R,r=int,input()/360.*32,' by #South#north#West#East#south#North#west#east#-#/#Between#and'.split('#')
a=''.join(r[A(c,16)]for c in'6A608A6928A6802A68A6808A4928A402A4A405A4958A1808A18A1805A1958A108A1A107A1957A1705A17A1707A3957A305A3A302A3927A6707A67A6702A6927A607').split('/')
if R%1==.5:print r[11],a[A(R)],r[12],
print a[A(round(R))]

Gracias @Jeen

Pregunta de todos modos
fuente
Estoy un poco confundido aquí @AsksAnyway, ¿para qué sirve el leviatán de una cuerda? ... Arrr ...
WallyWest
"Calcula" los nombres de los puntos cardinales. Es una forma de reducir el tamaño del código.
Pregunta de cualquier forma el
2

Perl 5.10, 262 257 254

Algo similar a una de las soluciones de Python:

$n=north;$e=east;$s=south;$w=west;
@d=($n,$n.$e,$e,$s.$e,$s,$s.$w,$w,$n.$w,$n);
sub p{$j=pop;$i=$j>>2;ucfirst(($d[$i],"$d[$i] by $d[$i+2&~1]","$d[$i+1&~1]-$d[$i|1]","$d[$i+1] by $d[$i&~1]")[$j&3])}
$a=<>/11.25+.5;
say$a==int$a&&'Between '.p($a-1).' and ',p$a

Cuatro nuevas líneas agregadas para facilitar la lectura.

Editar: Tres bytes menos gracias a @Dom Hastings

nwellnhof
fuente
Hola @nwellnhof, ¡parece bastante completo! Puede guardar algunos caracteres más, eliminando ;al final de sub py cambiar shifta pop.
Dom Hastings
@nwellhoff ¿No sabía que Perl podía aceptar cadenas sin que estuvieran entre comillas? (re: línea 1)
WallyWest
1
@ Eliseod'Annunzio Perl acepta cadenas sin comillas en modo no estricto si no entran en conflicto con nombres de funciones o palabras reservadas.
nwellnhof