Копай в Австралию - антиподы

24

Задний план

Бесчисленные поколения детей задавались вопросом, где бы они оказались, если бы вырыли яму прямо вниз. Оказывается, это, что неудивительно, было бы довольно опасно , но в любом случае ...

Антиподы - это точки, которые прямо противоположны друг другу на поверхности Земли. Это означает, что если бы была проведена линия между двумя точками, она прошла бы через центр Земли.

Вызов

Напишите программу или функцию, которая, учитывая точку, находит свой антипод.

В этом испытании точки представлены с использованием системы долгота-широта и градусов, минут дуги и секунд дуги. Чтобы найти антипод, поменяйте местами направления каждой ординаты ( N <-> Sи W <-> E) и вычтите долготу из 180градусов.

Пример:
взять точку N 50 26 23 W 4 18 29. Поменяйте местами, чтобы дать S 50 26 23 E 4 18 29. Вычтите координату долготы, 180 0 0чтобы дать 175 41 31, оставляя координаты антипода как S 50 26 23 E 175 41 31.

правила

вход

Набор координат широты и долготы в любом приемлемом формате , где каждая ордината содержит направление, количество градусов, количество минут дуги и количество секунд дуги.

Выход

Широта-долгота координат антипода в любом приемлемом формате , где каждая ордината содержит направление, количество градусов, количество минут дуги и количество секунд дуги.

Разумно предположить, что каждая часть координаты может быть однозначно различена.

Спекуляции

  • Направление для ординаты широты - Nили S, а для ординаты долготы - Wили E.
  • Все значения координат являются целыми числами. Значение градуса будет между 0и 90для широты, а также между 0и 180для долготы. Значения минуты дуги и секунды дуги для обеих ординат будут между 0и 59.
  • Если все значения для ординаты равны 0, любое направление приемлемо.
  • Нет необходимости дополнять нулями любые значения.
  • Ни одна ордината широты никогда не будет больше 90градусов, и никакая ордината долготы никогда не будет больше 180градусов.
  • Применяются стандартные лазейки .

Контрольные примеры

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

Полезные ссылки

Это , поэтому выигрывает самый короткий ответ в байтах!

TheBikingViking
источник
Это разумный формат? Четыре входа: массив из 3 чисел, символ, массив из трех чисел; разделены переводами строки
Луис Мендо
@ LuisMendo Если я не понимаю вас, я вижу только три входа; Я полагаю, вы хотите дополнительный символ? Я бы сказал, что это разумный формат. Под разумным я имею в виду, что каждая часть координаты может быть однозначно различена.
TheBikingViking
Да, я забыл первый символ. Благодарность!
Луис Мендо
3
«Довольно опасно»? Дружище, настоящая опасность в том, что ты попал сюда .
Эндрю Гримм
1
@busukxuan Извиняюсь, что не ответил раньше. Я бы сказал , что оба из этих форматов не являются разумными, поскольку спецификация требует N, S, Eили Wв направлении, в то время как избыточные 0вводит неоднозначность относительно того , какое значение представляет , какой компонент ординат.
TheBikingViking

Ответы:

1

05AB1E, 37 34 байта

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

Разъяснения

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

Попробуйте онлайн

Редактировать: 3 байта сохранены благодаря Аднану .

Emigna
источник
Вы можете сжать "NEWS"до ‘€Ã‘или даже '€Ãесли разрешены строчные буквы.
Аднан
@Adnan: Хорошо! Не думал о сжатии, так как строка уже была такой маленькой.
Эминья
6

JavaScript (ES6), 88 байт

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

Принимает 8 параметров и возвращает массив в качестве результата. Ожидается, aчто он будет одним из Nили Sаналогичным образом eбудет одним из Wили E. Расчеты:

  • fДолжен быть вычтен из 179, если один gили hненулевой, но 180, если оба gи hравны нулю (потому что нет заимствования), таким образом !(g|h), добавляется к 179.
  • gдолжен быть равен нулю, если оба gи hравны нулю, таким образом g|h&&, в противном случае его нужно вычесть из 59, если он hравен нулю, но 60, если он hравен нулю (потому что нет заимствования), таким образом !h, добавляется к 59.
  • h должен быть равен нулю, если он уже был равен нулю, в противном случае он просто вычитается из 60.

Другой способ смотреть на это заметить , что вычитание в двоичной системе достигается за счет добавления 1s дополнение плюс дополнительный 1. Перевод этой проблемы, мы принимаем 179-f, 59-gи 59-hи добавить 1 59-h+ 1 60-h, но если это 60 , то он несет Таким образом, желаемый результат равен нулю, если hизначально был равен нулю. Мы добавляем 1 к 59-gесли есть перенос из h, т.е. если hизначально был ноль. Опять же, мы должны разрешить перенос, который на этот раз происходит, если оба gи hравны нулю, и мы добавляем 1 179-fв этом случае.

Нил
источник
6

MATL , 51 байт

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

Формат ввода:

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

Выходной формат:

S
50 26 23
E
175  41  31

Попробуйте онлайн!

объяснение

'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
Луис Мендо
источник
Там опечатка в вашем объяснении на второй до последней строки: bnase.
TheBikingViking
1
@TheBikingViking Спасибо! Исправлено
Луис Мендо
4

Ракетка, 199 байт

(λ(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 пару из двух lists: один для широты и один для долготы. Каждый список имеет направление (в виде строчного символа ракетки) в качестве первого элемента и после него градусы, минуты дуги и секунды дуги. Выходы в том же формате

Racket будет интерпретировать эту пару из двух списков как один список с другим списком в качестве первого элемента. Это прекрасно, так как вы все равно можете получить доступ к широте и долготе, как если бы они были двумя списками в паре.

Использование:

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

Что может быть интерпретировано будущим кодом как '((n 43 9 9) (w 179 59 55))два списка.

Стивен Х.
источник
4

Pyth, 41 45 43 35 байт

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

Использует преобразование base-60 для поворота градусов и минут в секунды.

Формат ввода / вывода:

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

Он печатает строку каждый раз, когда вы вводите строку, поэтому, чтобы иметь красивый формат, вы можете либо использовать CLI и передать ввод, либо, что более удобно, использовать онлайн-реализацию Pyth .

В псевдокоде:

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
источник
@LuisMendo такой же, как у вас, но списки разделены запятыми, и без кавычек
busukxuan
4

Python 2, 140 122 байта

Обновлено:

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

При этом используется немного другой подход: установка значений для вычитания из долготы на основе минут и секунд. Если есть 0 минут и секунд, он вычитает 180 из градусов, а если есть> 0 минут и секунд, он вычитает 179, 59 и 60 из d, m, s соответственно.

Оригинал:

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

Принимает ввод в виде списка:, f(['N', 0, 0, 0, 'E', 0, 0, 0])преобразует долготу в десятичные градусы, вычитает из 180, затем преобразует обратно в градусы, минуты, секунды и восстанавливает список, переворачивая направления в процессе.

Un-golfed:

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

Попытайся

atlasologist
источник
3

JavaScript, 138 137 129 124 112 110

Улучшение 2 байта, вдохновленное кодом @ 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 = массив, содержащий 2x (1 заглавный символ и 3 int)
  • протестировано в 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
);

тесты

<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
источник
ах, я просто вижу, что у @Neil была та же идея, но более короткая параметризация
Тит
2

Python 3, 131 130 байт

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"

Форматы: углы - это кортежи формы (deg,min,sec), направления - формы N. Выводит четверку из 2 углов, за которыми следует направление.

Безголовая версия:

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
источник
1
Вы можете уменьшить это до 120 байтов, выполнив 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"]Это работает, используя тот факт, что Trueи Falseможет интерпретироваться как 1и 0, и, следовательно a if b else c, эквивалентно [c, a][b]. Кстати, я думаю, что ваш оригинальный код содержит опечатку; должно x=="W"быть z=="W"?
TheBikingViking
2

C #, 310 269 ​​байт

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

Ввод одной строки. Вы можете попробовать это на .NetFiddle .

Код

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

Если я не принимаю в stringкачестве входных данных, но char, float[], char, float[]я могу сделать:

C #, 167 166 165 163 152 148 147 139 байт

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

Код

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

Также я могу удалить 3600и использовать вместо этого для перемещения до 164 символов и 166 байтов. Должен ли я использовать это?


C #, 150 байт

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

Код

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

Более. NET способ! Я делегировать всю логику в .NET , struct TimeSpanи я абы использовать строку логики форматирования. Вход есть char, int, int, int, char, int, int, int. Я делюсь этим, чтобы дать некоторые идеи. Может быть, кто-то улучшится лучше, чем я.

Aloisdg говорит восстановить Монику
источник
Это, к сожалению, многословно.
Стивен Х.
@Fawful Я публикую другую версию с другими аргументами. Меньше многословного нет? Я до сих пор не могу избавиться от string.Join()...
говорит aloisdg Восстановить Монику
Обратите внимание, что это C # 6.0
Yytsi
@TuukkaX, так как это последняя версия C #, я не указал ее. Я буду, если я использую некоторую функцию un-release, такую ​​как функция C # 7.
говорит aloisdg Восстановить Монику
1
Ну, я не вижуreturn , я должен был добавить это сам ... С помощью тест a('N', new float[] { 50, 26, 23 }, 'W', new float[] { 4, 18, 29 })я получаю S 50 26 23 E 175.6919 41.51642 30.98511- Вы бы это пропуск?
понедельник,
0

Java, 199 177 или 151 или 134 байта

177 байтов решение, которое печатает результат

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

151 байтовое решение, которое возвращает результат в виде массива

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 байта, если мы использовали лямбда-нотацию

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
источник
0

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

Требуется 8 аргументов программы, в противном случае произойдет сбой. Передавайте аргументы как N 50 26 23 W 4 18 29. Указатели поворота N, S, E, W, должны быть капитализированы.

owacoder
источник
0

PostGIS, 123 байта

Tool-For-The-Job разочаровывающе многословен, отчасти из-за многословности SQL, а отчасти из-за необходимости приведения к геометрии и обратно:

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

С другой стороны, эта единственная функция преобразует точки, наборы точек или более сложные формы (такие как вся береговая линия Австралии и Новой Зеландии).

Тоби Спейт
источник
0

PHP, 148 байт

тот же подход, что и мой ответ JavaScript , посмотрите на разбивку

  • +16 функция над головой
  • +17 к $знакам
  • +12 для парантезов (другой приоритет оператора)
  • +4, foreachпотому что PHP array_mapимеет огромные накладные расходы
  • +1, (60-$v)%60потому что $v&&60-$vприводит к булеву в PHP
  • -8 работая над оригиналом
  • -4 с помощью chr, ordи некоторая арифметика на смену направления

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));}
  • функция работает на оригинал
  • формат: массив с 2x (1 заглавная буква, 3 int)

тесты

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

заброшенные идеи

  • Подход без петли с флагами переноса: +5
  • цикл назад с флагами переноса: +7
  • Я мог бы превратить это в программу для PHP <5.4, но не бери в голову: -3
Titus
источник
0

Befunge, 122 114 111 Bytes (110 символов)

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

Формат ввода:

N 50 26 23W 4 18 29

Обратите внимание, что направление долготы и секунды дуги должны быть объединены

Вы можете проверить код здесь

Maliafo
источник