Excavar a Australia - antípodas

24

Fondo

Innumerables generaciones de niños se han preguntado dónde terminarían si cavaran un agujero directamente hacia abajo. Resulta que esto, como era de esperar, sería bastante peligroso , pero de todos modos ...

Las antípodas son puntos que están directamente opuestos entre sí en la superficie de la Tierra. Esto significa que si se dibujara una línea entre los dos puntos, pasaría por el centro de la Tierra.

Reto

Escriba un programa o función que, dado un punto, encuentre su antípoda.

En este desafío, los puntos se representan utilizando el sistema de longitud-latitud y grados, minutos de arco y segundos de arco. Para encontrar la antípoda, intercambie las direcciones de cada ordenada ( N <-> Sy W <-> E) y reste la ordenada de longitud de los 180grados.

Ejemplo:
toma el punto N 50 26 23 W 4 18 29. Cambia las instrucciones para dar S 50 26 23 E 4 18 29. Resta la ordenada de longitud de 180 0 0para dar 175 41 31, dejando las coordenadas de antípoda como S 50 26 23 E 175 41 31.

Reglas

Entrada

Un conjunto de coordenadas de latitud y longitud, en cualquier formato razonable , donde cada ordenada contiene una dirección, una cantidad de grados, una cantidad de minutos de arco y una cantidad de segundos de arco.

Salida

Las coordenadas de latitud-longitud de la antípoda, en cualquier formato razonable , donde cada ordenada contiene una dirección, una cantidad de grados, una cantidad de minutos de arco y una cantidad de segundos de arco.

Considere razonable que cada parte de la coordenada se puede distinguir sin ambigüedades.

Especificaciones

  • La dirección para la ordenada de latitud es No S, y la de la ordenada de longitud es Wo E.
  • Todos los valores de coordenadas son enteros. El valor del grado será entre 0y 90para la latitud, y entre 0y 180para la longitud. Los valores de minuto de arco y segundo de arco para ambas ordenadas estarán entre 0y 59.
  • Si todos los valores para una ordenada son 0, cualquier dirección es aceptable.
  • No es necesario poner a cero ningún valor.
  • Ninguna ordenada de latitud será más grande que los 90grados, y ninguna ordenada de longitud será más grande que los 180grados.
  • Se aplican lagunas estándar .

Casos de prueba

N 50 26 23 W 4 18 29 -> S 50 26 23 E 175 41 31

S 43 9 9 E 0 0 5     -> N 43 9 9 W 179 59 55

N 0 0 0 E 0 0 0      -> S/N 0 0 0 W/E 180 0 0 (either direction fine in each case)

S 1 2 3 W 4 5 6      -> N 1 2 3 E 175 54 54

S 9 21 43 W 150 7 59 -> N 9 21 43 E 29 52 1

S 27 40 2 W 23 0 0   -> N 27 40 2 E 157 0 0

N 0 58 37 W 37 0 0   -> S 0 58 37 E 143 0 0

Enlaces útiles

Este es el , por lo que gana la respuesta más corta en bytes.

TheBikingViking
fuente
¿Es este un formato razonable? Cuatro entradas: matriz de 3 números, char, matriz de tres números; separados por líneas nuevas
Luis Mendo
@LuisMendo A menos que te malinterprete, solo puedo ver tres entradas; ¿Supongo que querrías un char extra? Yo diría que ese es un formato razonable. Por razonable, quiero decir esencialmente que cada parte de la coordenada se puede distinguir sin ambigüedades.
TheBikingViking
Sí, olvidé el primer personaje. ¡Gracias!
Luis Mendo
3
¿"Bastante peligroso"? Compañero, el verdadero peligro es una vez que llegas aquí .
Andrew Grimm
1
@busukxuan Disculpas por no responder antes. Yo diría que estos dos formatos no son razonables, ya que requiere la especificación N, S, E, o Wcomo una dirección, mientras que el redundantes 0ambigüedad introduce en cuanto a qué valor representa qué componente de la ordenada.
TheBikingViking

Respuestas:

1

05AB1E, 37 34 bytes

`60©3L<Rm*O3°648*s-®‰`s®‰s‚˜)'€Ã‡

Explicado

`                                      # split input to 4 lines with longitude on top
 60©3L<Rm*O                            # convert longitude to seconds
            3°648*                     # longitude 180 0 0 in seconds
                  s-                   # subtract our longitude from this
                    ®‰`                # get seconds part
                       s®‰             # get minute and degrees part
                          s‚˜)         # join to list
                              '€Ã‡    # translate directions

Pruébalo en línea

Editar: Guardado 3 bytes gracias a Adnan .

Emigna
fuente
Puede comprimir "NEWS"a ‘€Ã‘, o incluso '€Ãsi se permite minúsculas.
Adnan
@Adnan: ¡Qué bien! No pensé en comprimir ya que la cuerda ya era muy pequeña.
Emigna
6

JavaScript (ES6), 88 bytes

(a,b,c,d,e,f,g,h)=>[a<'S'?'S':'N',b,c,d,e<'W'?'W':'E',!(g|h)+179-f,g|h&&!h+59-g,h&&60-h]

Toma 8 parámetros y devuelve una matriz como resultado. Espera aser uno de No Sy de manera similar eser uno de Wo E. Cálculos:

  • fnecesita restarse de 179 si es go hno es cero, pero 180 si ambos gy hson cero (porque no hay préstamo), por lo tanto, !(g|h)se agrega al 179.
  • gnecesita ser cero si ambos gy hson cero, por lo tanto g|h&&, debe restarse de 59 si hno es cero pero 60 si hes cero (porque no hay préstamo), por lo tanto, !hse agrega al 59.
  • h necesita ser cero si ya era cero, de lo contrario, simplemente se resta de 60.

Otra forma de ver esto es darse cuenta de que resta en binario se consigue añadiendo el complemento 1s más un adicional 1. Traducido a este problema, tomamos 179-f, 59-gy 59-hy añadir 1. 59-h+ 1 es 60-h, pero si esto es 60 entonces se lleva , por lo que el resultado deseado es cero si horiginalmente era cero. Agregamos 1 a 59-gsi hay un carry from h, es decir, si horiginalmente era cero. Nuevamente tenemos que permitir un acarreo, que esta vez sucede si ambos gy hson cero, y agregamos 1 a 179-fen este caso.

Neil
fuente
6

MATL , 51 bytes

'NS'tPXEii'WE'tPXE648e3i60:qXJZA-JYAtn3-?2:&)wJZAwh

Formato de entrada:

'N'
[50 26 23]
'W'
[4 18 29]

Formato de salida:

S
50 26 23
E
175  41  31

Pruébalo en línea!

Explicación

'NS'tPXE     % Take input (string) implicitly. Exchange 'N' and 'S'
i            % Take input (array)
i'WE'tPXE    % Take input (string). Exchange 'W' and 'E'
648e3        % Push 648000
i            % Take input (array)
60:qXJ       % Push [0 1 ... 59]. Copy into clipboard J
ZA           % Convert second input array from base 60 to decimal
-            % Subtract
JYA          % Convert to base 60
tn3-?        % If length exceeds 3
  2:&)       %   Split into first two elements and then the rest
  w          %   Swap
  JZA        %   Convert from base 60 to decimal
  wh         %   Swap, concatenate
Luis Mendo
fuente
Hay un error tipográfico en su explicación de la segunda a la última línea: bnase.
TheBikingViking
1
@TheBikingViking ¡Gracias! Corregido
Luis Mendo
4

Raqueta, 199 bytes

(λ(l)(cons(cons(if(eq?(caar l)'n)'s'n)(cdar l))(cons(if(eq?(cadr l)'e)'w'e)(list (- 180(+(caddr l)(sgn(foldl + 0(cdddr l)))))(modulo(- 60(+(fourth l)(sgn(fifth l))))60)(modulo(- 60(fifth l))60)))))

Eso es terriblemente largo. Probablemente hay algunas cosas que podría hacer para acortarlo aún más, pero se estremece por haber terminado.

Toma un conspar de dos lists: uno para la latitud y otro para la longitud. Cada lista tiene la dirección (como un símbolo de Raqueta en minúscula) como su primer elemento y, a continuación, los grados, minutos de arco y segundos de arco. Salidas en el mismo formato

Racket interpretará este par de dos listas como una sola lista con otra lista como su primer elemento. Esto está perfectamente bien, ya que aún puede acceder a la latitud y la longitud como si fueran dos listas en un par.

Uso:

>    (
     (λ(l)(cons(cons(if(eq?(caar l)'n)'s'n)(cdar l))(cons(if(eq?(cadr l)'e)'w'e)(list (- 180(+(caddr l)(sgn(foldl + 0(cdddr l)))))(modulo(- 60(+(fourth l)(sgn(fifth l))))60)(modulo(- 60(fifth l))60)))))
     (cons (list 's 43 9 9) (list 'e 0 0 5)))
'((n 43 9 9) w 179 59 55)

Que puede ser interpretado por código futuro como '((n 43 9 9) (w 179 59 55))dos listas.

Steven H.
fuente
4

Pyth, 41 45 43 35 bytes

K60-"NS"ww-"EW"wA.D-*3^K3iEKK+.DGKH

Utiliza la conversión de base 60 para convertir grados y minutos en segundos.

Formato de E / S:

N
[1,2,3]
E
[4,5,6]

Imprime una línea cada vez que ingresa una línea, por lo que para tener un formato atractivo, puede usar la CLI y canalizar la entrada, o más convenientemente, usar la implementación de Pyth en línea .

En pseudocódigo:

K60                                              K = 60
   -"NS"w                                        "NS".remove(input())
         w                                       print(input())
          -"EW"w                                 "EW".remove(input())
                A.D                              G,H = divmod(
                   -*3^K3                          3*K**3 -
                         iEK                         baseToDec(input(),K)),
                            K                      K)
                             +.DGKH              divmod(G,K)+H
busukxuan
fuente
@LuisMendo igual que el tuyo, pero listas separadas por comas y sin comillas
busukxuan
4

Python 2, 140 122 bytes

Actualizado:

def f(c):x=([180,0,0],[179,59,60])[1<sum(c[6:8])];print['NS'['N'in c]]+c[1:4]+['EW'['E'in c]]+map(lambda x,y:x-y,x,c[5:8])

Esto utiliza un enfoque ligeramente diferente: establecer los valores para restar de la longitud en función de los minutos y segundos. Si hay 0 minutos y segundos, resta 180 de los grados, y si hay> 0 minutos y segundos, resta 179, 59 y 60 de d, m, s respectivamente.

Original:

def f(c):v=divmod;m,s=v((180-(c[5]+c[6]/60.+c[7]/3600.))*3600,60);d,m=v(m,60);print['NS'['N'in c]]+c[1:4]+['EW'['E'in c]]+map(round,[d,m,s])

Toma la entrada como una lista: f(['N', 0, 0, 0, 'E', 0, 0, 0])convierte la longitud a grados decimales, resta de 180, luego vuelve a convertir a grados, minutos, segundos y reconstruye la lista, volteando las direcciones en el proceso.

Sin golf:

def f(c):
    minutes,seconds=divmod((180-(c[5]+c[6]/60.+c[7]/3600.))*3600,60)
    degrees,minutes=divmod(minutes,60)
    print ['NS'['N'in c]]+c[1:4]+['EW'['E'in c]]+map(round,[degrees,minutes,seconds])

Intentalo

atlasólogo
fuente
3

JavaScript, 138 137 129 124 112 110

Mejora de 2 bytes inspirada en el código de @ Neil

f=a=>a.map((v,i,a)=>i%4?i>6?v&&60-v:i>5?(59-v+!a[7])%60:i>4?179-v+!(a[7]|a[6]):v:'NEWS'[3-'NEWS'.indexOf(v)]);
  • input = output = array que contiene 2x (1 mayúscula y 3 int)
  • probado en Firefox

sin golf

f=a=>a.map((v,i,a)=>
i%4?
    i>6?v&&60-v              // 7: invert seconds - old: (60-v)%60
    :i>5?(59-v+!a[7])%60     // 6: invert minutes, increase if seconds are 0
    :i>4?179-v+!(a[7]|a[6])  // 5: invert degrees, increase if seconds and minutes are 0
    :v                       // 1,2,3: unchanged
:'NEWS'[3-'NEWS'.indexOf(v)] // 0,4: swap directions
);

pruebas

<table id=out border=1><tr><th>in</th><th>out<th>expected</th><th>ok?</th></tr></table>
<script>
addR=(r,s)=>{var d=document.createElement('td');d.appendChild(document.createTextNode(s));r.appendChild(d)}
test=(x,e,f)=>{var y,r=document.createElement('tr');addR(r,x);addR(r,y=('function'==typeof f)?f(x):f);addR(r,e);addR(r,e.toString()==y.toString()?'Y':'N');document.getElementById('out').appendChild(r)}

samples=[
'N',50,26,23,'W',4,18,29,   'S',50,26,23,'E',175,41,31,
'S',43,9,9,'E',0,0,5,       'N',43,9,9,'W',179,59,55,
'N',0,0,0,'E',0,0,0,        'S',0,0,0,'W',180,0,0,
'S',1,2,3,'W',4,5,6,        'N',1,2,3,'E',175,54,54,
'S',9,21,43,'W',150,7,59,   'N',9,21,43,'E',29,52,1,
'S',27,40,2,'W',23,0,0,     'N',27,40,2,'E',157,0,0,
'N',0,58,37,'W',37,0,0,     'S',0,58,37,'E',143,0,0,
];
while (samples.length)
{
    x=samples.splice(0,8);
    e=samples.splice(0,8);
    test(x,e,h);
    test(e,x,h);
}
</script>
Titus
fuente
ah acabo de ver @Neil tenía la misma idea, pero algunos de parametrización más corto
Tito
2

Python 3, 131 130 bytes

def f(w,x,y,z):S=60;d=divmod;a,b,c=y;l,m=d(648e3-c-S*b-S*S*a,S);return w,"N" if x=="S" else "S",d(l,S)+(m,),"E" if z=="W" else "W"

Formatos: los ángulos son tuplas de la forma (deg,min,sec), las direcciones son de la forma N. Emite un cuádruple de 2 ángulos, cada uno seguido de su dirección.

Versión sin golf:

def f(latitude,NS,longitude,EW):
    degree,minute,second=longitude
    minute,second=divmod(648000-second-60*minute-60*60*degree,60)
    return latitude, "N" if NS=="S" else "S", divmod(minute,60)+(second,), "E" if EW=="W" else "W"
busukxuan
fuente
1
Puede reducir esto a 120 bytes haciendo def f(w,x,y,z):S=60;d=divmod;a,b,c=y;l,m=d(648e3-c-S*b-S*S*a,S);return w,["S","N"][x=="S"],d(l,S)+(m,),["W","E"][z=="W"]Esto funciona usando el hecho de que Truey Falsepuede interpretarse como 1y 0, y por a if b else clo tanto es equivalente a [c, a][b]. En una nota al margen, creo que su código original tiene un error tipográfico; debería x=="W"ser z=="W"?
TheBikingViking
2

C #, 310 269 ​​bytes

float[]t(string[]a,int n)=>a.Skip(n).Take(3).Select(float.Parse).ToArray();string A(string i){var s=i.Split(' ');var w=t(s,5);float a=180-(w[0]+w[1]/60+w[2]/3600),b=a%1*60;return(s[0][0]>82?"N":"S")+$" {string.Join(" ",t(s,1))} {(s[4][0]<70?'W':'E')} {a} {b} "+b%1*60;}

La entrada es una cadena. Puedes probarlo en .NetFiddle .

Código

float[]t(string[]a,int n)=>a.Skip(n).Take(3).Select(float.Parse).ToArray();
string A(string i) {
    var s=i.Split(' ');var w=t(s,5);float a=180-(w[0]+w[1]/60+w[2]/3600),b=a%1*60;
    return (s[0][0]>82?"N":"S")
        +$" {string.Join(" ",t(s,1))} {(s[4][0]<70?'W':'E')} {a} {b} "+b%1*60;
}

Si no tomo una stringentrada sino una char, float[], char, float[], puedo hacer:

C #, 167 166 165 163 152 148 147 139 bytes

(s,n,e,w)=>{float a=180-(w[0]+w[1]/60+w[2]/3600),b=a%1*60;return(s>82?"N":"S")+$" {string.Join(" ",n)} {(e<70?'W':'E')} {a} {b} "+b%1*60;};

Código

(s,n,e,w) => {
    float a=180-(w[0]+w[1]/60+w[2]/3600),b=a%1*60;
    return(s>82?"N":"S")+$" {string.Join(" ",n)} {(e<70?'W':'E')} {a} {b} "+b%1*60;
};

También puedo eliminar 3600y usar en su lugar para mover a 164 caracteres y 166 bytes. ¿Debo usarlo?


C #, 150 bytes

(s,n,m,p,e,w,x,y)=>{var t=new TimeSpan(180,0,0)-new TimeSpan(w,x,y);return(s>82?"N":"S")+$" {n} {m} {p} {(e<70?'W':'E')} {t.TotalHours} {t:%m\\ s}";};

Código

(s,n,m,p,e,w,x,y) => {
    var z=new TimeSpan(180,0,0)-new TimeSpan(w,x,y);
     return(s>82?"N":"S")+$" {n} {m} {p} {(e<70?'W':'E')} {z.TotalHours} {z:%m\\ s}";
};

¡Una forma más .NET! Delego toda la lógica a .NET struct TimeSpany yo ab uso el formato de cadenas de lógica. Entrada es char, int, int, int, char, int, int, int. Comparto este para dar algunas ideas. Tal vez alguien mejorará de una mejor manera que yo.

aloisdg dice Reinstate Monica
fuente
Eso es lamentablemente detallado.
Steven H.
@Fawful Publico otra versión con diferentes argumentos. Menos detallado no es? Todavía no puedo deshacerme de string.Join()...
aloisdg dice Reinstate Monica
Tenga en cuenta que esto es C # 6.0
Yytsi
@TuukkaX ya que es la última versión de C #, no lo especifiqué. Lo haré si uso alguna función de liberación como la función C # 7.
aloisdg dice Reinstate Monica
1
Bueno, no veo un return, tuve que agregarlo yo mismo ... Usando su prueba a('N', new float[] { 50, 26, 23 }, 'W', new float[] { 4, 18, 29 })que obtengo S 50 26 23 E 175.6919 41.51642 30.98511, ¿consideraría esto un pase?
cuando el
0

Java, 199177 o 151 o 134 bytes

Solución de 177 bytes que imprime el resultado

void t(int...a){int i=648000-(a[5]*3600+a[6]*60+a[7]);System.out.println(a[0]=='N'?"S":"N"+" "+a[1]+" "+a[2]+" "+a[3]+" "+(a[4]=='E'?"W":"E")+" "+i/3600+" "+i/60%60+" "+i%60);}

Solución de 151 bytes que devuelve el resultado como matriz

Object[]y(int...a){int i=648000-(a[5]*3600+a[6]*60+a[7]);return new Object[]{a[0]=='N'?"S":"N",a[1],a[2],a[3],a[4]=='E'?"W":"E",i/3600,i/60%60,i%60};}

134 Bytes si usamos la notación lambda

a->{int i=648000-a[5]*3600-a[6]*60-a[7];return new Object[]{a[0]=='N'?"S":"N",a[1],a[2],a[3],a[4]=='E'?"W":"E",i/3600,i/60%60,i%60};}
usuario902383
fuente
0

C, 188

main(int c,char**v){int n=*v[1]==78?83:78,e=*v[5]==69?87:69,b=648000-(atoi(v[6])*3600+atoi(v[7])*60+atoi(v[8]));printf("%c %s %s %s %c %d %d %d\n",n,v[2],v[3],v[4],e,b/3600,b/60%60,b%60);}

Requiere 8 argumentos de programa, de lo contrario fallará. Pase argumentos como N 50 26 23 W 4 18 29. Indicadores de dirección N, S, E, W, deben ser capitalizada.

owacoder
fuente
0

PostGIS, 123 bytes

Tool-For-The-Job es decepcionantemente detallado, en parte debido a la palabrería SQL y en parte debido a la necesidad de convertir a la geometría y viceversa:

CREATE FUNCTION f(p geography)
RETURNS geography
AS 'SELECT ST_Affine(p::geometry,1,0,0,-1,180,0)::geography' LANGUAGE sql;

Por otro lado, esta función única transformará puntos, colecciones de puntos o formas más complejas (como toda la costa de Australia y Nueva Zelanda).

Toby Speight
fuente
0

PHP, 148 bytes

mismo enfoque que mi respuesta de JavaScript , busque un desglose

  • +16 funciones generales
  • +17 para $señales
  • +12 para paréntesis (precedencia de operador diferente)
  • +4 porque foreachporque PHP array_maptiene una gran sobrecarga
  • +1 para (60-$v)%60porque se $v&&60-$vconvierte en booleano en PHP
  • -8 trabajando en el original
  • -4 mediante el uso chr, ordy algunas aritméticas en el cambio de dirección

function f(&$a){foreach($a as$i=>$v)$a[$i]=$i%4?($i>6?(60-$v)%60:($i>5?(59-$v+!$a[7])%60:($i>4?179-$v+!($a[7]|$a[6]):$v))):chr(($i?156:161)-ord($v));}
  • la función funciona en original
  • formato: matriz con 2x (1 letra mayúscula, 3 int)

pruebas

function out($a){if(!is_array($a))return$a;$r=[];foreach($a as$v)$r[]=out($v);return'['.join(',',$r).']';}
function cmp($a,$b){if(is_numeric($a)&&is_numeric($b))return 1e-2<abs($a-$b);if(is_array($a)&&is_array($b)&&count($a)==count($b)){foreach($a as $v){$w = array_shift($b);if(cmp($v,$w))return true;}return false;}return strcmp($a,$b);}
$samples=[
N,50,26,23,W,4,18,29,   S,50,26,23,E,175,41,31,
S,43,9,9,E,0,0,5,       N,43,9,9,W,179,59,55,
N,0,0,0,E,0,0,0,        S,0,0,0,W,180,0,0,
S,1,2,3,W,4,5,6,        N,1,2,3,E,175,54,54,
S,9,21,43,W,150,7,59,   N,9,21,43,E,29,52,1,
S,27,40,2,W,23,0,0,     N,27,40,2,E,157,0,0,
N,0,58,37,W,37,0,0,     S,0,58,37,E,143,0,0,
];
while ($samples)
{
    $xx=$x=array_splice($samples,0,8);
    $ee=$e=array_splice($samples,0,8);
    func($x); test($xx,$ee,$x);
    func($e); test($ee,$xx,$e);
}

ideas abandonadas

  • enfoque sin bucle con banderas de acarreo: +5
  • bucle hacia atrás con banderas de transporte: +7
  • Podría convertir esto en un programa para PHP <5.4, pero no importa: -3
Titus
fuente
0

Befunge, 122 114 111 Bytes (110 caracteres)

~"N"-v
 v"N"_"S"
v>,&.&.&.~"W"-
_"E"v"W"
+:v >,&"´"\-&"Z"*&
v\_\[email protected]\"<".-1\ <
>1-.:"Z"/"<"\-\"Z"%:#^_\..@

Formato de entrada:

N 50 26 23W 4 18 29

Observe la dirección de longitud y los segundos de arco deben estar agrupados

Puedes probar el código aquí

Maliafo
fuente