Converti i gradi in uno dei 32 punti cardinali


13

La bussola a 32 punti è ... interessante, per non dire altro.

Immagine

Di Denelson83 (opera propria) [ GFDL o CC-BY-SA-3.0 ], tramite Wikimedia Commons

La tua sfida è prendere una misura di grado e convertirla in una direzione sulla bussola a 32 punti.

Ogni direzione è 11,25 (360/32) gradi più avanti della precedente. Ad esempio, N (nord) è 0 gradi, NbE (nord-est) è 11,25 gradi, NNE (nord-nord-est) è 22,5 gradi, ecc.

Per quanto riguarda come dovresti ottenere le indicazioni,

  • 0 gradi è N, 90 gradi è E, 180 gradi è S e 270 gradi è W.

    • Queste sono chiamate direzioni cardinali.
  • I punti a metà strada tra le direzioni cardinali sono semplicemente le direzioni cardinali tra cui sono concatenati. N o S vanno sempre per primi e W o E sono sempre i secondi.

    • Queste sono chiamate direzioni ordinali.
  • I punti a metà strada tra le direzioni cardinale e ordinale sono le direzioni tra cui sono concatenati, di nuovo, con un "-" in mezzo. Le direzioni cardinali vanno prima, secondo ordinale.

    • Queste sono chiamate direzioni intercardinali secondarie.
  • I punti a metà strada tra le direzioni secondarie-intercardinali e le altre direzioni sono le altre direzioni "per" la direzione cardinale a cui sono più vicine (tranne quella direttamente accanto a loro, ovviamente).

    • Non ho idea di come si chiamino: P

Se tutta questa spiegazione fa male al cervello tanto quanto la mia, puoi fare riferimento a questo grafico:

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

Ecco una tabella più dettagliata e forse una migliore spiegazione dei punti cardinali.

La tua sfida è prendere input in gradi e produrre il nome completo della direzione della bussola a cui corrisponde, insieme alla sua abbreviazione.

Casi test:

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

Tutte le maiuscole devono essere preservate, come nei casi di test. Il numero massimo di posizioni decimali è 2. Tutti i numeri di input saranno maggiori o uguali a 0 e inferiori a 360. Se è presente un punto decimale, saranno presenti cifre su entrambi i lati (non è necessario gestirli .1o 1.).

Questo è , quindi vince il codice più breve in byte.


@WallyWest Hmm, questo consente array, ha diverse maiuscole e non ha "in mezzo", ma non me ne sono accorto (probabilmente a causa del ... interessante titolo: P). Vedrò cosa posso fare per renderlo abbastanza diverso ...
Maniglia della porta

3
@WallyWest Lì, ora devi anche stampare l'abbreviazione. Insieme a tutte le altre differenze, dovrebbe essere sufficiente per renderlo non duplice. (oh, anche questo ha trattini)
Maniglia della porta

@WallyWest Non ci sono risposte in "R" alla tua domanda precedente (non ce n'erano nemmeno in "C"!) Spero che questa volta ne vedremo alcuni, compagni di nave!
Level River St,

Sarebbe stato più divertente se ci fossero stati input da -360 a 360 gradi (negativo significa antiorario) e un bonus !.
Mukul Kumar,

Per le persone che non sono alla ricerca di una sfida, la soluzione semplice è quella di trovare il possibile output per il quale la distanza è minima dall'angolo di input, usando un nome della tabella di ricerca <-> nome.
Rivenfall,

Risposte:


4

Perl, 250 236 231 188 187

Modifica: alcuni byte sfruttano la simmetria (come ho visto nella soluzione @bazzargh)

+ Modifica: e alcuni trucchi malvagi ...

+ Modifica : torna da dove ho iniziato (lavorando con la lista, non con la stringa), e sfruttando più simmetria = 1 byte off e molto più brutta.

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

Pretty-stampati:

$_=(
    (@_=
        (
            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 richiesto a causa del rmodificatore.


Hai un refuso nel tuo codice: sourth dovrebbe essere south (seconda istruzione che inizia con s / b / by ...
RononDex,

Quei primi 3 regexps possono essere sostituiti da y / NS / SN /; per 10 caratteri
bazzargh,

@bazzargh, sì, e non solo ;-)
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)

Puoi copiare questo codice sulla tua console ed eseguirlo. Ti chiede l'inserimento dei gradi e genera il risultato conalert();

Ungolfed Javascript può essere trovato a questo violino: http://jsfiddle.net/AezL3/11


+1 Bello ma fai attenzione: "Tutte le maiuscole devono essere preservate, come nei casi di test."

@BenH Quale caso di test fallisce il controllo delle maiuscole? Grazie per questo, a proposito. Questo è stato utile per la mia interfaccia web che sto scrivendo.
Steven Lu

A proposito, questo muore per 355 gradi a 360 gradi. La correzione è semplice. Fai semplicemente calcPoint(32)quello che fa 0, così puoi farlo con %32o simili.
Steven Lu

@StevenLu mi ci è voluto un po 'per capire cosa vuoi dire, ma questa linea var name = calcPoint(input % 32);fa il trucco
Orwellophile,

4

Haskell 415 372 347 330 317 304 301C

Finì per convergere su una soluzione come @ VadimR (e la schiena della simmetria!). Utilizzo: h 219uscite"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)

Altri 3 caratteri spariti, grazie @shiona.


drop 1è uguale alla coda. Inoltre, se non sbaglio, puoi fare e l@(x:_)=x:tail$d lper radere ancora un altro carattere.
shiona,

non posso credere che mi sia mancato. Grazie!
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)})

Provalo online!

Questo è quello che ho ottenuto dopo aver giocato a golf con la risposta di Tony Goodwin ; pubblicato alla propria risposta a causa del collegamento TIO troppo lungo per un commento. Se sceglie di aggiornare la sua risposta a quanto sopra, eliminerò questa risposta.

Presumo che sia accettabile presentare una funzione come soluzione anziché come programma completo. In caso contrario, ecco un programma completo a 426 byte.

Mi aspetto che si possa ancora fare molto per accorciare b.

Modifica: golf off 44 byte, per gentile concessione del maestoso tricheco. Ancora non mi sento come bse avessi finito di giocare a golf.

Edit2: rasato altri 14 disimballando i dadi invece di usare keys()e items().


-1

Python, 2103 1647 1103 1034 924 889 848 byte

Molto tardi, lo so. Grazie per la sfida, sto impostando un magnetometro per la direzione del vento con il mio Pi e volevo una soluzione a 16 punti bussola come questa per alimentare gli algoritmi di previsioni meteorologiche. Tutto il mio codice è in Python, quindi ecco la versione della soluzione javascript già pubblicata in Python, ma con un tocco in più che è possibile specificare 32, 16 o 8 punti cardinali alla variabile j, e ho modificato l'offset di degHead nell'istruzione precedente, a seconda del numero di punti. Ho usato un alogoritmo di rinomina modificato (e ho usato variabili che potrei rinominare senza corrompere le parole!) Per assicurarmi di soddisfare i requisiti del caso della domanda.

So che non vincerà, dato che Python è più prolisso, e lo sono anch'io.

Versione breve:

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

Versione chiara

            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)

4
Questa risposta non mostra alcun tentativo di giocare a golf ed è quindi soggetta alla cancellazione in quanto non è un serio contendente per la sfida
pppery

Punto giusto - Ho pubblicato il tentativo di giocare a golf ora.
Tony Goodwin,

Perché hai così tanto rientro nella tua proposta? Non sembra parte della tua risposta, quindi non vedo il punto. Puoi anche giocare a golf molto di più, semplicemente rimuovendo tutto lo spazio bianco aggiuntivo, accorciando i nomi e le dichiarazioni delle variabili e rimuovendo del tutto le variabili ridondanti
Jo King

Grazie Jo, ho aggiornato di nuovo la versione. Ho capito tutto?
tony goodwin,

riutilizzato molto meglio un dizionario per i cardinali. Senza idee adesso. Spero abbastanza per qualificarti?
Tony Goodwin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.