Dig para a Austrália - antípodas

24

fundo

Inúmeras gerações de crianças se perguntam onde iriam parar se cavassem um buraco diretamente para baixo. Acontece que isso seria, sem surpresa, bastante perigoso , mas de qualquer maneira ...

Antípodas são pontos diretamente opostos um ao outro na superfície da Terra. Isso significa que se uma linha fosse traçada entre os dois pontos, ela passaria pelo centro da Terra.

Desafio

Escreva um programa ou função que, dado um ponto, encontre seu antípoda.

Neste desafio, os pontos são representados usando o sistema longitude-latitude e graus, minutos de arco e segundos de arco. Para encontrar o antípoda, troque as direções de cada ordenada ( N <-> Se W <-> E) e subtraia a ordenada da longitude de 180graus.

Exemplo:
Entenda N 50 26 23 W 4 18 29. Troque as instruções para dar S 50 26 23 E 4 18 29. Subtraia a ordenada de longitude de 180 0 0para dar 175 41 31, deixando as coordenadas do antípoda como S 50 26 23 E 175 41 31.

Regras

Entrada

Um conjunto de coordenadas de latitude-longitude, em qualquer formato razoável , em que cada ordenada contém uma direção, um número de graus, um número de minutos de arco e um número de segundos de arco.

Saída

As coordenadas de latitude e longitude do antípoda, em qualquer formato razoável , em que cada ordenada contém uma direção, um número de graus, um número de minutos do arco e um número de segundos do arco.

Por razoável, significa que cada parte da coordenada pode ser distinguida sem ambiguidade.

Especificações

  • A direção da ordenada da latitude é Nou S, e a da ordenada da longitude é Wou E.
  • Todos os valores de coordenadas são inteiros. O valor do grau será entre 0e 90para latitude e entre 0e 180para longitude. Os valores de minuto do arco e segundo do arco para as duas ordenadas estarão entre 0e 59.
  • Se todos os valores de uma ordenada forem 0, qualquer direção é aceitável.
  • Não é necessário zerar nenhum valor.
  • Nenhuma ordenada de latitude será maior que 90graus, e nenhuma ordenada de longitude será maior que 180graus.
  • Aplicam-se brechas padrão .

Casos de teste

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

Links Úteis

Isso é , então a resposta mais curta em bytes vence!

TheBikingViking
fonte
Esse é um formato razoável? Quatro entradas: matriz de 3 números, caractere, matriz de três números; separado por novas linhas
Luis Mendo
@LuisMendo A menos que eu esteja entendendo mal você, só consigo ver três entradas; Presumo que você gostaria de um char extra? Eu diria que esse é um formato razoável. Por razoável, quero dizer essencialmente que cada parte da coordenada pode ser distinguida sem ambiguidade.
TheBikingViking
Sim, eu esqueci o primeiro caractere. Obrigado!
Luis Mendo
3
"Um pouco perigoso"? Cara, o verdadeiro perigo é quando você chegar aqui .
Andrew Grimm
11
@busukxuan Desculpas por não responder mais cedo. Eu diria que ambos os formatos não são razoáveis, uma vez que a especificação exige N, S, E, ou Wcomo uma direção, enquanto o redundantes 0introduz ambiguidade quanto ao que valor representa qual componente da ordenada.
TheBikingViking

Respostas:

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

Experimente online

Editar: salvou 3 bytes graças a Adnan .

Emigna
fonte
Você pode compactar "NEWS"para ‘€Ã‘ou mesmo '€Ãse letras minúsculas forem permitidas.
Adnan
@Adnan: Legal! Não pensou em comprimir, já que a corda já era tão pequena.
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 e retorna uma matriz como resultado. Espera aser um de Nou Se da mesma forma eser um de Wou E. Cálculos:

  • fprecisa ser subtraído de 179 se é gou hnão é zero, mas 180 se ambos ge hsão zero (porque não há empréstimos), assim !(g|h)é adicionado ao 179.
  • gprecisa ser zero se ambos ge hsão zero, portanto g|h&&, caso contrário, precisa ser subtraído de 59 se hfor diferente de zero, mas 60 se hfor zero (porque não há empréstimos), portanto!h será adicionado ao 59.
  • h precisa ser zero se já era zero, caso contrário, é simplesmente subtraído de 60.

Outra maneira de olhar para isso é aviso de que subtraindo em binário é conseguido através da adição do complemento 1s mais uma 1. adicional Traduzido para este problema, tomamos 179-f, 59-ge 59-he adicionar 1. 59-h+ 1 é 60-h, mas se este é de 60, em seguida, ele carrega , portanto, o resultado desejado é zero se hera originalmente zero. Nós adicionamos 1 a 59-gse houver um carry de h, ou seja, se hera originalmente zero. Novamente, temos que permitir um carry, que desta vez acontece se ambos ge hsão zero, e adicionamos 1 179-fnesse caso.

Neil
fonte
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 saída:

S
50 26 23
E
175  41  31

Experimente online!

Explicação

'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
fonte
Há um erro de digitação em sua explicação sobre o segundo a última linha: bnase.
TheBikingViking
11
@TheBikingViking Obrigado! Corrigido
Luis Mendo
4

Raquete, 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)))))

Isso é terrivelmente longo. Provavelmente, há algumas coisas que eu poderia fazer para reduzi-lo ainda mais, mas tremo completamente.

Toma um conspar de dois lists: um para a latitude e outro para a longitude. Cada lista tem a direção (como um símbolo de raquete em minúsculas) como seu primeiro item e segue os graus, minutos de arco e segundos de arco. Saídas no mesmo formato

Racket interpretará esse par de duas listas como uma única lista com outra lista como seu primeiro elemento. Isso é perfeitamente correto, pois você ainda pode acessar a latitude e a longitude como se fossem duas listas em um 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 pode ser interpretado pelo código futuro como '((n 43 9 9) (w 179 59 55))duas listas.

Steven H.
fonte
4

Pitão, 41 45 43 35 bytes

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

Usa a conversão de base 60 para transformar graus e minutos em segundos.

Formato de E / S:

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

Ele imprime uma linha toda vez que você insere uma linha, para ter um formato bonito, você pode usar a CLI e canalizar a entrada ou, mais conveniente, usar a implementação Pyth online .

No 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
fonte
@LuisMendo mesmo que o seu, mas separados por vírgula listas e sem aspas
busukxuan
4

Python 2, 140 122 bytes

Atualizada:

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])

Isso usa uma abordagem um pouco diferente: definir os valores para subtrair da longitude com base nos minutos e segundos. Se houver 0 minutos e segundos, subtrai 180 dos graus e, se houver> 0 minutos e segundos, subtrai 179, 59 e 60 dos 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])

Pega a entrada como uma lista f(['N', 0, 0, 0, 'E', 0, 0, 0]):, converte a longitude em graus decimais, subtrai de 180, depois converte de volta para graus, minutos, segundos e reconstrói a lista, invertendo as direções no processo.

Sem golfe:

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])

Tente

atlasologist
fonte
3

JavaScript, 138 137 129 124 112 110

Melhoria de 2 bytes inspirada no 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 contendo 2x (1 caractere maiúsculo e 3 int)
  • testado no Firefox

destroçado

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
);

testes

<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
fonte
ah, acabei de ver que @Neil teve a mesma ideia, mas alguns parametrizando mais curtos
Titus
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: ângulos são tuplas da forma (deg,min,sec), direções são da forma N. Emite um quadruplo de 2 ângulos, cada um seguido por sua direção.

Versão não destruída:

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
fonte
11
Você pode reduzir isso para 120 bytes fazendo 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"]Isso funciona usando o fato de que Truee Falsepode ser interpretado como 1e 0, portanto, a if b else cé equivalente a [c, a][b]. Em uma nota lateral, acho que seu código original possui um erro de digitação; deveria 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;}

A entrada é uma sequência. Você pode experimentá-lo no .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;
}

Se eu não pegar a stringcomo entrada, mas a char, float[], char, float[], posso:

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;
};

Também posso remover 3600e usar para mover para 164 caracteres e 166 bytes. Devo usá-lo?


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}";
};

Uma maneira mais .NET! I delegar toda a lógica para o .NET struct TimeSpane eu ab utilizar a cadeia de formatação lógica. Entrada é char, int, int, int, char, int, int, int. Eu compartilho este para dar algumas idéias. Talvez alguém melhore de uma maneira melhor do que eu.

aloisdg diz Restabelecer Monica
fonte
Infelizmente isso é detalhado.
Steven H.
@ Fawful eu posto outra versão com argumentos diferentes. Menos detalhado não é? Eu ainda não consigo me livrarstring.Join() ...
aloisdg diz Reintegrar Monica
Observe que isso é C # 6.0
Yytsi 06/07/19
@TuukkaX, como é a versão mais recente do C #, não a especifiquei. Eu usarei se usar algum recurso de liberação da un, como o recurso C # 7.
Aloisdg diz Reinstate Monica
11
Bem, eu não vejo um return, tive que adicioná-lo eu mesmo ... Usando o teste a('N', new float[] { 50, 26, 23 }, 'W', new float[] { 4, 18, 29 })que recebo S 50 26 23 E 175.6919 41.51642 30.98511- você consideraria isso um passe?
onedaywhen
0

Java, 199 177 ou 151 ou 134 bytes

Solução de 177 bytes que imprime o 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);}

Solução de 151 bytes que retorna o 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 se usamos a notação 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};}
user902383
fonte
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);}

Requer 8 argumentos do programa; caso contrário, falhará. Passe argumentos como N 50 26 23 W 4 18 29. Indicadores de direção N, S, E, W, deve ser capitalizado.

owacoder
fonte
0

PostGIS, 123 bytes

A Ferramenta para o trabalho é decepcionantemente detalhada, em parte devido ao detalhamento do SQL e em parte devido à necessidade de converter para geometria e vice-versa:

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

Por outro lado, essa função única transformará pontos, coleções de pontos ou formas mais complexas (como toda a costa da Austrália e Nova Zelândia).

Toby Speight
fonte
0

PHP, 148 bytes

mesma abordagem da minha resposta JavaScript , procure um detalhamento

  • +16 função sobrecarga
  • +17 para $ sinais
  • +12 para parênteses (precedência diferente do operador)
  • +4 por foreachcausa do PHParray_map tem uma enorme sobrecarga
  • +1 para (60-$v)%60porque$v&&60-$v lança para booleano em PHP
  • -8 trabalhando no original
  • -4 usando chr, orde algumas aritméticas na troca de direção

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));}
  • função funciona no original
  • formato: matriz com 2x (1 caractere maiúsculo, 3 int)

testes

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);
}

idéias abandonadas

  • sem abordagem de loop com sinalizadores de transporte: +5
  • loop para trás com bandeiras de transporte: +7
  • Eu poderia transformar isso em um programa para PHP <5.4, mas não importa: -3
Titus
fonte
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 que a direção da longitude e os segundos do arco devem ser agrupados

Você pode testar o código aqui

Maliafo
fonte