Scava in Australia - antipodi


24

sfondo

Innumerevoli generazioni di bambini si sono chiesti dove finirebbero se scavassero un buco direttamente verso il basso. Si scopre che questo, ovviamente, sarebbe piuttosto pericoloso , ma comunque ...

Gli antipodi sono punti direttamente uno di fronte all'altro sulla superficie terrestre. Ciò significa che se una linea fosse tracciata tra i due punti, passerebbe attraverso il centro della Terra.

Sfida

Scrivi un programma o una funzione che, dato un punto, trova il suo antipode.

In questa sfida, i punti sono rappresentati usando il sistema longitudine-latitudine e gradi, minuti e secondi dell'arco. Per trovare l'antipode, scambia le direzioni di ciascuna ordinata ( N <-> Se W <-> E) e sottrai l'ordinata di longitudine dai 180gradi.

Esempio:
prendere il punto N 50 26 23 W 4 18 29. Scambia le indicazioni per dare S 50 26 23 E 4 18 29. Sottrarre l'ordinata di longitudine da 180 0 0dare 175 41 31, lasciando le coordinate antipode come S 50 26 23 E 175 41 31.

Regole

Ingresso

Un insieme di coordinate di latitudine-longitudine, in qualsiasi formato ragionevole , in cui ogni ordinata contiene una direzione, un numero di gradi, un numero di minuti d'arco e un numero di secondi d'arco.

Produzione

Le coordinate di latitudine-longitudine dell'antipode, in qualsiasi formato ragionevole , in cui ciascuna ordinata contiene una direzione, un numero di gradi, un numero di minuti d'arco e un numero di secondi d'arco.

Prendere ragionevole significa che ogni parte della coordinata può essere distinta in modo inequivocabile.

Specifiche

  • La direzione per l'ordinata di latitudine è No S, e quella per l'ordinata di longitudine è Wo E.
  • Tutti i valori delle coordinate sono numeri interi. Il valore del grado sarà compreso tra 0e 90per la latitudine e tra 0e 180per la longitudine. I valori dell'arco minuto e dell'arco secondo per entrambe le ordinate saranno compresi tra 0e 59.
  • Se tutti i valori di un'ordinata sono 0, entrambe le direzioni sono accettabili.
  • Non è necessario azzerare alcun valore.
  • Nessuna ordinata di latitudine sarà mai più grande dei 90gradi e nessuna ordinata di longitudine sarà mai più grande dei 180gradi.
  • Si applicano scappatoie standard .

Casi test

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

Link utili

Questo è , quindi vince la risposta più breve in byte!


È un formato ragionevole? Quattro ingressi: matrice di 3 numeri, carattere, matrice di tre numeri; separati da newline
Luis Mendo,

@LuisMendo A meno che non ti fraintenda, posso vedere solo tre input; Presumo che vorresti un personaggio extra? Direi che è un formato ragionevole. Con ragionevole intendo essenzialmente che ogni parte della coordinata può essere distinta in modo inequivocabile.
TheBikingViking

Sì, ho dimenticato il primo carattere. Grazie!
Luis Mendo,

3
"Piuttosto pericoloso"? Amico, il vero pericolo è una volta arrivato qui .
Andrew Grimm,

1
@busukxuan Ci scusiamo per non aver risposto prima. Direi che entrambe tali formati non sono ragionevoli, poiché le specifiche richiede N, S, E, o Wcome una direzione, mentre l'esubero 0introduce ambiguità su quale valore rappresenta quale componente delle ordinate.
TheBikingViking

Risposte:


1

05AB1E, 37 34 byte

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

spiegato

`                                      # 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

Provalo online

Modifica: salvato 3 byte grazie ad Adnan .


È possibile comprimere "NEWS"al ‘€Ã‘o anche '€Ãse è ammessa in minuscolo.
Adnan,

@Adnan: bello! Non pensavo di comprimerlo poiché la stringa era già così piccola.
Emigna,

6

JavaScript (ES6), 88 byte

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

Accetta 8 parametri e restituisce un array come risultato. Si aspetta ache sia uno Noo Ssimilmente euno Wo E. calcoli:

  • fdeve essere sottratto da 179 se uno go hè diverso da zero ge 180 se entrambi e hsono zero (perché non vi è alcun prestito), quindi !(g|h)viene aggiunto al 179.
  • gdeve essere zero se entrambi ge hsono zero, quindi g|h&&, altrimenti deve essere sottratto da 59 hse hè diverso da zero ma 60 se è zero (perché non vi è alcun prestito), quindi !hviene aggiunto al 59.
  • h deve essere zero se era già zero, altrimenti viene semplicemente sottratto da 60.

Un altro modo di guardare a questo è quello di notare che sottraendo in binario si ottiene con l'aggiunta del complemento 1s più un ulteriore 1. Tradotto a questo problema, prendiamo 179-f, 59-ge 59-he aggiungere 1. 59-h+ 1 è 60-h, ma se questo è il 60, allora porta , quindi il risultato desiderato è zero se hinizialmente era zero. Aggiungiamo 1 a 59-gse c'è un carry da h, cioè se horiginariamente era zero. Ancora una volta dobbiamo consentire un carry, che questa volta accade se entrambi ge hsono zero, e 179-fin questo caso aggiungiamo 1 .


6

MATL , 51 byte

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

Formato di input:

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

Formato di output:

S
50 26 23
E
175  41  31

Provalo online!

Spiegazione

'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

C'è un errore di battitura nella tua spiegazione sulla penultima riga: bnase.
TheBikingViking

1
@TheBikingViking Grazie! Corretto
Luis Mendo il

4

Racchetta, 199 byte

(λ(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)))))

È orribilmente lungo. Probabilmente ci sono alcune cose che potrei fare per accorciarlo ulteriormente, ma i brividi sono completamente fatto.

Prende una conscoppia di due lists: uno per la latitudine e uno per la longitudine. Ogni elenco ha la direzione (come un simbolo di racchetta minuscola) come primo elemento e seguendo i gradi, i minuti d'arco e i secondi d'arco. Output nello stesso formato

Racket interpreterà questa coppia di due liste come una singola lista con un'altra lista come primo elemento. Questo va perfettamente bene, poiché è ancora possibile accedere sia alla latitudine che alla longitudine come se fossero due elenchi in una coppia.

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)

Che può essere interpretato dal codice futuro come '((n 43 9 9) (w 179 59 55)), due elenchi.


4

Pyth, 41 45 43 35 byte

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

Utilizza la conversione base-60 per convertire gradi e minuti in secondi.

Formato I / O:

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

Stampa una riga ogni volta che si inserisce una riga, quindi per avere un formato gradevole, è possibile utilizzare l'interfaccia della riga di comando e reindirizzare l'input oppure, più comodamente, utilizzare l'implementazione Pyth online .

In pseudocodice:

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

@LuisMendo come i tuoi, ma elenchi separati da virgole e senza virgolette
busukxuan,

4

Python 2, 140 122 byte

aggiornato:

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

Questo utilizza un approccio leggermente diverso: impostare i valori da sottrarre dalla longitudine in base a minuti e secondi. Se ci sono 0 minuti e secondi, sottrae 180 dai gradi e se ci sono> 0 minuti e secondi, sottrae 179, 59 e 60 rispettivamente da d, m, s.

Originale:

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

Accetta input come un elenco: f(['N', 0, 0, 0, 'E', 0, 0, 0])converte la longitudine in gradi decimali, sottrae da 180, quindi converte in gradi, minuti, secondi e ricostruisce l'elenco, capovolgendo le direzioni nel processo.

Un-giocato a 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])

Provalo


3

JavaScript, 138 137 129 124 112 110

Miglioramento di 2 byte ispirato al codice di @ 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 contenente 2x (1 carattere maiuscolo e 3 int)
  • testato in Firefox

ungolfed

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

test

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

ah vedo solo che @Neil ha avuto la stessa idea, ma qualche parametrizzazione più breve
Tito

2

Python 3, 131 130 byte

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"

Formati: gli angoli sono tuple della forma (deg,min,sec), le direzioni sono della forma N. Emette un quadruplo di 2 angoli, ciascuno seguito dalla sua direzione.

Versione non golfata:

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"

1
È possibile ottenere questo fino a 120 byte facendo 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"]Questo funziona utilizzando il fatto che Truee Falsepuò essere interpretato come 1e 0, e quindi a if b else cè equivalente a [c, a][b]. In una nota a margine, penso che il tuo codice originale abbia un refuso; dovrebbe x=="W"essere z=="W"?
TheBikingViking

2

C #, 310 269 ​​byte

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

L'input è una stringa. Puoi provarlo su .NetFiddle .

Codice

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 non prendo un stringinput ma un char, float[], char, float[], posso fare:

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

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

Codice

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

Inoltre posso rimuovere 3600e usare invece per spostare a 164 caratteri e 166 byte. Dovrei usarlo?


C #, 150 byte

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

Codice

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

Un modo più .NET! Delego tutta la logica a .NET struct TimeSpane io ab utilizzare la stringa di formattazione logica. L'input è char, int, int, int, char, int, int, int. Condivido questo per dare alcune idee. Forse qualcuno migliorerà in un modo migliore di me.


Questo è purtroppo dettagliato.
Steven H.

@Fawful inserisco un'altra versione con argomenti diversi. Meno prolisso non lo è? Non riesco ancora a liberarmi di string.Join()...
aloisdg dice Reinstate Monica il

Si noti che questo è C # 6.0
Yytsi

@TuukkaX poiché è l'ultima versione di C #, non l'ho specificato. Lo farò se uso alcune funzionalità di rilascio come la funzione C # 7.
aloisdg dice Reinstate Monica il

1
Bene, non vedo un return, ho dovuto aggiungerlo da solo ... Usando il tuo test a('N', new float[] { 50, 26, 23 }, 'W', new float[] { 4, 18, 29 })ottengo S 50 26 23 E 175.6919 41.51642 30.98511- lo considereresti un passaggio?
Onedayquando il

0

Java, 199 177 o 151 o 134 byte

Soluzione di 177 byte che stampa il risultato

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

Soluzione di 151 byte che restituisce il risultato come matrice

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 byte se usassimo la notazione 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};}

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

Richiede 8 argomenti del programma, altrimenti fallirà. Passa argomenti come N 50 26 23 W 4 18 29. Indicatori di direzione N, S, E, W, devono essere capitalizzati.


0

PostGIS, 123 byte

Tool-For-The-Job è deludentemente prolisso, in parte a causa della proliferazione SQL e in parte a causa della necessità di eseguire il cast sulla geometria e sul retro:

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

D'altra parte, questa singola funzione trasformerà punti, raccolte di punti o forme più complesse (come l'intera costa dell'Australia e della Nuova Zelanda).


0

PHP, 148 byte

stesso approccio della mia risposta JavaScript , cerca lì una ripartizione

  • +16 funzioni generali
  • +17 per i $segni
  • +12 per le parentesi (precedenza dell'operatore diversa)
  • +4 foreachperché PHP array_mapha un enorme sovraccarico
  • +1 per (60-$v)%60perché viene $v&&60-$vlanciato in booleano in PHP
  • -8 lavorando sull'originale
  • -4 usando chr, orde alcune aritmetiche sullo scambio di direzione

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 funzione funziona sull'originale
  • formato: array con 2x (1 carattere maiuscolo, 3 int)

test

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

idee abbandonate

  • nessun approccio ad anello con flag carry: +5
  • loop indietro con carry flag: +7
  • Potrei trasformarlo in un programma per PHP <5.4, ma non importa: -3

0

Befunge, 122 114 111 byte (110 caratteri)

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

Formato di input:

N 50 26 23W 4 18 29

Notare che la direzione della longitudine e i secondi dell'arco devono essere raggruppati insieme

Puoi testare il codice qui

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.