Dig to Australia - antipodes
MATL, 51 bytes
'NS'tPXEii'WE'tPXE648e3i60:qXJZA-JYAtn3-?2:&)wJZAwh
Input format:
'N'
[50 26 23]
'W'
[4 18 29]
Output format:
S
50 26 23
E
175 41 31
Try it online!
Explanation
'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
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]
Takes 8 parameters and returns an array as the result. Expects a
to be one of N
or S
and similarly e
to be one of W
or E
. Calculations:
f
needs to be subtracted from 179 if eitherg
orh
is nonzero but 180 if bothg
andh
are zero (because there is no borrow), thus!(g|h)
is added to the 179.g
needs to be zero if bothg
andh
are zero, thusg|h&&
, otherwise it needs to be subtracted from 59 ifh
is nonzero but 60 ifh
is zero (because there is no borrow), thus!h
is added to the 59.h
needs to be zero if it was already zero, otherwise it is simply subtracted from 60.
Another way to look at this is to notice that subtracting in binary is achieved by adding the 1s complement plus an additional 1. Translated to this problem, we take 179-f
, 59-g
and 59-h
and add 1. 59-h
+ 1 is 60-h
, but if this is 60 then it carries, so the desired result is zero if h
was originally zero. We add 1 to 59-g
if there's a carry from h
, i.e. if h
was originally zero. Again we have to allow for a carry, which this time happens if both g
and h
are zero, and we add 1 to 179-f
in this case.
Racket, 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)))))
That's horribly long. There's probably some things I could do to shorten it further, but shudders I'm completely done.
Takes a cons
pair of two lists
: one for the latitude and one for the longitude. Each list has the direction (as a lowercase Racket symbol) as its first item and following it the degrees, arc-minutes, and arc-seconds. Outputs in the same format
Racket will interpret this pair of two lists as a single list with another list as its first element. This is perfectly fine, since you can still access both latitude and longitude as if they were two lists in a pair.
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)
Which can be interpreted by future code as '((n 43 9 9) (w 179 59 55))
, two lists.