Creusez en Australie - antipodes

24

Contexte

D'innombrables générations d'enfants se sont demandé où ils finiraient s'ils creusaient un trou directement vers le bas. Il s'avère que cela serait, sans surprise, plutôt dangereux , mais de toute façon ...

Les antipodes sont des points directement opposés à la surface de la Terre. Cela signifie que si une ligne était tracée entre les deux points, elle passerait par le centre de la Terre.

Défi

Écrivez un programme ou une fonction qui, à partir d'un point, trouve son antipode.

Dans ce défi, les points sont représentés en utilisant le système longitude-latitude et les degrés, les minutes d'arc et les secondes d'arc. Pour trouver l'antipode, permutez les directions de chaque ordonnée ( N <-> Set W <-> E) et soustrayez l'ordonnée de longitude des 180degrés.

Exemple:
prenez le point N 50 26 23 W 4 18 29. Échangez les directions à donner S 50 26 23 E 4 18 29. Soustrayez l'ordonnée de longitude de 180 0 0pour donner 175 41 31, en laissant les coordonnées antipode comme S 50 26 23 E 175 41 31.

Règles

Contribution

Un ensemble de coordonnées latitude-longitude, dans n'importe quel format raisonnable , où chaque ordonnée contient une direction, un nombre de degrés, un nombre de minutes d'arc et un nombre de secondes d'arc.

Sortie

Les coordonnées latitude-longitude de l'antipode, dans tout format raisonnable , où chaque ordonnée contient une direction, un nombre de degrés, un nombre de minutes d'arc et un nombre de secondes d'arc.

Prendre raisonnable signifie que chaque partie de la coordonnée peut être distinguée sans ambiguïté.

Spécifications

  • La direction de l'ordonnée de latitude est Nou S, et celle de l'ordonnée de longitude est Wou E.
  • Toutes les valeurs de coordonnées sont des entiers. La valeur du degré sera entre 0et 90pour la latitude, et entre 0et 180pour la longitude. Les valeurs des minutes d'arc et des secondes d'arc pour les deux ordonnées seront comprises entre 0et 59.
  • Si toutes les valeurs d'une ordonnée sont 0, l'une ou l'autre direction est acceptable.
  • Il n'est pas nécessaire de mettre à zéro les valeurs.
  • Aucune ordonnée de latitude ne sera jamais supérieure à des 90degrés, et aucune ordonnée de longitude ne sera jamais supérieure à des 180degrés.
  • Des échappatoires standard s'appliquent.

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

Liens utiles

C'est le , donc la réponse la plus courte en octets l'emporte!

TheBikingViking
la source
Est-ce un format raisonnable? Quatre entrées: tableau de 3 nombres, char, tableau de trois nombres; séparés par des nouvelles lignes
Luis Mendo
@LuisMendo À moins que je ne vous comprenne mal, je ne peux voir que trois entrées; Je suppose que vous voudriez un char supplémentaire? Je dirais que c'est un format raisonnable. Par raisonnable, j'entends essentiellement que chaque partie de la coordonnée peut être distinguée sans ambiguïté.
TheBikingViking
Oui, j'ai oublié le premier caractère. Merci!
Luis Mendo
3
"Plutôt dangereux"? Mon pote, le vrai danger est une fois que vous arrivez ici .
Andrew Grimm
1
@busukxuan Toutes mes excuses pour ne pas avoir répondu plus tôt. Je dirais que ces deux formats ne sont pas raisonnables, car la spécification exige N, S, Eou Wcomme une direction, alors que la redondance 0introduit l' ambiguïté à laquelle la valeur représente que composante de l'ordonnée.
TheBikingViking

Réponses:

1

05AB1E, 37 34 octets

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

Expliqué

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

Essayez-le en ligne

Edit: sauvé 3 octets grâce à Adnan .

Emigna
la source
Vous pouvez compresser "NEWS"à ‘€Ã‘ou même '€Ãsi minuscules est autorisée.
Adnan
@Adnan: Nice! Je n'ai pas pensé à compresser car la chaîne était déjà si petite.
Emigna
6

JavaScript (ES6), 88 octets

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

Prend 8 paramètres et renvoie un tableau comme résultat. S'attend aà être l'un de Nou Set de même eà l'un de Wou E. Calculs:

  • fdoit être soustrait de 179 si l'un gou l' autre ou hest différent de zéro mais 180 si les deux get hsont nuls (car il n'y a pas d'emprunt), !(g|h)est donc ajouté au 179.
  • gdoit être nul si les deux get hsont nuls, ainsi g|h&&, sinon il doit être soustrait de 59 si hest différent de zéro mais 60 si hest nul (car il n'y a pas d'emprunt), !hest donc ajouté au 59.
  • h doit être nul s'il était déjà nul, sinon il est simplement soustrait de 60.

Une autre façon de voir est d'avis que la soustraction en binaire est obtenue en ajoutant le complément à 1 , plus un 1. supplémentaire traduit à ce problème, nous prenons 179-f, 59-get 59-het ajouter 1. 59-h+ 1 est 60-h, mais si cela est 60 alors il porte , le résultat souhaité est donc zéro s'il hétait à l'origine zéro. Nous ajoutons 1 à 59-gs'il y a un report h, c'est-à-dire si hétait à l'origine zéro. Encore une fois, nous devons autoriser un report, qui se produit cette fois si les deux get hsont nuls, et nous ajoutons 1 à 179-fdans ce cas.

Neil
la source
6

MATL , 51 octets

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

Format d'entrée:

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

Format de sortie:

S
50 26 23
E
175  41  31

Essayez-le en ligne!

Explication

'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
la source
Il y a une faute de frappe dans votre explication sur la seconde dernière ligne: bnase.
TheBikingViking
1
@TheBikingViking Merci! Corrigé
Luis Mendo
4

Raquette, 199 octets

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

C'est horriblement long. Il y a probablement des choses que je pourrais faire pour le raccourcir davantage, mais je frissonne complètement.

Prend une conspaire de deux lists: un pour la latitude et un pour la longitude. Chaque liste a la direction (sous forme de symbole de raquette en minuscules) comme premier élément et suit les degrés, les minutes d'arc et les secondes d'arc. Sorties au même format

Racket interprétera cette paire de deux listes comme une seule liste avec une autre liste comme premier élément. C'est parfaitement bien, car vous pouvez toujours accéder à la latitude et à la longitude comme s'il s'agissait de deux listes dans une paire.

Usage:

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

Ce qui peut être interprété par le futur code comme '((n 43 9 9) (w 179 59 55))deux listes.

Steven H.
la source
4

Pyth, 41 45 43 35 octets

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

Utilise la conversion en base 60 pour transformer les degrés et les minutes en secondes.

Format d'E / S:

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

Il imprime une ligne chaque fois que vous entrez une ligne, donc pour avoir un format esthétique , vous pouvez utiliser l'interface CLI et diriger l'entrée, ou plus commodément, utiliser l'implémentation Pyth en ligne .

En pseudocode:

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
la source
@LuisMendo même que la vôtre, mais des listes séparées par des virgules et sans guillemets
busukxuan
4

Python 2, 140 122 octets

Mis à jour:

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

Cela utilise une approche légèrement différente: définir les valeurs à soustraire de la longitude en fonction des minutes et des secondes. S'il y a 0 minute et seconde, il soustrait 180 des degrés, et s'il y a> 0 minute et seconde, il soustrait 179, 59 et 60 respectivement du d, m, s.

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

Prend l'entrée comme une liste f(['N', 0, 0, 0, 'E', 0, 0, 0]):, convertit la longitude en degrés décimaux, soustrait de 180, puis reconvertit en degrés, minutes, secondes et reconstruit la liste, inversant les directions dans le processus.

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

Essayez-le

atlasologue
la source
3

JavaScript, 138 137 129 124 112 110

Amélioration de 2 octets inspirée du code 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)]);
  • entrée = sortie = tableau contenant 2x (1 caractère majuscule et 3 int)
  • testé dans Firefox

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

tests

<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
la source
ah je vois juste que @Neil a eu la même idée, mais un paramétrage plus court
Titus
2

Python 3, 131 130 octets

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"

Formats: les angles sont des tuples de la forme (deg,min,sec), les directions sont de la forme N. Génère un quadruple de 2 angles, chacun suivi de sa direction.

Version non golfée:

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
la source
1
Vous pouvez le réduire à 120 octets en faisant 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"]Cela fonctionne en utilisant le fait que Trueet Falsepeut être interprété comme 1et 0, et a if b else cest donc équivalent à [c, a][b]. En passant, je pense que votre code d'origine a une faute de frappe; devrait x=="W"être z=="W"?
TheBikingViking
2

C #, 310 269 ​​octets

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'entrée est une chaîne. Vous pouvez l'essayer sur .NetFiddle .

Code

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 je ne prends pas stringcomme entrée mais a char, float[], char, float[], je peux faire:

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

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

Code

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

Je peux également supprimer le 3600et utiliser à la place pour passer à 164 caractères et 166 octets. Dois-je l'utiliser?


C #, 150 octets

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

Code

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

Une manière plus .NET! Je délègue toute la logique du .NET struct TimeSpanet je ab utiliser la chaîne mise en forme logique. L'entrée est char, int, int, int, char, int, int, int. Je partage celui-ci pour donner quelques idées. Peut-être que quelqu'un s'améliorera mieux que moi.

aloisdg dit Réintégrer Monica
la source
C'est malheureusement verbeux.
Steven H.
@Fawful je poste une autre version avec des arguments différents. Moins verbeux, non? Je ne peux toujours pas me débarrasser de string.Join()...
Aloisdg dit Reinstate Monica
Notez que c'est C # 6.0
Yytsi
@TuukkaX puisque c'est la dernière version de C #, je ne l'ai pas spécifiée. Je le ferai si j'utilise une fonctionnalité de libération comme la fonctionnalité C # 7.
aloisdg dit Réintégrer Monica le
1
Eh bien, je ne suis pas voir un return, je devais ajouter moi - même ... En utilisant votre test a('N', new float[] { 50, 26, 23 }, 'W', new float[] { 4, 18, 29 })je reçois S 50 26 23 E 175.6919 41.51642 30.98511- envisageriez - vous ce un laissez - passer?
onedaywhen
0

Java, 199 177 ou 151 ou 134 octets

Solution de 177 octets qui imprime le résultat

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

Solution de 151 octets qui renvoie le résultat sous forme de tableau

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 octets si nous avons utilisé la notation 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
la source
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);}

Nécessite 8 arguments de programme, sinon il échouera. Passez des arguments comme N 50 26 23 W 4 18 29. Indicateurs de direction N, S, E, W, doivent être capitalisés.

owacoder
la source
0

PostGIS, 123 octets

L'outil pour le travail est décevant et verbeux, en partie à cause de la verbosité SQL et en partie à cause de la nécessité de passer à la géométrie et inversement:

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

D'un autre côté, cette fonction unique transformera des points, des collections de points ou des formes plus complexes (comme l'ensemble du littoral australien et néo-zélandais).

Toby Speight
la source
0

PHP, 148 octets

même approche que ma réponse JavaScript , regardez là pour une ventilation

  • +16 fonction de surcharge
  • +17 pour les $signes
  • +12 pour les parenthèses (priorité des opérateurs différents)
  • +4 foreachcar PHP array_mapa un énorme surcoût
  • +1 pour (60-$v)%60car $v&&60-$vtransforme en booléen en PHP
  • -8 en travaillant sur l'original
  • -4 en utilisant chr, ordet quelques arithmétiques sur le changement de direction

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 fonction fonctionne sur l'original
  • format: tableau avec 2x (1 caractère majuscule, 3 int)

tests

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ées abandonnées

  • pas d'approche en boucle avec des fanions: +5
  • boucle en arrière avec des drapeaux de transport: +7
  • Je pourrais transformer cela en un programme pour PHP <5.4, mais tant pis: -3
Titus
la source
0

Befunge, 122 114 111 octets (110 caractères)

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

Format d'entrée:

N 50 26 23W 4 18 29

Notez que la direction de la longitude et les secondes d'arc doivent être regroupées

Vous pouvez tester le code ici

Maliafo
la source