Konvertieren Sie Grad in einen der 32 Punkte des Kompasses

13

Der 32-Punkte-Kompass ist ... gelinde gesagt interessant.

Bild

Von Denelson83 (Eigene Arbeit) [ GFDL oder CC-BY-SA-3.0 ] über Wikimedia Commons

Ihre Herausforderung besteht darin, ein Gradmaß zu nehmen und es in eine Richtung auf dem 32-Punkt-Kompass umzuwandeln.

Jede Richtung ist 11,25 (360/32) Grad weiter als die vorherige. Beispielsweise beträgt N (Nord) 0 Grad, NbE (Nord-Ost) 11,25 Grad, NNE (Nord-Nordost) 22,5 Grad usw.

Wie sollen Sie die Anweisungen bekommen,

  • 0 Grad ist N, 90 Grad ist E, 180 Grad ist S und 270 Grad ist W.

    • Diese werden als Himmelsrichtungen bezeichnet.
  • Die halben Punkte zwischen den Himmelsrichtungen sind einfach die Himmelsrichtungen, zwischen denen sie verkettet sind. N oder S stehen immer an erster Stelle, und W oder E stehen immer an zweiter Stelle.

    • Diese werden Ordnungsrichtungen genannt.
  • Die halben Punkte zwischen der Kardinal- und der Ordinalrichtung sind die Richtungen, in denen sie wieder mit einem "-" dazwischen verkettet sind. Kardinalrichtungen gehen zuerst, Ordinalsekunde.

    • Diese werden sekundär-interkardinale Richtungen genannt.
  • Die Mittelpunkte zwischen sekundären und interkardinalen Richtungen und anderen Richtungen sind die anderen Richtungen "nach" der Kardinalrichtung, der sie am nächsten liegen (außer natürlich der direkt daneben).

    • Ich habe keine Ahnung, wie diese heißen: P

Wenn all diese Erklärungen Ihr Gehirn genauso verletzen wie meins, können Sie sich auf diese Tabelle beziehen:

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

Hier ist eine detailliertere Tabelle und möglicherweise eine bessere Erklärung der Himmelsrichtungen.

Ihre Herausforderung besteht darin, die Eingabe in Grad vorzunehmen und den vollständigen Namen der entsprechenden Kompassrichtung sowie die Abkürzung auszugeben.

Testfälle:

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

Die Groß- und Kleinschreibung muss wie in den Testfällen erhalten bleiben. Die maximale Anzahl von Dezimalstellen ist 2. Alle Eingabenummern sind größer oder gleich 0 und kleiner als 360. Wenn ein Dezimalpunkt vorhanden ist, werden auf beiden Seiten Ziffern angezeigt (Sie müssen nicht mit .1oder umgehen 1.).

Das ist , also gewinnt der kürzeste Code in Bytes.

Türknauf
quelle
@WallyWest Hmm, dieser erlaubt Arrays, hat unterschiedliche Groß- und Kleinschreibung und kein "dazwischen", aber ich habe das nicht bemerkt (möglicherweise wegen des ... interessanten Titels: P). Ich werde sehen, was ich tun kann, um es anders zu machen ...
Türklinke
3
@WallyWest Dort müssen Sie nun auch die Abkürzung ausgeben. Zusammen mit all den anderen Unterschieden sollte das ausreichen, um es zu einem Nicht-Dup zu machen. (Oh, auch dieser hat Striche)
Türknauf
@WallyWest Es gibt keine Antworten in "R" auf Ihre vorherige Frage (es gab nicht einmal eine in "C"!) Ich hoffe, wir sehen uns diesmal, Schiffskameraden!
Level River St
Wäre spaßiger gewesen, wenn Sie einen Wert von -360 bis 360 Grad (negativ bedeutet gegen den Uhrzeigersinn) und einen Bonus eingegeben hätten !.
Mukul Kumar

Antworten:

4

Perl, 250 236 231 188 187

Bearbeiten: Einige Bytes aus Ausnutzung der Symmetrie (wie ich in @bazzargh Lösung gesehen habe)

+ Bearbeiten: Und ein paar böse Tricks ...

+ Bearbeiten : Zurück zu meinem Ausgangspunkt (Arbeiten mit der Liste, nicht mit der Zeichenfolge) und Ausnutzen von mehr Symmetrie = 1 Byte weniger und viel hässlicher.

$_=((@_=(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

Hübsch gedruckt:

$_=(
    (@_=
        (
            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

5.014 wegen rModifikator erforderlich .

user2846289
quelle
Sie haben einen Tippfehler in Ihrem Code: sourth sollte südlich sein (2. Anweisung, die mit s / b / by
RononDex
Diese ersten 3 regulären Ausdrücke können durch y / NS / SN / ersetzt werden. für 10 Zeichen
bazzargh
@bazzargh, ja, und nicht nur das ;-)
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)

Sie können diesen Code auf Ihre Konsole kopieren und ausführen. Es fordert Sie zur Eingabe der Grade auf und gibt das Ergebnis mit ausalert();

Ungolfed Javascript kann auf dieser Seite gefunden werden: http://jsfiddle.net/AezL3/11

RononDex
quelle
+1 Schön, aber Vorsicht: "Alle Großschreibung muss erhalten bleiben, wie in den Testfällen."
@BenH Welcher Testfall hat die Großschreibung nicht bestanden? Danke dafür, übrigens. Dies war praktisch für mein Webinterface, das ich schreibe.
Steven Lu
Übrigens stirbt dies für 355 Grad bis 360 Grad. Die Lösung ist einfach. calcPoint(32)Mach einfach das , was 0 macht, damit du das mit %32oder ähnlichem machen kannst .
Steven Lu
@StevenLu Ich habe eine Weile gebraucht, um herauszufinden, was du var name = calcPoint(input % 32);
meinst
4

Haskell 415 372 347 330 317 304 301C

Konvergierte auf einer Lösung wie @ VadimR (und die Symmetrie zurück!). Verwendung: h 219Ausgänge"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)

Noch 3 Zeichen, danke @shiona.

bazzargh
quelle
drop 1ist das gleiche wie Schwanz. Auch wenn ich mich nicht irre, kannst du e l@(x:_)=x:tail$d lnoch einen Saibling rasieren.
Shiona
Ich kann nicht glauben, dass ich das verpasst habe. Vielen Dank!
bazzargh
0

Python 3.8 , 482 438 424 Bytes

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

Probieren Sie es online!

Dies ist, was ich nach einigem Golfen von Tony Goodwins Antwort bekam ; Wird bei einer eigenen Antwort gepostet, da der TIO-Link für einen Kommentar zu lang ist. Wenn er beschließt, seine Antwort auf das oben Gesagte zu aktualisieren, werde ich diese Antwort löschen.

Ich gehe davon aus, dass es akzeptabel ist, eine Funktion als Lösung und nicht als vollständiges Programm einzureichen. Wenn nicht, hier ein volles Programm mit 426 Bytes.

Ich gehe davon aus, dass noch viel getan werden kann, um zu verkürzen b.

Edit: Ab 44 Bytes mit freundlicher Genehmigung des majestätischen Walrosses. bIch habe immer noch nicht das Gefühl, dass es fertig ist, Golf zu spielen.

Edit2: Rasiert weitere 14 durch Auspacken von Dikten anstatt mit keys()und items().

Setzen Sie Monica wieder ein
quelle
-1

Python, 2103 1647 1103 1034 924 889 848 Bytes

Sehr spät, ich weiß. Vielen Dank für die Herausforderung, ich richte mit meinem Pi ein Magnetometer für die Windrichtung ein und wollte eine solche 16-Punkt-Kompass-Lösung, die in die Wettervorhersagealgorithmen eingeht. Mein gesamter Code ist in Python, daher gibt es hier eine Version der Javascript-Lösung, die bereits in Python veröffentlicht wurde, aber mit einer zusätzlichen Wendung, bei der Sie entweder 32, 16 oder 8 Punkte des Kompasses bei der Variablen j angeben können, und ich habe den Versatz geändert von degHead in der Anweisung davor, abhängig von der Anzahl der Punkte. Ich habe einen geänderten Umbenennungsalogorithmus verwendet (und Variablen verwendet, die ich umbenennen konnte, ohne die Wörter zu beschädigen!), Um sicherzustellen, dass ich die Fallanforderungen der Frage erfüllte.

Ich weiß, dass dies nicht gewinnen wird, da Python wortreicher ist, und ich auch.

Kurzfassung:

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

Klare Version

            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
quelle
4
Diese Antwort zeigt keinen Golfversuch und kann daher als nicht ernsthafter Anwärter auf die Herausforderung
gestrichen werden
Guter Punkt - Ich habe den Versuch, jetzt Golf zu spielen, veröffentlicht.
Tony Goodwin
Warum haben Sie so viele Einrückungen in Ihrer Einreichung? Es scheint nicht Teil Ihrer Antwort zu sein, daher verstehe ich den Sinn nicht. Sie können auch viel mehr Golf spielen, indem Sie alle zusätzlichen Leerzeichen entfernen, Variablennamen und Deklarationen kürzen und redundante Variablen insgesamt entfernen
Jo King,
Danke Jo, ich habe die Version nochmal aktualisiert. Habe ich alles bekommen?
Tony Goodwin
ein Wörterbuch für Kardinäle viel besser wiederverwendet. Keine Ideen mehr. Hoffentlich genug, um sich zu qualifizieren?
Tony Goodwin