Gali ke Australia - antipode

24

Latar Belakang

Tak terhitung generasi anak yang bertanya-tanya di mana mereka akan berakhir jika mereka menggali lubang langsung ke bawah. Ternyata ini, secara mengejutkan, akan agak berbahaya , tapi bagaimanapun ...

Antipoda adalah titik yang saling berhadapan secara langsung di permukaan bumi. Ini berarti bahwa jika sebuah garis ditarik di antara kedua titik, itu akan melewati pusat Bumi.

Tantangan

Tulis program atau fungsi yang, diberi titik, menemukan antipode-nya.

Dalam tantangan ini, titik direpresentasikan menggunakan sistem garis lintang-bujur dan derajat, menit busur dan detik busur. Untuk menemukan antipode, tukar arah setiap ordinat ( N <-> Sdan W <-> E) dan kurangi garis bujur dari 180derajat.

Contoh:
Ambil intinya N 50 26 23 W 4 18 29. Tukar arah untuk memberi S 50 26 23 E 4 18 29. Kurangi garis bujur dari 180 0 0memberi 175 41 31, biarkan koordinat antipode sebagai S 50 26 23 E 175 41 31.

Aturan

Memasukkan

Seperangkat koordinat garis lintang-bujur, dalam format apa pun yang masuk akal , di mana setiap ordinat berisi arah, sejumlah derajat, sejumlah menit busur, dan sejumlah detik busur.

Keluaran

Koordinat garis lintang-bujur dari antipode, dalam format apa pun yang masuk akal , di mana setiap ordinat berisi arah, sejumlah derajat, sejumlah menit busur, dan sejumlah detik busur.

Berarti masuk akal berarti bahwa setiap bagian dari koordinat dapat dibedakan secara jelas.

Spesifikasi

  • Arah untuk garis lintang ordinasi adalah Natau S, dan garis bujur adalah Watau E.
  • Semua nilai koordinat adalah bilangan bulat. Nilai derajat akan berada di antara 0dan 90untuk lintang, dan antara 0dan 180untuk bujur. Nilai arc menit dan arc kedua untuk kedua ordinat akan berada di antara 0dan 59.
  • Jika semua nilai untuk suatu ordinat adalah 0, kedua arah dapat diterima.
  • Tidak perlu mem-pad nilai apa pun.
  • Tidak ada garis lintang yang akan lebih besar dari 90derajat, dan tidak ada garis bujur yang lebih besar dari 180derajat.
  • Celah standar berlaku.

Uji kasus

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

Tautan yang bermanfaat

Ini , jadi jawaban tersingkat dalam byte menang!

TheBikingViking
sumber
Apakah ini format yang masuk akal? Empat input: array 3 angka, char, array tiga angka; dipisahkan oleh baris baru
Luis Mendo
@LuisMendo Kecuali saya salah paham, saya hanya bisa melihat tiga input; Saya menganggap Anda ingin char ekstra? Saya akan mengatakan bahwa itu adalah format yang masuk akal. Secara masuk akal, saya pada dasarnya berarti bahwa setiap bagian dari koordinat dapat dibedakan secara jelas.
TheBikingViking
Ya, saya lupa char pertama. Terima kasih!
Luis Mendo
3
"Agak berbahaya"? Mate, bahaya sebenarnya adalah begitu Anda tiba di sini .
Andrew Grimm
1
@busukxuan Permintaan maaf karena tidak merespons lebih cepat. Saya akan mengatakan bahwa kedua format tersebut tidak masuk akal, karena spec membutuhkan N, S, E, atau Wsebagai arah, sedangkan berlebihan 0memperkenalkan ambiguitas untuk yang nilai merupakan yang komponen ordinat.
TheBikingViking

Jawaban:

1

05AB1E, 37 34 byte

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

Dijelaskan

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

Cobalah online

Sunting: Disimpan 3 byte berkat Adnan .

Emigna
sumber
Anda dapat memampatkan "NEWS"ke ‘€Ã‘atau bahkan '€Ãjika huruf kecil diperbolehkan.
Adnan
@ Adnan: Bagus! Tidak berpikir untuk mengompres karena senarnya sudah sangat kecil.
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]

Mengambil 8 parameter dan mengembalikan array sebagai hasilnya. Diharapkan amenjadi salah satu dari Ndan Sdan juga emenjadi salah satu dari Watau E. Perhitungan:

  • fperlu dikurangi dari 179 jika salah satu gatau htidak nol tetapi 180 jika keduanya gdan hnol (karena tidak ada pinjaman), dengan demikian !(g|h)ditambahkan ke 179.
  • gharus nol jika keduanya gdan hnol, dengan demikian g|h&&, jika tidak maka harus dikurangi dari 59 jika hbukan nol tetapi 60 jika hnol (karena tidak ada pinjaman), dengan demikian !hditambahkan ke 59.
  • h harus nol jika sudah nol, jika tidak hanya dikurangi dari 60.

Cara lain untuk melihat ini adalah untuk melihat bahwa mengurangkan dalam biner dicapai dengan menambahkan pelengkap 1s plus tambahan 1. Diterjemahkan untuk masalah ini, kita mengambil 179-f, 59-gdan 59-hdan menambahkan 1. 59-h+ 1 adalah 60-h, tetapi jika ini adalah 60 maka membawa , jadi hasil yang diinginkan adalah nol jika hawalnya nol. Kami menambahkan 1 59-gjika ada carry dari h, yaitu jika hawalnya nol. Sekali lagi kita harus memungkinkan untuk membawa, yang kali ini terjadi jika keduanya gdan hnol, dan kami menambahkan 1 179-fdalam hal ini.

Neil
sumber
6

MATL , 51 byte

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

Masukkan format:

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

Format output:

S
50 26 23
E
175  41  31

Cobalah online!

Penjelasan

'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
sumber
Ada kesalahan ketik dalam penjelasan Anda pada kedua baris terakhir: bnase.
TheBikingViking
1
@TheBikingViking Terima kasih! Diperbaiki
Luis Mendo
4

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

Itu sangat panjang. Mungkin ada beberapa hal yang bisa saya lakukan untuk mempersingkat lebih jauh, tetapi saya merasa gemetar .

Mengambil conssepasang dua lists: satu untuk garis lintang dan satu untuk garis bujur. Setiap daftar memiliki arah (sebagai simbol Racket huruf kecil) sebagai item pertama dan mengikutinya derajat, menit busur, dan detik busur. Output dalam format yang sama

Racket akan mengartikan pasangan dari dua daftar ini sebagai satu daftar dengan daftar lainnya sebagai elemen pertama. Ini sangat baik, karena Anda masih dapat mengakses lintang dan bujur seolah-olah mereka adalah dua daftar berpasangan.

Pemakaian:

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

Yang dapat ditafsirkan dengan kode masa depan sebagai '((n 43 9 9) (w 179 59 55)), dua daftar.

Steven H.
sumber
4

Pyth, 41 45 43 35 byte

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

Menggunakan konversi basis-60 untuk mengubah derajat dan menit menjadi detik.

Format I / O:

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

Ini mencetak garis setiap kali Anda memasukkan garis, sehingga untuk memiliki format yang terlihat bagus, Anda dapat menggunakan CLI dan menyalurkan input, atau lebih mudah, menggunakan implementasi Pyth online .

Dalam 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
sumber
@LuisMendo sama seperti milik Anda, tetapi daftar yang dipisahkan koma, dan tanpa tanda kutip
busukxuan
4

Python 2, 140 122 byte

Diperbarui:

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

Ini menggunakan pendekatan yang sedikit berbeda: mengatur nilai untuk mengurangi dari garis bujur berdasarkan menit dan detik. Jika ada 0 menit dan detik, itu mengurangi 180 dari derajat, dan jika ada> 0 menit dan detik, itu mengurangi 179, 59, dan 60 dari masing-masing d, m, s.

Asli:

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

Mengambil input sebagai daftar: f(['N', 0, 0, 0, 'E', 0, 0, 0]) :, mengonversi garis bujur menjadi derajat desimal, mengurangi dari 180, lalu mengonversi kembali ke derajat, menit, detik dan membangun kembali daftar, membalik arah dalam proses.

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

Cobalah

ahli atlasologi
sumber
3

JavaScript, 138 137 129 124 112 110

Peningkatan 2 byte terinspirasi oleh kode @ 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 yang mengandung 2x (1 karakter huruf besar dan 3 int)
  • diuji di 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
);

tes

<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
sumber
ah saya hanya melihat @Neil punya ide yang sama, tetapi beberapa parametrizing lebih pendek
Titus
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"

Format: sudut adalah tupel bentuk (deg,min,sec), arah adalah bentuk N. Menghasilkan empat kali lipat dari 2 sudut, masing-masing diikuti oleh arahnya.

Versi tidak disatukan:

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
sumber
1
Anda bisa mendapatkan ini hingga 120 byte dengan melakukan 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"]ini bekerja dengan menggunakan fakta bahwa Truedan Falsedapat diartikan sebagai 1dan 0, dan karenanya a if b else csetara dengan [c, a][b]. Di samping catatan, saya pikir kode asli Anda memiliki kesalahan ketik; harus x=="W"menjadi 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;}

Inputnya adalah satu string. Anda dapat mencobanya di .NetFiddle .

Kode

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

Jika saya tidak mengambil stringinput sebagai tetapi char, float[], char, float[], saya dapat melakukan:

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

Kode

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

Saya juga dapat menghapus 3600dan menggunakan sebagai gantinya untuk pindah ke 164 karakter dan 166 byte. Haruskah saya menggunakannya?


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

Kode

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

Cara yang lebih .NET! Saya mendelegasikan semua logika ke .NET struct TimeSpandan saya ab menggunakan string yang memformat logika. Masukan adalah char, int, int, int, char, int, int, int. Saya membagikan yang ini untuk memberikan beberapa ide. Mungkin seseorang akan meningkat dengan cara yang lebih baik daripada saya.

aloisdg kata Reinstate Monica
sumber
Sayangnya itu bertele-tele.
Steven H.
@Fawful Saya memposting versi lain dengan argumen yang berbeda. Lebih sedikit verbose bukan? Saya masih tidak bisa menyingkirkan string.Join()...
aloisdg berkata Reinstate Monica
Perhatikan bahwa ini adalah C # 6.0
Yytsi
@ TuukkaX karena ini adalah versi terbaru dari C #, saya tidak menentukannya. Saya akan melakukannya jika saya menggunakan beberapa fitur un release seperti fitur C # 7.
aloisdg mengatakan Reinstate Monica
1
Nah, saya tidak melihat sebuah return, aku harus menambahkan sendiri ... Menggunakan tes a('N', new float[] { 50, 26, 23 }, 'W', new float[] { 4, 18, 29 })saya mendapatkan S 50 26 23 E 175.6919 41.51642 30.98511- akan Anda menganggap ini lulus?
Jumat
0

Java, 199 177 atau 151 atau 134 Bytes

177 Bytes solusi yang mencetak hasil

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 Bytes solusi yang mengembalikan hasil sebagai array

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 jika kita menggunakan notasi 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};}
pengguna902383
sumber
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);}

Membutuhkan 8 argumen program, akan gagal jika tidak. Lewati argumen seperti N 50 26 23 W 4 18 29. Indikator arah N, S, E, W, harus dikapitalisasi.

owacoder
sumber
0

PostGIS, 123 byte

Tool-For-The-Job sangat mengecewakan, sebagian karena SQL wordiness dan sebagian lagi karena kebutuhan untuk menggunakan geometri dan kembali:

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

Di sisi lain, fungsi tunggal ini akan mengubah titik, kumpulan titik, atau bentuk yang lebih kompleks (seperti seluruh garis pantai Australia dan Selandia Baru).

Toby Speight
sumber
0

PHP, 148 byte

pendekatan yang sama seperti jawaban JavaScript saya , lihat di sana untuk rincian

  • +16 fungsi overhead
  • +17 untuk $tanda - tanda
  • +12 untuk paranthes (prioritas operator berbeda)
  • +4 untuk foreachkarena PHP array_mapmemiliki overhead yang besar
  • +1 untuk (60-$v)%60karena $v&&60-$vdilemparkan ke boolean di PHP
  • -8 dengan mengerjakan yang asli
  • -4 dengan menggunakan chr, orddan beberapa aritmatika pada swap arah

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));}
  • berfungsi bekerja pada aslinya
  • format: array dengan 2x (1 karakter huruf besar, 3 int)

tes

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

ide-ide terlantar

  • tidak ada pendekatan loop dengan flag carry: +5
  • loop mundur dengan membawa bendera: +7
  • Saya bisa mengubahnya menjadi program untuk PHP <5.4, tetapi tidak apa-apa: -3
Titus
sumber
0

Befunge, 122 114 111 Bytes (110 karakter)

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

Masukkan format:

N 50 26 23W 4 18 29

Perhatikan bahwa arah bujur dan busur detik harus saling berhimpit

Anda dapat menguji kode di sini

Maliafo
sumber