Konversikan derajat ke salah satu dari 32 titik kompas

13

Kompas 32 poin itu ... menarik, untuk sedikitnya.

gambar

Oleh Denelson83 (Pekerjaan sendiri) [ GFDL atau CC-BY-SA-3.0 ], melalui Wikimedia Commons

Tantangan Anda adalah mengambil tingkat gelar, dan mengubahnya menjadi arah pada kompas 32 poin.

Setiap arah adalah 11,25 (360/32) derajat lebih jauh dari sebelumnya. Misalnya, N (utara) adalah 0 derajat, NbE (utara oleh timur) adalah 11,25 derajat, NNE (utara-timur laut) adalah 22,5 derajat, dll.

Adapun bagaimana Anda seharusnya mendapatkan arahan,

  • 0 derajat adalah N, 90 derajat adalah E, 180 derajat adalah S, dan 270 derajat adalah W.

    • Ini disebut arah mata angin.
  • Titik setengah antara arah mata angin hanyalah arah mata angin mereka di antara disatukan. N atau S selalu menjadi yang pertama, dan W atau E selalu menjadi yang kedua.

    • Ini disebut arahan ordinal.
  • Titik tengah antara arah kardinal dan ordinal adalah arah mereka berada di antara disatukan, lagi, dengan "-" di antaranya. Arahan kardinal pergi dulu, ordinal kedua.

    • Ini disebut arahan sekunder-interardinal.
  • Titik setengah antara arah sekunder-interardinal dan arah lainnya adalah arah lain "oleh" arah kardinal yang paling dekat dengan mereka (selain yang langsung di sebelahnya).

    • Saya tidak tahu apa namanya: P

Jika semua penjelasan ini menyakiti otak Anda seperti halnya otak saya, Anda dapat merujuk pada bagan ini:

1   North               N
2   North by east       NbE
3   North-northeast     NNE
4   Northeast by north  NEbN
5   Northeast           NE
6   Northeast by east   NEbE
7   East-northeast      ENE
8   East by north       EbN
9   East                E
10  East by south       EbS
11  East-southeast      ESE
12  Southeast by east   SEbE
13  Southeast           SE
14  Southeast by south  SEbS
15  South-southeast     SSE
16  South by east       SbE
17  South               S
18  South by west       SbW
19  South-southwest     SSW
20  Southwest by south  SWbS
21  Southwest           SW
22  Southwest by west   SWbW
23  West-southwest      WSW
24  West by south       WbS
25  West                W
26  West by north       WbN
27  West-northwest      WNW
28  Northwest by west   NWbW
29  Northwest           NW
30  Northwest by north  NWbN
31  North-northwest     NNW
32  North by west       NbW

Berikut adalah bagan yang lebih terperinci dan mungkin penjelasan yang lebih baik tentang titik-titik kompas.

Tantangan Anda adalah mengambil input dalam derajat, dan menampilkan nama lengkap dari arah kompas yang sesuai dengannya, beserta singkatannya.

Kasus uji:

Input  Output
0      North N
23.97  North-northeast NNE
33.7   Northeast by north NEbN
73.12  East-northeast ENE
73.13  East by north EbN
219    Southwest by south SWbS
275    West W
276    West by north WbN
287    West-northwest WNW

Semua huruf besar harus dipertahankan, seperti dalam kasus uji. Jumlah maksimum tempat desimal adalah 2. Semua angka input akan lebih besar dari atau sama dengan 0, dan kurang dari 360. Jika ada titik desimal, akan ada digit di kedua sisi (Anda tidak harus menangani .1atau 1.).

Ini adalah , jadi kode terpendek dalam byte menang.

Gagang pintu
sumber
@WallyWest Hmm, yang ini memungkinkan array, memiliki kapitalisasi yang berbeda, dan tidak memiliki "antara," tapi saya tidak melihat itu (mungkin karena ... judul yang menarik: P). Saya akan melihat apa yang dapat saya lakukan untuk membuatnya cukup berbeda ...
Gagang Pintu
3
@WallyWest Di sana, sekarang Anda harus menampilkan singkatan juga. Seiring dengan semua perbedaan lainnya, itu sudah cukup untuk membuatnya menjadi non-dup. (oh, juga yang ini juga memiliki garis
putus
@WallyWest Tidak ada jawaban dalam "R" untuk pertanyaan Anda sebelumnya (bahkan tidak ada dalam "C"!) Saya harap kita akan melihat beberapa kali ini, teman sekapal!
Level River St
Akan lebih menyenangkan jika ada input dari -360 ke 360 ​​derajat (negatif berarti berlawanan arah jarum jam) dan bonus !.
Mukul Kumar
Bagi orang yang tidak mencari tantangan, solusi mudahnya adalah menemukan kemungkinan keluaran yang jaraknya minimal dari sudut input, menggunakan sudut tabel pencarian <-> nama.
Rivenfall

Jawaban:

4

Perl, 250 236 231 188 187

Sunting: Beberapa byte dari mengeksploitasi simetri (seperti yang saya lihat di solusi @bazzargh)

+ Edit: Dan beberapa trik jahat ...

+ Edit : Kembali ke tempat saya memulai (bekerja dengan list, bukan string), dan mengeksploitasi lebih banyak simetri = 1 byte off dan jauh lebih jelek.

$_=((@_=(1,@_=qw(1b3 1-13 13b1 13 13b3 3-13 3b1),3,map{y/1/2/r}reverse@_)),map{y/312/421/r}@_)[int<>/11.25+.5];print ucfirst s/\w/(' by ',north,south,east,west)[$&]/ger,' ',y/1-4-/NSEW/dr

Cukup dicetak:

$_=(
    (@_=
        (
            1,
            @_=qw(1b3 1-13 13b1 13 13b3 3-13 3b1),
            3,
            map{y/1/2/r}reverse@_
        )
    ),map{y/312/421/r}@_
)[int<>/11.25+.5];

print ucfirst s/\w/(' by ',north,south,east,west)[$&]/ger,' ',y/1-4-/NSEW/dr

Diperlukan 5.014 karena rpengubah.

pengguna2846289
sumber
Anda memiliki salah ketik dalam kode Anda: sourth harus selatan (pernyataan ke-2 yang dimulai dengan s / b / oleh ...
RononDex
3 regexps pertama tersebut dapat digantikan oleh y / NS / SN /; untuk 10 karakter
bazzargh
@bazzargh, ya, dan tidak hanya itu ;-)
user2846289
6

Javascript 470 453 438 434 432 421 404

s=String;s.prototype.a=s.prototype.replace;var a=prompt()/11.25,a=a+0.5|0,b,k,c=a,d=c%8,c=c/8|0,e=["north","east","south","west"],f,g,h;f=e[c];g=e[(c+1)%4];h=f==e[0]|f==e[2]?f+g:g+f;b="1;1 by 2;1-C;C by 1;C;C by 2;2-C;2 by 1".split(";")[d].a(1,f).a(2,g).a("C",h);k=b.a(/north/g,"N").a(/east/g,"E").a(/south/g,"S").a(/west/g,"W").a(/by/g,"b").a(/[\s-]/g,"");b=b[0].toUpperCase()+b.slice(1);alert(b+" "+k)

Anda dapat menyalin kode ini ke konsol Anda dan menjalankannya. Ini meminta Anda untuk input derajat dan output hasilnyaalert();

Javascript yang tidak dikumpulkan dapat ditemukan di biola ini: http://jsfiddle.net/AezL3/11

RononDex
sumber
+1 Bagus tapi hati-hati: "Semua huruf besar harus dipertahankan, seperti dalam kasus uji."
@BenH Kasus uji mana yang gagal dalam pemeriksaan huruf besar? Terima kasih untuk ini, btw. Ini berguna untuk antarmuka web yang saya tulis.
Steven Lu
Omong-omong, ini mati untuk 355 derajat hingga 360 derajat. Cara mengatasinya mudah. Lakukan saja calcPoint(32)apa yang dilakukan 0, sehingga Anda dapat melakukan ini %32atau yang serupa.
Steven Lu
@ SevenLu butuh beberapa saat untuk mencari tahu apa yang Anda maksud, tetapi baris var name = calcPoint(input % 32);ini berhasil
Orwellophile
4

Haskell 415 372 347 330 317 304 301C

Akhirnya konvergen pada solusi seperti @ VadimR (dan simetri kembali!). Penggunaan: h 219output"Southwest by south SWbS"

d"N"="north"
d"S"="south"
d"E"="east"
d"W"="west"
d"b"=" by "
d"-"="-"
d(x:y)=d[x]++d y
e(x:y)=x:tail(d$x:y)
k 'N'='S'
k 'S'='N'
k 'E'='W'
k x=x
r="N NbE N-NE NEbN NE NEbE E-NE EbN E EbS E-SE SEbE SE SEbS S-SE SbE "
p=words$r++(map k r)
g x=p!!mod(round$x/11.25)32
h x=e(g x)++(filter(/='-')$' ':g x)

3 karakter lagi hilang, terima kasih @shiona.

bazzargh
sumber
drop 1sama dengan ekor. Juga jika saya tidak salah, Anda dapat melakukan e l@(x:_)=x:tail$d luntuk mencukur satu char lagi.
shiona
tidak percaya aku melewatkan itu. Terima kasih!
bazzargh
0

Python 3.8 , 482 438 424 byte

lambda h:' '.join([b(h),a(a(a(b(h)),1),d={' by ':'b','-':''})])
L=str.lower
c={'North':'N','East':'E','South':'S','West':'W'}
a=lambda t,l=0,d=c:[*(t:=t.replace([i,L(i)][l],d[i])for i in[*d])][-1]
b=lambda h,k=[*c]:a('W|W by x|W-z|Z by w|Z|Z by x|X-z|X by w'.split('|')[int((q:=h*4/45+.5)%8)],d={'W':(W:=[*k][(v:=int(q//8)%4)]),'X':(X:=[*k][(v+1)%4]),'w':(w:=L(W)),'x':(x:=L(X)),'Z':(Z:=[W+x,X+w][W in'EastWest']),'z':L(Z)})

Cobalah online!

Ini adalah apa yang saya dapatkan setelah bermain golf jawaban tony goodwin ; diposting pada jawabannya sendiri karena tautan TIO terlalu panjang untuk dikomentari. Jika dia memilih untuk memperbarui jawabannya di atas, saya akan menghapus jawaban ini.

Saya mengasumsikan bahwa dapat diterima untuk menyerahkan fungsi sebagai solusi daripada program lengkap. Jika tidak, berikut adalah program lengkap dengan kecepatan 426 byte.

Saya berharap masih banyak yang bisa dilakukan untuk mempersingkat b.

Sunting: Memotong 44 byte, milik walrus yang megah. Masih tidak merasa seperti bselesai bermain golf.

Sunting2: Memotong 14 lainnya dengan membongkar dicts daripada menggunakan keys()dan items().

Pasang kembali Monica
sumber
-1

Python, 2103 1647 1103 1034 924 889 848 byte

Sangat terlambat, saya tahu. Terima kasih atas tantangannya, saya menyiapkan magnetometer untuk arah angin dengan Pi saya, dan ingin solusi kompas 16 titik seperti ini untuk dimasukkan ke dalam algoritma peramalan cuaca. Semua kode saya adalah dalam Python, jadi di sini adalah versi dari solusi javascript yang sudah diposting di Python, tetapi dengan twist tambahan yang dapat Anda tentukan 32, 16, atau 8 titik kompas pada variabel j, dan saya telah mengubah offset dari degHead dalam pernyataan sebelumnya, tergantung pada jumlah poin. Saya menggunakan alogoritma ganti nama yang dimodifikasi (dan menggunakan variabel yang bisa saya ganti namanya tanpa merusak kata-kata!) Untuk memastikan saya memenuhi persyaratan kasus dari pertanyaan tersebut.

Saya tahu ini tidak akan menang, karena Python lebih bertele-tele, dan saya juga.

Versi pendek:

  def a(t,d,l):
    for i,j in d.items():
      if l:
        i=i.lower()
      t=t.replace(i,j)
    return t
  def b(h,q):
    p=32
    r=360
    h=(h+(r/q/2))/(r/p)
    j=int(int(int(h %8)%8/(p/q))*p/q)
    h=int(h/8)%4
    k=c.keys()
    u=['W','W by x','W-z','Z by w','Z','Z by x','X-z','X by w']
    d={}
    d['W']=list(k)[h]
    d['w']=d['W'].lower()
    d['X']=list(k)[(h+1)%4]
    d['x']=d['X'].lower()
    if(d['W']=='North' or d['W']=='South'):
      d['Z']=d['W']+d['x']
    else:
      d['Z']=d['X']+d['w']
    d['z']=d['Z'].lower()
    return a(u[j],d,0)
  def g(n):
    n=a(n,c,0)
    n=a(n,c,1)
    d={'by':'b',' ':'','-':''}
    return a(n,d,0)
  def v(m):
    while True:
      try:
        return float(input(m))
      except ValueError:
        print("?")
  c={'North':'N','East':'E','South':'S','West':'W'}
  while True:
    h=v("?")
    n=b(h,32)
    print(h,n,g(n))

Bersihkan versi

            import math
            import sys

            def calcPoint(degHead, points):
                maxPoints=32
                if points not in(8,16,32):
                    sys.exit("not a good question")
                degHead=(degHead+(360/points/2))/(360/maxPoints)
                j =int(int( int(degHead  % 8)%8/(maxPoints/points))*maxPoints/points)
                degHead = int(degHead / 8) % 4
                cardinal = ['North', 'East', 'South', 'West']
                pointDesc = ['W', 'W by x', 'W-z', 'Z by w', 'Z', 'Z by x', 'X-z', 'X by w']#vars not compass points
                W = cardinal[degHead]
                X = cardinal[(degHead + 1) % 4]
                w=W.lower()
                x=X.lower()
                if (W == cardinal[0] or W == cardinal[2]) :
                    Z =W + x
                else:
                    Z =X + w
                z=Z.lower()
                return pointDesc[j].replace('W', W).replace('X', X).replace('w', w).replace('x', x).replace('Z', Z).replace('z', z);

            def getShortName(name): 
                return name.replace('North', 'N').replace('East', 'E').replace('South', 'S').replace('West', 'W').replace('north', 'N').replace('east', 'E').replace('south', 'S').replace('west', 'W').replace('by', 'b').replace(' ', '').replace('-', '')

            def input_number(msg, err_msg=None):
                while True:
                    try:
                        return float(input(msg))
                    except ValueError:
                        sys.exit("not a number")

            while True:
                headingCalib=input_number("input a number: ")
                print (headingCalib, end=' ')
                name = calcPoint(headingCalib,32) #degrees heading, points of compass 8,16 or 32)
                print (name, end=' ')
                shortName = getShortName(name)
                print (shortName)
tony goodwin
sumber
4
Jawaban ini tidak menunjukkan usaha untuk bermain golf dan karenanya harus dihapus sebagai bukan pesaing serius untuk tantangan
pppery
Poin wajar - Saya sudah memposting upaya bermain golf sekarang.
tony goodwin
Mengapa Anda memiliki banyak lekukan dalam kiriman Anda? Sepertinya itu bukan bagian dari jawaban Anda, jadi saya tidak mengerti intinya. Anda juga dapat bermain golf ini lebih banyak, hanya dengan menghapus semua spasi putih, memperpendek nama variabel dan deklarasi, dan menghapus variabel berlebihan sama sekali
Jo King
Terima kasih Jo, saya telah memperbarui versi lagi. Apakah saya mendapatkan semuanya?
tony goodwin
menggunakan kembali kamus untuk kardinal jauh lebih baik. Kehabisan ide sekarang. Semoga cukup untuk lolos?
tony goodwin