
Avast me hearties!
There be many aland lubber that knowsnaught of the pirate ways and gives direction by degree!They know not how tobox the compass!
[0.0, 16.87, 16.88, 33.75, 50.62, 50.63, 67.5, 84.37, 84.38, 101.25, 118.12, 118.13, 135.0, 151.87, 151.88, 168.75, 185.62, 185.63, 202.5, 219.37, 219.38, 236.25, 253.12, 253.13, 270.0, 286.87, 286.88, 303.75, 320.62, 320.63, 337.5, 354.37, 354.38]. (They should give the same order of points but are spread throughout the ranges of acceptance).for i in 0..32 inclusive: heading = i * 11.25 case i %3: if 1: heading += 5.62; break if 2: heading -= 5.62; break end index = ( i mod 32) + 1
V majors = ‘north east south west’.split(‘ ’)majors *= 2V quarter1 = ‘N,N by E,N-NE,NE by N,NE,NE by E,E-NE,E by N’.split(‘,’)V quarter2 = quarter1.map(p -> p.replace(‘NE’, ‘EN’))F degrees2compasspoint(=d) d = (d % 360) + 360 / 64 V majorindex = Int(d / 90) V minorindex = Int((d % 90 * 4) I/ 45) V p1 = :majors[majorindex] V p2 = :majors[majorindex + 1] [String] q I p1 C (‘north’, ‘south’) q = :quarter1 E q = :quarter2 R q[minorindex].replace(‘N’, p1).replace(‘E’, p2).capitalize():start:L(i) 0.<33 V d = i * 11.25 S i % 3 1 d += 5.62 2 d -= 5.62 V n = i % 32 + 1 print(‘#2.0 #<18 #4.2°’.format(n, degrees2compasspoint(d), d))
1 North 0.00° 2 North by east 16.87° 3 North-northeast 16.88°...31 North-northwest 337.50°32 North by west 354.37° 1 North 354.38°
Atari 8-bit computer is able to show up to 40 characters per row. Therefore abbreviations of direction have been used instead of the full names.
INCLUDE "D2:PRINTF.ACT" ;from the Action! Tool KitINCLUDE "D2:REAL.ACT" ;from the Action! Tool KitDEFINE PTR="CARD"PROC InitNames(PTR ARRAY names) names(0)="N" names(1)="NbE" names(2)="NNE" names(3)="NEbN" names(4)="NE" names(5)="NEbE" names(6)="ENE" names(7)="EbN" names(8)="E" names(9)="EbS" names(10)="ESE" names(11)="SEbE" names(12)="SE" names(13)="SEbS" names(14)="SSE" names(15)="SbE" names(16)="S" names(17)="SbW" names(18)="SSW" names(19)="SWbS" names(20)="SW" names(21)="SWbW" names(22)="WSW" names(23)="WbS" names(24)="W" names(25)="WbN" names(26)="WNW" names(27)="NWbW" names(28)="NW" names(29)="NWbN" names(30)="NNW" names(31)="NbW" names(32)="N"RETURNPROC PrintIndex(BYTE i) CHAR ARRAY s(5) StrB(i,s) PrintF("%2S",s)RETURNBYTE FUNC FindDot(CHAR ARRAY s) BYTE i FOR i=1 TO s(0) DO IF s(i)='. THEN RETURN (i) FI ODRETURN (0)PROC PrintAngle(REAL POINTER a) CHAR ARRAY s(10) BYTE pos StrR(a,s) pos=FindDot(s) IF pos=0 THEN s(0)==+3 s(s(0)-2)='. s(s(0)-1)='0 s(s(0)-0)='0 ELSEIF pos=s(0)-1 THEN s(0)==+1 s(s(0)-0)='0 FI PrintF("%6S",s)RETURNINT FUNC GetIndex(REAL POINTER a) REAL r32,r360,r1,r2 IntToReal(32,r32) IntToReal(360,r360) RealMult(a,r32,r1) RealDiv(r1,r360,r2)RETURN (RealToInt(r2))PROC Main() DEFINE COUNT="33" PTR ARRAY names(COUNT) INT i,m,ind,x,y REAL ri,r11_25,r5_62,rh,r1 Put(125) PutE() ;clear the screen InitNames(names) ValR("11.25",r11_25) ValR("5.62",r5_62) FOR i=0 TO 32 DO IntToReal(i,ri) RealMult(ri,r11_25,rh) m=i MOD 3 IF m=1 THEN RealAdd(rh,r5_62,r1) RealAssign(r1,rh) ELSEIF m=2 THEN RealSub(rh,r5_62,r1) RealAssign(r1,rh) FI ind=GetIndex(rh) IF i<16 THEN x=2 y=i+1 ELSE x=20 y=i-15 FI Position(x,y) PrintIndex(ind MOD (COUNT-1)+1) x==+3 Position(x,y) Print(names(ind)) x==+5 Position(x,y) PrintAngle(rh) ODRETURNScreenshot from Atari 8-bit computer
1 N 0.00 17 S 185.62 2 NbE 16.87 18 SbW 185.63 3 NNE 16.88 19 SSW 202.50 4 NEbN 33.75 20 SWbS 219.37 5 NE 50.62 21 SW 219.38 6 NEbE 50.63 22 SWbW 236.25 7 ENE 67.50 23 WSW 253.12 8 EbN 84.37 24 WbS 253.13 9 E 84.38 25 W 270.0010 EbS 101.25 26 WbN 286.8711 ESE 118.12 27 WNW 286.8812 SEbE 118.13 28 NWbW 303.7513 SE 135.00 29 NW 320.6214 SEbS 151.87 30 NWbN 320.6315 SSE 151.88 31 NNW 337.5016 SbE 168.75 32 NbW 354.37 1 N 354.38
Inspired bythe C++ program, but without the need for a specific library.
withAda.Text_IO;procedureBox_The_CompassistypeDegreesisdigits5range0.00..359.99;typeIndex_Typeismod32;functionLong_Name(Short:String)returnStringisfunctionChar_To_Name(Char:Character)returnStringisbegincaseChariswhen'N'|'n'=>returnChar&"orth";when'S'|'s'=>returnChar&"outh";when'E'|'e'=>returnChar&"ast";when'W'|'w'=>returnChar&"est";when'b'=>return" by ";when'-'=>return"-";whenothers=>raiseConstraint_Error;endcase;endChar_To_Name;beginifShort'Length=0or elseShort(Short'First)=' 'thenreturn"";elsereturnChar_To_Name(Short(Short'First))&Long_Name(Short(Short'First+1..Short'Last));endif;endLong_Name;procedurePut_Line(Angle:Degrees)isfunctionIndex(D:Degrees)returnIndex_TypeisbeginreturnIndex_Type(Integer(Degrees'Rounding(D/11.25))mod32);endIndex;I:Integer:=Integer(Index(Angle))+1;packageDIOis newAda.Text_IO.Float_IO(Degrees);Abbr:constantarray(Index_Type)ofString(1..4):=("N ","Nbe ","N-ne","Nebn","Ne ","Nebe","E-ne","Ebn ","E ","Ebs ","E-se","Sebe","Se ","Sebs","S-se","Sbe ","S ","Sbw ","S-sw","Swbs","Sw ","Swbw","W-sw","Wbs ","W ","Wbn ","W-nw","Nwbw","Nw ","Nwbn","N-nw","Nbw ");beginDIO.Put(Angle,Fore=>3,Aft=>2,Exp=>0);-- format "zzx.xx"Ada.Text_IO.Put(" |");ifI<=9thenAda.Text_IO.Put(" ");endif;Ada.Text_IO.Put_Line(" "&Integer'Image(I)&" | "&Long_Name(Abbr(Index(Angle))));endPut_Line;Difference:constantarray(0..2)ofDegrees'Base:=(0=>0.0,1=>+5.62,2=>-5.62);beginAda.Text_IO.Put_Line(" angle | box | compass point");Ada.Text_IO.Put_Line(" ---------------------------------");forIin0..32loopPut_Line(Degrees(Degrees'Base(I)*11.25+Difference(Imod3)));endloop;endBox_The_Compass;
Output:
angle | box | compass point --------------------------------- 0.00 | 1 | North 16.87 | 2 | North by east 16.88 | 3 | North-northeast 33.75 | 4 | Northeast by north 50.62 | 5 | Northeast 50.63 | 6 | Northeast by east 67.50 | 7 | East-northeast 84.37 | 8 | East by north 84.38 | 9 | East101.25 | 10 | East by south118.12 | 11 | East-southeast118.13 | 12 | Southeast by east135.00 | 13 | Southeast151.87 | 14 | Southeast by south151.88 | 15 | South-southeast168.75 | 16 | South by east185.62 | 17 | South185.63 | 18 | South by west202.50 | 19 | South-southwest219.37 | 20 | Southwest by south219.38 | 21 | Southwest236.25 | 22 | Southwest by west253.12 | 23 | West-southwest253.13 | 24 | West by south270.00 | 25 | West286.87 | 26 | West by north286.88 | 27 | West-northwest303.75 | 28 | Northwest by west320.62 | 29 | Northwest320.63 | 30 | Northwest by north337.50 | 31 | North-northwest354.37 | 32 | North by west354.38 | 1 | North
#!/usr/local/bin/a68g --script #[]STRING long by nesw = (" by ", "North", "East", "South", "West"), short by nesw = ("b", "N", "E", "S", "W");MODE MINUTES = REAL; # minutes type #INT last minute=360*60;INT point width=last minute OVER 32;PROC direction name = (REAL direction in minutes, []STRING locale directions)STRING: ( STRING by = locale directions[1]; []STRING nesw = locale directions[@-1]; PRIO MASK = 7; # same PRIOrity as * and / # OP MASK = (INT n, BITS lower)INT: ABS (BIN n AND NOT lower), DECAP = (STRING s)STRING: IF UPB s > 1 THEN REPR (ABS s[1]-ABS "A"+ABS "a")+s[2:] ELSE s FI; PROC point name = (INT in point)STRING: ( INT point = in point MOD 32 # 32 points of a compass #; IF point MOD 8 = 0 THEN# name the principle point: eg. N, E, S or W # nesw[point OVER 8] ELIF point MOD 4 = 0 THEN# name the half: eg. NE, SE, SW or NW # point name((point+8)MASK 2r1111)+DECAP point name(point MASK 2r1111 + 8) ELIF point MOD 2 = 0 THEN# name the quarter: eg. N-NE, E-NE, E-SE, S-SE, S-SW, W-SW, W-NW or N-NW # point name((point+4)MASK 2r111)+"-"+point name(point MASK 2r111 + 4) ELSE # Name the sixteenth point: ## eg. NbE,NEbN,NEbE,EbN,EbS,SEbE,SEbS,SbE,SbW,SWbS,SWbW,WbS,WbN,NWbW,NWbN,NbW # INT opp point = point OVER 8 + ABS NOT ODD (point OVER 2); point name((point+2)MASK 2r11)+ by +nesw(opp point MOD 4) FI ); point name(ROUND(direction in minutes/point width)));PROC traditional name = (MINUTES minutes)STRING: ( INT degrees = ROUND(minutes / 60); degrees=0 |"Tramontana" |: degrees=45 |"Greco or Bora" |: degrees=90 |"Levante" |: degrees=135|"Sirocco" |: degrees=180|"Ostro" |: degrees=225|"Libeccio" |: degrees=270|"Poniente or Zephyrus"|: degrees=315|"Mistral" |: degrees=360|"Tramontana" |"");# First generate the test set results #test:( printf($"Test:"l$); FOR i FROM 0 TO 32 DO REAL heading = i * 11.25 + CASE i MOD 3 IN +5.62, -5.62 OUT 0 ESAC; INT index = ( i MOD 32) + 1; printf(($zd" ", g23k, zzd.zzl$, index , direction name(heading*60, long by nesw), heading)) OD);table:( OP OVER = (REAL r, INT base)INT: ENTIER ABS r OVER base, MOD = (REAL r, INT base)REAL: ( INT i = ENTIER r; i MOD base + r - i); printf( $l"Table:"l " #|Compass point"22k"|Abbr|Traditional wind point| Lowest°′ | Middle°′ | Highest°′"l$ ); OP DEGMIN = (REAL minutes)STRUCT(INT d, REAL m): (minutes MOD last minute OVER 60, minutes MOD 60); FOR point FROM 1 TO 32 DO REAL centre = (point-1) * point width; REAL from = centre - point width/2, to = centre + point width/2-1/120; printf(( $g(-2)"|"$, point, $g$, direction name(centre, long by nesw), $22k"|"g$, direction name(centre, short by nesw), $27k"|"g$, traditional name(centre), $50k$, $"|"g(-3)"°", dd.dd"′"$, DEGMIN from, DEGMIN centre, DEGMIN to, $l$ )) OD)Output:
Test: 1 North 0.00 2 North by East 16.87 3 North-Northeast 16.88 4 Northeast by North 33.75 5 Northeast 50.62 6 Northeast by East 50.63 7 East-Northeast 67.50 8 East by North 84.37 9 East 84.3810 East by South 101.2511 East-Southeast 118.1212 Southeast by East 118.1313 Southeast 135.0014 Southeast by South 151.8715 South-Southeast 151.8816 South by East 168.7517 South 185.6218 South by West 185.6319 South-Southwest 202.5020 Southwest by South 219.3721 Southwest 219.3822 Southwest by West 236.2523 West-Southwest 253.1224 West by South 253.1325 West 270.0026 West by North 286.8727 West-Northwest 286.8828 Northwest by West 303.7529 Northwest 320.6230 Northwest by North 320.6331 North-Northwest 337.5032 North by West 354.37 1 North 354.38Table: #|Compass point |Abbr|Traditional wind point| Lowest°′ | Middle°′ | Highest°′ 1|North |N |Tramontana |354°22.50′| 0°00.00′| 5°37.49′ 2|North by East |NbE | | 5°37.50′| 11°15.00′| 16°52.49′ 3|North-Northeast |N-NE| | 16°52.50′| 22°30.00′| 28°07.49′ 4|Northeast by North|NEbN| | 28°07.50′| 33°45.00′| 39°22.49′ 5|Northeast |NE |Greco or Bora | 39°22.50′| 45°00.00′| 50°37.49′ 6|Northeast by East |NEbE| | 50°37.50′| 56°15.00′| 61°52.49′ 7|East-Northeast |E-NE| | 61°52.50′| 67°30.00′| 73°07.49′ 8|East by North |EbN | | 73°07.50′| 78°45.00′| 84°22.49′ 9|East |E |Levante | 84°22.50′| 90°00.00′| 95°37.49′10|East by South |EbS | | 95°37.50′|101°15.00′|106°52.49′11|East-Southeast |E-SE| |106°52.50′|112°30.00′|118°07.49′12|Southeast by East |SEbE| |118°07.50′|123°45.00′|129°22.49′13|Southeast |SE |Sirocco |129°22.50′|135°00.00′|140°37.49′14|Southeast by South|SEbS| |140°37.50′|146°15.00′|151°52.49′15|South-Southeast |S-SE| |151°52.50′|157°30.00′|163°07.49′16|South by East |SbE | |163°07.50′|168°45.00′|174°22.49′17|South |S |Ostro |174°22.50′|180°00.00′|185°37.49′18|South by West |SbW | |185°37.50′|191°15.00′|196°52.49′19|South-Southwest |S-SW| |196°52.50′|202°30.00′|208°07.49′20|Southwest by South|SWbS| |208°07.50′|213°45.00′|219°22.49′21|Southwest |SW |Libeccio |219°22.50′|225°00.00′|230°37.49′22|Southwest by West |SWbW| |230°37.50′|236°15.00′|241°52.49′23|West-Southwest |W-SW| |241°52.50′|247°30.00′|253°07.49′24|West by South |WbS | |253°07.50′|258°45.00′|264°22.49′25|West |W |Poniente or Zephyrus |264°22.50′|270°00.00′|275°37.49′26|West by North |WbN | |275°37.50′|281°15.00′|286°52.49′27|West-Northwest |W-NW| |286°52.50′|292°30.00′|298°07.49′28|Northwest by West |NWbW| |298°07.50′|303°45.00′|309°22.49′29|Northwest |NW |Mistral |309°22.50′|315°00.00′|320°37.49′30|Northwest by North|NWbN| |320°37.50′|326°15.00′|331°52.49′31|North-Northwest |N-NW| |331°52.50′|337°30.00′|343°07.49′32|North by West |NbW | |343°07.50′|348°45.00′|354°22.49′
OS X Yosemite onwards (uses Foundation classes for record handling etc)
(ES6 version)
Functional composition, allowing for additional languages, and different numbers of compass points – see the test section)
useframework"Foundation"usescriptingadditions-- BOXING THE COMPASS --------------------------------------------------------propertyplstLangs:[{|name|:"English"}&¬{expansions:{N:"north",S:"south",E:"east",W:"west",b:" by "}}&¬{|N|:"N",|NNNE|:"NbE",|NNE|:"N-NE",|NNENE|:"NEbN",|NE|:"NE",|NENEE|:"NEbE"}&¬{|NEE|:"E-NE",|NEEE|:"EbN",|E|:"E",|EEES|:"EbS",|EES|:"E-SE",|EESES|:"SEbE"}&¬{|ES|:"SE",|ESESS|:"SEbS",|ESS|:"S-SE",|ESSS|:"SbE",|S|:"S",|SSSW|:"SbW"}&¬{|SSW|:"S-SW",|SSWSW|:"SWbS",|SW|:"SW",|SWSWW|:"SWbW",|SWW|:"W-SW"}&¬{|SWWW|:"WbS",|W|:"W",|WWWN|:"WbN",|WWN|:"W-NW",|WWNWN|:"NWbW"}&¬{|WN|:"NW",|WNWNN|:"NWbN",|WNN|:"N-NW",|WNNN|:"NbW"},¬¬{|name|:"Chinese",|N|:"北",|NNNE|:"北微东",|NNE|:"东北偏北"}&¬{|NNENE|:"东北微北",|NE|:"东北",|NENEE|:"东北微东",|NEE|:"东北偏东"}&¬{|NEEE|:"东微北",|E|:"东",|EEES|:"东微南",|EES|:"东南偏东",|EESES|:"东南微东"}&¬{|ES|:"东南",|ESESS|:"东南微南",|ESS|:"东南偏南",|ESSS|:"南微东",|S|:"南"}&¬{|SSSW|:"南微西",|SSW|:"西南偏南",|SSWSW|:"西南微南",|SW|:"西南"}&¬{|SWSWW|:"西南微西",|SWW|:"西南偏西",|SWWW|:"西微南",|W|:"西"}&¬{|WWWN|:"西微北",|WWN|:"西北偏西",|WWNWN|:"西北微西",|WN|:"西北"}&¬{|WNWNN|:"西北微北",|WNN|:"西北偏北",|WNNN|:"北微西"}]-- Scale invariant keys for points of the compass-- (allows us to look up a translation for one scale of compass (32 here)-- for use in another size of compass (8 or 16 points)-- (Also semi-serviceable as more or less legible keys without translation)-- compassKeys :: Int -> [String]oncompassKeys(intDepth)-- Simplest compass divides into two hemispheres-- with one peak of ambiguity to the left,-- and one to the right (encoded by the commas in this list):seturCompassto["N","S","N"]-- Necessity drives recursive subdivision of broader directions, shrinking-- boxes down to a workable level of precision:scriptsubdivisionon|λ|(lstCompass,N)ifN≤1thenlstCompasselsescriptsubKeyson|λ|(a,x,i,xs)-- Borders between N and S engender E and W.-- further subdivisions (boxes)-- concatenate their two parent keys.ifi>1thencond(N=intDepth,¬a&{cond(x="N","W","E")}&x,¬a&{item(i-1)ofxs&x}&x)elsea&xendifend|λ|endscript|λ|(foldl(subKeys,{},lstCompass),N-1)endifend|λ|endscripttellsubdivisiontoitems1thru-2of|λ|(urCompass,intDepth)endcompassKeys-- pointIndex :: Int -> Num -> StringonpointIndex(power,degrees)setnBoxesto2^powersetitoround(degrees+(360/(nBoxes*2)))¬mod360*nBoxes/360roundingupcond(i>0,i,1)endpointIndex-- pointNames :: Int -> Int -> [String]onpointNames(precision,iBox)setktoitemiBoxofcompassKeys(precision)scripttranslationon|λ|(recLang)setmaybeTranstokeyValue(recLang,k)setstrBrieftocond(maybeTransismissing value,k,maybeTrans)setrecExpandtokeyValue(recLang,"expansions")ifrecExpandis notmissing valuethenscriptexpandon|λ|(c)setttokeyValue(recExpand,c)cond(tis notmissing value,t,c)end|λ|endscriptsetstrNameto(intercalate(cond(precision>5," ",""),¬map(expand,charactersofstrBrief)))toUpper(textitem1ofstrName)&textitems2thru-1ofstrNameelsestrBriefendifend|λ|endscriptmap(translation,plstLangs)endpointNames-- maxLen :: [String] -> IntonmaxLen(xs)lengthofmaximumBy(comparing(my|length|),xs)endmaxLen-- alignRight :: Int -> String -> StringonalignRight(nWidth,x)justifyRight(nWidth,space,x)endalignRight-- alignLeft :: Int -> String -> StringonalignLeft(nWidth,x)justifyLeft(nWidth,space,x)endalignLeft-- show :: asString => a -> Textonshow(x)xasstringendshow-- compassTable :: Int -> [Num] -> Maybe StringoncompassTable(precision,xs)ifprecision<1thenmissing valueelsesetintPadto2setrightAlignedtocurry(alignRight)setleftAlignedtocurry(alignLeft)setjointocurry(myintercalate)-- INDEX COLUMNsetlstIndextomap(|λ|(precision)ofcurry(pointIndex),xs)setlstStrIndextomap(show,lstIndex)setnIndexWidthtomaxLen(lstStrIndex)setcolIndextomap(|λ|(nIndexWidth+intPad)ofrightAligned,lstStrIndex)-- ANGLES COLUMNscriptdegreeFormaton|λ|(x)set{c,m}tosplitOn(".",xasstring)c&"."&(text1thru2of(m&"0"))&"°"end|λ|endscriptsetlstAnglestomap(degreeFormat,xs)setnAngleWidthtomaxLen(lstAngles)+intPadsetcolAnglestomap(|λ|(nAngleWidth)ofrightAligned,lstAngles)-- NAMES COLUMNSscriptprecisionNameson|λ|(iBox)pointNames(precision,iBox)end|λ|endscriptsetlstTranstotranspose(map(precisionNames,lstIndex))setlstTransWidthstomap(maxLen,lstTrans)scriptspacedNameson|λ|(lstLang,i)map(|λ|((itemioflstTransWidths)+2)ofleftAligned,lstLang)end|λ|endscriptsetcolsTranstomap(spacedNames,lstTrans)-- TABLEintercalate(linefeed,¬map(|λ|("")ofjoin,¬transpose({colIndex}&{colAngles}&¬{replicate(lengthoflstIndex," ")}&colsTrans)))endifendcompassTable-- TEST ----------------------------------------------------------------------onrunsetxsto[0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,¬84.38,101.25,118.12,118.13,135.0,151.87,151.88,168.75,¬185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,¬270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,¬354.38]-- If we supply other precisions, like 4 or 6, (2^n -> 16 or 64 boxes)-- the bearings will be divided amongst smaller or larger numbers of boxes,-- either using name translations retrieved by the generic hash-- or using the keys of the hash itself (combined with any expansions)-- to substitute for missing names for very finely divided boxes.compassTable(5,xs)-- // 2^5 -> 32 boxesendrun-- GENERIC FUNCTIONS ----------------------------------------------------------- comparing :: (a -> b) -> (a -> a -> Ordering)oncomparing(f)setmftomReturn(f)scripton|λ|(a,b)setxtomf's|λ|(a)setytomf's|λ|(b)ifx<ythen-1elseifx>ythen1else0endifendifend|λ|endscriptendcomparing-- cond :: Bool -> a -> a -> aoncond(bool,f,g)ifboolthenfelsegendifendcond-- curry :: (Script|Handler) -> Scriptoncurry(f)scripton|λ|(a)scripton|λ|(b)|λ|(a,b)ofmReturn(f)end|λ|endscriptend|λ|endscriptendcurry-- foldl :: (a -> b -> a) -> a -> [b] -> aonfoldl(f,startValue,xs)tellmReturn(f)setvtostartValuesetlngtolengthofxsrepeatwithifrom1tolngsetvto|λ|(v,itemiofxs,i,xs)endrepeatreturnvendtellendfoldl-- intercalate :: Text -> [Text] -> Textonintercalate(strText,lstText)set{dlm,mytext item delimiters}to{mytext item delimiters,strText}setstrJoinedtolstTextastextsetmytext item delimiterstodlmreturnstrJoinedendintercalate-- justifyLeft :: Int -> Char -> Text -> TextonjustifyLeft(N,cFiller,strText)ifN>lengthofstrTextthentext1thruNof(strText&replicate(N,cFiller))elsestrTextendifendjustifyLeft-- justifyRight :: Int -> Char -> Text -> TextonjustifyRight(N,cFiller,strText)ifN>lengthofstrTextthentext-Nthru-1of((replicate(N,cFiller)astext)&strText)elsestrTextendifendjustifyRight-- keyValue :: Record -> String -> Maybe StringonkeyValue(rec,strKey)setcatocurrent applicationsetvto(ca'sNSDictionary'sdictionaryWithDictionary:rec)'sobjectForKey:strKeyifvis notmissing valuethenitem1of((ca'sNSArray'sarrayWithObject:v)aslist)elsemissing valueendifendkeyValue-- length :: [a] -> Inton|length|(xs)lengthofxsend|length|-- map :: (a -> b) -> [a] -> [b]onmap(f,xs)tellmReturn(f)setlngtolengthofxssetlstto{}repeatwithifrom1tolngsetendoflstto|λ|(itemiofxs,i,xs)endrepeatreturnlstendtellendmap-- maximumBy :: (a -> a -> Ordering) -> [a] -> aonmaximumBy(f,xs)setcmptomReturn(f)scriptmaxon|λ|(a,b)ifaismissing valueorcmp's|λ|(a,b)<0thenbelseaendifend|λ|endscriptfoldl(max,missing value,xs)endmaximumBy-- Lift 2nd class handler function into 1st class script wrapper-- mReturn :: Handler -> ScriptonmReturn(f)ifclassoffisscriptthenfelsescriptproperty|λ|:fendscriptendifendmReturn-- replicate :: Int -> a -> [a]onreplicate(N,a)setoutto{}ifN<1thenreturnoutsetdblto{a}repeatwhile(N>1)if(Nmod2)>0thensetouttoout&dblsetNto(Ndiv2)setdblto(dbl&dbl)endrepeatreturnout&dblendreplicate-- splitOn :: Text -> Text -> [Text]onsplitOn(strDelim,strMain)set{dlm,mytext item delimiters}to{mytext item delimiters,strDelim}setxstotextitemsofstrMainsetmytext item delimiterstodlmreturnxsendsplitOn-- transpose :: [[a]] -> [[a]]ontranspose(xss)scriptcolumnon|λ|(_,iCol)scriptrowon|λ|(xs)itemiColofxsend|λ|endscriptmap(row,xss)end|λ|endscriptmap(column,item1ofxss)endtranspose-- toLower :: String -> StringontoLower(str)setcatocurrent application((ca'sNSString'sstringWithString:(str))'s¬lowercaseStringWithLocale:(ca'sNSLocale'scurrentLocale()))astextendtoLower-- toTitle :: String -> StringontoTitle(str)setcatocurrent application((ca'sNSString'sstringWithString:(str))'s¬capitalizedStringWithLocale:(ca'sNSLocale'scurrentLocale()))astextendtoTitle-- toUpper :: String -> StringontoUpper(str)setcatocurrent application((ca'sNSString'sstringWithString:(str))'s¬uppercaseStringWithLocale:(ca'sNSLocale'scurrentLocale()))astextendtoUpper
1 0.00° North 北 2 16.87° North by east 北微东 3 16.88° North-northeast 东北偏北 4 33.75° Northeast by north 东北微北 5 50.62° Northeast 东北 6 50.63° Northeast by east 东北微东 7 67.50° East-northeast 东北偏东 8 84.37° East by north 东微北 9 84.38° East 东 10 101.25° East by south 东微南 11 118.12° East-southeast 东南偏东 12 118.13° Southeast by east 东南微东 13 135.00° Southeast 东南 14 151.87° Southeast by south 东南微南 15 151.88° South-southeast 东南偏南 16 168.75° South by east 南微东 17 185.62° South 南 18 185.63° South by west 南微西 19 202.50° South-southwest 西南偏南 20 219.37° Southwest by south 西南微南 21 219.38° Southwest 西南 22 236.25° Southwest by west 西南微西 23 253.12° West-southwest 西南偏西 24 253.13° West by south 西微南 25 270.00° West 西 26 286.87° West by north 西微北 27 286.88° West-northwest 西北偏西 28 303.75° Northwest by west 西北微西 29 320.62° Northwest 西北 30 320.63° Northwest by north 西北微北 31 337.50° North-northwest 西北偏北 32 354.37° North by west 北微西 1 354.38° North 北
ondegreesToCompassPoint(degrees)setcardinalsto{"north","east","south","west"}setidxto((degrees/11.25)asinteger)mod32setqIdxtoidxmod8if(qIdx=0)thenreturncardinals'sitem(idxdiv8+1)setnstocardinals'sitem(3-(idx+24)div16mod2*2)setewtocardinals'sitem((idxdiv16+1)*2)if(idxmod16>7)thensetqIdxto8-qIdxif(qIdx=1)thenreturnns&" by "&ewif(qIdx=2)thenreturnns&"-"&ns&ewif(qIdx=3)thenreturnns&ew&" by "&nsif(qIdx=4)thenreturnns&ewif(qIdx=5)thenreturnns&ew&" by "&ewif(qIdx=6)thenreturnew&"-"&ns&ewreturnew&" by "&ns-- qIdx = 7.enddegreesToCompassPointonjoin(lst,delim)setastidtoAppleScript'stext item delimiterssetAppleScript'stext item delimiterstodelimsettxttolstastextsetAppleScript'stext item delimiterstoastidreturntxtendjoinontask()setoutputto{"","Index Compass point Degrees"}setinputsto{0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,¬118.13,135.0,151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,¬253.12,253.13,270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38}repeatwithifrom1to(countinputs)setdegreestoinputs'sitemisetcpidto(degreesToCompassPoint(degrees))'sidsetcpid'sfirstitemto(cpid'sbeginning)mod32+64setcompassPointtostringidcpidsetdegreestodegreesastextsetentryto{text-2thru-1of(space&((i-1)mod32+1)),¬text1thru18of(compassPoint&" "),¬text(offsetof"."indegrees)thruendof(" "°rees)}setendofoutputtojoin(entry," ")endrepeatjoin(output,linefeed)endtasktask()
"Index Compass point Degrees 1 North 0.0 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.5 8 East by north 84.37 9 East 84.3810 East by south 101.2511 East-southeast 118.1212 Southeast by east 118.1313 Southeast 135.014 Southeast by south 151.8715 South-southeast 151.8816 South by east 168.7517 South 185.6218 South by west 185.6319 South-southwest 202.520 Southwest by south 219.3721 Southwest 219.3822 Southwest by west 236.2523 West-southwest 253.1224 West by south 253.1325 West 270.026 West by north 286.8727 West-northwest 286.8828 Northwest by west 303.7529 Northwest 320.6230 Northwest by north 320.6331 North-northwest 337.532 North by west 354.37 1 North 354.38"
get_Index(angle){returnMod(floor(angle/11.25+0.5),32)+1}get_Abbr_From_Index(i){staticpoints:=["N","NbE","NNE","NEbN","NE","NEbE","ENE","EbN","E","EbS","ESE","SEbE","SE","SEbS","SSE","SbE","S","SbW","SSW","SWbS","SW","SWbW","WSW","WbS","W","WbN","WNW","NWbW","NW","NWbN","NNW","NbW"]returnpoints[i]}Build_Name_From_Abbr(a){LoopParse,a{i:=A_Indexif((i=2)&&(SubStr(a,i,1)!="b")&&(StrLen(a)==3))retval.="-"retval.={N:"north",S:"south",E:"east",W:"west",b:" by "}[A_LoopField]}returnChr(Asc(SubStr(retval,1,1))-32).SubStr(retval,2)}; testheadings:=[0.00,16.87,16.88,33.75,50.62,50.63,67.50,84.37,84.38,101.25,118.12,118.13,135.00,151.87,151.88,168.75,185.62,185.63,202.50,219.37,219.38,236.25,253.12,253.13,270.00,286.87,286.88,303.75,320.62,320.63,337.50,354.37,354.38]Forn,ainheadings{i:=get_Index(a)out.=SubStr(" "i,-1)" ".SubStr(Build_Name_From_Abbr(get_Abbr_From_Index(i))." ",1,24).SubStr(" "a,-5)."`r`n" ;}clipboard:=out
1 North 0.00 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.50 8 East by north 84.37 9 East 84.3810 East by south 101.2511 East-southeast 118.1212 Southeast by east 118.1313 Southeast 135.0014 Southeast by south 151.8715 South-southeast 151.8816 South by east 168.7517 South 185.6218 South by west 185.6319 South-southwest 202.5020 Southwest by south 219.3721 Southwest 219.3822 Southwest by west 236.2523 West-southwest 253.1224 West by south 253.1325 West 270.0026 West by north 286.8727 West-northwest 286.8828 Northwest by west 303.7529 Northwest 320.6230 Northwest by north 320.6331 North-northwest 337.5032 North by west 354.37 1 North 354.38
Local$avArray[33]=[0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,118.13,135.0,_151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270.0,286.87,286.88,_303.75,320.62,320.63,337.5,354.37,354.38]For$i=0ToUBound($avArray)-1Boxing_the_compass($avArray[$i])NextFuncBoxing_the_compass($Degree)Local$namearray[33]=["North","North by east","North-northeast","Northeast by north","Northeast",_"Northeast by east","East-northeast","East by north","East","East by south","East-southeast",_"Southeast by east","Southeast","Southeast by south","South-southeast","South by east","South",_"South by west","South-southwest","Southwest by south","Southwest","Southwest by west","West-southwest",_"West by south","West","West by north","West-northwest","Northwest by west","Northwest","Northwest by north",_"North-northwest","North by west","North"]ConsoleWrite(StringFormat("%-2s",Mod(Floor($Degree/11.25+0.5),32))&" : "&_StringFormat("%-20s",$namearray[Mod(Floor($Degree/11.25+0.5),32)])&" : "&$Degree&@CRLF)EndFunc;==>Boxing_the_compass
Output :
0 : North : 01 : North by east : 16.872 : North-northeast : 16.883 : Northeast by north : 33.754 : Northeast : 50.625 : Northeast by east : 50.636 : East-northeast : 67.57 : East by north : 84.378 : East : 84.389 : East by south : 101.2510 : East-southeast : 118.1211 : Southeast by east : 118.1312 : Southeast : 13513 : Southeast by south : 151.8714 : South-southeast : 151.8815 : South by east : 168.7516 : South : 185.6217 : South by west : 185.6318 : South-southwest : 202.519 : Southwest by south : 219.3720 : Southwest : 219.3821 : Southwest by west : 236.2522 : West-southwest : 253.1223 : West by south : 253.1324 : West : 27025 : West by north : 286.8726 : West-northwest : 286.8827 : Northwest by west : 303.7528 : Northwest : 320.6229 : Northwest by north : 320.6330 : North-northwest : 337.531 : North by west : 354.370 : North : 354.38
#!/usr/bin/awk -fBEGIN{split("N NbE NNE NEbN NE NEbE ENE EbN E EbS ESE SEbE SE SEbS SSE SbE S SbW SSW SWbS SW SWbW WSW WbS W WbN WNW NWbW NW NWbN NNW NbW",A," ");}functionceil(x){y=int(x)returny<x?y+1:y}functioncompassbox(d){returnceil(((d+360/64)%360)*32/360);}{box=compassbox($1);printf"%6.2f : %2d\t%s\n",$1,box,A[box];}
Output:
0.00 : 1N 16.87 : 2NbE 16.88 : 3NNE 33.75 : 4NEbN 50.62 : 5NE 50.63 : 6NEbE 67.50 : 7ENE 84.37 : 8EbN 84.38 : 9E101.25 : 10EbS118.12 : 11ESE118.13 : 12SEbE135.00 : 13SE151.87 : 14SEbS151.88 : 15SSE168.75 : 16SbE185.62 : 17S185.63 : 18SbW202.50 : 19SSW219.37 : 20SWbS219.38 : 21SW236.25 : 22SWbW253.12 : 23WSW253.13 : 24WbS270.00 : 25W286.87 : 26WbN286.88 : 27WNW303.75 : 28NWbW320.62 : 29NW320.63 : 30NWbN337.50 : 31NNW354.37 : 32NbW354.38 : 1N
arraybase 1dim names$ = {"North", "North by east", "North-northeast", "Northeast by north", "Northeast", "Northeast by east", "East-northeast", "East by north", "East", "East by south", "East-southeast", "Southeast by east", "Southeast", "Southeast by south", "South-southeast", "South by east", "South", "South by west", "South-southwest", "Southwest by south", "Southwest", "Southwest by west", "West-southwest", "West by south", "West", "West by north", "West-northwest", "Northwest by west", "Northwest", "Northwest by north", "North-northwest", "North by west", "North"}dim grados = {0, 16.87, 16.88, 33.75, 50.62, 50.63, 67.5, 84.37, 84.38, 101.25, 118.12, 118.13, 135, 151.87, 151.88, 168.75, 185.62, 185.63, 202.5, 219.37, 219.38, 236.25, 253.12, 253.13, 270, 286.87, 286.88, 303.75, 320.62, 320.63, 337.5, 354.37, 354.38}for i = grados[?,] to grados[?] j = int((grados[i] + 5.625) / 11.25) if j > 31 then j -= 32 print rjust(string(j),2); " "; ljust(string(names$[j+1]),20); grados[i]next iDIMbearing(32)bearing()=0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,\\84.38,101.25,118.12,118.13,135.0,151.87,151.88,168.75,\\185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,\\270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38FORi%=0TO32box%=FNcompassbox(bearing(i%),compass$)PRINT;bearing(i%),;box%,compass$NEXTENDDEFFNcompassbox(bearing,RETURNbox$)LOCALpt%pt%=INT(bearing/360*32+0.5)MOD32box$=FNpt(pt%)LEFT$(box$,1)=CHR$(ASC(LEFT$(box$,1))-32)=pt%+1DEFFNpt(pt%)LOCALpt$():DIMpt$(3)IFpt%AND1THEN=FNpt((pt%+1)AND28)+" by "+\\FNpt(((2-(pt%AND2))*4)+pt%AND24)IFpt%AND2THEN=FNpt((pt%+2)AND24)+"-"+FNpt((pt%OR4)AND28)IFpt%AND4THEN=FNpt((pt%+8)AND16)+FNpt((pt%OR8)AND24)pt$()="north","east","south","west"=pt$(pt%DIV8)
Output:
0 1 North16.87 2 North by east16.88 3 North-northeast33.75 4 Northeast by north50.62 5 Northeast50.63 6 Northeast by east67.5 7 East-northeast84.37 8 East by north84.38 9 East101.25 10 East by south118.12 11 East-southeast118.13 12 Southeast by east135 13 Southeast151.87 14 Southeast by south151.88 15 South-southeast168.75 16 South by east185.62 17 South185.63 18 South by west202.5 19 South-southwest219.37 20 Southwest by south219.38 21 Southwest236.25 22 Southwest by west253.12 23 West-southwest253.13 24 West by south270 25 West286.87 26 West by north286.88 27 West-northwest303.75 28 Northwest by west320.62 29 Northwest320.63 30 Northwest by north337.5 31 North-northwest354.37 32 North by west354.38 1 North
100dimnames$(31)110restore300120forc=0toubound(names$)130reada$140names$(c)=a$150nextc160dimdegrees(32)170restore380180forc=0toubound(degrees)190readb200degrees(c)=b210nextc220fori=0toubound(degrees)230j=int((degrees(i)+5.625)/11.25)240ifj>31thenj=j-32250printusing"####.##";degrees(i);260printusing" ## ";j;270printnames$(j)280nexti290end300data"North","North by east","North-northeast","Northeast by north"310data"Northeast","Northeast by east","East-northeast","East by north"320data"East","East by south","East-southeast","Southeast by east"330data"Southeast","Southeast by south","South-southeast","South by east"340data"South","South by west","South-southwest","Southwest by south"350data"Southwest","Southwest by west","West-southwest","West by south"360data"West","West by north","West-northwest","Northwest by west","Northwest"370data"Northwest by north","North-northwest","North by west","North"380data0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25390data118.12,118.13,135,151.87,151.88,168.75,185.62,185.63,202.5,219.37400data219.38,236.25,253.12,253.13,270,286.87,286.88,303.75,320.62,320.63410data337.5,354.37,354.388
Same as FreeBASIC entry.
100dimn$(31)110restore300120forc=0to31130reada$140n$(c)=a$150nextc160dimd(32)170restore380180forc=0to32190readb200d(c)=b210nextc220fori=0to32230j=int((d(i)+5.625)/11.25)240ifj>31thenj=j-32250printusing"####.##";d(i);260printusing" ## ";j;270printn$(j)280nexti290end300data"North","North by east","North-northeast","Northeast by north"310data"Northeast","Northeast by east","East-northeast","East by north"320data"East","East by south","East-southeast","Southeast by east"330data"Southeast","Southeast by south","South-southeast","South by east"340data"South","South by west","South-southwest","Southwest by south"350data"Southwest","Southwest by west","West-southwest","West by south"360data"West","West by north","West-northwest","Northwest by west","Northwest"370data"Northwest by north","North-northwest","North by west","North"380data0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25390data118.12,118.13,135,151.87,151.88,168.75,185.62,185.63,202.5,219.37400data219.38,236.25,253.12,253.13,270,286.87,286.88,303.75,320.62,320.63410data337.5,354.37,354.38
Same as FreeBASIC entry.
100 PROGRAM "Compass.bas"110 STRING DR$(1 TO 33)*18120 FOR I=1 TO 33130 READ DR$(I)140 NEXT 150 DO 160 READ IF MISSING EXIT DO:D170 LET DIR=COMP(D)180 PRINT D;TAB(12);DIR,DR$(DIR)190 LOOP 200 DEF COMP(D)=CEIL(MOD((D+360/64),360)*32/360)210 DATA North,North by east,North-northeast,Northeast by north,Northeast,Northeast by east,East-northeast,East by north,East,East by south,East-southeast,Southeast by east,Southeast,Southeast by south,South-southeast,South by east220 DATA South,South by west,South-southwest,Southwest by south,Southwest,Southwest by west,West-southwest,West by south,West,West by north,West-northwest,Northwest by west,Northwest,Northwest by north,North-northwest,North by west,North230 DATA 0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,118.13,135.0,151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38
Output:
0 1 North 16.87 2 North by east 16.88 3 North-northeast 33.75 4 Northeast by north 50.62 5 Northeast 50.63 6 Northeast by east 67.5 7 East-northeast 84.37 8 East by north 84.38 9 East 101.25 10 East by south 118.12 11 East-southeast 118.13 12 Southeast by east 135 13 Southeast 151.87 14 Southeast by south 151.88 15 South-southeast 168.75 16 South by east 185.62 17 South 185.63 18 South by west 202.5 19 South-southwest 219.37 20 Southwest by south 219.38 21 Southwest 236.25 22 Southwest by west 253.12 23 West-southwest 253.13 24 West by south 270 25 West 286.87 26 West by north 286.88 27 West-northwest 303.75 28 Northwest by west 320.62 29 Northwest 320.63 30 Northwest by north 337.5 31 North-northwest 354.37 32 North by west 354.38 1 North
TheGW-BASIC solution works without any changes.
100arrayn$110forc=0to31120reada$130letn$(c)=a$140nextc150arrayd160forc=0to33170readb180letd(c)=b190nextc200fori=1to33210letj=int((d(i)+5.625)/11.25)220ifj>31thenletj=j-32230printd(i);" ";j;" ";n$(j)240nexti250end260data"North","North by east","North-northeast","Northeast by north"270data"Northeast","Northeast by east","East-northeast","East by north"280data"East","East by south","East-southeast","Southeast by east"290data"Southeast","Southeast by south","South-southeast","South by east"300data"South","South by west","South-southwest","Southwest by south"310data"Southwest","Southwest by west","West-southwest","West by south"320data"West","West by north","West-northwest","Northwest by west","Northwest"330data"Northwest by north","North-northwest","North by west","North"340data0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25350data118.12,118.13,135,151.87,151.88,168.75,185.62,185.63,202.5,219.37360data219.38,236.25,253.12,253.13,270,286.87,286.88,303.75,320.62,320.63370data337.5,354.37,354.38
Same as FreeBASIC entry.
>>::"}"9**\4+3%79*9*5-*79*9*5--+:5>>>06p:55+%68*+v^_@#!`*84:+1<v*9"}"*+55,,,".",,,$$_^#!:-1g60/+55\<>_06g:v>55+,^>/5+55+/48*::::,,,,%:1+.9,:06p48*\-0v|p60-1<|<!p80:<N|Ev"northwest"0"North by west"0p8<>:#,_>>>_08g1-^W|S>"-htroN"0"htron yb tsewhtroN"0v#v"est-northwest"0"Northwest by west"0"Northwest"<N>"W"0"htron yb tseW"0"tseW"0"htuos yb tseW"0"ts"v#v0"Southwest"0"Southwest by west"0"West-southwe"<S>"htuos yb tsewhtuoS"0"tsewhtuos-htuoS"0"tsew y"v#v"h-southeast"0"South by east"0"South"0"South b"<E>"tuoS"0"htuos yb tsaehtuoS"0"tsaehtuoS"0"tsae "v#v"East by south"0"East-southeast"0"Southeast by"<W>0"tsaE"0"htron yb tsaE"0"tsaehtron-tsaE"0"tsae"v#v"rtheast by north"0"Northeast"0"Northeast by "<<^>"oN"0"tsaehtron-htroN"0"tsae yb htroN"0"htroN"01
000.00 1 North016.87 2 North by east016.88 3 North-northeast033.75 4 Northeast by north050.62 5 Northeast050.63 6 Northeast by east067.50 7 East-northeast084.37 8 East by north084.38 9 East101.25 10 East by south118.12 11 East-southeast118.13 12 Southeast by east135.00 13 Southeast151.87 14 Southeast by south151.88 15 South-southeast168.75 16 South by east185.62 17 South185.63 18 South by west202.50 19 South-southwest219.37 20 Southwest by south219.38 21 Southwest236.25 22 Southwest by west253.12 23 West-southwest253.13 24 West by south270.00 25 West286.87 26 West by north286.88 27 West-northwest303.75 28 Northwest by west320.62 29 Northwest320.63 30 Northwest by north337.50 31 North-northwest354.37 32 North by west354.38 1 North
LikeWikipedia's article, this program uses indexes to count the headings. There are now 33 headings, from 1 to 33, because 0.0 and 354.38 are different angles. (This differs from the task pseudocode, which mapped the 32 compass points to indexes.)
#include<stdio.h>intmain(){inti,j;doubledegrees[]={0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,118.13,135.0,151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38};constchar*names="North ""North by east ""North-northeast ""Northeast by north ""Northeast ""Northeast by east ""East-northeast ""East by north ""East ""East by south ""East-southeast ""Southeast by east ""Southeast ""Southeast by south ""South-southeast ""South by east ""South ""South by west ""South-southwest ""Southwest by south ""Southwest ""Southwest by west ""West-southwest ""West by south ""West ""West by north ""West-northwest ""Northwest by west ""Northwest ""Northwest by north ""North-northwest ""North by west ""North ";for(i=0;i<33;i++){j=.5+degrees[i]*32/360;printf("%2d %.22s %6.2f\n",(j%32)+1,names+(j%32)*22,degrees[i]);}return0;}
Output:
1 North 0.00 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.50 8 East by north 84.37 9 East 84.3810 East by south 101.2511 East-southeast 118.1212 Southeast by east 118.1313 Southeast 135.0014 Southeast by south 151.8715 South-southeast 151.8816 South by east 168.7517 South 185.6218 South by west 185.6319 South-southwest 202.5020 Southwest by south 219.3721 Southwest 219.3822 Southwest by west 236.2523 West-southwest 253.1224 West by south 253.1325 West 270.0026 West by north 286.8727 West-northwest 286.8828 Northwest by west 303.7529 Northwest 320.6230 Northwest by north 320.6331 North-northwest 337.5032 North by west 354.37 1 North 354.38
usingSystem;usingSystem.Collections.Generic;namespaceBoxTheCompass{classCompass{string[]cp=newstring[]{"North","North by east","North-northeast","Northeast by north","Northeast","Northeast by east","East-northeast","East by north","East","East by south","East-southeast","Southeast by east","Southeast","Southeast by south","South-southeast","South by east","South","South by west","South-southwest","Southwest by south","Southwest","Southwest by west","West-southwest","West by south","West","West by north","West-northwest","Northwest by west","Northwest","Northwest by north","North-northwest","North by west","North"};publicvoidcompassHeading(floata){inth=Convert.ToInt32(Math.Floor(a/11.25f+.5f))%32;Console.WriteLine("{0,2}: {1,-22} : {2,6:N}",h+1,cp[h],a);}};classProgram{staticvoidMain(string[]args){Compassc=newCompass();float[]degs=newfloat[]{0.0f,16.87f,16.88f,33.75f,50.62f,50.63f,67.5f,84.37f,84.38f,101.25f,118.12f,118.13f,135.0f,151.87f,151.88f,168.75f,185.62f,185.63f,202.5f,219.37f,219.38f,236.25f,253.12f,253.13f,270.0f,286.87f,286.88f,303.75f,320.62f,320.63f,337.5f,354.37f,354.38f};foreach(floatdindegs)c.compassHeading(d);Console.WriteLine("\nPress any key to continue...");Console.ReadKey();}}}
1: North : 0.00 2: North by east : 16.87 3: North-northeast : 16.88 4: Northeast by north : 33.75 5: Northeast : 50.62 6: Northeast by east : 50.63 7: East-northeast : 67.50 8: East by north : 84.37 9: East : 84.3810: East by south : 101.2511: East-southeast : 118.1212: Southeast by east : 118.1313: Southeast : 135.0014: Southeast by south : 151.8715: South-southeast : 151.8816: South by east : 168.7517: South : 185.6218: South by west : 185.6319: South-southwest : 202.5020: Southwest by south : 219.3721: Southwest : 219.3822: Southwest by west : 236.2523: West-southwest : 253.1224: West by south : 253.1325: West : 270.0026: West by north : 286.8727: West-northwest : 286.8828: Northwest by west : 303.7529: Northwest : 320.6230: Northwest by north : 320.6331: North-northwest : 337.5032: North by west : 354.37 1: North : 354.38
Using the Boost libraries
#include<string>#include<boost/array.hpp>#include<boost/assign/list_of.hpp>#include<boost/format.hpp>#include<boost/foreach.hpp>#include<iostream>#include<math.h>usingstd::string;usingnamespaceboost::assign;intget_Index(floatangle){returnstatic_cast<int>(floor(angle/11.25+0.5))%32+1;}stringget_Abbr_From_Index(inti){staticboost::array<std::string,32>points(list_of("N")("NbE")("NNE")("NEbN")("NE")("NEbE")("ENE")("EbN")("E")("EbS")("ESE")("SEbE")("SE")("SEbS")("SSE")("SbE")("S")("SbW")("SSW")("SWbS")("SW")("SWbW")("WSW")("WbS")("W")("WbN")("WNW")("NWbW")("NW")("NWbN")("NNW")("NbW"));returnpoints[i-1];}stringBuild_Name_From_Abbreviation(stringa){stringretval;for(inti=0;i<a.size();++i){if((1==i)&&(a[i]!='b')&&(a.size()==3))retval+="-";switch(a[i]){case'N':retval+="north";break;case'S':retval+="south";break;case'E':retval+="east";break;case'W':retval+="west";break;case'b':retval+=" by ";break;}}retval[0]=toupper(retval[0]);returnretval;}intmain(){boost::array<float,33>headings(list_of(0.0)(16.87)(16.88)(33.75)(50.62)(50.63)(67.5)(84.37)(84.38)(101.25)(118.12)(118.13)(135.0)(151.87)(151.88)(168.75)(185.62)(185.63)(202.5)(219.37)(219.38)(236.25)(253.12)(253.13)(270.0)(286.87)(286.88)(303.75)(320.62)(320.63)(337.5)(354.37)(354.38));inti;boost::formatf("%1$4d %2$-20s %3$_7.2f");BOOST_FOREACH(floata,headings){i=get_Index(a);std::cout<<f%i%Build_Name_From_Abbreviation(get_Abbr_From_Index(i))%a<<std::endl;}return0;}
Output:
1 North 0.00 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.50 8 East by north 84.37 9 East 84.38 10 East by south 101.25 11 East-southeast 118.12 12 Southeast by east 118.13 13 Southeast 135.00 14 Southeast by south 151.87 15 South-southeast 151.88 16 South by east 168.75 17 South 185.62 18 South by west 185.63 19 South-southwest 202.50 20 Southwest by south 219.37 21 Southwest 219.38 22 Southwest by west 236.25 23 West-southwest 253.12 24 West by south 253.13 25 West 270.00 26 West by north 286.87 27 West-northwest 286.88 28 Northwest by west 303.75 29 Northwest 320.62 30 Northwest by north 320.63 31 North-northwest 337.50 32 North by west 354.37 1 North 354.38
(nsboxing-the-compass(:use[clojure.string:only[capitalize]]))(defheadings(for[i(range0(inc32))](let[heading(*i11.25)](case(modi3)1(+heading5.62)2(-heading5.62)heading))))(defnangle2compass[angle](let[dirs["N""NbE""N-NE""NEbN""NE""NEbE""E-NE""EbN""E""EbS""E-SE""SEbE""SE""SEbS""S-SE""SbE""S""SbW""S-SW""SWbS""SW""SWbW""W-SW""WbS""W""WbN""W-NW""NWbW""NW""NWbN""N-NW""NbW"]unpack{\N"north"\E"east"\W"west"\S"south"\b" by "\-"-"}sep(/360(countdirs))dir(int(/(mod(+angle(/sep2))360)sep))](capitalize(applystr(mapunpack(dirsdir))))))(print(applystr(map-indexed#(format"%2s %-18s %7.2f\n"(inc(mod%132))(angle2compass%2)%2)headings)))
Output:
1 North 0.00 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.50 8 East by north 84.37 9 East 84.3810 East by south 101.2511 East-southeast 118.1212 Southeast by east 118.1313 Southeast 135.0014 Southeast by south 151.8715 South-southeast 151.8816 South by east 168.7517 South 185.6218 South by west 185.6319 South-southwest 202.5020 Southwest by south 219.3721 Southwest 219.3822 Southwest by west 236.2523 West-southwest 253.1224 West by south 253.1325 West 270.0026 West by north 286.8727 West-northwest 286.8828 Northwest by west 303.7529 Northwest 320.6230 Northwest by north 320.6331 North-northwest 337.5032 North by west 354.37 1 North 354.38
Works with GnuCOBOL
identificationdivision.program-id.box-compass.datadivision.working-storagesection.01pointpic 99.01degreesusagefloat-short.01degrees-roundedpic 999v99.01show-degreespic zz9.99.01boxpic z9.01fudgepic 9.01compasspic x(4).01compass-pointpic x(18).01shortformpic x.01short-names.05short-namepic x(4)occurs33times.01overlay.05value"N "&"NbE "&"N-NE"&"NEbN"&"NE "&"NEbE"&"E-NE"&"EbN "&"E "&"EbS "&"E-SE"&"SEbE"&"SE "&"SEbS"&"S-SE"&"SbE "&"S "&"SbW "&"S-SW"&"SWbS"&"SW "&"SWbW"&"W-SW"&"WbS "&"W "&"WbN "&"W-NW"&"NWbW"&"NW "&"NWbN"&"N-NW"&"NbW "&"N ".proceduredivision.display"Index Compass point Degree"moveoverlaytoshort-names.performvaryingpointfrom0by1untilpoint>32computebox=functionmod(point32)+1computedegrees=point*11.25computefudge=functionmod(point3)evaluatefudgewhenequal1add5.62todegreeswhenequal2subtract5.62fromdegreesend-evaluatecomputedegrees-roundedrounded=degreesmovedegrees-roundedtoshow-degreesinspectshow-degreesreplacingtrailing'00'by'0 'inspectshow-degreesreplacingtrailing'50'by'5 'moveshort-name(point+1)tocompassmovespacestocompass-pointdisplayspaceboxspacespacespacewithnoadvancingperformvaryingtallyfrom1by1untiltally>4movecompass(tally:1)toshortformmovefunctionconcatenate(functiontrim(compass-point),functionsubstitute(shortform,"N","North","E","East","S","South","W","West","b"," byZ","-","-"))tocompass-pointend-performmovefunctionsubstitute(compass-point,"Z"," ")tocompass-pointmovefunctionlower-case(compass-point)tocompass-pointmovefunctionupper-case(compass-point(1:1))tocompass-point(1:1)displaycompass-pointspaceshow-degreesend-performgoback.
Index Compass point Degree 1 North 0.0 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.5 8 East by north 84.37 9 East 84.38 10 East by south 101.25 11 East-southeast 118.12 12 Southeast by east 118.13 13 Southeast 135.0 14 Southeast by south 151.87 15 South-southeast 151.88 16 South by east 168.75 17 South 185.62 18 South by west 185.63 19 South-southwest 202.5 20 Southwest by south 219.37 21 Southwest 219.38 22 Southwest by west 236.25 23 West-southwest 253.12 24 West by south 253.13 25 West 270.0 26 West by north 286.87 27 West-northwest 286.88 28 Northwest by west 303.75 29 Northwest 320.62 30 Northwest by north 320.63 31 North-northwest 337.5 32 North by west 354.37 1 North 354.38
importstd.stdio,std.string,std.math,std.array;structboxTheCompass{immutablestaticstring[32]points;purenothrowstaticthis(){immutablecardinal=["north","east","south","west"];immutabledesc=["1","1 by 2","1-C","C by 1","C","C by 2","2-C","2 by 1"];foreach(immutablei;0..4){immutables1=cardinal[i];immutables2=cardinal[(i+1)%4];immutablesc=(s1=="north"||s1=="south")?(s1~s2):(s2~s1);foreach(immutablej;0..8)points[i*8+j]=desc[j].replace("1",s1).replace("2",s2).replace("C",sc);}}staticstringopCall(indoubledegrees)pure/*nothrow*/{immutabletestD=(degrees/11.25)+0.5;returnpoints[cast(int)floor(testD%32)].capitalize;}}voidmain(){foreach(immutablei;0..33){immutableheading=i*11.25+[0,5.62,-5.62][i%3];writefln("%s\t%18s\t%s",i%32+1,heading.boxTheCompass,heading);}}
1 North 02 North by east 16.873 North-northeast 16.884 Northeast by north 33.755 Northeast 50.626 Northeast by east 50.637 East-northeast 67.58 East by north 84.379 East 84.3810 East by south 101.2511 East-southeast 118.1212 Southeast by east 118.1313 Southeast 13514 Southeast by south 151.8715 South-southeast 151.8816 South by east 168.7517 South 185.6218 South by west 185.6319 South-southwest 202.520 Southwest by south 219.3721 Southwest 219.3822 Southwest by west 236.2523 West-southwest 253.1224 West by south 253.1325 West 27026 West by north 286.8727 West-northwest 286.8828 Northwest by west 303.7529 Northwest 320.6230 Northwest by north 320.6331 North-northwest 337.532 North by west 354.371 North 354.38
voidmain(){importstd.stdio;immutablebox=["North","North by east","North-northeast","Northeast by north","Northeast","Northeast by east","East-northeast","East by north","East","East by south","East-southeast","Southeast by east","Southeast","Southeast by south","South-southeast","South by east","South","South by west","South-southwest","Southwest by south","Southwest","Southwest by west","West-southwest","West by south","West","West by north","West-northwest","Northwest by west","Northwest","Northwest by north","North-northwest","North by west"];immutableangles=[0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,118.13,135.0,151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38];foreach(immutablephi;angles){immutablei=(cast(int)(phi*32.0/360.0+0.5))%32;writefln("%2d %18s %6.2f",i+1,box[i],phi);}}
1 North 0.00 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.50 8 East by north 84.37 9 East 84.3810 East by south 101.2511 East-southeast 118.1212 Southeast by east 118.1313 Southeast 135.0014 Southeast by south 151.8715 South-southeast 151.8816 South by east 168.7517 South 185.6218 South by west 185.6319 South-southwest 202.5020 Southwest by south 219.3721 Southwest 219.3822 Southwest by west 236.2523 West-southwest 253.1224 West by south 253.1325 West 270.0026 West by north 286.8727 West-northwest 286.8828 Northwest by west 303.7529 Northwest 320.6230 Northwest by north 320.6331 North-northwest 337.5032 North by west 354.37 1 North 354.38
SeePascal.
func$ expand cp$ . for c$ in strchars cp$ if c$ = "N" r$ &= "north" elif c$ = "E" r$ &= "east" elif c$ = "S" r$ &= "south" elif c$ = "W" r$ &= "west" elif c$ = "b" r$ &= "by" else r$ &= "-" . . h$ = strchar (strcode substr r$ 1 1 - 32) return h$ & substr r$ 2 999.proc main . cp$[] = [ "N" "NbE" "N-NE" "NEbN" "NE" "NEbE" "E-NE" "EbN" "E" "EbS" "E-SE" "SEbE" "SE" "SEbS" "S-SE" "SbE" "S" "SbW" "S-SW" "SWbS" "SW" "SWbW" "W-SW" "WbS" "W" "WbN" "W-NW" "NWbW" "NW" "NWbN" "N-NW" "NbW" ] print "Index Degrees Compass point" print "----- ------- -------------" for i = 0 to 32 ind = (i + 1) mod1 32 heading = i * 11.25 if i mod 3 = 1 heading += 5.62 elif i mod 3 = 2 heading -= 5.62 . print ind & "\t" & heading & "\t" & expand cp$[ind] ..main
Index Degrees Compass point----- ------- -------------10North216.87Northbyeast316.88North-northeast433.75Northeastbynorth550.62Northeast650.63Northeastbyeast767.50East-northeast884.37Eastbynorth984.38East10101.25Eastbysouth11118.12East-southeast12118.13Southeastbyeast13135Southeast14151.87Southeastbysouth15151.88South-southeast16168.75Southbyeast17185.62South18185.63Southbywest19202.50South-southwest20219.37Southwestbysouth21219.38Southwest22236.25Southwestbywest23253.12West-southwest24253.13Westbysouth25270West26286.87Westbynorth27286.88West-northwest28303.75Northwestbywest29320.62Northwest30320.63Northwestbynorth31337.50North-northwest32354.37Northbywest1354.38North
defmoduleBoxdodefpheaddoEnum.chunk(~w(north east south west north),2,1)|>Enum.flat_map(fn[a,b]->c=ifa=="north"ora=="south",do:"#{a}#{b}",else:"#{b}#{a}"[a,"#{a} by#{b}","#{a}-#{c}","#{c} by#{a}",c,"#{c} by#{b}","#{b}-#{c}","#{b} by#{a}"]end)|>Enum.with_index|>Enum.map(fn{s,i}->{i+1,String.capitalize(s)}end)|>Map.newenddefcompassdoheader=head()angles=Enum.map(0..32,fni->i*11.25+elem({0,5.62,-5.62},rem(i,3))end)Enum.each(angles,fndegrees->index=rem(round(32*degrees/360),32)+1:io.format"~2w ~-20s ~6.2f~n",[index,header[index],degrees]end)endendBox.compass
1 North 0.00 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.50 8 East by north 84.37 9 East 84.3810 East by south 101.2511 East-southeast 118.1212 Southeast by east 118.1313 Southeast 135.0014 Southeast by south 151.8715 South-southeast 151.8816 South by east 168.7517 South 185.6218 South by west 185.6319 South-southwest 202.5020 Southwest by south 219.3721 Southwest 219.3822 Southwest by west 236.2523 West-southwest 253.1224 West by south 253.1325 West 270.0026 West by north 286.8727 West-northwest 286.8828 Northwest by west 303.7529 Northwest 320.6230 Northwest by north 320.6331 North-northwest 337.5032 North by west 354.37 1 North 354.38
constant names = {"North","North by east","North-northeast","Northeast by north", "Northeast","Northeast by east","East-northeast","East by north","East", "East by south","East-southeast","Southeast by east","Southeast","Southeast by south", "South-southeast","South by east","South","South by west","South-southwest", "Southwest by south","Southwest","Southwest by west","West-southwest", "West by south","West","West by north","West-northwest","Northwest by west", "Northwest","Northwest by north","North-northwest","North by west"}function deg2ind(atom degree) return remainder(floor(degree*32/360+.5),32)+1end functionsequence degreesdegrees = {}for i = 0 to 32 do degrees &= i*11.25 + 5.62*(remainder(i+1,3)-1)end forinteger jfor i = 1 to length(degrees) do j = deg2ind(degrees[i]) printf(1, "%6.2f %2d %-22s\n", {degrees[i], j, names[j]})end forOutput:
0.00 1 North 16.87 2 North by east 16.88 3 North-northeast 33.75 4 Northeast by north 50.62 5 Northeast 50.63 6 Northeast by east 67.50 7 East-northeast 84.37 8 East by north 84.38 9 East101.25 10 East by south118.12 11 East-southeast118.13 12 Southeast by east135.00 13 Southeast151.87 14 Southeast by south151.88 15 South-southeast168.75 16 South by east185.62 17 South185.63 18 South by west202.50 19 South-southwest219.37 20 Southwest by south219.38 21 Southwest236.25 22 Southwest by west253.12 23 West-southwest253.13 24 West by south270.00 25 West286.87 26 West by north286.88 27 West-northwest303.75 28 Northwest by west320.62 29 Northwest320.63 30 Northwest by north337.50 31 North-northwest354.37 32 North by west354.38 1 North
letbox=[|"North";"North by east";"North-northeast";"Northeast by north";"Northeast";"Northeast by east";"East-northeast";"East by north";"East";"East by south";"East-southeast";"Southeast by east";"Southeast";"Southeast by south";"South-southeast";"South by east";"South";"South by west";"South-southwest";"Southwest by south";"Southwest";"Southwest by west";"West-southwest";"West by south";"West";"West by north";"West-northwest";"Northwest by west";"Northwest";"Northwest by north";"North-northwest";"North by west"|][0.0;16.87;16.88;33.75;50.62;50.63;67.5;84.37;84.38;101.25;118.12;118.13;135.0;151.87;151.88;168.75;185.62;185.63;202.5;219.37;219.38;236.25;253.12;253.13;270.0;286.87;286.88;303.75;320.62;320.63;337.5;354.37;354.38]|>List.iter(funphi->leti=(int(phi*32./360.+0.5))%32printf"%3d %18s %6.2f°\n"(i+1)box.[i]phi)
1 North 0.00° 2 North by east 16.87° 3 North-northeast 16.88° 4 Northeast by north 33.75° 5 Northeast 50.62° 6 Northeast by east 50.63° 7 East-northeast 67.50° 8 East by north 84.37° 9 East 84.38° 10 East by south 101.25° 11 East-southeast 118.12° 12 Southeast by east 118.13° 13 Southeast 135.00° 14 Southeast by south 151.87° 15 South-southeast 151.88° 16 South by east 168.75° 17 South 185.62° 18 South by west 185.63° 19 South-southwest 202.50° 20 Southwest by south 219.37° 21 Southwest 219.38° 22 Southwest by west 236.25° 23 West-southwest 253.12° 24 West by south 253.13° 25 West 270.00° 26 West by north 286.87° 27 West-northwest 286.88° 28 Northwest by west 303.75° 29 Northwest 320.62° 30 Northwest by north 320.63° 31 North-northwest 337.50° 32 North by west 354.37° 1 North 354.38°
USING:formattingkernelmathsequences;CONSTANT:box{"North""North by east""North-northeast""Northeast by north""Northeast""Northeast by east""East-northeast""East by north""East""East by south""East-southeast""Southeast by east""Southeast""Southeast by south""South-southeast""South by east""South""South by west""South-southwest""Southwest by south""Southwest""Southwest by west""West-southwest""West by south""West""West by north""West-northwest""Northwest by west""Northwest""Northwest by north""North-northwest""North by west"}{0 16.87 16.88 33.75 50.62 50.63 67.5 84.37 84.38 101.25118.12 118.13 135 151.87 151.88 168.75 185.62 185.63 202.5219.37 219.38 236.25 253.12 253.13 270 286.87 286.88 303.75320.62 320.63 337.5 354.37 354.38}[dup32*360/f0.5+>integer32mod[1+][boxnth]bi"%6.2f° %2d %s\n"printf]each
0.00° 1 North 16.87° 2 North by east 16.88° 3 North-northeast 33.75° 4 Northeast by north 50.62° 5 Northeast 50.63° 6 Northeast by east 67.50° 7 East-northeast 84.37° 8 East by north 84.38° 9 East101.25° 10 East by south118.12° 11 East-southeast118.13° 12 Southeast by east135.00° 13 Southeast151.87° 14 Southeast by south151.88° 15 South-southeast168.75° 16 South by east185.62° 17 South185.63° 18 South by west202.50° 19 South-southwest219.37° 20 Southwest by south219.38° 21 Southwest236.25° 22 Southwest by west253.12° 23 West-southwest253.13° 24 West by south270.00° 25 West286.87° 26 West by north286.88° 27 West-northwest303.75° 28 Northwest by west320.62° 29 Northwest320.63° 30 Northwest by north337.50° 31 North-northwest354.37° 32 North by west354.38° 1 North
ProgramCompassimplicit noneinteger::i,indreal::headingdoi=0,32heading=i*11.25if(mod(i,3)==1)thenheading=heading+5.62else if(mod(i,3)==2)thenheading=heading-5.62end ifind=mod(i,32)+1write(*,"(i2, a20, f8.2)")ind,compasspoint(heading),headingend docontainsfunctioncompasspoint(h)character(18)::compasspointcharacter(18)::points(32)=(/"North ","North by east ","North-northeast ",&"Northeast by north","Northeast ","Northeast by east ","East-northeast ",&"East by north ","East ","East by south ","East-southeast ",&"Southeast by east ","Southeast ","Southeast by south","South-southeast ",&"South by east ","South ","South by west ","South-southwest ",&"Southwest by south","Southwest ","Southwest by west ","West-southwest ",&"West by south ","West ","West by north ","West-northwest ",&"Northwest by west ","Northwest ","Northwest by north","North-northwest ",&"North by west "/)real,intent(in)::hreal::xx=h/11.25+1.5if(x>=33.0)x=x-32.0compasspoint=points(int(x))end functioncompasspointend programCompass
Output:
1 North 0.00 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.50 8 East by north 84.37 9 East 84.3810 East by south 101.2511 East-southeast 118.1212 Southeast by east 118.1313 Southeast 135.0014 Southeast by south 151.8715 South-southeast 151.8816 South by east 168.7517 South 185.6218 South by west 185.6319 South-southwest 202.5020 Southwest by south 219.3721 Southwest 219.3822 Southwest by west 236.2523 West-southwest 253.1224 West by south 253.1325 West 270.0026 West by north 286.8727 West-northwest 286.8828 Northwest by west 303.7529 Northwest 320.6230 Northwest by north 320.6331 North-northwest 337.5032 North by west 354.37 1 North 354.38
' version 04-11-2016' compile with: fbc -s consoleDimAsStringnames(0To...)={"North","North by east","North-northeast",_"Northeast by north","Northeast","Northeast by east","East-northeast",_"East by north","East","East by south","East-southeast",_"Southeast by east","Southeast","Southeast by south","South-southeast",_"South by east","South","South by west","South-southwest",_"Southwest by south","Southwest","Southwest by west","West-southwest",_"West by south","West","West by north","West-northwest",_"Northwest by west","Northwest","Northwest by north","North-northwest",_"North by west","North"}DimAsDoubledegrees(0To...)={0,16.87,16.88,33.75,50.62,50.63,_67.5,84.37,84.38,101.25,118.12,118.13,135,151.87,151.88,168.75,_185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270,_286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38}DimAsULongi,jFori=LBound(degrees)ToUBound(degrees)j=Int((degrees(i)+5.625)/11.25)Ifj>31Thenj=j-32PrintUsing"####.## ## ";degrees(i);j;Printnames(j)Next' empty keyboard bufferWhileInkey<>"":WendPrint:Print"hit any key to end program"SleepEnd
0.00 0 North 16.87 1 North by east 16.88 2 North-northeast 33.75 3 Northeast by north 50.62 4 Northeast 50.63 5 Northeast by east 67.50 6 East-northeast 84.37 7 East by north 84.38 8 East 101.25 9 East by south 118.12 10 East-southeast 118.13 11 Southeast by east 135.00 12 Southeast 151.87 13 Southeast by south 151.88 14 South-southeast 168.75 15 South by east 185.62 16 South 185.63 17 South by west 202.50 18 South-southwest 219.37 19 Southwest by south 219.38 20 Southwest 236.25 21 Southwest by west 253.12 22 West-southwest 253.13 23 West by south 270.00 24 West 286.87 25 West by north 286.88 26 West-northwest 303.75 27 Northwest by west 320.62 28 Northwest 320.63 29 Northwest by north 337.50 30 North-northwest 354.37 31 North by west 354.38 0 North
window 1,@"Box the Compass"_Name = 0_Degrees = 1// mda defaults to mda _Namemda(0)=@"North":mda(1)=@"North by east":mda(2)=@"North-northeast"mda(3)=@"Northeast by north":mda(4)=@"Northeast":mda(5)=@"Northeast by east":mda(6)=@"East-northeast"mda(7)=@"East by north":mda(8)=@"East":mda(9)=@"East by south":mda(10)=@"East-southeast"mda(11)=@"Southeast by east":mda(12)=@"Southeast":mda(13)=@"Southeast by south":mda(14)=@"South-southeast"mda(15)=@"South by east":mda(16)= @"South":mda(17)= @"South by west":mda(18)= @"South-southwest"mda(19)=@"Southwest by south":mda(20)=@"Southwest":mda(21)=@"Southwest by west":mda(22)=@"West-southwest"mda(23)=@"West by south":mda(24)=@"West":mda(25)=@"West by north":mda(26)=@"West-northwest"mda(27)=@"Northwest by west":mda(28)=@"Northwest":mda(29)=@"Northwest by north":mda(30)=@"North-northwest"mda(31)=@"North by west":mda(32)=@"North"mda _Degrees (0) = { 0, 16.87, 16.88, 33.75, 50.62, 50.63,¬67.5, 84.37, 84.38, 101.25, 118.12, 118.13, 135, 151.87, 151.88, 168.75,¬185.62, 185.63, 202.5, 219.37, 219.38, 236.25, 253.12, 253.13, 270,¬286.87, 286.88, 303.75, 320.62, 320.63, 337.5, 354.37, 354.38 }unsigned Long i, jFor i = 0 To 32 j = fix((mda_double _Degrees(i) + 5.625) / 11.25) If j > 31 Then j = j - 32 Print Using "###.## "; (mda_double _Degrees(i)); Print Using "## "; j; Print mda _Name(j)Nexthandleevents0.00 0 North 16.87 1 North by east 16.88 2 North-northeast 33.75 3 Northeast by north 50.62 4 Northeast 50.63 5 Northeast by east 67.50 6 East-northeast 84.37 7 East by north 84.38 8 East 101.25 9 East by south 118.12 10 East-southeast 118.13 11 Southeast by east 135.00 12 Southeast 151.87 13 Southeast by south 151.88 14 South-southeast 168.75 15 South by east 185.62 16 South 185.63 17 South by west 202.50 18 South-southwest 219.37 19 Southwest by south 219.38 20 Southwest 236.25 21 Southwest by west 253.12 22 West-southwest 253.13 23 West by south 270.00 24 West 286.87 25 West by north 286.88 26 West-northwest 303.75 27 Northwest by west 320.62 28 Northwest 320.63 29 Northwest by north 337.50 30 North-northwest 354.37 31 North by west 354.38 0 North
Click this link to run this code
PublicSubMain()DimfDegAsFloat[]=[0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,118.13,135.0,151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38]DimcHeadingAsCollection=["N":"North","S":"South","W":"West","E":"East","b":"by"]DimsHeadingAsString[]=["N","NbE","NNE","NEbE","NE","NEbE","ENE","EbN","E","EbS","ESE","SEbE","SE","SEbS","SSE","SbE","S","SbW","SSW","SWbS","SW","SWbW","WSW","WbS","W","WbN","WNW","NWbW","NW","NWbN","NNW","NbW"]DimsiLoopAsShortDimsDirectionAsStringDimfCount,fTempAsFloatForEachfCountInfDegfTemp=Round(fCount/11.25)IffTemp=32ThenfTemp=0ForsiLoop=0ToLen(sHeading[fTemp])sDirection&=cHeading[Mid(sHeading[fTemp],siLoop+1,1)]&" "NextPrint"Index="&Format(fTemp+1,"#0")&" "&Format(Str(fCount),"##0.00")&" degrees = "&sDirectionsDirection=""NextEnd
Output:
Index= 1 0.00 degrees = North Index= 2 16.87 degrees = North by East Index= 3 16.88 degrees = North North East Index= 4 33.75 degrees = North East by East Index= 5 50.62 degrees = North East Index= 6 50.63 degrees = North East by East Index= 7 67.50 degrees = East North East Index= 8 84.37 degrees = East by North Index= 9 84.38 degrees = East Index=10 101.25 degrees = East by South Index=11 118.12 degrees = East South East Index=12 118.13 degrees = South East by East Index=13 135.00 degrees = South East Index=14 151.87 degrees = South East by South Index=15 151.88 degrees = South South East Index=16 168.75 degrees = South by East Index=17 185.62 degrees = South Index=18 185.63 degrees = South by West Index=19 202.50 degrees = South South West Index=20 219.37 degrees = South West by South Index=21 219.38 degrees = South West Index=22 236.25 degrees = South West by West Index=23 253.12 degrees = West South West Index=24 253.13 degrees = West by South Index=25 270.00 degrees = West Index=26 286.87 degrees = West by North Index=27 286.88 degrees = West North West Index=28 303.75 degrees = North West by West Index=29 320.62 degrees = North West Index=30 320.63 degrees = North West by North Index=31 337.50 degrees = North North West Index=32 354.37 degrees = North by West Index= 1 354.38 degrees = North
packagemainimport"fmt"// function required by taskfuncdegrees2compasspoint(hfloat32)string{returncompassPoint[cpx(h)]}// cpx returns integer index from 0 to 31 corresponding to compass point.// input heading h is in degrees. Note this index is a zero-based index// suitable for indexing into the table of printable compass points,// and is not the same as the index specified to be printed in the output.funccpx(hfloat32)int{x:=int(h/11.25+.5)%32ifx<0{x+=32}returnx}// printable compass pointsvarcompassPoint=[]string{"North","North by east","North-northeast","Northeast by north","Northeast","Northeast by east","East-northeast","East by north","East","East by south","East-southeast","Southeast by east","Southeast","Southeast by south","South-southeast","South by east","South","South by west","South-southwest","Southwest by south","Southwest","Southwest by west","West-southwest","West by south","West","West by north","West-northwest","Northwest by west","Northwest","Northwest by north","North-northwest","North by west",}funcmain(){fmt.Println("Index Compass point Degree")fori,h:=range[]float32{0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,118.13,135.0,151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38}{index:=i%32+1// printable index computed per pseudocodefmt.Printf("%4d %-19s %7.2f°\n",index,degrees2compasspoint(h),h)}}
Index Compass point Degree 1 North 0.00° 2 North by east 16.87° 3 North-northeast 16.88° 4 Northeast by north 33.75° 5 Northeast 50.62° 6 Northeast by east 50.63° 7 East-northeast 67.50° 8 East by north 84.37° 9 East 84.38° 10 East by south 101.25° 11 East-southeast 118.12° 12 Southeast by east 118.13° 13 Southeast 135.00° 14 Southeast by south 151.87° 15 South-southeast 151.88° 16 South by east 168.75° 17 South 185.62° 18 South by west 185.63° 19 South-southwest 202.50° 20 Southwest by south 219.37° 21 Southwest 219.38° 22 Southwest by west 236.25° 23 West-southwest 253.12° 24 West by south 253.13° 25 West 270.00° 26 West by north 286.87° 27 West-northwest 286.88° 28 Northwest by west 303.75° 29 Northwest 320.62° 30 Northwest by north 320.63° 31 North-northwest 337.50° 32 North by west 354.37° 1 North 354.38°
defasCompassPoint(angle){defcardinalDirections=["north","east","south","west"]intindex=Math.floor(angle/ 11.25 + 0.5) int cardinalIndex = (index /8)defc1=cardinalDirections[cardinalIndex%4]defc2=cardinalDirections[(cardinalIndex+1)%4]defc3=(cardinalIndex==0||cardinalIndex==2)?"$c1$c2":"$c2$c1"defpoint=["$c1","$c1 by $c2","$c1-$c3","$c3 by $c1","$c3","$c3 by $c2","$c2-$c3","$c2 by $c1"][index%8]point.substring(0,1).toUpperCase()+point.substring(1)}Number.metaClass.asCompassPoint={asCompassPoint(delegate)}[0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,118.13,135.0,151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38].eachWithIndex{angle,index->println"${(index % 32) + 1}".padRight(3)+"${angle.asCompassPoint().padLeft(20)} $angle\u00b0"}
Output:
1 North 0.0°2 North by east 16.87°3 North-northeast 16.88°4 Northeast by north 33.75°5 Northeast 50.62°6 Northeast by east 50.63°7 East-northeast 67.5°8 East by north 84.37°9 East 84.38°10 East by south 101.25°11 East-southeast 118.12°12 Southeast by east 118.13°13 Southeast 135.0°14 Southeast by south 151.87°15 South-southeast 151.88°16 South by east 168.75°17 South 185.62°18 South by west 185.63°19 South-southwest 202.5°20 Southwest by south 219.37°21 Southwest 219.38°22 Southwest by west 236.25°23 West-southwest 253.12°24 West by south 253.13°25 West 270.0°26 West by north 286.87°27 West-northwest 286.88°28 Northwest by west 303.75°29 Northwest 320.62°30 Northwest by north 320.63°31 North-northwest 337.5°32 North by west 354.37°1 North 354.38°
importData.Char(toUpper)importData.Maybe(fromMaybe)importText.Printf(PrintfType,printf)dirs::[String]dirs=["N","NbE","N-NE","NEbN","NE","NEbE","E-NE","EbN","E","EbS","E-SE","SEbE","SE","SEbS","S-SE","SbE","S","SbW","S-SW","SWbS","SW","SWbW","W-SW","WbS","W","WbN","W-NW","NWbW","NW","NWbN","N-NW","NbW"]-- Index between 0 and 31 -> the corresponding compass point name.pointName::Int->StringpointName=capitalize.concatMap(fromMaybe"?".fromChar).(dirs!!)wherefromCharc=lookupc[('N',"north"),('S',"south"),('E',"east"),('W',"west"),('b'," by "),('-',"-")]capitalize(c:cs)=toUpperc:cs-- Degrees -> compass point index between 0 and 31.pointIndex::Double->IntpointIndexd=(round(d*1000)+5625)`mod`360000`div`11250printPointName::PrintfTypet=>String->tprintPointNamed=letdeg=readd::Doubleidx=pointIndexdeginprintf"%2d %-18s %6.2f°\n"(idx+1)(pointNameidx)degmain::IO()main=mapM_(printPointName.show)[0..31]
Output:
1 North 0.00° 2 North by east 16.87° 3 North-northeast 16.88° 4 Northeast by north 33.75° 5 Northeast 50.62° 6 Northeast by east 50.63° 7 East-northeast 67.50° 8 East by north 84.37° 9 East 84.38°10 East by south 101.25°11 East-southeast 118.12°12 Southeast by east 118.13°13 Southeast 135.00°14 Southeast by south 151.87°15 South-southeast 151.88°16 South by east 168.75°17 South 185.62°18 South by west 185.63°19 South-southwest 202.50°20 Southwest by south 219.37°21 Southwest 219.38°22 Southwest by west 236.25°23 West-southwest 253.12°24 West by south 253.13°25 West 270.00°26 West by north 286.87°27 West-northwest 286.88°28 Northwest by west 303.75°29 Northwest 320.62°30 Northwest by north 320.63°31 North-northwest 337.50°32 North by west 354.37° 1 North 354.38°
import Algorithms as algo;import Text as text;class Compass { _majors = none; _quarter1 = none; _quarter2 = none; constructor() { _majors = algo.materialize( text.split( "north east south west", " " ), tuple ); _majors += _majors; _quarter1 = text.split( "N,N by E,N-NE,NE by N,NE,NE by E,E-NE,E by N", "," ); _quarter2 = algo.materialize( algo.map( _quarter1, @( s ){ copy( s ).replace( "NE", "EN" ); } ), list ); } degrees_to_compasspoint( d ) { d = d % 360. + 360. / 64.; majorindex, minor = ( integer( d ) / 90, d % 90. ); minorindex = integer( minor * 4. ) / 45; p1, p2 = _majors[majorindex: majorindex + 2]; q = none; if ( p1 ∈ { "north", "south" } ) { q = _quarter1; } else { q = _quarter2; } return ( text.capitalize( copy( q[minorindex] ).replace( "N", p1 ).replace( "E", p2 ) ) ); }}main() { print( " # | Angle | Compass point\n" "---+---------|-------------------\n" ); c = Compass(); for ( i : algo.range( 33 ) ) { d = real( i ) * 11.25; m = i % 3; if ( m == 1 ) { d += 5.62; } else if ( m == 2 ) { d -= 5.62; } n = i % 32 + 1; print( "{:2d} | {:6.2f}° | {}\n".format( n, d, c.degrees_to_compasspoint( d ) ) ); }}Output:
# | Angle | Compass point---+---------|------------------- 1 | 0.00° | North 2 | 16.87° | North by east 3 | 16.88° | North-northeast 4 | 33.75° | Northeast by north 5 | 50.62° | Northeast 6 | 50.63° | Northeast by east 7 | 67.50° | East-northeast 8 | 84.37° | East by north 9 | 84.38° | East10 | 101.25° | East by south11 | 118.12° | East-southeast12 | 118.13° | Southeast by east13 | 135.00° | Southeast14 | 151.87° | Southeast by south15 | 151.88° | South-southeast16 | 168.75° | South by east17 | 185.62° | South18 | 185.63° | South by west19 | 202.50° | South-southwest20 | 219.37° | Southwest by south21 | 219.38° | Southwest22 | 236.25° | Southwest by west23 | 253.12° | West-southwest24 | 253.13° | West by south25 | 270.00° | West26 | 286.87° | West by north27 | 286.88° | West-northwest28 | 303.75° | Northwest by west29 | 320.62° | Northwest30 | 320.63° | Northwest by north31 | 337.50° | North-northwest32 | 354.37° | North by west 1 | 354.38° | North
The following code works in both languages.
linkstrings,numbersproceduremain()everyheading:=11.25*(i:=0to32)do{casei%3of{1:heading+:=5.622:heading-:=5.62}write(right(i%32+1,3)," ",left(direction(heading),20)," ",fix(heading,,7,2))}endproceduredirection(d)# compass heading given +/- degreesstaticdirsinitial{everyput(dirs:=[],replacem(!["N","NbE","N-NE","NEbN","NE","NEbE","E-NE","EbN","E","EbS","E-SE","SEbE","SE","SEbS","S-SE","SbE","S","SbW","S-SW","SWbS","SW","SWbW","W-SW","WbS","W","WbN","W-NW","NWbW","NW","NWbN","N-NW","NbW"],"N","north","E","east","W","west","S","south","b"," by "))}returndirs[round(((((d%360)+360)%360)/11.25))%32+1]end
strings for replacemnumbers for round, fix
Output:
1 north 0.00 2 north by east 16.87 3 north-northeast 16.88 4 northeast by north 33.75 5 northeast 50.62 6 northeast by east 50.63 7 east-northeast 67.50 8 east by north 84.37 9 east 84.38 10 east by south 101.25 11 east-southeast 118.12 12 southeast by east 118.13 13 southeast 135.00 14 southeast by south 151.87 15 south-southeast 151.88 16 south by east 168.75 17 south 185.62 18 south by west 185.63 19 south-southwest 202.50 20 southwest by south 219.37 21 southwest 219.38 22 southwest by west 236.25 23 west-southwest 253.12 24 west by south 253.13 25 west 270.00 26 west by north 286.87 27 west-northwest 286.88 28 northwest by west 303.75 29 northwest 320.62 30 northwest by north 320.63 31 north-northwest 337.50 32 north by west 354.37 1 north 354.38
require'strings'subs=:'N,north,S,south,E,east,W,west,b, by ,'dirs=:subs(toupper@{.,}.)@rplc~L:10&(<;._2)0 :0 -. ' ',LF N,NbE,N-NE,NEbN,NE,NEbE,E-NE,EbN,E,EbS,E-SE,SEbE,SE,SEbS,S-SE,SbE, S,SbW,S-SW,SWbS,SW,SWbW,W-SW,WbS,W,WbN,W-NW,NWbW,NW,NWbN,N-NW,NbW,)indice=:32|0.5<.@+%&11.25deg2pnt=:dirs{~indice
Example use:
i.100123456789deg2pnti.10┌─────┬─────┬─────┬─────┬─────┬─────┬─────────────┬─────────────┬─────────────┬─────────────┐│North│North│North│North│North│North│Northbyeast│Northbyeast│Northbyeast│Northbyeast│└─────┴─────┴─────┴─────┴─────┴─────┴─────────────┴─────────────┴─────────────┴─────────────┘
Required example:
(":@>:@indice,.' ',.>@deg2pnt,.' ',.":@,.)(*&11.25+5.62*01_1{~3&|)i.331North02Northbyeast16.873North-northeast16.884Northeastbynorth33.755Northeast50.626Northeastbyeast50.637East-northeast67.58Eastbynorth84.379East84.3810Eastbysouth101.2511East-southeast118.1212Southeastbyeast118.1313Southeast13514Southeastbysouth151.8715South-southeast151.8816Southbyeast168.7517South185.6218Southbywest185.6319South-southwest202.520Southwestbysouth219.3721Southwest219.3822Southwestbywest236.2523West-southwest253.1224Westbysouth253.1325West27026Westbynorth286.8727West-northwest286.8828Northwestbywest303.7529Northwest320.6230Northwestbynorth320.6331North-northwest337.532Northbywest354.371North354.38
For this task, I used anenumeration to contain all 32-points of the compass.
The bounds and mid-points can then be derived using theenum ordinal value.
ThetoString method breaks down theenum name into characters, and replaces each with their corresponding written value.
enumCompass{N,NbE,NNE,NEbN,NE,NEbE,ENE,EbN,E,EbS,ESE,SEbE,SE,SEbS,SSE,SbE,S,SbW,SSW,SWbS,SW,SWbW,WSW,WbS,W,WbN,WNW,NWbW,NW,NWbN,NNW,NbW;floatmidpoint(){floatmidpoint=(360/32f)*ordinal();returnmidpoint==0?360:midpoint;}float[]bounds(){floatbound=(360/32f)/2f;floatmidpoint=midpoint();floatboundA=midpoint-bound;floatboundB=midpoint+bound;if(boundB>360)boundB-=360;returnnewfloat[]{boundA,boundB};}staticCompassparse(floatdegrees){float[]bounds;float[]boundsN=N.bounds();for(Compassvalue:Compass.values()){bounds=value.bounds();if(degrees>=boundsN[0]||degrees<boundsN[1])returnN;if(degrees>=bounds[0]&°rees<bounds[1])returnvalue;}returnnull;}@OverridepublicStringtoString(){String[]strings=newString[name().length()];intindex=0;for(charletter:name().toCharArray()){switch(letter){case'N'->strings[index]="north";case'E'->strings[index]="east";case'S'->strings[index]="south";case'W'->strings[index]="west";case'b'->strings[index]="by";}index++;}Stringstring=strings[0].substring(0,1).toUpperCase()+strings[0].substring(1);switch(strings.length){case2->string+=strings[1];case3->{if(strings[1].equals("by")){string+=" %s %s".formatted(strings[1],strings[2]);}else{string+="-%s%s".formatted(strings[1],strings[2]);}}case4->{string+=String.join(" ",strings[1],strings[2],strings[3]);}}returnstring;}}
0 North 0.001 North by east 16.872 North-northeast 16.883 Northeast by north 33.754 Northeast 50.625 Northeast by east 50.636 East-northeast 67.507 East by north 84.378 East 84.389 East by south 101.2510 East-southeast 118.1211 Southeast by east 118.1312 Southeast 135.0013 Southeast by south 151.8714 South-southeast 151.8815 South by east 168.7516 South 185.6217 South by west 185.6318 South-southwest 202.5019 Southwest by south 219.3720 Southwest 219.3821 Southwest by west 236.2522 West-southwest 253.1223 West by south 253.1324 West 270.0025 West by north 286.8726 West-northwest 286.8827 Northwest by west 303.7528 Northwest 320.6229 Northwest by north 320.6330 North-northwest 337.5031 North by west 354.370 North 354.38
An iterative, web-based approach:
functioncreateRow(i,point,heading){vartr=document.createElement('tr'),td;td=document.createElement('td');td.appendChild(document.createTextNode(i));tr.appendChild(td);td=document.createElement('td');point=point.substr(0,1).toUpperCase()+point.substr(1);td.appendChild(document.createTextNode(point));tr.appendChild(td);td=document.createElement('td');td.appendChild(document.createTextNode(heading));tr.appendChild(td);returntr;}functiongetPoint(i){varj=i%8,i=Math.floor(i/8)%4,cardinal=['north','east','south','west'],pointDesc=['1','1 by 2','1-C','C by 1','C','C by 2','2-C','2 by 1'],str1,str2,strC;str1=cardinal[i];str2=cardinal[(i+1)%4];strC=(str1==='north'||str1==='south')?str1+str2:str2+str1;returnpointDesc[j].replace('1',str1).replace('2',str2).replace('C',strC);}vari,heading,table=document.createElement('table'),tbody=document.createElement('tbody'),tr;for(i=0;i<=32;i+=1){heading=i*11.25+[0,5.62,-5.62][i%3];tr=createRow(i%32+1,getPoint(i),heading+'°');tbody.appendChild(tr);}table.appendChild(tbody);document.body.appendChild(table);
Output:
1North0°2North by east16.87°3North-northeast16.88°4Northeast by north33.75°5Northeast50.62°6Northeast by east50.63°7East-northeast67.5°8East by north84.37°9East84.38°10East by south101.25°11East-southeast118.12°12Southeast by east118.13°13Southeast135°14Southeast by south151.87°15South-southeast151.88°16South by east168.75°17South185.62°18South by west185.63°19South-southwest202.5°20Southwest by south219.37°21Southwest219.38°22Southwest by west236.25°23West-southwest253.12°24West by south253.13°25West270°26West by north286.87°27West-northwest286.88°28Northwest by west303.75°29Northwest320.62°30Northwest by north320.63°31North-northwest337.5°32North by west354.37°1North354.38°
Functional composition, allowing for additional languages (and different numbers of compass points)
(()=>{'use strict';// GENERIC FUNCTIONS// toTitle :: String -> StringlettoTitle=s=>s.length?(s[0].toUpperCase()+s.slice(1)):'';// COMPASS DATA AND FUNCTIONS// Scale invariant keys for points of the compass// (allows us to look up a translation for one scale of compass (32 here)// for use in another size of compass (8 or 16 points)// (Also semi-serviceable as more or less legible keys without translation)// compassKeys :: Int -> [String]letcompassKeys=depth=>{leturCompass=['N','S','N'],subdivision=(compass,n)=>n<=1?(compass):subdivision(// Borders between N and S engender E and W.// other new boxes concatenate their parent keys.compass.reduce((a,x,i,xs)=>{if(i>0){return(n===depth)?(a.concat([x==='N'?'W':'E'],x)):a.concat([xs[i-1]+x,x]);}elsereturna.concat(x);},[]),n-1);returnsubdivision(urCompass,depth).slice(0,-1);};// https://zh.wikipedia.org/wiki/%E7%BD%97%E7%9B%98%E6%96%B9%E4%BD%8DletlstLangs=[{'name':'English',expansions:{N:'north',S:'south',E:'east',W:'west',b:' by ','-':'-'},'N':'N','NNNE':'NbE','NNE':'N-NE','NNENE':'NEbN','NE':'NE','NENEE':'NEbE','NEE':'E-NE','NEEE':'EbN','E':'E','EEES':'EbS','EES':'E-SE','EESES':'SEbE','ES':'SE','ESESS':'SEbS','ESS':'S-SE','ESSS':'SbE','S':'S','SSSW':'SbW','SSW':'S-SW','SSWSW':'SWbS','SW':'SW','SWSWW':'SWbW','SWW':'W-SW','SWWW':'WbS','W':'W','WWWN':'WbN','WWN':'W-NW','WWNWN':'NWbW','WN':'NW','WNWNN':'NWbN','WNN':'N-NW','WNNN':'NbW'},{'name':'Chinese','N':'北','NNNE':'北微东','NNE':'东北偏北','NNENE':'东北微北','NE':'东北','NENEE':'东北微东','NEE':'东北偏东','NEEE':'东微北','E':'东','EEES':'东微南','EES':'东南偏东','EESES':'东南微东','ES':'东南','ESESS':'东南微南','ESS':'东南偏南','ESSS':'南微东','S':'南','SSSW':'南微西','SSW':'西南偏南','SSWSW':'西南微南','SW':'西南','SWSWW':'西南微西','SWW':'西南偏西','SWWW':'西微南','W':'西','WWWN':'西微北','WWN':'西北偏西','WWNWN':'西北微西','WN':'西北','WNWNN':'西北微北','WNN':'西北偏北','WNNN':'北微西'}];// pointIndex :: Int -> Num -> IntletpointIndex=(power,degrees)=>{letnBoxes=(power?Math.pow(2,power):32);returnMath.ceil((degrees+(360/(nBoxes*2)))%360*nBoxes/360)||1;};// pointNames :: Int -> Int -> [String]letpointNames=(precision,iBox)=>{letk=compassKeys(precision)[iBox-1];returnlstLangs.map(dctLang=>{lets=dctLang[k]||k,// fallback to key if no translationdctEx=dctLang.expansions;returndctEx?toTitle(s.split('').map(c=>dctEx[c]).join(precision>5?' ':'')).replace(/ /g,' '):s;});};// maximumBy :: (a -> a -> Ordering) -> [a] -> aletmaximumBy=(f,xs)=>xs.reduce((a,x)=>a===undefined?x:(f(x,a)>0?x:a),undefined);// justifyLeft :: Int -> Char -> Text -> TextletjustifyLeft=(n,cFiller,strText)=>n>strText.length?((strText+replicate(n,cFiller).join('')).substr(0,n)):strText;// justifyRight :: Int -> Char -> Text -> TextletjustifyRight=(n,cFiller,strText)=>n>strText.length?((replicate(n,cFiller).join('')+strText).slice(-n)):strText;// replicate :: Int -> a -> [a]letreplicate=(n,a)=>{letv=[a],o=[];if(n<1)returno;while(n>1){if(n&1)o=o.concat(v);n>>=1;v=v.concat(v);}returno.concat(v);};// transpose :: [[a]] -> [[a]]lettranspose=xs=>xs[0].map((_,iCol)=>xs.map((row)=>row[iCol]));// length :: [a] -> Int// length :: Text -> Intletlength=xs=>xs.length;// compareByLength = (a, a) -> (-1 | 0 | 1)letcompareByLength=(a,b)=>{let[na,nb]=[a,b].map(length);returnna<nb?-1:na>nb?1:0;};// maxLen :: [String] -> IntletmaxLen=xs=>maximumBy(compareByLength,xs).length;// compassTable :: Int -> [Num] -> Maybe StringletcompassTable=(precision,xs)=>{if(precision<1)returnundefined;else{letintPad=2;letlstIndex=xs.map(x=>pointIndex(precision,x)),lstStrIndex=lstIndex.map(x=>x.toString()),nIndexWidth=maxLen(lstStrIndex),colIndex=lstStrIndex.map(x=>justifyRight(nIndexWidth,' ',x));letlstAngles=xs.map(x=>x.toFixed(2)+'°'),nAngleWidth=maxLen(lstAngles)+intPad,colAngles=lstAngles.map(x=>justifyRight(nAngleWidth,' ',x));letlstTrans=transpose(lstIndex.map(i=>pointNames(precision,i))),lstTransWidths=lstTrans.map(x=>maxLen(x)+2),colsTrans=lstTrans.map((lstLang,i)=>lstLang.map(x=>justifyLeft(lstTransWidths[i],' ',x)));returntranspose([colIndex].concat([colAngles],[replicate(lstIndex.length," ")]).concat(colsTrans)).map(x=>x.join('')).join('\n');}}// TESTletxs=[0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,118.13,135.0,151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38];// If we supply other precisions, like 4 or 6, (2^n -> 16 or 64 boxes)// the bearings will be divided amongst smaller or larger numbers of boxes,// either using name translations retrieved by the generic hash// or using the hash itself (combined with any expansions)// to substitute for missing names for very finely divided boxes.returncompassTable(5,xs);// 2^5 -> 32 boxes})();
1 0.00° North 北 2 16.87° North by east 北微东 3 16.88° North-northeast 东北偏北 4 33.75° Northeast by north 东北微北 5 50.62° Northeast 东北 6 50.63° Northeast by east 东北微东 7 67.50° East-northeast 东北偏东 8 84.37° East by north 东微北 9 84.38° East 东 10 101.25° East by south 东微南 11 118.12° East-southeast 东南偏东 12 118.13° Southeast by east 东南微东 13 135.00° Southeast 东南 14 151.87° Southeast by south 东南微南 15 151.88° South-southeast 东南偏南 16 168.75° South by east 南微东 17 185.62° South 南 18 185.63° South by west 南微西 19 202.50° South-southwest 西南偏南 20 219.37° Southwest by south 西南微南 21 219.38° Southwest 西南 22 236.25° Southwest by west 西南微西 23 253.12° West-southwest 西南偏西 24 253.13° West by south 西微南 25 270.00° West 西 26 286.87° West by north 西微北 27 286.88° West-northwest 西北偏西 28 303.75° Northwest by west 西北微西 29 320.62° Northwest 西北 30 320.63° Northwest by north 西北微北 31 337.50° North-northwest 西北偏北 32 354.37° North by west 北微西 1 354.38° North 北
Also works with gojq, the Go implementation of jq, and with fq.
Adapted fromWren
# Input: the input heading given as a number in degrees.# Output: the corresponding integer index (from 0 to 31 inclusive)# into the table, compassPoint, of compass point names.def cpx: (((. / 11.25) + 0.5)|floor % 32) | if . < 0 then . + 32 else . end;# Compass point namesdef compassPoint: [ "North", "North by east", "North-northeast", "Northeast by north", "Northeast", "Northeast by east", "East-northeast", "East by north", "East", "East by south", "East-southeast", "Southeast by east", "Southeast", "Southeast by south", "South-southeast", "South by east", "South", "South by west", "South-southwest", "Southwest by south", "Southwest", "Southwest by west", "West-southwest", "West by south", "West", "West by north", "West-northwest", "Northwest by west", "Northwest", "Northwest by north", "North-northwest", "North by west"];### The task# Input: heading in degreesdef degreesToCompassPoint: compassPoint[cpx];def r: [ 0.0, 16.87, 16.88, 33.75, 50.62, 50.63, 67.5, 84.37, 84.38, 101.25, 118.12, 118.13, 135.0, 151.87, 151.88, 168.75, 185.62, 185.63, 202.5, 219.37, 219.38, 236.25, 253.12, 253.13, 270.0, 286.87, 286.88, 303.75, 320.62, 320.63, 337.5, 354.37, 354.38];def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;"Index Compass point Heading",(r as $r | range(0; $r|length) | $r[.] as $h | ((.%32) + 1) as $index # index as per requirements | ($h | degreesToCompassPoint) as $d | "\($index|lpad(3)) \($d|lpad(20)) \($h)°")Index Compass point Heading 1 North 0° 2 North by east 16.87° 3 North-northeast 16.88° 4 Northeast by north 33.75° 5 Northeast 50.62° 6 Northeast by east 50.63° 7 East-northeast 67.5° 8 East by north 84.37° 9 East 84.38° 10 East by south 101.25° 11 East-southeast 118.12° 12 Southeast by east 118.13° 13 Southeast 135° 14 Southeast by south 151.87° 15 South-southeast 151.88° 16 South by east 168.75° 17 South 185.62° 18 South by west 185.63° 19 South-southwest 202.5° 20 Southwest by south 219.37° 21 Southwest 219.38° 22 Southwest by west 236.25° 23 West-southwest 253.12° 24 West by south 253.13° 25 West 270° 26 West by north 286.87° 27 West-northwest 286.88° 28 Northwest by west 303.75° 29 Northwest 320.62° 30 Northwest by north 320.63° 31 North-northwest 337.5° 32 North by west 354.37° 1 North 354.38°
usingPrintffunctiondegree2compasspoint(d::Float64)majors=("north","east","south","west","north","east","south","west")quarter1=("N","N by E","N-NE","NE by N","NE","NE by E","E-NE","E by N")quarter2=map(p->replace(p,"NE"=>"EN"),quarter1)d=d%360+360/64imajor,minor=divrem(d,90)iminor=div(minor*4,45)imajor+=1iminor+=1p1,p2=majors[imajor:imajor+1]q=p1in("north","south")?quarter1:quarter2titlecase(replace(replace(q[iminor],'N'=>p1),'E'=>p2))endforiin0:32d=i*11.25i%3==1&&(d+=5.62)i%3==2&&(d-=5.62)@printf("%2i%-17s%10.2f°\n",i%32+1,degree2compasspoint(d),d)end
1 North 0.00° 2 North By East 16.87° 3 North-Northeast 16.88° 4 Northeast By North 33.75° 5 Northeast 50.62° 6 Northeast By East 50.63° 7 East-Northeast 67.50° 8 East By North 84.37° 9 East 84.38°10 East By South 101.25°11 East-Southeast 118.12°12 Southeast By East 118.13°13 Southeast 135.00°14 Southeast By South 151.87°15 South-Southeast 151.88°16 South By East 168.75°17 South 185.62°18 South By West 185.63°19 South-Southwest 202.50°20 Southwest By South 219.37°21 Southwest 219.38°22 Southwest By West 236.25°23 West-Southwest 253.12°24 West By South 253.13°25 West 270.00°26 West By North 286.87°27 West-Northwest 286.88°28 Northwest By West 303.75°29 Northwest 320.62°30 Northwest By North 320.63°31 North-Northwest 337.50°32 North By West 354.37° 1 North 354.38°
The representation of the names was inspired by Tcl (etc.).
d:("N;Nbe;N-ne;Nebn;Ne;Nebe;E-ne;Ebn;")d,:("E;Ebs;E-se;Sebe;Se;Sebs;S-se;Sbe;")d,:("S;Sbw;S-sw;Swbs;Sw;Swbw;W-sw;Wbs;")d,:("W;Wbn;W-nw;Nwbw;Nw;Nwbn;N-nw;Nbw;N")split:{1_'(&x=y)_x:y,x}dd:split[d;";"]/ lookup tables1:"NEWSnewsb-"s2:("North";"East";"West";"South";"north";"east";"west";"south";" by ";"-")c:.({`$x}'s1),'{`$x}'s2/ create the dictionarycc:{,/{$c[`$$x]}'x}/ lookup function/ calculate the degreesf:{m:x!3;(11.25*x)+:[1=m;+5.62;2=m;-5.62;0]}
The table:
`0:{((2$(1+x!32))," ",(-19$cc@dd[x]),(6.2$f@x))}'!#dd1North0.002Northbyeast16.873North-northeast16.884Northeastbynorth33.755Northeast50.626Northeastbyeast50.637East-northeast67.508Eastbynorth84.379East84.3810Eastbysouth101.2511East-southeast118.1212Southeastbyeast118.1313Southeast135.0014Southeastbysouth151.8715South-southeast151.8816Southbyeast168.7517South185.6218Southbywest185.6319South-southwest202.5020Southwestbysouth219.3721Southwest219.3822Southwestbywest236.2523West-southwest253.1224Westbysouth253.1325West270.0026Westbynorth286.8727West-northwest286.8828Northwestbywest303.7529Northwest320.6230Northwestbynorth320.6331North-northwest337.5032Northbywest354.371North354.38
// version 1.1.2funexpand(cp:String):String{valsb=StringBuilder()for(cincp){sb.append(when(c){'N'->"north"'E'->"east"'S'->"south"'W'->"west"'b'->" by "else->"-"})}returnsb.toString().capitalize()}funmain(args:Array<String>){valcp=arrayOf("N","NbE","N-NE","NEbN","NE","NEbE","E-NE","EbN","E","EbS","E-SE","SEbE","SE","SEbS","S-SE","SbE","S","SbW","S-SW","SWbS","SW","SWbW","W-SW","WbS","W","WbN","W-NW","NWbW","NW","NWbN","N-NW","NbW")println("Index Degrees Compass point")println("----- ------- -------------")valf="%2d %6.2f %s"for(iin0..32){valindex=i%32varheading=i*11.25when(i%3){1->heading+=5.622->heading-=5.62}println(f.format(index+1,heading,expand(cp[index])))}}
Index Degrees Compass point----- ------- ------------- 1 0.00 North 2 16.87 North by east 3 16.88 North-northeast 4 33.75 Northeast by north 5 50.62 Northeast 6 50.63 Northeast by east 7 67.50 East-northeast 8 84.37 East by north 9 84.38 East10 101.25 East by south11 118.12 East-southeast12 118.13 Southeast by east13 135.00 Southeast14 151.87 Southeast by south15 151.88 South-southeast16 168.75 South by east17 185.62 South18 185.63 South by west19 202.50 South-southwest20 219.37 Southwest by south21 219.38 Southwest22 236.25 Southwest by west23 253.12 West-southwest24 253.13 West by south25 270.00 West26 286.87 West by north27 286.88 West-northwest28 303.75 Northwest by west29 320.62 Northwest30 320.63 Northwest by north31 337.50 North-northwest32 354.37 North by west 1 354.38 North
val box = ["North", "North by east", "North-northeast", "Northeast by north", "Northeast", "Northeast by east", "East-northeast", "East by north", "East", "East by south", "East-southeast", "Southeast by east", "Southeast", "Southeast by south", "South-southeast", "South by east", "South", "South by west", "South-southwest", "Southwest by south", "Southwest", "Southwest by west", "West-southwest", "West by south", "West", "West by north", "West-northwest", "Northwest by west", "Northwest", "Northwest by north", "North-northwest", "North by west"]val angles = [ 0.0, 16.87, 16.88, 33.75, 50.62, 50.63, 67.5, 84.37, 84.38, 101.25, 118.12, 118.13, 135.0, 151.87, 151.88, 168.75, 185.62, 185.63, 202.5, 219.37, 219.38, 236.25, 253.12, 253.13, 270.0, 286.87, 286.88, 303.75, 320.62, 320.63, 337.5, 354.37, 354.38]writeln "index degrees compass point"writeln "----- ------- -------------"for phi in angles { val i = trunc(phi * 32 / 360 + 0.5) rem 32 + 1 writeln "{{i:5}} {{phi:r2:6}} {{box[i]}}"}index degrees compass point----- ------- ------------- 1 0.00 North 2 16.87 North by east 3 16.88 North-northeast 4 33.75 Northeast by north 5 50.62 Northeast 6 50.63 Northeast by east 7 67.50 East-northeast 8 84.37 East by north 9 84.38 East 10 101.25 East by south 11 118.12 East-southeast 12 118.13 Southeast by east 13 135.00 Southeast 14 151.87 Southeast by south 15 151.88 South-southeast 16 168.75 South by east 17 185.62 South 18 185.63 South by west 19 202.50 South-southwest 20 219.37 Southwest by south 21 219.38 Southwest 22 236.25 Southwest by west 23 253.12 West-southwest 24 253.13 West by south 25 270.00 West 26 286.87 West by north 27 286.88 West-northwest 28 303.75 Northwest by west 29 320.62 Northwest 30 320.63 Northwest by north 31 337.50 North-northwest 32 354.37 North by west 1 354.38 North
definepointsarray()=>{local(points=array)loop(-from=0,-to=32)=>{local(heading=loop_count*11.25)if(loop_count%3==1)=>{#heading+=5.62else(loop_count%3==2)#heading-=5.62}#points->insert(#heading)}return#points}definecompassShort=>array('N','Nbe','N-ne','Nebn','Ne','Nebe','E-ne','Ebn','E','Ebs','E-se','Sebe','Se','Sebs','S-se','Sbe','S','Sbw','S-sw','Swbs','Sw','Swbw','W-sw','Wbs','W','Wbn','W-nw','Nwbw','Nw','Nwbn','N-nw','Nbw','N')definecompassLong(short::string)=>{local(o=string)withiin#short->valuesdo=>{#o->append(compassLongProcessor(#i))}return#o}definecompassLongProcessor(char::string)=>{#char=='N'?return#char+'orth'#char=='S'?return#char+'outh'#char=='E'?return#char+'ast'#char=='W'?return#char+'est'#char=='b'?return' by '#char=='-'?return'-'}// test output points as decimals//pointsarray// test output the array of text values//compassShort// test output the long names of the text values//with s in compassShort do => {^ compassLong(#s) + '\r' ^}'angle | box | compass point---------------------------------'local(counter=0)withpinpointsarraydo=>{^local(pformatted=#p->asString(-precision=2))while(#pformatted->size<6)=>{#pformatted->append(' ')}#counter+=1#counter>32?#counter=1#pformatted+' | '+(#counter<10?' ')+#counter+' | '+compassLong(compassShort->get(#counter))+'\r'^}
angle | box | compass point---------------------------------0.00 | 1 | North16.87 | 2 | North by east16.88 | 3 | North-northeast33.75 | 4 | Northeast by north50.62 | 5 | Northeast50.63 | 6 | Northeast by east67.50 | 7 | East-northeast84.37 | 8 | East by north84.38 | 9 | East101.25 | 10 | East by south118.12 | 11 | East-southeast118.13 | 12 | Southeast by east135.00 | 13 | Southeast151.87 | 14 | Southeast by south151.88 | 15 | South-southeast168.75 | 16 | South by east185.62 | 17 | South185.63 | 18 | South by west202.50 | 19 | South-southwest219.37 | 20 | Southwest by south219.38 | 21 | Southwest236.25 | 22 | Southwest by west253.12 | 23 | West-southwest253.13 | 24 | West by south270.00 | 25 | West286.87 | 26 | West by north286.88 | 27 | West-northwest303.75 | 28 | Northwest by west320.62 | 29 | Northwest320.63 | 30 | Northwest by north337.50 | 31 | North-northwest354.37 | 32 | North by west354.38 | 1 | North
dim point$( 32)for i =1 to 32 read d$: point$( i) =d$next ifor i = 0 to 32 heading = i *11.25 if ( i mod 3) =1 then heading = heading +5.62 else if ( i mod 3) =2 then heading = heading -5.62 end if ind = i mod 32 +1 print ind, compasspoint$( heading), headingnext iendfunction compasspoint$( h) x = h /11.25 +1.5 if (x >=33.0) then x =x -32.0 compasspoint$ = point$( int( x))end functiondata "North ", "North by east ", "North-northeast "data "Northeast by north", "Northeast ", "Northeast by east ", "East-northeast "data "East by north ", "East ", "East by south ", "East-southeast "data "Southeast by east ", "Southeast ", "Southeast by south", "South-southeast "data "South by east ", "South ", "South by west ", "South-southwest "data "Southwest by south", "Southwest ", "Southwest by west ", "West-southwest "data "West by south ", "West ", "West by north ", "West-northwest "data "Northwest by west ", "Northwest ", "Northwest by north", "North-northwest "data "North by west
Output:
1 North 02 North by east 16.873 North-northeast 16.884 Northeast by north 33.755 Northeast 50.626 Northeast by east 50.637 East-northeast 67.58 East by north 84.379 East 84.3810 East by south 101.2511 East-southeast 118.1212 Southeast by east 118.1313 Southeast 13514 Southeast by south 151.8715 South-southeast 151.8816 South by east 168.7517 South 185.6218 South by west 185.6319 South-southwest 202.520 Southwest by south 219.3721 Southwest 219.3822 Southwest by west 236.2523 West-southwest 253.1224 West by south 253.1325 West 27026 West by north 286.8727 West-northwest 286.8828 Northwest by west 303.7529 Northwest 320.6230 Northwest by north 320.6331 North-northwest 337.532 North by west 354.371 North 354.38
; This is not strictly LLVM, as it uses the C library function "printf".; LLVM does not provide a way to print values, so the alternative would be; to just load the string into memory, and that would be boring.; Additional comments have been inserted, as well as changes made from the output produced by clang such as putting more meaningful labels for the jumps;--- The declarations for the external C functionsdeclarei32@printf(i8*,...)$"COMPASS_STR"=comdatany$"OUTPUT_STR"=comdatany@main.degrees=privateunnamed_addrconstant[33xdouble][double0.000000e+00,double1.687000e+01,double1.688000e+01,double3.375000e+01,double5.062000e+01,double5.063000e+01,double6.750000e+01,double8.437000e+01,double0x40551851EB851EB8,double1.012500e+02,double1.181200e+02,double1.181300e+02,double1.350000e+02,double1.518700e+02,double1.518800e+02,double1.687500e+02,double1.856200e+02,double1.856300e+02,double2.025000e+02,double2.193700e+02,double2.193800e+02,double2.362500e+02,double2.531200e+02,double2.531300e+02,double2.700000e+02,double2.868700e+02,double2.868800e+02,double3.037500e+02,double3.206200e+02,double3.206300e+02,double3.375000e+02,double3.543700e+02,double3.543800e+02],align16@"COMPASS_STR"=linkonce_odrunnamed_addrconstant[727xi8]c"North North by east North-northeast Northeast by north Northeast Northeast by east East-northeast East by north East East by south East-southeast Southeast by east Southeast Southeast by south South-southeast South by east South South by west South-southwest Southwest by south Southwest Southwest by west West-southwest West by south West West by north West-northwest Northwest by west Northwest Northwest by north North-northwest North by west North \00",comdat,align1@"OUTPUT_STR"=linkonce_odrunnamed_addrconstant[19xi8]c"%2d %.22s %6.2f\0A\00",comdat,align1; Function Attrs: noinline nounwind optnone uwtabledefinei32@main()#0{%1=allocai32,align4;-- allocate i%2=allocai32,align4;-- allocate j%3=alloca[33xdouble],align16;-- allocate degrees%4=allocai8*,align8;-- allocate names%5=bitcast[33xdouble]*%3toi8*callvoid@llvm.memcpy.p0i8.p0i8.i64(i8*%5,i8*bitcast([33xdouble]*@main.degreestoi8*),i64264,i3216,i1false)storei8*getelementptrinbounds([727xi8],[727xi8]*@"COMPASS_STR",i320,i320),i8**%4,align8storei320,i32*%1,align4;-- i = 0brlabel%looploop:%6=loadi32,i32*%1,align4;-- load i%7=icmpslti32%6,33;-- i < 33bri1%7,label%loop_body,label%exitloop_body:%8=loadi32,i32*%1,align4;-- load i%9=sexti32%8toi64;-- sign extend i%10=getelementptrinbounds[33xdouble],[33xdouble]*%3,i640,i64%9;-- calculate index of degrees[i]%11=loaddouble,double*%10,align8;-- load degrees[i]%12=fmuldouble%11,3.200000e+01;-- degrees[i] * 32%13=fdivdouble%12,3.600000e+02;-- degrees[i] * 32 / 360.0%14=fadddouble5.000000e-01,%13;-- 0.5 + degrees[i] * 32 / 360.0%15=fptosidouble%14toi32;-- convert floating point to integerstorei32%15,i32*%2,align4;-- write result to j%16=loadi8*,i8**%4,align8;-- load names%17=loadi32,i32*%2,align4;-- load j%18=sremi32%17,32;-- j % 32%19=mulnswi32%18,22;-- (j % 32) * 22%20=sexti32%19toi64;-- sign extend the result%21=getelementptrinboundsi8,i8*%16,i64%20;-- load names at the calculated offset%22=loadi32,i32*%2,align4;-- load j%23=sremi32%22,32;-- j % 32%24=addnswi32%23,1;-- (j % 32) + 1%25=calli32(i8*,...)@printf(i8*getelementptrinbounds([19xi8],[19xi8]*@"OUTPUT_STR",i320,i320),i32%24,i8*%21,double%11)%26=loadi32,i32*%1,align4;-- load i%27=addnswi32%26,1;-- increment istorei32%27,i32*%1,align4;-- store ibrlabel%loopexit:reti320}; Function Attrs: argmemonly nounwinddeclarevoid@llvm.memcpy.p0i8.p0i8.i64(i8*nocapturewriteonly,i8*nocapturereadonly,i64,i32,i1)#1attributes#0={noinlinenounwindoptnoneuwtable"correctly-rounded-divide-sqrt-fp-math"="false""disable-tail-calls"="false""less-precise-fpmad"="false""no-frame-pointer-elim"="false""no-infs-fp-math"="false""no-jump-tables"="false""no-nans-fp-math"="false""no-signed-zeros-fp-math"="false""no-trapping-math"="false""stack-protector-buffer-size"="8""target-cpu"="x86-64""target-features"="+fxsr,+mmx,+sse,+sse2,+x87""unsafe-fp-math"="false""use-soft-float"="false"}attributes#1={argmemonlynounwind}
1 North 0.00 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.50 8 East by north 84.37 9 East 84.3810 East by south 101.2511 East-southeast 118.1212 Southeast by east 118.1313 Southeast 135.0014 Southeast by south 151.8715 South-southeast 151.8816 South by east 168.7517 South 185.6218 South by west 185.6319 South-southwest 202.5020 Southwest by south 219.3721 Southwest 219.3822 Southwest by west 236.2523 West-southwest 253.1224 West by south 253.1325 West 270.0026 West by north 286.8727 West-northwest 286.8828 Northwest by west 303.7529 Northwest 320.6230 Northwest by north 320.6331 North-northwest 337.5032 North by west 354.37 1 North 354.38
; List of abbreviated compass point labelsmake "compass_points [ N NbE N-NE NEbN NE NEbE E-NE EbN E EbS E-SE SEbE SE SEbS S-SE SbE S SbW S-SW SWbS SW SWbW W-SW WbS W WbN W-NW NWbW NW NWbN N-NW NbW ]; List of angles to testmake "test_angles [ 0.00 16.87 16.88 33.75 50.62 50.63 67.50 84.37 84.38 101.25 118.12 118.13 135.00 151.87 151.88 168.75 185.62 185.63 202.50 219.37 219.38 236.25 253.12 253.13 270.00 286.87 286.88 303.75 320.62 320.63 337.50 354.37 354.38 ]; make comparisons case-sensitivemake "caseignoredp "false; String utilities: search and replaceto replace_in :src :from :to output map [ ifelse equalp ? :from [:to] [?] ] :srcend; pad with spacesto pad :string :length output cascade [lessp :length count ?] [word ? "\ ] :stringend; capitalize first letterto capitalize :string output word (uppercase first :string) butfirst :stringend; convert compass point abbreviation to full text of labelto expand_point :abbr foreach [[N north] [E east] [S south] [W west] [b \ by\ ]] [ make "abbr replace_in :abbr (first ?) (last ?) ] output capitalize :abbrend; modulus function that returns 1..N instead of 0..N-1to adjusted_modulo :n :d output sum 1 modulo (difference :n 1) :dend; convert a compass angle from degrees into a box index (1..32)to compass_point :degrees make "degrees modulo :degrees 360 output adjusted_modulo (sum 1 int quotient (sum :degrees 5.625) 11.25) 32end; Now output the table of test dataprint (sentence (pad "Degrees 7) "\| (pad "Closest\ Point 18) "\| "Index )foreach :test_angles [ local "index make "index compass_point ? local "abbr make "abbr item :index :compass_points local "label make "label expand_point :abbr print (sentence (form ? 7 2) "\| (pad :label 18) "\| (form :index 2 0) )]; and exitbye
Output:
Degrees | Closest Point | Index 0.00 | North | 1 16.87 | North by east | 2 16.88 | North-northeast | 3 33.75 | Northeast by north | 4 50.62 | Northeast | 5 50.63 | Northeast by east | 6 67.50 | East-northeast | 7 84.37 | East by north | 8 84.38 | East | 9 101.25 | East by south | 10 118.12 | East-southeast | 11 118.13 | Southeast by east | 12 135.00 | Southeast | 13 151.87 | Southeast by south | 14 151.88 | South-southeast | 15 168.75 | South by east | 16 185.62 | South | 17 185.63 | South by west | 18 202.50 | South-southwest | 19 219.37 | Southwest by south | 20 219.38 | Southwest | 21 236.25 | Southwest by west | 22 253.12 | West-southwest | 23 253.13 | West by south | 24 270.00 | West | 25 286.87 | West by north | 26 286.88 | West-northwest | 27 303.75 | Northwest by west | 28 320.62 | Northwest | 29 320.63 | Northwest by north | 30 337.50 | North-northwest | 31 354.37 | North by west | 32 354.38 | North | 1
-- List of abbreviated compass point labelscompass_points={"N","NbE","N-NE","NEbN","NE","NEbE","E-NE","EbN","E","EbS","E-SE","SEbE","SE","SEbS","S-SE","SbE","S","SbW","S-SW","SWbS","SW","SWbW","W-SW","WbS","W","WbN","W-NW","NWbW","NW","NWbN","N-NW","NbW"}-- List of angles to testtest_angles={0.00,16.87,16.88,33.75,50.62,50.63,67.50,84.37,84.38,101.25,118.12,118.13,135.00,151.87,151.88,168.75,185.62,185.63,202.50,219.37,219.38,236.25,253.12,253.13,270.00,286.87,286.88,303.75,320.62,320.63,337.50,354.37,354.38}-- capitalize a stringfunctioncapitalize(s)returns:sub(1,1):upper()..s:sub(2)end-- convert compass point abbreviation to full text of labelfunctionexpand_point(abbr)forfrom,toinpairs({N="north",E="east",S="south",W="west",b=" by "})doabbr=abbr:gsub(from,to)endreturncapitalize(abbr)end-- modulus function that returns 1..N instead of 0..N-1functionadjusted_modulo(n,d)return1+(n-1)%dend-- convert a compass angle from degrees into a box index (1..32)functioncompass_point(degrees)degrees=degrees%360returnadjusted_modulo(1+math.floor((degrees+5.625)/11.25),32)end-- Now output the table of test dataheader_format="%-7s | %-18s | %s"row_format="%7.2f | %-18s | %2d"print(header_format:format("Degrees","Closest Point","Index"))fori,angleinipairs(test_angles)doindex=compass_point(angle)abbr=compass_points[index]label=expand_point(abbr)print(row_format:format(angle,label,index))end
Output:
Degrees | Closest Point | Index 0.00 | North | 1 16.87 | North by east | 2 16.88 | North-northeast | 3 33.75 | Northeast by north | 4 50.62 | Northeast | 5 50.63 | Northeast by east | 6 67.50 | East-northeast | 7 84.37 | East by north | 8 84.38 | East | 9 101.25 | East by south | 10 118.12 | East-southeast | 11 118.13 | Southeast by east | 12 135.00 | Southeast | 13 151.87 | Southeast by south | 14 151.88 | South-southeast | 15 168.75 | South by east | 16 185.62 | South | 17 185.63 | South by west | 18 202.50 | South-southwest | 19 219.37 | Southwest by south | 20 219.38 | Southwest | 21 236.25 | Southwest by west | 22 253.12 | West-southwest | 23 253.13 | West by south | 24 270.00 | West | 25 286.87 | West by north | 26 286.88 | West-northwest | 27 303.75 | Northwest by west | 28 320.62 | Northwest | 29 320.63 | Northwest by north | 30 337.50 | North-northwest | 31 354.37 | North by west | 32 354.38 | North | 1
In a For Next loop we can change loop variable inside block, but the actual loop hidden variable can't change so for next iteration we get the proper value.
ModuleCheckIt{Locale1033'change decimal point char to dot.Form80,50' set console to 80 characters by 50 lines\\Functionheading()getapositivedoubleasdegreesandreturnthecompassindex(1forNorth)Functionheading(d){d1=ddiv11.25ifd1mod3=1thend+=5.62:d1=ddiv11.25=d1mod32+1}Dimwind$(1to32)wind$(1)="North","North by east","North-northeast","Northeast by north","Northeast"wind$(6)="Northeast by east","East-northeast","East by north","East","East by south","East-southeast"wind$(12)="Southeast by east","Southeast","Southeast by south","South-southeast","South by east","South"wind$(18)="South by west","South-southwest","Southwest by south","Southwest","Southwest by west","West-southwest"wind$(24)="West by south","West","West by north","West-northwest","Northwest by west","Northwest","Northwest by north"wind$(31)="North-northwest","North by west"oldvalue=-2newvalue=2Print" angle | box | compass point"Print"-------+-----+---------------------"Fori=0to360step0.005newvalue=heading(i)if(newvaluemod3)=2theni+=5.62:newvalue=heading(i)ifoldvalue<>newvaluethenPrintformat$("{0:2:-6}°| {1::-2} | {2}",i,newvalue,wind$(newvalue)):oldvalue=newvalue:refreshNexti}CheckIt
angle | box | compass point-------+-----+--------------------- 0.00°| 1 | North 16.87°| 2 | North by east 16.88°| 3 | North-northeast 33.75°| 4 | Northeast by north 50.62°| 5 | Northeast 50.63°| 6 | Northeast by east 67.50°| 7 | East-northeast 84.37°| 8 | East by north 84.38°| 9 | East101.25°| 10 | East by south118.12°| 11 | East-southeast118.13°| 12 | Southeast by east135.00°| 13 | Southeast151.87°| 14 | Southeast by south151.88°| 15 | South-southeast168.75°| 16 | South by east185.62°| 17 | South185.63°| 18 | South by west202.50°| 19 | South-southwest219.37°| 20 | Southwest by south219.38°| 21 | Southwest236.25°| 22 | Southwest by west253.12°| 23 | West-southwest253.13°| 24 | West by south270.00°| 25 | West286.87°| 26 | West by north286.88°| 27 | West-northwest303.75°| 28 | Northwest by west320.62°| 29 | Northwest320.63°| 30 | Northwest by north337.50°| 31 | North-northwest354.37°| 32 | North by west354.38°| 1 | North
Map[List[Part[#,1],dirs[[Part[#,1]]],ToString@Part[#,2]<>"°"]&,Map[{Floor[Mod[#+5.625,360]/11.25]+1,#}&,input]]//TableForm
1North0.°2North by east16.87°3North-northeast16.88°4Northeast by north33.75°5Northeast50.62°6Northeast by east50.63°7East-northeast67.5°8East by north84.37°9East84.38°10East by Southeast101.25°11East-southeast118.12°12Southeast by east118.13°13Southeast135.°14Southeast by south151.87°15South-southeast151.88°16South by east168.75°17South185.62°18South by West185.63°19South-southwest202.5°20Southwest by south219.37°21Southwest219.38°22Southwest by west236.25°23West-southwest253.12°24West by south253.13°25West270.°26West by north286.87°27West-northwest286.88°28Northwest by west303.75°29Northwest320.62°30Northwest by north320.63°31North-northwest337.5°32North by west354.37°1North354.38°
functionb=compassbox(d)b=ceil(mod(d+360/64,360)*32/360);end;
Output:
>> x=[0.0, 16.87, 16.88, 33.75, 50.62, 50.63, 67.5, 84.37, 84.38, 101.25, 118.12, 118.13, 135.0, 151.87, 151.88, 168.75, 185.62, 185.63, 202.5, 219.37, 219.38, 236.25, 253.12, 253.13, 270.0, 286.87, 286.88, 303.75, 320.62, 320.63, 337.5, 354.37, 354.38]';printf(' angle : box\n'); printf('%6.2f : %2i\n',[x,compassbox(x)]'); angle : box 0.00 : 1 16.87 : 2 16.88 : 3 33.75 : 4 50.62 : 5 50.63 : 6 67.50 : 7 84.37 : 8 84.38 : 9101.25 : 10118.12 : 11118.13 : 12135.00 : 13151.87 : 14151.88 : 15168.75 : 16185.62 : 17185.63 : 18202.50 : 19219.37 : 20219.38 : 21236.25 : 22253.12 : 23253.13 : 24270.00 : 25286.87 : 26286.88 : 27303.75 : 28320.62 : 29320.63 : 30337.50 : 31354.37 : 32354.38 : 1MODULEBoxTheCompass;FROMFormatStringIMPORTFormatString;FROMRealStrIMPORTRealToStr;FROMTerminalIMPORTWriteString,WriteLn,Write,ReadChar;PROCEDUREexpand(cp:ARRAYOFCHAR);VARi:INTEGER=0;BEGINWHILEcp[i]#0CDOIFi=0THENCASEcp[i]OF'N':WriteString("North")|'E':WriteString("East")|'S':WriteString("South")|'W':WriteString("West")|'b':WriteString(" by ")ELSEWriteString("-");END;ELSECASEcp[i]OF'N':WriteString("north")|'E':WriteString("east")|'S':WriteString("south")|'W':WriteString("west")|'b':WriteString(" by ")ELSEWriteString("-");END;END;INC(i)END;ENDexpand;PROCEDUREFormatReal(r:REAL);VARbuf:ARRAY[0..63]OFCHAR;u,v:INTEGER;w:REAL;BEGINu:=TRUNC(r);w:=r-FLOAT(u);v:=TRUNC(100.0*w);FormatString("%6i.%'02i",buf,u,v);WriteString(buf);ENDFormatReal;VARcp:ARRAY[0..31]OFARRAY[0..4]OFCHAR={"N","NbE","N-NE","NEbN","NE","NEbE","E-NE","EbN","E","EbS","E-SE","SEbE","SE","SEbS","S-SE","SbE","S","SbW","S-SW","SWbS","SW","SWbW","W-SW","WbS","W","WbN","W-NW","NWbW","NW","NWbN","N-NW","NbW"};buf:ARRAY[0..63]OFCHAR;i,index:INTEGER;heading:REAL;BEGINWriteString("Index Degrees Compass point");WriteLn;WriteString("----- ------- -------------");WriteLn;FORi:=0TO32DOindex:=iMOD32;heading:=FLOAT(i)*11.25;CASEiMOD3OF1:heading:=heading+5.62;|2:heading:=heading-5.62;ELSE(* empty *)END;FormatString("%2i ",buf,index+1);WriteString(buf);FormatReal(heading);WriteString(" ");expand(cp[index]);WriteLnEND;ReadCharENDBoxTheCompass.
The TCL implementation was the starting point, but this isn't an exact translation.
BOXING(DEGREE) ;This takes in a degree heading, nominally from 0 to 360, and returns the compass point name. QUIT:((DEGREE<0)||(DEGREE>360)) "land lubber can't read a compass" NEW DIRS,UNP,UNPACK,SEP,DIR,DOS,D,DS,I,F SET DIRS="N^NbE^N-NE^NEbN^NE^NEbE^E-NE^EbN^E^EbS^E-SE^SEbE^SE^SEbS^S-SE^SbE^" SET DIRS=DIRS_"S^SbW^S-SW^SWbS^SW^SWbW^W-SW^WbS^W^WbN^W-NW^NWbW^NW^NWbN^N-NW^NbW" SET UNP="NESWb" SET UNPACK="north^east^south^west^ by " SET SEP=360/$LENGTH(DIRS,"^") SET DIR=(DEGREE/SEP)+1.5 SET DIR=$SELECT((DIR>33):DIR-32,1:DIR) SET DOS=$NUMBER(DIR-.5,0) SET D=$PIECE(DIRS,"^",DIR) SET DS="" FOR I=1:1:$LENGTH(D) DO . SET F=$FIND(UNP,$EXTRACT(D,I)) SET DS=DS_$SELECT((F>0):$PIECE(UNPACK,"^",F-1),1:$E(D,I)) KILL DIRS,UNP,UNPACK,SEP,DIR,D,I,F QUIT DOS_"^"_DSBOXWRITE NEW POINTS,UP,LO,DIR,P,X SET POINTS="0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,118.13,135.0,151.87," SET POINTS=POINTS_"151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270.0,286.87," SET POINTS=POINTS_"286.88,303.75,320.62,320.63,337.5,354.37,354.38" SET UP="ABCDEFGHIJKLMNOPQRSTUVWXYZ" SET LO="abcdefghijklmnopqrstuvwxyz" FOR P=1:1:$LENGTH(POINTS,",") DO . SET X=$$BOXING($PIECE(POINTS,",",P)) . ;Capitalize the initial letter of the direction . SET DIR=$PIECE(X,"^",2) . SET DIR=$TRANSLATE($EXTRACT(DIR,1),LO,UP)_$EXTRACT(DIR,2,$LENGTH(DIR)) . WRITE $PIECE(X,"^"),?5,DIR,?40,$JUSTIFY($PIECE(POINTS,",",P),10,2),! KILL POINTS,UP,LO,DIR,P,X QUIT
Output:
Debugger executing 'BOXWRITE^COMPASS'1 North 0.002 North by east 16.873 North-northeast 16.884 Northeast by north 33.755 Northeast 50.626 Northeast by east 50.637 East-northeast 67.508 East by north 84.379 East 84.3810 East by south 101.2511 East-southeast 118.1212 Southeast by east 118.1313 Southeast 135.0014 Southeast by south 151.8715 South-southeast 151.8816 South by east 168.7517 South 185.6218 South by west 185.6319 South-southwest 202.5020 Southwest by south 219.3721 Southwest 219.3822 Southwest by west 236.2523 West-southwest 253.1224 West by south 253.1325 West 270.0026 West by north 286.8727 West-northwest 286.8828 Northwest by west 303.7529 Northwest 320.6230 Northwest by north 320.6331 North-northwest 337.5032 North by west 354.371 North 354.38
/* NetRexx */optionsreplaceformatcommentsjavacrossrefsavelogsymbolsnobinaryutf8classRCBoxTheCompasspropertiespublicconstant_FULL='_FULL'propertiesindirectheadings=Rexxrosepoints=Rexx/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */methodRCBoxTheCompass()publicsetHeadings(makeHeadings)setRosepoints(makeRosepoints)return/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */methodmain(args=String[])publicstaticbox=RCBoxTheCompass()cp=box.getCompassPointsloopr_=1tocp[0]saycp[r_]endr_sayhx=box.getHeadingsReport(box.getHeadings)loopr_=1tohx[0]sayhx[r_]endr_sayreturn/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */methodgetDecimalAngle(degrees,minutes,seconds)publicstaticreturnsRexxdegrees=degrees*10%10minutes=minutes*10%10angle=degrees+(minutes/60+(seconds/60/60))returnangle/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */methodgetDegreesMinutesSeconds(angle)publicstaticreturnsRexxdegrees=angle*100%100minutes=((angle-degrees)*60)*100%100seconds=((((angle-degrees)*60)-minutes)*60)*100%100returndegreesminutesseconds/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */methodgetHeadingsReport(bearings)publicreturnsRexxr_=0table=''r_=r_+1;table[0]=r_;table[r_]='Idx'-'Abbr'-'Compass Point'.left(20)-'Degrees'.right(10)looph_=1tobearings[0]heading=bearings[h_]index=getRosepointIndex(heading)parsegetRosepoint(index)p_abbrevp_fullr_=r_+1;table[0]=r_;table[r_]=index.right(3)-p_abbrev.left(4)-p_full.left(20)-heading.format(6,3).right(10)endh_returntable/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */methodgetRosepointIndex(heading)publicreturnsRexxone_pt=360/32hn=heading//360hi=hn%one_ptifhn>hi*one_pt+one_pt/2thendohi=hi+1--greaterthanmaxrangeforthispoint;bumptonextpointendidx=hi//32+1--addonetogetindexintorosepointsindexedstringreturnidx/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */methodgetRosepoint(index)publicreturnsRexxrp=getRosepointsreturnrp[index]rp[index,_FULL]/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */methodmakeRosepoints()privatereturnsRexxp_=0rp=''p_=p_+1;rp[0]=p_;rp[p_]='N';rp[p_,_FULL]='North'p_=p_+1;rp[0]=p_;rp[p_]='NbE';rp[p_,_FULL]='North by East'p_=p_+1;rp[0]=p_;rp[p_]='NNE';rp[p_,_FULL]='North-Northeast'p_=p_+1;rp[0]=p_;rp[p_]='NEbn';rp[p_,_FULL]='Northeast by North'p_=p_+1;rp[0]=p_;rp[p_]='NE';rp[p_,_FULL]='Northeast'p_=p_+1;rp[0]=p_;rp[p_]='NEbE';rp[p_,_FULL]='Northeast by East'p_=p_+1;rp[0]=p_;rp[p_]='ENE';rp[p_,_FULL]='East-Northeast'p_=p_+1;rp[0]=p_;rp[p_]='EbN';rp[p_,_FULL]='East by North'p_=p_+1;rp[0]=p_;rp[p_]='E';rp[p_,_FULL]='East'p_=p_+1;rp[0]=p_;rp[p_]='EbS';rp[p_,_FULL]='East by South'p_=p_+1;rp[0]=p_;rp[p_]='ESE';rp[p_,_FULL]='East-Southeast'p_=p_+1;rp[0]=p_;rp[p_]='SEbE';rp[p_,_FULL]='Southeast by East'p_=p_+1;rp[0]=p_;rp[p_]='SE';rp[p_,_FULL]='Southeast'p_=p_+1;rp[0]=p_;rp[p_]='SEbS';rp[p_,_FULL]='Southeast by South'p_=p_+1;rp[0]=p_;rp[p_]='SSE';rp[p_,_FULL]='South-Southeast'p_=p_+1;rp[0]=p_;rp[p_]='SbE';rp[p_,_FULL]='South by East'p_=p_+1;rp[0]=p_;rp[p_]='S';rp[p_,_FULL]='South'p_=p_+1;rp[0]=p_;rp[p_]='SbW';rp[p_,_FULL]='South by West'p_=p_+1;rp[0]=p_;rp[p_]='SSW';rp[p_,_FULL]='South-Southwest'p_=p_+1;rp[0]=p_;rp[p_]='SWbS';rp[p_,_FULL]='Southwest by South'p_=p_+1;rp[0]=p_;rp[p_]='SW';rp[p_,_FULL]='Southwest'p_=p_+1;rp[0]=p_;rp[p_]='SWbW';rp[p_,_FULL]='Southwest by West'p_=p_+1;rp[0]=p_;rp[p_]='WSW';rp[p_,_FULL]='Southwest'p_=p_+1;rp[0]=p_;rp[p_]='WbS';rp[p_,_FULL]='West by South'p_=p_+1;rp[0]=p_;rp[p_]='W';rp[p_,_FULL]='West'p_=p_+1;rp[0]=p_;rp[p_]='WbN';rp[p_,_FULL]='West by North'p_=p_+1;rp[0]=p_;rp[p_]='WNW';rp[p_,_FULL]='West-Northwest'p_=p_+1;rp[0]=p_;rp[p_]='NWbW';rp[p_,_FULL]='Northwest by West'p_=p_+1;rp[0]=p_;rp[p_]='NW';rp[p_,_FULL]='Northwest'p_=p_+1;rp[0]=p_;rp[p_]='NWbN';rp[p_,_FULL]='Northwest by North'p_=p_+1;rp[0]=p_;rp[p_]='NNW';rp[p_,_FULL]='North-Northwest'p_=p_+1;rp[0]=p_;rp[p_]='NbW';rp[p_,_FULL]='North by West'returnrp/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */methodmakeHeadings()privatereturnsRexxhdg=''hdg[0]=0points=32loopi_=0topointsheading=i_*360/pointsselectcasei_//3when1thenheading_h=heading+5.62when2thenheading_h=heading-5.62otherwiseheading_h=headingendix=hdg[0]+1;hdg[0]=ix;hdg[ix]=heading_hendi_returnhdg/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */methodgetCompassPoints()publicreturnsRexxr_=0table=''r_=r_+1;table[0]=r_;table[r_]='Idx'-'Abbr'-'Compass Point'.left(20)-'Low (Deg.)'.right(10)-'Mid (Deg.)'.right(10)-'Hi (Deg.)'.right(10)--onepointofthecompassis360/32(11.25)degrees--usingfunctionstocalculatethisjustforfunone_pt=360/32parsegetDegreesMinutesSeconds(one_pt/2)adamas.points=32looph_=0topoints-1heading=h_*360/pointshmin=heading-getDecimalAngle(ad,am,as)hmax=heading+getDecimalAngle(ad,am,as)ifhmin<0thendohmin=hmin+360endifhmax>=360thendohmax=hmax-360endindex=getRosepointIndex(heading)parsegetRosepoint(index)p_abbrevp_fullr_=r_+1;table[0]=r_;table[r_]=index.right(3)-p_abbrev.left(4)-p_full.left(20)-hmin.format(6,3).right(10)-heading.format(6,3).right(10)-hmax.format(6,3).right(10)endh_returntable
Idx Abbr Compass Point Low (Deg.) Mid (Deg.) Hi (Deg.) 1 N North 354.375 0.000 5.625 2 NbE North by East 5.625 11.250 16.875 3 NNE North-Northeast 16.875 22.500 28.125 4 NEbn Northeast by North 28.125 33.750 39.375 5 NE Northeast 39.375 45.000 50.625 6 NEbE Northeast by East 50.625 56.250 61.875 7 ENE East-Northeast 61.875 67.500 73.125 8 EbN East by North 73.125 78.750 84.375 9 E East 84.375 90.000 95.625 10 EbS East by South 95.625 101.250 106.875 11 ESE East-Southeast 106.875 112.500 118.125 12 SEbE Southeast by East 118.125 123.750 129.375 13 SE Southeast 129.375 135.000 140.625 14 SEbS Southeast by South 140.625 146.250 151.875 15 SSE South-Southeast 151.875 157.500 163.125 16 SbE South by East 163.125 168.750 174.375 17 S South 174.375 180.000 185.625 18 SbW South by West 185.625 191.250 196.875 19 SSW South-Southwest 196.875 202.500 208.125 20 SWbS Southwest by South 208.125 213.750 219.375 21 SW Southwest 219.375 225.000 230.625 22 SWbW Southwest by West 230.625 236.250 241.875 23 WSW Southwest 241.875 247.500 253.125 24 WbS West by South 253.125 258.750 264.375 25 W West 264.375 270.000 275.625 26 WbN West by North 275.625 281.250 286.875 27 WNW West-Northwest 286.875 292.500 298.125 28 NWbW Northwest by West 298.125 303.750 309.375 29 NW Northwest 309.375 315.000 320.625 30 NWbN Northwest by North 320.625 326.250 331.875 31 NNW North-Northwest 331.875 337.500 343.125 32 NbW North by West 343.125 348.750 354.375Idx Abbr Compass Point Degrees 1 N North 0.000 2 NbE North by East 16.870 3 NNE North-Northeast 16.880 4 NEbn Northeast by North 33.750 5 NE Northeast 50.620 6 NEbE Northeast by East 50.630 7 ENE East-Northeast 67.500 8 EbN East by North 84.370 9 E East 84.380 10 EbS East by South 101.250 11 ESE East-Southeast 118.120 12 SEbE Southeast by East 118.130 13 SE Southeast 135.000 14 SEbS Southeast by South 151.870 15 SSE South-Southeast 151.880 16 SbE South by East 168.750 17 S South 185.620 18 SbW South by West 185.630 19 SSW South-Southwest 202.500 20 SWbS Southwest by South 219.370 21 SW Southwest 219.380 22 SWbW Southwest by West 236.250 23 WSW Southwest 253.120 24 WbS West by South 253.130 25 W West 270.000 26 WbN West by North 286.870 27 WNW West-Northwest 286.880 28 NWbW Northwest by West 303.750 29 NW Northwest 320.620 30 NWbN Northwest by North 320.630 31 NNW North-Northwest 337.500 32 NbW North by West 354.370 1 N North 354.380
importmath,sequtils,strformat,strutilsconstheadingNames:array[1..32,string]=["North","North by east","North-northeast","Northeast by north","Northeast","Northeast by east","East-northeast","East by north","East","East by south","East-southeast","Southeast by east","Southeast","Southeast by south","South-southeast","South by east","South","South by west","South-southwest","Southwest by south","Southwest","Southwest by west","West-southwest","West by south","West","West by north","West-northwest","Northwest by west","Northwest","Northwest by north","North-northwest","North by west"]maxNameLength=headingNames.mapIt(it.len).maxdegreesPerHeading=360/32functoCompassIndex(degree:float):1..32=vardegree=(degree+degreesPerHeading/2).floorMod360int(degree/degreesPerHeading)+1functoCompassHeading(degree:float):string=headingNames[degree.toCompassIndex]foriin0..32:letheading=float(i)*11.25+(caseimod3of1:5.62of2:-5.62else:0)index=heading.toCompassIndexcompassHeading=heading.toCompassHeading.alignLeft(maxNameLength)echofmt"{index:>2} {compassHeading} {heading:6.2f}"
Output:
1 North 0.00 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.50 8 East by north 84.37 9 East 84.3810 East by south 101.2511 East-southeast 118.1212 Southeast by east 118.1313 Southeast 135.0014 Southeast by south 151.8715 South-southeast 151.8816 South by east 168.7517 South 185.6218 South by west 185.6319 South-southwest 202.5020 Southwest by south 219.3721 Southwest 219.3822 Southwest by west 236.2523 West-southwest 253.1224 West by south 253.1325 West 270.0026 West by north 286.8727 West-northwest 286.8828 Northwest by west 303.7529 Northwest 320.6230 Northwest by north 320.6331 North-northwest 337.5032 North by west 354.37 1 North 354.38
class BoxCompass { function : Main(args : String[]) ~ Nil { points := [ "North ", "North by east ", "North-northeast ", "Northeast by north", "Northeast ", "Northeast by east ", "East-northeast ", "East by north ", "East ", "East by south ", "East-southeast ", "Southeast by east ", "Southeast ", "Southeast by south", "South-southeast ", "South by east ", "South ", "South by west ", "South-southwest ", "Southwest by south", "Southwest ", "Southwest by west ", "West-southwest ", "West by south ", "West ", "West by north ", "West-northwest ", "Northwest by west ", "Northwest ", "Northwest by north", "North-northwest ", "North by west " ]; for(i := 0; i<= 32; i += 1;) { heading := i * 11.25; select(i % 3) { label 1: { heading += 5.62; } label 2: { heading -= 5.62; } }; IO.Console->Print((i % 32) + 1)->Print('\t')->Print(points[GetPoint(heading)]) ->Print('\t')->PrintLine(heading); }; } function : GetPoint(degrees : Float) ~ Int { return (degrees / 11.25 + 0.5)->Floor()->As(Int) % 32; }}Output
1North 02North by east 16.873North-northeast 16.884Northeast by north33.755Northeast 50.626Northeast by east 50.637East-northeast 67.58East by north 84.379East 84.3810East by south 101.2511East-southeast 118.1212Southeast by east 118.1313Southeast 13514Southeast by south151.8715South-southeast 151.8816South by east 168.7517South 185.6218South by west 185.6319South-southwest 202.520Southwest by south219.3721Southwest 219.3822Southwest by west 236.2523West-southwest 253.1224West by south 253.1325West 27026West by north 286.8727West-northwest 286.8828Northwest by west 303.7529Northwest 320.6230Northwest by north320.6331North-northwest 337.532North by west 354.371North 354.38
lettest_cases=[0.0;16.87;16.88;33.75;50.62;50.63;67.5;84.37;84.38;101.25;118.12;118.13;135.0;151.87;151.88;168.75;185.62;185.63;202.5;219.37;219.38;236.25;253.12;253.13;270.0;286.87;286.88;303.75;320.62;320.63;337.5;354.37;354.38];;letdirections=["North";"North by East";"North-Northeast";"Northeast by North";"Northeast";"Northeast by East";"East-Northeast";"East by North";"East";"East by South";"East-Southeast";"Southeast by East";"Southeast";"Southeast by South";"South-Southeast";"South by East";"South";"South by West";"South-Southwest";"Southwest by South";"Southwest";"Southwest by West";"West-Southwest";"West by South";"West";"West by North";"West-Northwest";"Northwest by West";"Northwest";"Northwest by North";"North-Northwest";"North by West";];;letget_direction_indexinput=letshifted=(input+.5.6201)inletshifted=ifshifted>360.thenshifted-.360.elseshiftedinint_of_float(shifted/.11.25);;letprint_directioninput=letindex=get_direction_indexinputinletdirection=List.nthdirectionsindexinlettest=Printf.printf"%3d %-20s %.2f\n"(index+1)directionintestinput;;List.iter(print_direction)test_cases;;
Sample output:
1 North 0.00 2 North by East 16.87 3 North-Northeast 16.88 4 Northeast by North 33.75 5 Northeast 50.62 6 Northeast by East 50.63 7 East-Northeast 67.50 8 East by North 84.37 9 East 84.38 10 East by South 101.25 11 East-Southeast 118.12 12 Southeast by East 118.13 13 Southeast 135.00 14 Southeast by South 151.87 15 South-Southeast 151.88 16 South by East 168.75 17 South 185.62 18 South by West 185.63 19 South-Southwest 202.50 20 Southwest by South 219.37 21 Southwest 219.38 22 Southwest by West 236.25 23 West-Southwest 253.12 24 West by South 253.13 25 West 270.00 26 West by North 286.87 27 West-Northwest 286.88 28 Northwest by West 303.75 29 Northwest 320.62 30 Northwest by North 320.63 31 North-Northwest 337.50 32 North by West 354.37 1 North 354.38
/* Rexx */Doglobs='!DEG !MIN !SEC !FULL'Drop!DEG!MIN!SEC!FULLsign.=''sign.!DEG='c2b0'x--degreesign:U+00B0sign.!MIN='e280b2'x--prime:U+2032sign.!SEC='e280b3'x--doubleprime:U+2033points.=''Calldisplay_compass_pointsCalldisplay_sampleSayheadings.=''headings.0=0Callmake_headingsCallflush_queueDoh_=1toheadings.0Queueheadings.h_Endh_Calldisplay_sampleSayReturnEndExit/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */flush_queue:ProcedureDoDoq_=1toqueued()Parsepull.Endq_ReturnEndExit/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */display_sample:ProcedureExposepoints.sign.(globs)DoDoq_=1toqueued()Parsepullheadingindex=get_index(heading)ParseValueget_point(index)withp_abbrevp_fullSayindex~right(3),p_abbrev~left(4)p_full~left(20),heading~format(5,3)||sign.!DEG'('format_degrees_minutes_seconds(heading)')',''Endq_ReturnEndExit/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */display_compass_points:ProcedureExposepoints.sign.(globs)Dopoints=32one_pt=360/pointsDoh_=0topoints-1heading=h_*360/pointshmin=heading-one_pt/2hmax=heading+one_pt/2Ifhmin<0thenDohmin=hmin+360EndIfhmax>=360thenDohmax=hmax-360Endindex=(h_//points)+1ParseValueget_point(index)withp_abbrevp_fullSayindex~right(3),p_abbrev~left(4)p_full~left(20),hmin~format(5,3)||sign.!DEG'('format_degrees_minutes_seconds(hmin)')',heading~format(5,3)||sign.!DEG'('format_degrees_minutes_seconds(heading)')',hmax~format(5,3)||sign.!DEG'('format_degrees_minutes_seconds(hmax)')',''Endh_SayReturnEndExit/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */make_headings:ProcedureExposeheadings.Dopoints=32Doi_=0topointsheading=i_*360/32it=i_//3SelectWhenit=1thenDoheading_h=heading+5.62EndWhenit=2thenDoheading_h=heading-5.62EndOtherwiseDoheading_h=headingEndEndindex=(i_//points)+1ix=headings.0+1;headings.0=ix;headings.ix=heading_hEndi_ReturnEndExit/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */get_index:ProcedureDoParseArgheading.one_pt=360/32hn=heading//360hi=hn%one_ptIfhn>hi*one_pt+one_pt/2thenDohi=hi+1--greaterthanmaxrangeforthispoint;bumptonextpointEndidx=hi//32+1--addonetogetindexintopoints.stemReturnidxEndExit/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */get_point:ProcedureExposepoints.sign.(globs)DoParseargindex.Callget_pointsReturnpoints.indexpoints.index.!FULLEndExit/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */get_points:ProcedureExposepoints.sign.(globs)DoDrop!FULLpoints.=''p_=0p_=p_+1;points.0=p_;points.p_='N';points.p_.!FULL='North'p_=p_+1;points.0=p_;points.p_='NbE';points.p_.!FULL='North by East'p_=p_+1;points.0=p_;points.p_='NNE';points.p_.!FULL='North-Northeast'p_=p_+1;points.0=p_;points.p_='NEbn';points.p_.!FULL='Northeast by North'p_=p_+1;points.0=p_;points.p_='NE';points.p_.!FULL='Northeast'p_=p_+1;points.0=p_;points.p_='NEbE';points.p_.!FULL='Northeast by East'p_=p_+1;points.0=p_;points.p_='ENE';points.p_.!FULL='East-Northeast'p_=p_+1;points.0=p_;points.p_='EbN';points.p_.!FULL='East by North'p_=p_+1;points.0=p_;points.p_='E';points.p_.!FULL='East'p_=p_+1;points.0=p_;points.p_='EbS';points.p_.!FULL='East by South'p_=p_+1;points.0=p_;points.p_='ESE';points.p_.!FULL='East-Southeast'p_=p_+1;points.0=p_;points.p_='SEbE';points.p_.!FULL='Southeast by East'p_=p_+1;points.0=p_;points.p_='SE';points.p_.!FULL='Southeast'p_=p_+1;points.0=p_;points.p_='SEbS';points.p_.!FULL='Southeast by South'p_=p_+1;points.0=p_;points.p_='SSE';points.p_.!FULL='South-Southeast'p_=p_+1;points.0=p_;points.p_='SbE';points.p_.!FULL='South by East'p_=p_+1;points.0=p_;points.p_='S';points.p_.!FULL='South'p_=p_+1;points.0=p_;points.p_='SbW';points.p_.!FULL='South by West'p_=p_+1;points.0=p_;points.p_='SSW';points.p_.!FULL='South-Southwest'p_=p_+1;points.0=p_;points.p_='SWbS';points.p_.!FULL='Southwest by South'p_=p_+1;points.0=p_;points.p_='SW';points.p_.!FULL='Southwest'p_=p_+1;points.0=p_;points.p_='SWbW';points.p_.!FULL='Southwest by West'p_=p_+1;points.0=p_;points.p_='WSW';points.p_.!FULL='Southwest'p_=p_+1;points.0=p_;points.p_='WbS';points.p_.!FULL='West by South'p_=p_+1;points.0=p_;points.p_='W';points.p_.!FULL='West'p_=p_+1;points.0=p_;points.p_='WbN';points.p_.!FULL='West by North'p_=p_+1;points.0=p_;points.p_='WNW';points.p_.!FULL='West-Northwest'p_=p_+1;points.0=p_;points.p_='NWbW';points.p_.!FULL='Northwest by West'p_=p_+1;points.0=p_;points.p_='NW';points.p_.!FULL='Northwest'p_=p_+1;points.0=p_;points.p_='NWbN';points.p_.!FULL='Northwest by North'p_=p_+1;points.0=p_;points.p_='NNW';points.p_.!FULL='North-Northwest'p_=p_+1;points.0=p_;points.p_='NbW';points.p_.!FULL='North by West'ReturnEndExit/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */get_decimal_angle:ProcedureExposesign.(globs)DoParseArgdegrees.,minutes.,seconds.degrees=degrees*10%10minutes=minutes*10%10angle=degrees+minutes/60+seconds/60/60ReturnangleEndExit/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */format_decimal_angle:ProcedureExposesign.(globs)DoParseArgdegrees.,minutes.,seconds.Returnget_decimal_angle(degrees,minutes,seconds)~format(5,3)||sign.!DEGEndExit/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */get_degrees_minutes_seconds:ProcedureExposesign.(globs)DoParseargangle.degrees=angle*100%100minutes=((angle-degrees)*60)*100%100seconds=((((angle-degrees)*60)-minutes)*60)*100%100ReturndegreesminutessecondsEndExit/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */format_degrees_minutes_seconds:ProcedureExposesign.(globs)DoParseargangle.ParseValueget_degrees_minutes_seconds(angle)withdegreesminutesseconds.formatted=degrees~right(3)||sign.!DEG||minutes~right(2,0)||sign.!MIN||seconds~right(2,0)||sign.!SECReturnformattedEndExit
1 N North 354.375° (354°22′30″) 0.000° ( 0°00′00″) 5.625° ( 5°37′30″) 2 NbE North by East 5.625° ( 5°37′30″) 11.250° ( 11°15′00″) 16.875° ( 16°52′30″) 3 NNE North-Northeast 16.875° ( 16°52′30″) 22.500° ( 22°30′00″) 28.125° ( 28°07′30″) 4 NEbn Northeast by North 28.125° ( 28°07′30″) 33.750° ( 33°45′00″) 39.375° ( 39°22′30″) 5 NE Northeast 39.375° ( 39°22′30″) 45.000° ( 45°00′00″) 50.625° ( 50°37′30″) 6 NEbE Northeast by East 50.625° ( 50°37′30″) 56.250° ( 56°15′00″) 61.875° ( 61°52′30″) 7 ENE East-Northeast 61.875° ( 61°52′30″) 67.500° ( 67°30′00″) 73.125° ( 73°07′30″) 8 EbN East by North 73.125° ( 73°07′30″) 78.750° ( 78°45′00″) 84.375° ( 84°22′30″) 9 E East 84.375° ( 84°22′30″) 90.000° ( 90°00′00″) 95.625° ( 95°37′30″) 10 EbS East by South 95.625° ( 95°37′30″) 101.250° (101°15′00″) 106.875° (106°52′30″) 11 ESE East-Southeast 106.875° (106°52′30″) 112.500° (112°30′00″) 118.125° (118°07′30″) 12 SEbE Southeast by East 118.125° (118°07′30″) 123.750° (123°45′00″) 129.375° (129°22′30″) 13 SE Southeast 129.375° (129°22′30″) 135.000° (135°00′00″) 140.625° (140°37′30″) 14 SEbS Southeast by South 140.625° (140°37′30″) 146.250° (146°15′00″) 151.875° (151°52′30″) 15 SSE South-Southeast 151.875° (151°52′30″) 157.500° (157°30′00″) 163.125° (163°07′30″) 16 SbE South by East 163.125° (163°07′30″) 168.750° (168°45′00″) 174.375° (174°22′30″) 17 S South 174.375° (174°22′30″) 180.000° (180°00′00″) 185.625° (185°37′30″) 18 SbW South by West 185.625° (185°37′30″) 191.250° (191°15′00″) 196.875° (196°52′30″) 19 SSW South-Southwest 196.875° (196°52′30″) 202.500° (202°30′00″) 208.125° (208°07′30″) 20 SWbS Southwest by South 208.125° (208°07′30″) 213.750° (213°45′00″) 219.375° (219°22′30″) 21 SW Southwest 219.375° (219°22′30″) 225.000° (225°00′00″) 230.625° (230°37′30″) 22 SWbW Southwest by West 230.625° (230°37′30″) 236.250° (236°15′00″) 241.875° (241°52′30″) 23 WSW Southwest 241.875° (241°52′30″) 247.500° (247°30′00″) 253.125° (253°07′30″) 24 WbS West by South 253.125° (253°07′30″) 258.750° (258°45′00″) 264.375° (264°22′30″) 25 W West 264.375° (264°22′30″) 270.000° (270°00′00″) 275.625° (275°37′30″) 26 WbN West by North 275.625° (275°37′30″) 281.250° (281°15′00″) 286.875° (286°52′30″) 27 WNW West-Northwest 286.875° (286°52′30″) 292.500° (292°30′00″) 298.125° (298°07′30″) 28 NWbW Northwest by West 298.125° (298°07′30″) 303.750° (303°45′00″) 309.375° (309°22′30″) 29 NW Northwest 309.375° (309°22′30″) 315.000° (315°00′00″) 320.625° (320°37′30″) 30 NWbN Northwest by North 320.625° (320°37′30″) 326.250° (326°15′00″) 331.875° (331°52′30″) 31 NNW North-Northwest 331.875° (331°52′30″) 337.500° (337°30′00″) 343.125° (343°07′30″) 32 NbW North by West 343.125° (343°07′30″) 348.750° (348°45′00″) 354.375° (354°22′30″) 1 N North 0.000° ( 0°00′00″) 2 NbE North by East 16.870° ( 16°52′12″) 3 NNE North-Northeast 16.880° ( 16°52′48″) 4 NEbn Northeast by North 33.750° ( 33°45′00″) 5 NE Northeast 50.620° ( 50°37′12″) 6 NEbE Northeast by East 50.630° ( 50°37′48″) 7 ENE East-Northeast 67.500° ( 67°30′00″) 8 EbN East by North 84.370° ( 84°22′12″) 9 E East 84.380° ( 84°22′48″) 10 EbS East by South 101.250° (101°15′00″) 11 ESE East-Southeast 118.120° (118°07′12″) 12 SEbE Southeast by East 118.130° (118°07′48″) 13 SE Southeast 135.000° (135°00′00″) 14 SEbS Southeast by South 151.870° (151°52′12″) 15 SSE South-Southeast 151.880° (151°52′48″) 16 SbE South by East 168.750° (168°45′00″) 17 S South 185.620° (185°37′12″) 18 SbW South by West 185.630° (185°37′48″) 19 SSW South-Southwest 202.500° (202°30′00″) 20 SWbS Southwest by South 219.370° (219°22′12″) 21 SW Southwest 219.380° (219°22′48″) 22 SWbW Southwest by West 236.250° (236°15′00″) 23 WSW Southwest 253.120° (253°07′12″) 24 WbS West by South 253.130° (253°07′48″) 25 W West 270.000° (270°00′00″) 26 WbN West by North 286.870° (286°52′12″) 27 WNW West-Northwest 286.880° (286°52′48″) 28 NWbW Northwest by West 303.750° (303°45′00″) 29 NW Northwest 320.620° (320°37′12″) 30 NWbN Northwest by North 320.630° (320°37′48″) 31 NNW North-Northwest 337.500° (337°30′00″) 32 NbW North by West 354.370° (354°22′12″) 1 N North 354.380° (354°22′48″)
box(x)={["North","North by east","North-northeast","Northeast by north","Northeast","Northeast by east","East-northeast","East by north","East","East by south","East-southeast","Southeast by east","Southeast","Southeast by south","South-southeast","South by east","South","South by west","South-southwest","Southwest by south","Southwest","Southwest by west","West-southwest","West by south","West","West by north","West-northwest","Northwest by west","Northwest","Northwest by north","North-northwest","North by west"][round(x*4/45)%32+1]};for(i=0,32,print(i%32+1" "box(x=i*11.25+if(i%3==1,5.62,if(i%3==2,-5.62)))" "x))Output:
1 North 02 North by east 16.87000003 North-northeast 16.88000004 Northeast by north 33.75000005 Northeast 50.62000006 Northeast by east 50.63000007 East-northeast 67.50000008 East by north 84.37000009 East 84.380000010 East by south 101.25000011 East-southeast 118.12000012 Southeast by east 118.13000013 Southeast 135.00000014 Southeast by south 151.87000015 South-southeast 151.88000016 South by east 168.75000017 South 185.62000018 South by west 185.63000019 South-southwest 202.50000020 Southwest by south 219.37000021 Southwest 219.38000022 Southwest by west 236.25000023 West-southwest 253.12000024 West by south 253.13000025 West 270.00000026 West by north 286.87000027 West-northwest 286.88000028 Northwest by west 303.75000029 Northwest 320.62000030 Northwest by north 320.63000031 North-northwest 337.50000032 North by west 354.3700001 North 354.380000
programBoxTheCompass(output);functioncompasspoint(angle:real):string;constpoints:array[1..32]ofstring=('North ','North by east ','North-northeast ','Northeast by north','Northeast ','Northeast by east ','East-northeast ','East by north ','East ','East by south ','East-southeast ','Southeast by east ','Southeast ','Southeast by south','South-southeast ','South by east ','South ','South by west ','South-southwest ','Southwest by south','Southwest ','Southwest by west ','West-southwest ','West by south ','West ','West by north ','West-northwest ','Northwest by west ','Northwest ','Northwest by north','North-northwest ','North by west ');varindex:integer;beginindex:=round(angle/11.25);index:=indexmod32+1;compasspoint:=points[index];end;vari:integer;heading:real;beginfori:=0to32dobeginheading:=i*11.25;case(imod3)of1:heading:=heading+5.62;2:heading:=heading-5.62;end;writeln((imod32)+1:2,' ',compasspoint(heading),' ',heading:8:4);end;end.
Output:
:> ./BoxTheCompass 1 North 0.0000 2 North by east 16.8700 3 North-northeast 16.8800 4 Northeast by north 33.7500 5 Northeast 50.6200 6 Northeast by east 50.6300 7 East-northeast 67.5000 8 East by north 84.3700 9 East 84.380010 East by south 101.250011 East-southeast 118.120012 Southeast by east 118.130013 Southeast 135.000014 Southeast by south 151.870015 South-southeast 151.880016 South by east 168.750017 South 185.620018 South by west 185.630019 South-southwest 202.500020 Southwest by south 219.370021 Southwest 219.380022 Southwest by west 236.250023 West-southwest 253.120024 West by south 253.130025 West 270.000026 West by north 286.870027 West-northwest 286.880028 Northwest by west 303.750029 Northwest 320.620030 Northwest by north 320.630031 North-northwest 337.500032 North by west 354.3700 1 North 354.3800
Don't waste brain cells calculating names, not worth the effort. Code is probably shorter, faster, and easier to read this way.
useutf8;my@names=("North","North by east","North-northeast","Northeast by north","Northeast","Northeast by east","East-northeast","East by north","East","East by south","East-southeast","Southeast by east","Southeast","Southeast by south","South-southeast","South by east","South","South by west","South-southwest","Southwest by south","Southwest","Southwest by west","West-southwest","West by south","West","West by north","West-northwest","Northwest by west","Northwest","Northwest by north","North-northwest","North by west",);my@angles=(0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,118.13,135.0,151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38);for(@angles){my$i=int(($_*32/360)+.5)%32;printf"%3d %18s %6.2f°\n",$i+1,$names[$i],$_;}
output
1 North 0.00° 2 North by east 16.87° 3 North-northeast 16.88° 4 Northeast by north 33.75° 5 Northeast 50.62° 6 Northeast by east 50.63° 7 East-northeast 67.50° 8 East by north 84.37° 9 East 84.38° 10 East by south 101.25° 11 East-southeast 118.12° 12 Southeast by east 118.13° 13 Southeast 135.00° 14 Southeast by south 151.87° 15 South-southeast 151.88° 16 South by east 168.75° 17 South 185.62° 18 South by west 185.63° 19 South-southwest 202.50° 20 Southwest by south 219.37° 21 Southwest 219.38° 22 Southwest by west 236.25° 23 West-southwest 253.12° 24 West by south 253.13° 25 West 270.00° 26 West by north 286.87° 27 West-northwest 286.88° 28 Northwest by west 303.75° 29 Northwest 320.62° 30 Northwest by north 320.63° 31 North-northwest 337.50° 32 North by west 354.37° 1 North 354.38°
Unlike the Perl guy, for me the maths is the boring bit, building those strings is the fun!
withjavascript_semanticsfunctionget225(integerd,stringp1,stringp2,stringp4)stringp3=p1&'-'&lower(p2)p2&=" by "&lower(p1)p1&=" by "&lower(p4)ifdthenreturn{p1,p3,p2}-- eg {North by east,North-northeast,Northeast by north}elsereturn{p2,p3,p1}-- eg {Northeast by east,East-northeast,East by north}endifendfunctionfunctionget45(sequenceres,integerd,stringp1,stringp2)stringp3res=append(res,p1)-- North/East/South/Westifdthenp3=p1&lower(p2)-- Northeast/Southwestelsep3=p2&lower(p1)-- Southeast/Northwestendifres&=get225(1,p1,p3,p2)-- eg get225(1,North,Northeast,East)-- -> {North by east,North-northeast,Northeast by north}res=append(res,p3)-- Northeast/Southeast/Southwest/Northwestres&=get225(0,p2,p3,p1)-- eg get225(0,East,Northeast,North)-- -> {Northeast by east,East-northeast,East by north}returnresendfunctionfunctionget90(sequencepoints)sequenceres={}fori=1tolength(points)dores=get45(res,remainder(i,2),points[i],points[remainder(i,4)+1])endfor-- ie get45(1,North,East)-- get45(0,East,South)-- get45(1,South,West)-- get45(0,West,North)returnresendfunctionconstantcompass_points=get90({"North","East","South","West"})fori=1to33doatomtest_point=(i-1)*11.25+5.62*(remainder(i,3)-1)integercompass_point=remainder(floor(test_point*32/360+0.5),32)+1printf(1,"%2d %-22s %6.2f\n",{compass_point,compass_points[compass_point],test_point})endfor
If you like, you can regard d=1 (both of them) as "clockwise-name-inherit" and d=0 as "anti-clockwise-name-inherit".
1 North 0.00 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.50 8 East by north 84.37 9 East 84.3810 East by south 101.2511 East-southeast 118.1212 Southeast by east 118.1313 Southeast 135.0014 Southeast by south 151.8715 South-southeast 151.8816 South by east 168.7517 South 185.6218 South by west 185.6319 South-southwest 202.5020 Southwest by south 219.3721 Southwest 219.3822 Southwest by west 236.2523 West-southwest 253.1224 West by south 253.1325 West 270.0026 West by north 286.8727 West-northwest 286.8828 Northwest by west 303.7529 Northwest 320.6230 Northwest by north 320.6331 North-northwest 337.5032 North by west 354.37 1 North 354.38
of course the following way works just as well, and produces the same output (more sensible but less fun, full standalone program)
withjavascript_semanticsconstantcompass_points={"North","North by east","North-northeast","Northeast by north","Northeast","Northeast by east","East-northeast","East by north","East","East by south","East-southeast","Southeast by east","Southeast","Southeast by south","South-southeast","South by east","South","South by west","South-southwest","Southwest by south","Southwest","Southwest by west","West-southwest","West by south","West","West by north","West-northwest","Northwest by west","Northwest","Northwest by north","North-northwest","North by west"},test_points={0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,118.13,135.0,151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38}fortintest_pointsdointegercompass_point=remainder(floor(t*32/360+0.5),32)+1printf(1,"%2d %-22s %6.2f\n",{compass_point,compass_points[compass_point],t})endfor
go => Names = ["North", "North by east", "North-northeast", "Northeast by north", "Northeast", "Northeast by east", "East-northeast", "East by north", "East", "East by south", "East-southeast", "Southeast by east", "Southeast", "Southeast by south","South-southeast", "South by east", "South", "South by west", "South-southwest", "Southwest by south", "Southwest", "Southwest by west", "West-southwest", "West by south", "West", "West by north", "West-northwest", "Northwest by west", "Northwest", "Northwest by north", "North-northwest", "North by west", "North" ], foreach(I in 0..32) J = I mod 32, D = I * 11.25, if I mod 3 == 1 then D := D + 5.62 end, if I mod 3 == 2 then D := D - 5.62 end, printf("%2d %-20s %6.2f\n", J+1, Names[J+1], D) end, nl.1 North 0.00 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.50 8 East by North 84.37 9 East 84.3810 East by south 101.2511 East-southeast 118.1212 Southeast by east 118.1313 Southeast 135.0014 Southeast by south 151.8715 South-southeast 151.8816 South by east 168.7517 South 185.6218 South by west 185.6319 South-southwest 202.5020 Southwest by south 219.3721 Southwest 219.3822 Southwest by west 236.2523 West-southwest 253.1224 West by south 253.1325 West 270.0026 West by north 286.8727 West-northwest 286.8828 Northwest by west 303.7529 Northwest 320.6230 Northwest by north 320.6331 North-northwest 337.5032 North by west 354.37 1 North 354.38
(scl 3)(setq *Compass # Build lookup table (let H -16.875 (mapcar '((Str) (cons (inc 'H 11.25) # Heading in degrees (pack # Compass point (replace (chop Str) "N" "north" "E" "east" "S" "south" "W" "west" "b" " by " ) ) ) ) '("N" "NbE" "N-NE" "NEbN" "NE" "NEbE" "E-NE" "EbN" "E" "EbS" "E-SE" "SEbE" "SE" "SEbS" "S-SE" "SbE" "S" "SbW" "S-SW" "SWbS" "SW" "SWbW" "W-SW" "WbS" "W" "WbN" "W-NW" "NWbW" "NW" "NWbN" "N-NW" "NbW" "N" ) ) ) )(de heading (Deg) (rank (% Deg 360.00) *Compass) )(for I (range 0 32) (let H (* I 11.25) (case (% I 3) (1 (inc 'H 5.62)) (2 (dec 'H 5.62)) ) (tab (3 1 -18 8) (inc (% I 32)) NIL (cdr (heading H)) (round H 2) ) ) )Output:
1 north 0.00 2 north by east 16.87 3 north-northeast 16.88 4 northeast by north 33.75 5 northeast 50.62 6 northeast by east 50.63 7 east-northeast 67.50 8 east by north 84.37 9 east 84.38 10 east by south 101.25 11 east-southeast 118.12 12 southeast by east 118.13 13 southeast 135.00 14 southeast by south 151.87 15 south-southeast 151.88 16 south by east 168.75 17 south 185.62 18 south by west 185.63 19 south-southwest 202.50 20 southwest by south 219.37 21 southwest 219.38 22 southwest by west 236.25 23 west-southwest 253.12 24 west by south 253.13 25 west 270.00 26 west by north 286.87 27 west-northwest 286.88 28 northwest by west 303.75 29 northwest 320.62 30 northwest by north 320.63 31 north-northwest 337.50 32 north by west 354.37 1 north 354.38
localfmt=require"fmt"---'cpx' returns integer index from 1 to 32 corresponding to compass point.-- Input heading h is in degrees.localfunctioncpx(h)localx=math.floor(h/11.25+0.5)%32ifx<0thenx+=32endreturnx+1end-- Printable compass points.localcompass_point={"North","North by east","North-northeast","Northeast by north","Northeast","Northeast by east","East-northeast","East by north","East","East by south","East-southeast","Southeast by east","Southeast","Southeast by south","South-southeast","South by east","South","South by west","South-southwest","Southwest by south","Southwest","Southwest by west","West-southwest","West by south","West","West by north","West-northwest","Northwest by west","Northwest","Northwest by north","North-northwest","North by west"}-- Function required by task.localfunctiondegrees_to_compass_point(h)returncompass_point[cpx(h)]endlocalr={0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,118.13,135.0,151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38}print("Index Compass point Degree")locali=0forrashdolocalindex=i%32+1locald=degrees_to_compass_point(h)fmt.print("%4d %-19s %7.2f°",index,d,h)i+=1end
Index Compass point Degree 1 North 0.00° 2 North by east 16.87° 3 North-northeast 16.88° 4 Northeast by north 33.75° 5 Northeast 50.62° 6 Northeast by east 50.63° 7 East-northeast 67.50° 8 East by north 84.37° 9 East 84.38° 10 East by south 101.25° 11 East-southeast 118.12° 12 Southeast by east 118.13° 13 Southeast 135.00° 14 Southeast by south 151.87° 15 South-southeast 151.88° 16 South by east 168.75° 17 South 185.62° 18 South by west 185.63° 19 South-southwest 202.50° 20 Southwest by south 219.37° 21 Southwest 219.38° 22 Southwest by west 236.25° 23 West-southwest 253.12° 24 West by south 253.13° 25 West 270.00° 26 West by north 286.87° 27 West-northwest 286.88° 28 Northwest by west 303.75° 29 Northwest 320.62° 30 Northwest by north 320.63° 31 North-northwest 337.50° 32 North by west 354.37° 1 North 354.38°
functionConvert-DegreeToDirection([double]$Degree){$Directions=@('n','n by e','n-ne','ne by n','ne','ne by e','e-ne','e by n','e','e by s','e-se','se by e','se','se by s','s-se','s by e','s','s by w','s-sw','sw by s','sw','sw by w','w-sw','w by s','w','w by n','w-nw','nw by w','nw','nw by n','n-nw','n by w','n').Replace('s','south').Replace('e','east').Replace('n','north').Replace('w','west')$Directions[[math]::floor(($Degree%360)/11.25+0.5)]}$x=0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,118.13,135.0,151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38$x|%{Convert-DegreeToDirection-Degree$_}
northnorth by eastnorth-northeastnortheast by northnortheastnortheast by easteast-northeasteast by northeasteast by southeast-southeastsoutheast by eastsoutheastsoutheast by southsouth-southeastsouth by eastsouthsouth by westsouth-southwestsouthwest by southsouthwestsouthwest by westwest-southwestwest by southwestwest by northwest-northwestnorthwest by westnorthwestnorthwest by northnorth-northwestnorth by westnorth
A more general solution allowing you to choose whether to use 4, 8, 16, or 32 compass points.
functionConvert-DegreeToDirection([double]$Degree,[int]$Points){$Directions=@('n','n by e','n-ne','ne by n','ne','ne by e','e-ne','e by n','e','e by s','e-se','se by e','se','se by s','s-se','s by e','s','s by w','s-sw','sw by s','sw','sw by w','w-sw','w by s','w','w by n','w-nw','nw by w','nw','nw by n','n-nw','n by w','n').Replace('s','south').Replace('e','east').Replace('n','north').Replace('w','west')$Directions[[math]::floor((($Degree%360)*$Points/360+0.5))*32/$Points]}$x=0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,118.13,135.0,151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38$Values=@()ForEach($Degreein$X){$Values+=[pscustomobject]@{Degree=$Degree32=(Convert-DegreeToDirection-Degree$Degree-Points32)16=(Convert-DegreeToDirection-Degree$Degree-Points16)8=(Convert-DegreeToDirection-Degree$Degree-Points8)4=(Convert-DegreeToDirection-Degree$Degree-Points4)}}$Values|Format-Table
Degree 32 16 8 4 ------ -- -- - - 0 north north north north 16.87 north by east north-northeast north north 16.88 north-northeast north-northeast north north 33.75 northeast by north northeast northeast north 50.62 northeast northeast northeast east 50.63 northeast by east northeast northeast east 67.5 east-northeast east-northeast east east 84.37 east by north east east east 84.38 east east east east 101.25 east by south east-southeast east east 118.12 east-southeast east-southeast southeast east 118.13 southeast by east east-southeast southeast east 135 southeast southeast southeast south151.87 southeast by south south-southeast southeast south151.88 south-southeast south-southeast southeast south168.75 south by east south south south185.62 south south south south185.63 south by west south south south 202.5 south-southwest south-southwest southwest south219.37 southwest by south southwest southwest south219.38 southwest southwest southwest south236.25 southwest by west west-southwest southwest west 253.12 west-southwest west-southwest west west 253.13 west by south west-southwest west west 270 west west west west 286.87 west by north west-northwest west west 286.88 west-northwest west-northwest west west 303.75 northwest by west northwest northwest west 320.62 northwest northwest northwest north320.63 northwest by north northwest northwest north 337.5 north-northwest north-northwest north north354.37 north by west north north north354.38 north north north north
Part 1 : The following knowledge base takes a heading in degrees and returns the correct 32-point compass heading. It can also go in the other direction.
compassangle(1,'North',n,0.00).compassangle(2,'North by east',nbe,11.25).compassangle(3,'North-northeast',nne,22.50).compassangle(4,'Northeast by north',nebn,33.75).compassangle(5,'Northeast',ne,45.00).compassangle(6,'Norteast by east',nebe,56.25).compassangle(7,'East-northeast',ene,67.50).compassangle(8,'East by North',ebn,78.75).compassangle(9,'East',e,90.00).compassangle(10,'East by south',ebs,101.25).compassangle(11,'East-southeast',ese,112.50).compassangle(12,'Southeast by east',sebe,123.75).compassangle(13,'Southeast',se,135.00).compassangle(14,'Southeast by south',sebs,146.25).compassangle(15,'South-southeast',sse,157.50).compassangle(16,'South by east',sbe,168.75).compassangle(17,'South',s,180.00).compassangle(18,'South by west',sbw,191.25).compassangle(19,'South-southwest',ssw,202.50).compassangle(20,'Southwest by south',swbs,213.75).compassangle(21,'Southwest',sw,225.00).compassangle(22,'Southwest by west',swbw,236.25).compassangle(23,'West-southwest',wsw,247.50).compassangle(24,'West by south',wbs,258.75).compassangle(25,'West',w,270.00).compassangle(26,'West by north',wbn,281.25).compassangle(27,'West-northwest',wnw,292.50).compassangle(28,'Northwest by west',nwbw,303.75).compassangle(29,'Northwest',nw,315.00).compassangle(30,'Northwest by north',nwbn,326.25).compassangle(31,'North-northwest',nnw,337.50).compassangle(32,'North by west',nbw,348.75).compassangle(1,'North',n,360.00).compassangle(Index,Name,Heading,Angle):-nonvar(Angle),resolveindex(Angle,Index),compassangle(Index,Name,Heading,_).resolveindex(Angle,Index):-NisAngle/11.25+0.5,Iisfloor(N),Indexis(Imod32)+1.
Part 2 : The following rules print a table of indexes.
printTableRow(Angle):-compassangle(Index,Name,_,Angle),write(Index),write(' '),write(Name),write(' '),write(Angle).printTable([X|Xs]):-printTableRow(X),nl,printTable(Xs),!.printTable([]).
The following query prints the required table.
?-printTable([0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,118.13,135.0,151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38]).1North0.02Northbyeast16.873North-northeast16.884Northeastbynorth33.755Northeast50.626Norteastbyeast50.637East-northeast67.58EastbyNorth84.379East84.3810Eastbysouth101.2511East-southeast118.1212Southeastbyeast118.1313Southeast135.014Southeastbysouth151.8715South-southeast151.8816Southbyeast168.7517South185.6218Southbywest185.6319South-southwest202.520Southwestbysouth219.3721Southwest219.3822Southwestbywest236.2523West-southwest253.1224Westbysouth253.1325West270.026Westbynorth286.8727West-northwest286.8828Northwestbywest303.7529Northwest320.6230Northwestbynorth320.6331North-northwest337.532Northbywest354.371North354.38true.
DataSectionData.s"N","north","E","east","W","west","S","south","b"," by ";abbreviations,expansionsData.s"N NbE N-NE NEbN NE NEbE E-NE EbN E EbS E-SE SEbE SE SEbS S-SE SbE";dirsData.s"S SbW S-SW SWbS SW SWbW W-SW WbS W WbN W-NW NWbW NW NWbN N-NW NbW"EndDataSection;initializedataNewMapdirSubst.s()Definei,abbr.s,expansion.sFori=1To5Read.sabbrRead.sexpansiondirSubst(abbr)=expansionNextDimdirs.s(32)Definej,s.sForj=0To1Read.ss.sFori=0To15abbr.s=StringField(s,i+1," ")dirs(j*16+i)=abbrNextNext;expandabbreviatedcompasspointandcapitalizeProcedure.sabbr2compassPoint(abbr.s)ShareddirSubst()Protectedi,compassPoint.s,key.sFori=1ToLen(abbr)key.s=Mid(abbr,i,1)IfFindMapElement(dirSubst(),key)compassPoint+dirSubst(key)ElsecompassPoint+keyEndIfNextProcedureReturnUCase(Left(compassPoint,1))+Mid(compassPoint,2)EndProcedureProcedure.sangle2compass(angle.f)Shareddirs()Staticsegment.f=360.0/32;widthofeachcompasssegmentProtecteddir;workoutwhichsegmentcontainsthecompassangledir=Int((Mod(angle,360)/segment)+0.5);converttoanameddirectionProcedureReturnabbr2compassPoint(dirs(dir))EndProcedure;boxthecompassIfOpenConsole()Definei,heading.f,indexFori=0To32heading=i*11.25Ifi%3=1heading+5.62EndIfIfi%3=2heading-5.62EndIfindex=i%32+1PrintN(RSet(Str(index),2)+" "+LSet(angle2compass(heading),18)+RSet(StrF(heading,2),7))NextPrint(#CRLF$+#CRLF$+"Press ENTER to exit"):Input()CloseConsole()EndIf
Sample output:
1 North 0.00 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.50 8 East by north 84.37 9 East 84.3810 East by south 101.2511 East-southeast 118.1212 Southeast by east 118.1313 Southeast 135.0014 Southeast by south 151.8715 South-southeast 151.8816 South by east 168.7517 South 185.6218 South by west 185.6319 South-southwest 202.5020 Southwest by south 219.3721 Southwest 219.3822 Southwest by west 236.2523 West-southwest 253.1224 West by south 253.1325 West 270.0026 West by north 286.8727 West-northwest 286.8828 Northwest by west 303.7529 Northwest 320.6230 Northwest by north 320.6331 North-northwest 337.5032 North by west 354.37 1 354.38
majors='north east south west'.split()majors*=2# no need for modulo laterquarter1='N,N by E,N-NE,NE by N,NE,NE by E,E-NE,E by N'.split(',')quarter2=[p.replace('NE','EN')forpinquarter1]defdegrees2compasspoint(d):d=(d%360)+360/64majorindex,minor=divmod(d,90.)majorindex=int(majorindex)minorindex=int((minor*4)//45)p1,p2=majors[majorindex:majorindex+2]ifp1in{'north','south'}:q=quarter1else:q=quarter2returnq[minorindex].replace('N',p1).replace('E',p2).capitalize()if__name__=='__main__':foriinrange(33):d=i*11.25m=i%3ifm==1:d+=5.62elifm==2:d-=5.62n=i%32+1print('%2i%-18s%7.2f°'%(n,degrees2compasspoint(d),d))
1 North 0.00° 2 North by east 16.87° 3 North-northeast 16.88° 4 Northeast by north 33.75° 5 Northeast 50.62° 6 Northeast by east 50.63° 7 East-northeast 67.50° 8 East by north 84.37° 9 East 84.38°10 East by south 101.25°11 East-southeast 118.12°12 Southeast by east 118.13°13 Southeast 135.00°14 Southeast by south 151.87°15 South-southeast 151.88°16 South by east 168.75°17 South 185.62°18 South by west 185.63°19 South-southwest 202.50°20 Southwest by south 219.37°21 Southwest 219.38°22 Southwest by west 236.25°23 West-southwest 253.12°24 West by south 253.13°25 West 270.00°26 West by north 286.87°27 West-northwest 286.88°28 Northwest by west 303.75°29 Northwest 320.62°30 Northwest by north 320.63°31 North-northwest 337.50°32 North by west 354.37° 1 North 354.38°
DECLAREFUNCTIONcompasspoint$(h!)DIMSHAREDpoint$(32)FORi=1TO32READd$:point$(i)=d$NEXTiFORi=0TO32heading=i*11.25IF(iMOD3)=1THENheading=heading+5.62ELSEIF(iMOD3)=2THENheading=heading-5.62ENDIFind=iMOD32+1PRINTind,compasspoint$(heading),headingNEXTiENDDATA"North ","North by east ","North-northeast ","Northeast by north"DATA"Northeast ","Northeast by east ","East-northeast ","East by north "DATA"East ","East by south ","East-southeast ","Southeast by east "DATA"Southeast ","Southeast by south","South-southeast ","South by east "DATA"South ","South by west ","South-southwest ","Southwest by south"DATA"Southwest ","Southwest by west ","West-southwest ","West by south "DATA"West ","West by north ","West-northwest ","Northwest by west "DATA"Northwest ","Northwest by north","North-northwest ","North by west "FUNCTIONcompasspoint$(h)x=h/11.25+1.5IF(x>=33!)THENx=x-32!compasspoint$=point$(INT(x))ENDFUNCTION
switch,case andotherwise are define atMetaprogramming#Quackery.
[ tuck space swap of join swap split drop echo$ ] is lecho$ ( $ n --> ) [ table ] is heading $ "N NbE N-NE NEbN NE NEbE E-NE EbN E EbS E-SE SEbE SE SEbS S-SE SbE S SbW S-SW SWbS SW SWbW W-SW WbS W WbN W-NW NWbW NW NWbN N-NW NbW" nest$ witheach [ $ "" swap witheach [ [ switch char N case $ "north" char E case $ "east" char S case $ "south" char W case $ "west" char b case $ " by " otherwise $ "-" ] join ] ' heading put ] [ 4 45 v* 1 2 v+ / 32 mod heading ] is degrees->compass$ ( n/d --> $ ) $ " 0.0 16.87 16.88 33.75 50.62 50.63 67.5 84.37 84.38 101.25 118.12 118.13 135.0 151.87 151.88 168.75 185.62 185.63 202.5 219.37 219.38 236.25 253.12 253.13 270.0 286.87 286.88 303.75 320.62 320.63 337.5 354.37 354.38" nest$ witheach [ i^ 32 mod 1+ dup 10 < if sp echo sp dup $->v drop degrees->compass$ 19 lecho$ echo$ cr ]
1 north 0.0 2 north by east 16.87 3 north-northeast 16.88 4 northeast by north 33.75 5 northeast 50.62 6 northeast by east 50.63 7 east-northeast 67.5 8 east by north 84.37 9 east 84.3810 east by south 101.2511 east-southeast 118.1212 southeast by east 118.1313 southeast 135.014 southeast by south 151.8715 south-southeast 151.8816 south by east 168.7517 south 185.6218 south by west 185.6319 south-southwest 202.520 southwest by south 219.3721 southwest 219.3822 southwest by west 236.2523 west-southwest 253.1224 west by south 253.1325 west 270.026 west by north 286.8727 west-northwest 286.8828 northwest by west 303.7529 northwest 320.6230 northwest by north 320.6331 north-northwest 337.532 north by west 354.37 1 north 354.38
R (also known as Arrr me hearties!) is ideally suited to this task. Here's an easy to understand but inefficient way to solve it:
# Build a table of directionspts<-data.frame(des=c("N","NxE","NNE","NExN","NE","NExE","ENE","ExN","E","ExS","ESE","SExE","SE","SExS","SSE","SxE","S","SxW","SSW","SWxS","SW","SWxW","WSW","WxS","W","WxN","WNW","NWxW","NW","NWxN","NNW","NxW","N"))pts$deg<-seq(0,360,360/32)heading<-Vectorize(function(deg){res<-pts# Calculate the absolute difference between each# point on the table and the function inputres$diff<-abs(res$deg-deg)# Sort the table by abs difference, return the firstres<-res[order(res$diff),]res[1,]$des[1]})
Here are the test inputs:
test<-data.frame(deg=c(0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,118.13,135.0,151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38))test$heading<-heading(test$deg)test
Check that the output headings cover the full range of headings:
all.equal(test$heading,pts$des)
> test deg heading1 0.00 N2 16.87 NxE3 16.88 NNE4 33.75 NExN5 50.62 NE6 50.63 NExE7 67.50 ENE8 84.37 ExN9 84.38 E10 101.25 ExS11 118.12 ESE12 118.13 SExE13 135.00 SE14 151.87 SExS15 151.88 SSE16 168.75 SxE17 185.62 S18 185.63 SxW19 202.50 SSW20 219.37 SWxS21 219.38 SW22 236.25 SWxW23 253.12 WSW24 253.13 WxS25 270.00 W26 286.87 WxN27 286.88 WNW28 303.75 NWxW29 320.62 NW30 320.63 NWxN31 337.50 NNW32 354.37 NxW33 354.38 N> all.equal(test$heading, pts$des)[1] TRUE
#langracket;;; Generate the headings and boxes(define(i->heading/boxi)(values(let((heading(*i#e11.25)))(case(moduloi3)((1)(+heading#e5.62))((2)(-heading#e5.62))(elseheading)))(add1(moduloi32))))(define-values(headings-listbox-list)(for/lists(h-lsti-lst)((i(in-range0(add132))))(i->heading/boxi)))(definebox-names(list"North""North by east""North-northeast""Northeast by north""Northeast""Northeast by east""East-northeast""East by north""East""East by south""East-southeast""Southeast by east""Southeast""Southeast by south""South-southeast""South by east""South""South by west""South-southwest""Southwest by south""Southwest""Southwest by west""West-southwest""West by south""West""West by north""West-northwest""Northwest by west""Northwest""Northwest by north""North-northwest""North by west"))(define(heading->boxh)(let*((n-boxes(lengthbox-names))(box-width(/360n-boxes)))(add1(modulo(ceiling(-(/hbox-width)1/2))n-boxes))));;; displays a single row of the table, can also be used for titles(define(display-rowbap)(printf"~a | ~a | ~a~%"(~ab#:width2#:align'right)(~aa#:width6#:align'right)(~ap)));;; display the table(display-row"#""Angle""Point")(displayln"---+--------+-------------------")(for((headingheadings-list))(let*((box-number(heading->boxheading)));; by coincidence, default value of the second argument to;; real->decimal-string "decimal-digits" is 2,... just what we want!(display-rowbox-number(real->decimal-stringheading)(list-refbox-names(sub1box-number)))))(module+test(requirerackunit);;; unit test heading->box (the business end of the implementation)(check-=(heading->box354.38)10)(check-=(heading->box5.62)10)(check-=(heading->box5.63)20)(check-=(heading->box16.87)20))
Output:
# | Angle | Point---+--------+------------------- 1 | 0.00 | North 2 | 16.87 | North by east 3 | 16.88 | North-northeast 4 | 33.75 | Northeast by north 5 | 50.62 | Northeast 6 | 50.63 | Northeast by east 7 | 67.50 | East-northeast 8 | 84.37 | East by north 9 | 84.38 | East10 | 101.25 | East by south11 | 118.12 | East-southeast12 | 118.13 | Southeast by east13 | 135.00 | Southeast14 | 151.87 | Southeast by south15 | 151.88 | South-southeast16 | 168.75 | South by east17 | 185.62 | South18 | 185.63 | South by west19 | 202.50 | South-southwest20 | 219.37 | Southwest by south21 | 219.38 | Southwest22 | 236.25 | Southwest by west23 | 253.12 | West-southwest24 | 253.13 | West by south25 | 270.00 | West26 | 286.87 | West by north27 | 286.88 | West-northwest28 | 303.75 | Northwest by west29 | 320.62 | Northwest30 | 320.63 | Northwest by north31 | 337.50 | North-northwest32 | 354.37 | North by west 1 | 354.38 | North
(formerly Perl 6)
subpoint (Int$index) {my$ix =$index %32;if$ix +&1 {"&point(($ix + 1) +& 28) by &point(((2 - ($ix +& 2)) * 4) + $ix +& 24)" }elsif$ix +&2 {"&point(($ix + 2) +& 24)-&point(($ix +| 4) +& 28)" }elsif$ix +&4 {"&point(($ix + 8) +& 16)&point(($ix +| 8) +& 24)" }else {<north east south west>[$ixdiv8]; }}subtest-angle ($ix) {$ix *11.25 + (0,5.62, -5.62)[$ix %3 ] }subangle-to-point(\𝜽) {floor𝜽 /360 *32 +0.5 }for0 ..32 ->$ix {my \𝜽 =test-angle($ix);printf" %2d %6.2f° %s\n",$ix %32 +1,𝜽,tcpointangle-to-point𝜽;}
Output:
1 0.00° North 2 16.87° North by east 3 16.88° North-northeast 4 33.75° Northeast by north 5 50.62° Northeast 6 50.63° Northeast by east 7 67.50° East-northeast 8 84.37° East by north 9 84.38° East 10 101.25° East by south 11 118.12° East-southeast 12 118.13° Southeast by east 13 135.00° Southeast 14 151.87° Southeast by south 15 151.88° South-southeast 16 168.75° South by east 17 185.62° South 18 185.63° South by west 19 202.50° South-southwest 20 219.37° Southwest by south 21 219.38° Southwest 22 236.25° Southwest by west 23 253.12° West-southwest 24 253.13° West by south 25 270.00° West 26 286.87° West by north 27 286.88° West-northwest 28 303.75° Northwest by west 29 320.62° Northwest 30 320.63° Northwest by north 31 337.50° North-northwest 32 354.37° North by west 1 354.38° North
Rebol[title:"Rosetta code: Box the compass"file:%Box_the_compass.r3url:https://rosettacode.org/wiki/Box_the_compassneeds:3.10.0;; or something like that]form-angle:func["Format the angle as a string with at least one decimal and pad to 2 decimals"angle[decimal!]][angle:formround/toangle0.01pad/withfind/lastangle#"."3#"0";; ensure two digits after the decimal pointappendangle#"°";; add the degree symbol]compass:context[points:nonemake-points:function[/verbose][out:copy[];; Define a character set for the four main directionsmain-dir:charset"NESW";; 32-wind compass notation (with quarter winds and by-points)words:[NNbENNENEbNNENEbEENEEbNEEbSESESEbESESEbSSSESbESSbWSSWSWbSSWSWbWWSWWbSWWbNWNWNWbWNWNWbNNNWNbWN];; Replacement map from shorthand characters to full words (and spacing)replacement:#[#"N""north"#"b"" by "#"S""south"#"E""east"#"W""west"]i:0;; index of the current compass point (0..32)foreachwordwords[;; Compute heading angle:;; Each step is 11.25°, with offsets of +5.62, 0.0, or -5.62 for the 1/3 sub-steps.heading:i*11.25+(pickz[0.05.62-5.62]i%3);; Start with the symbolic label (e.g., "NEbE") as a mutable stringtext:tostring!word;; Insert a hyphen after the first main direction if followed by two more main directions;; (e.g., "NEbE" -> "N-EbE")parsetext[1main-dirahead2main-dirinsert"-"];; Expand shorthand letters to full words using the replacement table:;; - Replace N/S/E/W with north/south/east/west;; - Replace 'b' with " by "parsetext[any[p:changeskip(any[replacement/(p/1)p/1])]];; Capitalize first letter of the expanded label (e.g., "north by east" -> "North by east")uppercase/parttext1ifverbose[;; Print three columns:;; - Ordinal index within 32-wind cycle (1..32);; - Formatted angle;; - Expanded textual compass pointprint[pad(i%32+1)-3padform-angleheading-7padformword5text]]rependout[headingwordtext]++i]new-line/skipouttrue3out]nearest-text:function["Returns the nearest compass point text for a given angle."angle[number!integer!decimal!]][;; :lazily build the points table if not already builtunlesspoints[points:make-points];; Normalize query angle into [0,360)angle:angle%360.0ifangle<0[angle:angle+360.0]best-diff:1e9;; Walk triples: angle word textforeach[degwrdtxt]points[;; Compute minimal circular differencediff:absdeg-angleifdiff<best-diff[best-diff:diffbest:txt;; remember the text for the closest heading]]best]];; Print all angle textscompass/make-points/verboseprint"^/Resolve texts for random angles:"random/seed1loop5[angle:random360.0print[padform-angleangle-7compass/nearest-textangle]]
1 0.00° N North 2 16.87° NbE North by east 3 16.88° NNE North-northeast 4 33.75° NEbN Northeast by north 5 50.62° NE Northeast 6 50.63° NEbE Northeast by east 7 67.50° ENE East-northeast 8 84.37° EbN East by north 9 84.38° E East 10 101.25° EbS East by south 11 118.12° ESE East-southeast 12 118.13° SEbE Southeast by east 13 135.00° SE Southeast 14 151.87° SEbS Southeast by south 15 151.88° SSE South-southeast 16 168.75° SbE South by east 17 185.62° S South 18 185.63° SbW South by west 19 202.50° SSW South-southwest 20 219.37° SWbS Southwest by south 21 219.38° SW Southwest 22 236.25° SWbW Southwest by west 23 253.12° WSW West-southwest 24 253.13° WbS West by south 25 270.00° W West 26 286.87° WbN West by north 27 286.88° WNW West-northwest 28 303.75° NWbW Northwest by west 29 320.62° NW Northwest 30 320.63° NWbN Northwest by north 31 337.50° NNW North-northwest 32 354.37° NbW North by west 1 354.38° N NorthResolve texts for random angles: 24.64° North-northeast233.98° Southwest by west119.07° Southeast by east 97.76° East by south357.45° North
Red[]d:charset[#"N"#"E"#"S"#"W"];; main directionshm:#();; hm = hashmap - key= heading, value = [box , compass point]compass-points:[NNbENNENEbNNENEbEENEEbNEEbSESESEbESESEbSSSESbESSbWSSWSWbSSWSWbWWSWWbSWWbNWNWNWbWNWNWbNNNWNbWN]expand:func[cprepl][;; expand compass point to wordsparsecp[copyathrudahead2dinsert"-"];; insert "-" after first direction, if followed by 2 moreforeach[srcdst]repl[replace/allcpto-stringsrcto-stringdst];; N -> north ...uppercase/partcp1;; convert first letter to uppercase]print-line:does[print[pad/lefthm/:heading/13padhm/:heading/220heading]]forallcompass-points[i:(index? compass-points)-1;; so i = 0..33heading:i*11.25+either1=rem:i%3[5.62];; rem = remainder[eitherrem=2[-5.62][0.0]]hm/:heading:reduce[(i%32+1)expandto-stringcompass-points/1[Nnorthb" by "SsouthEeastWwest]]print-lineheading]
output
1 North 0.0 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.5 8 East by north 84.37 9 East 84.38 10 East by south 101.25 11 East-southeast 118.12 12 Southeast by east 118.13 13 Southeast 135.0 14 Southeast by south 151.87 15 South-southeast 151.88 16 South by east 168.75 17 South 185.62 18 South by west 185.63 19 South-southwest 202.5 20 Southwest by south 219.37 21 Southwest 219.38 22 Southwest by west 236.25 23 West-southwest 253.12 24 West by south 253.13 25 West 270.0 26 West by north 286.87 27 West-northwest 286.88 28 Northwest by west 303.75 29 Northwest 320.62 30 Northwest by north 320.63 31 North-northwest 337.5 32 North by west 354.37 1 North 354.38>>
This version does normalization of the (degree) heading and can also handle negative headings.
/*REXX program "boxes the compass" *//* [from degree (º) headings ---> a 32 point set]. */ParseArgdegreesIfdegrees=''Thendegrees=016.8716.8833.7550.6250.6367.584.3784.38101.25,118.12118.13135151.87151.88168.75185.62185.63202.5,219.37219.38236.25253.12253.13270286.87286.88303.75,320.62320.63337.5354.37354.38names='n nbe n-ne nebn ne nebe e-ne ebn e ebs e-se sebe se sebs s-se sbe','s sbw s-sw swbs sw swbw w-sw wbs w wbn w-nw nwbw nw nwbn n-nw nbw'nn=words(names)+1/* nn: used for integer ÷ remainder */dirs='north south east west'/* define cardinal compass directions*//* choose a glyph for degree (°).*/If4=='f4'xThen/* is this system an EBCDIC system*/degsym='a1'xElsedegsym='f8'x/* or degsym='a7'x */Sayright(degsym'heading',30)center('compass heading',20)Sayright('--------',30)copies('-',20)pad=' '/* used to interject a blank for o */Doi=1Towords(degrees)x=word(degrees,i)/* obtain one of the degree headings */Sayright(format(x,,2)degsym,30-1)padboxheading(x)EndExit/* stick a fork in it, we're all done*//*---------------------------------------------------------------------*/boxheading:y=arg(1)//360Ify<0Theny=360-y/* normalize heading within unit circle */z=word(names,trunc(max(1,(y/11.25+1.5)//nn)))/* degrees->heading *//* n e s w are now replaced by north east south west, respectively */Dok=1Towords(dirs)d=word(dirs,k)z=changestr(left(d,1),z,d)EndReturnchangestr('b',z,' by ')/* expand 'b' ---? ' by '. */
Some older REXXes don't have a changestr BIF, so one is included here ──► CHANGESTR.REX.
ºheading compass heading ════════ ════════════════════ 0.00º north 16.87º north by east 16.88º north-northeast 33.75º northeast by north 50.62º northeast 50.63º northeast by east 67.50º east-northeast 84.37º east by north 84.38º east 101.25º east by south 118.12º east-southeast 118.13º southeast by east 135.00º southeast 151.87º southeast by south 151.88º south-southeast 168.75º south by east 185.62º south 185.63º south by west 202.50º south-southwest 219.37º southwest by south 219.38º southwest 236.25º southwest by west 253.12º west-southwest 253.13º west by south 270.00º west 286.87º west by north 286.88º west-northwest 303.75º northwest by west 320.62º northwest 320.63º northwest by north 337.50º north-northwest 354.37º north by west 354.38º north
# Project : Box the compassnames = ["North", "North by east", "North-northeast", "Northeast by north", "Northeast", "Northeast by east", "East-northeast", "East by north", "East", "East by south", "East-southeast", "Southeast by east", "Southeast", "Southeast by south", "South-southeast", "South by east", "South", "South by west", "South-southwest", "Southwest by south", "Southwest", "Southwest by west", "West-southwest", "West by south", "West", "West by north", "West-northwest", "Northwest by west", "Northwest", "Northwest by north", "North-northwest", "North by west", "North"] degrees = [0, 16.87, 16.88, 33.75, 50.62, 50.63, 67.5, 84.37, 84.38, 101.25, 118.12, 118.13, 135, 151.87, 151.88, 168.75, 185.62, 185.63, 202.5, 219.37, 219.38, 236.25, 253.12, 253.13, 270, 286.87, 286.88, 303.75, 320.62, 320.63, 337.5, 354.37, 354.38] for i = 1 to len(degrees) j = floor((degrees[i] + 5.625) / 11.25) if j > 31 j = j - 32 ok see "" + degrees[i] + " " + j + " " if j != 0 see "" + names[j+1] + nl else see "" + names[len(names)] + nl oknext
Output:
0 0 North16.87 1 North by east16.88 2 North-northeast33.75 3 Northeast by north50.62 4 Northeast50.63 5 Northeast by east67.50 6 East-northeast84.37 7 East by north84.38 8 East101.25 9 East by south118.12 10 East-southeast118.13 11 Southeast by east135 12 Southeast151.87 13 Southeast by south151.88 14 South-southeast168.75 15 South by east185.62 16 South185.63 17 South by west202.50 18 South-southwest219.37 19 Southwest by south219.38 20 Southwest236.25 21 Southwest by west253.12 22 West-southwest253.13 23 West by south270 24 West286.87 25 West by north286.88 26 West-northwest303.75 27 Northwest by west320.62 28 Northwest320.63 29 Northwest by north337.50 30 North-northwest354.37 31 North by west354.38 0 North
| RPL code | Comment |
|---|---|
≪ { "north" "east" "south" "west" } SWAP 8 / IP 1 + GET LAST 1 + DUP 5 ≠ SWAP 1 IFTE GET ≫ 'I→QDT' STO≪ → pattern a b ≪ "" 1 pattern SIZEFOR j pattern j DUP SUB DUP "X" == a ROT DUP "Y" == b ROT IFTE IFTE +NEXT ≫ ≫ 'FILLXY' STO≪ 11.25 / 0.5 + FLOOR 32 MOD { "X" "X by Y" "X-XY" "XY by X" "XY" "XY by Y" "Y-XY" "Y by X" "Y" } OVER 8 MOD 1 + GET SWAPI→QDTFILLXY≫ '→HDG' STO | I→QDT( index → "wind1" "wind2" ) // index ∈ [0,31]Get wind1Get wind2FILLXY( "pattern" "a" "b" → "string" )Initialize output string and loop get jth character of pattern replace "X" by "a" and "Y" by b add to output string→HDG( angle → "heading" ) // angle in degreeesConvert angle into compass indexNaming patternsGet pattern, get winds and convert into heading |
The demonstration has been limited to a few significant cases, due to the poor display capabilities of typical RPL devices (e.g. 4 x 22 characters on a HP-28S) :
≪{ 0 16.87 16.88 33.75 50.62 354.37 354.38 } { } 1 3 PICK SIZEFOR j OVER j GET→HDG +NEXT SWAP DROP ≫ EVAL
1: { "north" "north by east" "north-northeast" "northeast by north" "northeast" "north by west" "north" }Headings=%w(north east south west north).each_cons(2).flat_mapdo|a,b|[a,"#{a} by#{b}","#{a}-#{a}#{b}","#{a}#{b} by#{a}","#{a}#{b}","#{a}#{b} by#{b}","#{b}-#{a}#{b}","#{b} by#{a}"]endHeadings.prependnildefheading(degrees)i=degrees.quo(360).*(32).round.%(32).+(1)[i,Headings[i]]end# an array of angles, in degreesangles=(0..32).map{|i|i*11.25+[0,5.62,-5.62][i%3]}angles.eachdo|degrees|index,name=headingdegreesprintf"%2d %20s %6.2f\n",index,name.center(20),degreesend
1 north 0.00 2 north by east 16.87 3 north-northeast 16.88 4 northeast by north 33.75 5 northeast 50.62 6 northeast by east 50.63 7 east-northeast 67.50 8 east by north 84.37 9 east 84.3810 east by south 101.2511 east-southeast 118.1212 southeast by east 118.1313 southeast 135.0014 southeast by south 151.8715 south-southeast 151.8816 south by east 168.7517 south 185.6218 south by west 185.6319 south-southwest 202.5020 southwest by south 219.3721 southwest 219.3822 southwest by west 236.2523 west-southwest 253.1224 west by south 253.1325 west 270.0026 west by north 286.8727 west-northwest 286.8828 northwest by west 303.7529 northwest 320.6230 northwest by north 320.6331 north-northwest 337.5032 north by west 354.37 1 north 354.38
global direct$dim direct$(22)direct$(1) = "y" 'bydirect$(4) = "ast" 'Eastdirect$(13) = "orth" 'Northdirect$(18) = "outh" 'Soutndirect$(22) = "est" 'Westdim point$(32)for i =1 to 32: read point$(i) :next ihtml "<table border=1>" for i = 0 to 32 hdng = i * 11.25 if (i mod 3) = 1 then hdng = hdng +5.62 else if (i mod 3) = 2 then hdng = hdng -5.62 end if pointer = i mod 32 + 1 html "<TR><TD align=right>";pointer;"</td><td>";compas$(hdng);"</td><td>";hdng;"</td></tr>"next ihtml "</table>"end function compas$(hd)x = hd /11.25 + 1.5if (x >=33.0) then x =x -32.0 p$ = point$(int(x)) for i = 1 to len(p$) compas$ = compas$ + mid$(p$,i,1) + direct$(max(asc(upper$(mid$(p$,i,1)))-65,0)) next iend function data "N","N b e","N-ne","Ne b n","Ne","Ne b e","E-ne","E b n","E","E b s","E-se"data "Se b e","Se","Se b s","S-se","S b e","S","S b w","S-sw","Sw b s","Sw","Sw b w"data "W-sw","W b s","W","W b n","W-nw","Nw b w","Nw","Nw b n","N-nw","N b w"
1 North 0.0 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.5 8 East by north 84.37 9 East 84.38 10 East by south 101.25 11 East-southeast 118.12 12 Southeast by east 118.13 13 Southeast 135.0 14 Southeast by south 151.87 15 South-southeast 151.88 16 South by east 168.75 17 South 185.62 18 South by west 185.63 19 South-southwest 202.5 20 Southwest by south 219.37 21 Southwest 219.38 22 Southwest by west 236.25 23 West-southwest 253.12 24 West by south 253.13 25 West 270.0 26 West by north 286.87 27 West-northwest 286.88 28 Northwest by west 303.75 29 Northwest 320.62 30 Northwest by north 320.63 31 North-northwest 337.5 32 North by west 354.37 1 North 354.38
fnexpand(cp:&str)->String{letmutout=String::new();forcincp.chars(){out.push_str(matchc{'N'=>"north",'E'=>"east",'S'=>"south",'W'=>"west",'b'=>" by ",_=>"-",});}out}fnmain(){letcp=["N","NbE","N-NE","NEbN","NE","NEbE","E-NE","EbN","E","EbS","E-SE","SEbE","SE","SEbS","S-SE","SbE","S","SbW","S-SW","SWbS","SW","SWbW","W-SW","WbS","W","WbN","W-NW","NWbW","NW","NWbN","N-NW","NbW"];println!("Index Degrees Compass point");println!("----- ------- -------------");foriin0..=32{letindex=i%32;letheading=iasf32*11.25+matchi%3{1=>5.62,2=>-5.62,_=>0.0,};println!("{:2} {:6.2} {}",index+1,heading,expand(cp[index]));}}
Index Degrees Compass point----- ------- ------------- 1 0.00 north 2 16.87 north by east 3 16.88 north-northeast 4 33.75 northeast by north 5 50.62 northeast 6 50.63 northeast by east 7 67.50 east-northeast 8 84.37 east by north 9 84.38 east10 101.25 east by south11 118.12 east-southeast12 118.13 southeast by east13 135.00 southeast14 151.87 southeast by south15 151.88 south-southeast16 168.75 south by east17 185.62 south18 185.63 south by west19 202.50 south-southwest20 219.37 southwest by south21 219.38 southwest22 236.25 southwest by west23 253.12 west-southwest24 253.13 west by south25 270.00 west26 286.87 west by north27 286.88 west-northwest28 303.75 northwest by west29 320.62 northwest30 320.63 northwest by north31 337.50 north-northwest32 354.37 north by west 1 354.38 north
Inspired by Java version
objectBoxingTheCompassextendsApp{valcardinal=List("north","east","south","west")valpointDesc=List("1","1 by 2","1-C","C by 1","C","C by 2","2-C","2 by 1")valpointDeg:Int=>Double=i=>{valfswitch:Int=>Int=i=>imatch{case1=>1;case2=>-1;case_=>0}i*11.25+fswitch(i%3)*5.62}valdeg2ind:Double=>Int=deg=>(deg*32/360+.5).toInt%32+1valpointName:Int=>String=ind=>{vali=ind-1valstr1=cardinal(i%32/8)valstr2=cardinal((i%32/8+1)%4)valstrC=if((str1=="north")||(str1=="south"))str1+str2elsestr2+str1pointDesc(i%32%8).replace("1",str1).replace("2",str2).replace("C",strC).capitalize}(0to32).map(i=>Triple(pointDeg(i),deg2ind(pointDeg(i)),pointName(deg2ind(pointDeg(i))))).map{t=>(printf("%s\t%18s\t%s°\n",t._2,t._3,t._1))}}
Output:
1 North0.0°2 North by east16.87°3 North-northeast16.88°4Northeast by north33.75°5 Northeast50.62°6 Northeast by east50.63°7 East-northeast67.5°8 East by north84.37°9 East84.38°10 East by south101.25°11 East-southeast118.12°12 Southeast by east118.13°13 Southeast135.0°14Southeast by south151.87°15 South-southeast151.88°16 South by east168.75°17 South185.62°18 South by west185.63°19 South-southwest202.5°20Southwest by south219.37°21 Southwest219.38°22 Southwest by west236.25°23 West-southwest253.12°24 West by south253.13°25 West270.0°26 West by north286.87°27 West-northwest286.88°28 Northwest by west303.75°29 Northwest320.62°30Northwest by north320.63°31 North-northwest337.5°32 North by west354.37°1 North354.38°
$ include "seed7_05.s7i"; include "float.s7i";const array string: names is [] ("North", "North by east", "North-northeast", "Northeast by north", "Northeast", "Northeast by east", "East-northeast", "East by north", "East", "East by south", "East-southeast", "Southeast by east", "Southeast", "Southeast by south", "South-southeast", "South by east", "South", "South by west", "South-southwest", "Southwest by south", "Southwest", "Southwest by west", "West-southwest", "West by south", "West", "West by north", "West-northwest", "Northwest by west", "Northwest", "Northwest by north", "North-northwest", "North by west", "North");const proc: main is func local const array float: degrees is [] (0.0, 16.87, 16.88, 33.75, 50.62, 50.63, 67.5, 84.37, 84.38, 101.25, 118.12, 118.13, 135.0, 151.87, 151.88, 168.75, 185.62, 185.63, 202.5, 219.37, 219.38, 236.25, 253.12, 253.13, 270.0, 286.87, 286.88, 303.75, 320.62, 320.63, 337.5, 354.37, 354.38); var integer: index is 0; var integer: nameIndex is 0; begin for key index range degrees do nameIndex := round(degrees[index] * 32.0 / 360.0); writeln(succ(pred(index) rem 32) lpad 2 <& " " <& names[succ(nameIndex rem 32)] rpad 22 <& degrees[index] digits 2 lpad 6); end for; end func;Output:
1 North 0.00 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.50 8 East by north 84.37 9 East 84.3810 East by south 101.2511 East-southeast 118.1212 Southeast by east 118.1313 Southeast 135.0014 Southeast by south 151.8715 South-southeast 151.8816 South by east 168.7517 South 185.6218 South by west 185.6319 South-southwest 202.5020 Southwest by south 219.3721 Southwest 219.3822 Southwest by west 236.2523 West-southwest 253.1224 West by south 253.1325 West 270.0026 West by north 286.8727 West-northwest 286.8828 Northwest by west 303.7529 Northwest 320.6230 Northwest by north 320.6331 North-northwest 337.5032 North by west 354.37 1 North 354.38
funcpoint(index){varix=(index%32);if(ix&1){"#{point((ix+1)&28)} by#{point(((2-(ix&2))*4)+ix&24)}"}elsif(ix&2){"#{point((ix+2)&24)}-#{point((ix|4)&28)}"}elsif(ix&4){"#{point((ix+8)&16)}#{point((ix|8)&24)}"}else{<northeastsouthwest>[ix/8]}}functest_angle(ix){ix*11.25+[0,5.62,-5.62][ix%3]};funcangle_to_point(𝜽){(𝜽/360*32)+0.5->floor};forixinrange(0,32){var𝜽=test_angle(ix);printf(" %2d %6.2f° %s\n",ix%32+1,𝜽,point(angle_to_point(𝜽)).tc);}
1 0.00° North 2 16.87° North by east 3 16.88° North-northeast 4 33.75° Northeast by north 5 50.62° Northeast 6 50.63° Northeast by east 7 67.50° East-northeast 8 84.37° East by north 9 84.38° East 10 101.25° East by south 11 118.12° East-southeast 12 118.13° Southeast by east 13 135.00° Southeast 14 151.87° Southeast by south 15 151.88° South-southeast 16 168.75° South by east 17 185.62° South 18 185.63° South by west 19 202.50° South-southwest 20 219.37° Southwest by south 21 219.38° Southwest 22 236.25° Southwest by west 23 253.12° West-southwest 24 253.13° West by south 25 270.00° West 26 286.87° West by north 27 286.88° West-northwest 28 303.75° Northwest by west 29 320.62° Northwest 30 320.63° Northwest by north 31 337.50° North-northwest 32 354.37° North by west 1 354.38° North
/*Boxing The Compass by rbytes December 2017*/GET SCREEN SIZE sw,shOPTION BASE 1DIM point$(32,5)FOR i=1 TO 32FOR j=1 TO 5READ point$(i,j)NEXT jNEXT ihtml$= "<table border=1>" html$&= "<TR><TD align=right></td><td>Boxing The Compass</td><td>Abbr</td><td>Min</td><td>Med</td><td>Max</td></tr>"FOR i =1 TO 32 html$&= "<TR><TD align=right>"&i&"</td><td>"&point$(i,1)&"</td><td>"&point$(i,2)&"</td><td>"&point$(i,3)&"</td><td>"&point$(i,4)&"</td><td>"&point$(i,5)&"</td></tr>"NEXT ihtml$&= "</table>"BROWSER "compass" AT 0,0 SIZE sw-20,sh-20BROWSER "compass" TEXT html$PAUSE 20ENDDATA "North", "N", "354.38", "0", "5.62", "North by east", "NbE", "5.63", "11.25", "16.87"DATA "North-northeast", "NNE", "16.88", "22.50", "28.12", "Northeast by north", "NEbN", "28.13", "33.75", "39.37"DATA "Northeast", "NE", "39.38", "45.00", "50.62", "Northeast by east", "NEbE", "50.63", "56.25", "61.87"DATA "East-northeast", "ENE", "61.88", "67.50", "73.12", "East by north", "EbN", "73.13", "78.75", "84.37"DATA "East", "E", "84.38", "90.00", "95.62", "East by south", "EbS", "95.63", "101.25", "106.87"DATA "East-southeast", "ESE", "106.88", "112.50", "118.12", "Southeast by east", "SEbE", "118.13", "123.75", "129.37"DATA "Southeast", "SE", "129.38", "135.00", "140.62", "Southeast by south", "SEbS", "140.63", "146.25", "151.87"DATA "South-southeast", "SSE", "151.88", "157.50", "163.12", "South by east", "SbE", "163.13", "168.75", "174.37"DATA "South", "S", "174.38", "180.00", "185.62", "South by west", "SbW", "185.63", "191.25", "196.87"DATA "South-southwest", "SSW", "196.88", "202.50", "208.12", "Southwest by south", "SWbS", "208.13", "213.75", "219.37"DATA "Southwest", "SW", "219.38", "225.00", "230.62", "Southwest by west", "SWbW", "230.63", "236.25", "241.87"DATA "West-southwest", "WSW", "241.88", "247.50", "253.12", "West by south", "WbS", "253.13", "258.75", "264.37"DATA "West", "W", "264.38", "270.00", "275.62", "West by north", "WbN", "275.63", "281.25", "286.87"DATA "West-northwest", "WNW", "286.88", "292.50", "298.12", "Northwest by west", "NWbW", "298.13", "303.75", "309.37"DATA "Northwest", "NW", "309.38", "315.00", "320.62", "Northwest by north", "NWbN", "320.63", "326.25", "331.87"DATA "North-northwest", "NNW", "331.88", "337.50", "343.12", "North by west", "NbW", "343.13", "348.75", "354.37"
Output:
This chart actually displays as a table in a browser object running in smart Basic Boxing The Compass Abbr Min Med Max 1 North N 354.38 0 5.62 2 North by east NbE 5.63 11.25 16.87 3 North-northeast NNE 16.88 22.50 28.12 4 Northeast by north NEbN 28.13 33.75 39.37 5 Northeast NE 39.38 45.00 50.62 6 Northeast by east NEbE 50.63 56.25 61.87 7 East-northeast ENE 61.88 67.50 73.12 8 East by north EbN 73.13 78.75 84.37 9 East E 84.38 90.00 95.6210 East by south EbS 95.63 101.25 106.8711 East-southeast ESE 106.88 112.50 118.1212 Southeast by east SEbE 118.13 123.75 129.3713 Southeast SE 129.38 135.00 140.6214 Southeast by south SEbS 140.63 146.25 151.8715 South-southeast SSE 151.88 157.50 163.1216 South by east SbE 163.13 168.75 174.3717 South S 174.38 180.00 185.6218 South by west SbW 185.63 191.25 196.8719 South-southwest SSW 196.88 202.50 208.1220 Southwest by south SWbS 208.13 213.75 219.3721 Southwest SW 219.38 225.00 230.6222 Southwest by west SWbW 230.63 236.25 241.8723 West-southwest WSW 241.88 247.50 253.1224 West by south WbS 253.13 258.75 264.3725 West W 264.38 270.00 275.6226 West by north WbN 275.63 281.25 286.8727 West-northwest WNW 286.88 292.50 298.1228 Northwest by west NWbW 298.13 303.75 309.3729 Northwest NW 309.38 315.00 320.6230 Northwest by north NWbN 320.63 326.25 331.8731 North-northwest NNW 331.88 337.50 343.1232 North by west NbW 343.13 348.75 354.37
local val box = Array.fromList [ "North", "North by east", "North-northeast", "Northeast by north", "Northeast", "Northeast by east", "East-northeast", "East by north", "East", "East by south", "East-southeast", "Southeast by east", "Southeast", "Southeast by south", "South-southeast", "South by east", "South", "South by west", "South-southwest", "Southwest by south", "Southwest", "Southwest by west", "West-southwest", "West by south", "West", "West by north", "West-northwest", "Northwest by west", "Northwest", "Northwest by north", "North-northwest", "North by west"] val phis = Array.fromList [ 0.0, 16.87, 16.88, 33.75, 50.62, 50.63, 67.5, 84.37, 84.38, 101.25, 118.12, 118.13, 135.0, 151.87, 151.88, 168.75, 185.62, 185.63, 202.5, 219.37, 219.38, 236.25, 253.12, 253.13, 270.0, 286.87, 286.88, 303.75, 320.62, 320.63, 337.5, 354.37, 354.38 ]inval _ = Array.app (fn phi => let val i = Real.trunc ((phi * 32.0) / 360.0 + 0.5) mod 32 in print (StringCvt.padLeft #" " 3 (Int.toString (i+1)) ^ " " ^ StringCvt.padLeft #" " 18 (Array.sub (box, i)) ^ " " ^ Real.fmt (StringCvt.FIX (SOME 2)) phi ^ "\n") end) phisend
1 North 0.00 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.50 8 East by north 84.37 9 East 84.38 10 East by south 101.25 11 East-southeast 118.12 12 Southeast by east 118.13 13 Southeast 135.00 14 Southeast by south 151.87 15 South-southeast 151.88 16 South by east 168.75 17 South 185.62 18 South by west 185.63 19 South-southwest 202.50 20 Southwest by south 219.37 21 Southwest 219.38 22 Southwest by west 236.25 23 West-southwest 253.12 24 West by south 253.13 25 West 270.00 26 West by north 286.87 27 West-northwest 286.88 28 Northwest by west 303.75 29 Northwest 320.62 30 Northwest by north 320.63 31 North-northwest 337.50 32 North by west 354.37 1 North 354.38
Implementation:
importFoundationextensionDouble{varnearestQr:Double{(self*4.0).rounded(.toNearestOrAwayFromZero)/4.0}}extensionMeasurement<UnitAngle>/*: ExpressibleByFloatLiteral*/{varcos:Double{Darwin.cos(self.converted(to:.radians).value)}varsin:Double{Darwin.sin(self.converted(to:.radians).value)}}structCompass{varbearing:Measurement<UnitAngle>varstyle:Style=.RNinit(_deg:Double,_min:Double=0,_sec:Double=0,style:Style=.RN){self.bearing=.init(value:deg+min/60.0+sec/360.0,unit:.degrees)self.style=style}staticfuncdegreesToPoints(_deg:Double)->Double{(deg/360*32).nearestQr}varpoint:Double{Self.degreesToPoints(self.bearing.value)}varquad:(String,String){(bearing.cos<0?"S":"N",bearing.sin<0?"W":"E")}varstep:(Int,Double){lettemp=8-abs(abs(self.point-16)-8)return(Int(temp),temp.truncatingRemainder(dividingBy:1))}enumStyle{caseRN,USN,noBy}varformats=["N","NxE","NNE","NExN","NE","NExE","ENE","ExN","E"]letfractions=["¼","½","¾"]varinvertedPoints:[Int]{switchself.style{case.RN:[3,6,7]case.USN:[3,7]case.noBy:[1,5,7]}}funcnamed()->String{var(pt,frac)=self.stepvarfracStr:String=""iffrac!=0.0{ifinvertedPoints.contains(pt){pt+=1fracStr=fractions.reversed()[Int(frac*4)-1]+"N"}else{fracStr=fractions[Int(frac*4)-1]+"E"}}return(self.formats[pt]+fracStr).replacing(/(N|E)/){$0.output.0=="N"?self.quad.0:self.quad.1}.replacing(/x/){_in"by"}}}
Execution:
letarr=[000.00,016.87,016.88,033.75,050.62,050.63,067.50,084.37,084.38,090.00,101.25,118.12,118.13,135.00,151.87,151.88,168.75,185.62,185.63,202.50,219.37,219.38,236.25,253.12,253.13,270.00,286.87,286.88,303.75,320.62,320.63,337.50,354.37,354.38]letarr2=stride(from:0,through:360,by:22.5/8.0)letpointFormatter=NumberFormatter()pointFormatter.minimumIntegerDigits=2pointFormatter.minimumFractionDigits=2fordinarr{letc=Compass(d,style:.RN)print(pointFormatter.string(from:c.pointasNSNumber)!,c.dms,c.named())}
Result:
00.00 000°00'00" N01.50 016°52'12" NbyE½E01.50 016°52'47" NbyE½E03.00 033°45'00" NEbyN04.50 050°37'11" NE½E04.50 050°37'48" NE½E06.00 067°30'00" ENE07.50 084°22'12" E½N07.50 084°22'47" E½N08.00 090°00'00" E09.00 101°15'00" EbyS10.50 118°07'12" SEbyE½E10.50 118°07'47" SEbyE½E12.00 135°00'00" SE13.50 151°52'12" SSE½E13.50 151°52'47" SSE½E15.00 168°45'00" SbyE16.50 185°37'12" S½W16.50 185°37'47" S½W18.00 202°30'00" SSW19.50 219°22'12" SW½S19.50 219°22'47" SW½S21.00 236°15'00" SWbyW22.50 253°07'12" WbyS½S22.50 253°07'47" WbyS½S24.00 270°00'00" W25.50 286°52'12" WbyN½N25.50 286°52'47" WbyN½N27.00 303°45'00" NWbyW28.50 320°37'12" NW½N28.50 320°37'47" NW½N30.00 337°30'00" NNW31.50 354°22'12" N½W31.50 354°22'47" N½W
procangle2compass{angle}{setdirs{NNbEN-NENEbNNENEbEE-NEEbNEEbSE-SESEbESESEbSS-SESbESSbWS-SWSWbSSWSWbWW-SWWbSWWbNW-NWNWbWNWNWbNN-NWNbW}setunpack{N"north"E"east"W"west"S"south"b" by "}# Compute the width of each compass segmentsetsep[expr{360.0/[llength$dirs]}]# Work out which segment contains the compass anglesetdir[expr{round((fmod($angle+$sep/2,360)-$sep/2)/$sep)}]# Convert to a named direction, capitalized as in the wikipedia articlereturn[stringtotitle[stringmap$unpack[lindex$dirs$dir]]]}# Box the compass, using the variable generation algorithm describedfor{seti0}{$i<33}{incri}{setheading[expr{$i*11.25}]if{$i%3==1}{setheading[expr{$heading+5.62}]}if{$i%3==2}{setheading[expr{$heading-5.62}]}setindex[expr{$i%32+1}]# Pretty-print the results of converting an angle to a compass headingputs[format"%2i %-18s %7.2f°"$index[angle2compass$heading]$heading]}
Output:
1 North 0.00° 2 North by east 16.87° 3 North-northeast 16.88° 4 Northeast by north 33.75° 5 Northeast 50.62° 6 Northeast by east 50.63° 7 East-northeast 67.50° 8 East by north 84.37° 9 East 84.38°10 East by south 101.25°11 East-southeast 118.12°12 Southeast by east 118.13°13 Southeast 135.00°14 Southeast by south 151.87°15 South-southeast 151.88°16 South by east 168.75°17 South 185.62°18 South by west 185.63°19 South-southwest 202.50°20 Southwest by south 219.37°21 Southwest 219.38°22 Southwest by west 236.25°23 West-southwest 253.12°24 West by south 253.13°25 West 270.00°26 West by north 286.87°27 West-northwest 286.88°28 Northwest by west 303.75°29 Northwest 320.62°30 Northwest by north 320.63°31 North-northwest 337.50°32 North by west 354.37° 1 North 354.38°
DIMpoint$(32)FUNCTIONcompasspoint$(h)LETx=h/11.25+1.5IF(x>=33)THENLETx=x-32LETcompasspoint$=point$(INT(x))ENDFUNCTIONRESTOREDATA"North ","North by east ","North-northeast ","Northeast by north"DATA"Northeast ","Northeast by east ","East-northeast ","East by north "DATA"East ","East by south ","East-southeast ","Southeast by east "DATA"Southeast ","Southeast by south","South-southeast ","South by east "DATA"South ","South by west ","South-southwest ","Southwest by south"DATA"Southwest ","Southwest by west ","West-southwest ","West by south "DATA"West ","West by north ","West-northwest ","Northwest by west "DATA"Northwest ","Northwest by north","North-northwest ","North by west "FORi=1TO32READd$LETpoint$(i)=d$NEXTiFORi=0TO32LETheading=i*11.25IFREMAINDER(i,3)=1THENLETheading=heading+5.62ELSEIFREMAINDER(i,3)=2THENLETheading=heading-5.62ENDIFLETind=REMAINDER(i,32)+1PRINTind,compasspoint$(heading),headingNEXTiEND
Since uBasic is an integer interpreter, we have to do some scaling to perform this task.
Push 0, 1687, 1688, 3375, 5062, 5063, 6750, 8437, 8438, 10125, 11812, 11813Push 13500, 15187, 15188, 16875, 18562, 18563, 20250, 21937, 21938, 23625Push 25312, 25313, 27000, 28687, 28688, 30375, 32062, 32063, 33750, 35437Push 35438 ' Use the stack as a DATA statementFor x = 32 To 0 Step -1 ' Now read the values, but reverse @(x) = Pop() ' Since the last value is on topNext ' of the data stackFor x = 0 To 32 ' Here comes the payload j = ((@(x) * 32 / 3600) + 5) / 10 ' Scale by ten, then correct Print Using "_#";(j % 32) + 1;" "; ' Print heading GoSub 100 + ((j % 32) * 10) ' Now get the compass point Print Using "__#.##"; @(x) ' Finally, print the angle ' which is scaled by 100NextEnd ' All compass points100 Print "North "; : Return110 Print "North by east "; : Return120 Print "North-northeast "; : Return130 Print "Northeast by north "; : Return140 Print "Northeast "; : Return150 Print "Northeast by east "; : Return160 Print "East-northeast "; : Return170 Print "East by north "; : Return180 Print "East "; : Return190 Print "East by south "; : Return200 Print "East-southeast "; : Return210 Print "Southeast by east "; : Return220 Print "Southeast "; : Return230 Print "Southeast by south "; : Return240 Print "South-southeast "; : Return250 Print "South by east "; : Return260 Print "South "; : Return270 Print "South by west "; : Return280 Print "South-southwest "; : Return290 Print "Southwest by south "; : Return300 Print "Southwest "; : Return310 Print "Southwest by west "; : Return320 Print "West-southwest "; : Return330 Print "West by south "; : Return340 Print "West "; : Return350 Print "West by north "; : Return360 Print "West-northwest "; : Return370 Print "Northwest by west "; : Return380 Print "Northwest "; : Return390 Print "Northwest by north "; : Return400 Print "North-northwest "; : Return410 Print "North by west "; : Return420 Print "North "; : Return
1 North 0.00 2 North by east 16.87 3 North-northeast 16.88 4 Northeast by north 33.75 5 Northeast 50.62 6 Northeast by east 50.63 7 East-northeast 67.50 8 East by north 84.37 9 East 84.3810 East by south 101.2511 East-southeast 118.1212 Southeast by east 118.1313 Southeast 135.0014 Southeast by south 151.8715 South-southeast 151.8816 South by east 168.7517 South 185.6218 South by west 185.6319 South-southwest 202.5020 Southwest by south 219.3721 Southwest 219.3822 Southwest by west 236.2523 West-southwest 253.1224 West by south 253.1325 West 270.0026 West by north 286.8727 West-northwest 286.8828 Northwest by west 303.7529 Northwest 320.6230 Northwest by north 320.6331 North-northwest 337.5032 North by west 354.37 1 North 354.380 OK, 0:900
Requires the standard POSIX bc(1) command to perform floating-point arithmetic.
# List of abbreviated compass point labelscompass_points=(NNbEN-NENEbNNENEbEE-NEEbNEEbSE-SESEbESESEbSS-SESbESSbWS-SWSWbSSWSWbWW-SWWbSWWbNW-NWNWbWNWNWbNN-NWNbW)# List of angles to testtest_angles=(0.0016.8716.8833.7550.6250.6367.5084.3784.38101.25118.12118.13135.00151.87151.88168.75185.62185.63202.50219.37219.38236.25253.12253.13270.00286.87286.88303.75320.62320.63337.50354.37354.38)capitalize(){printf'%s%s\n'"$(tra-zA-Z<<<"${1:0:1}")""${1:1}"}# convert compass point abbreviation to full text of labelfunctionexpand_point{locallabel=$1set--NnorthEeastSsouthWwestb" by "while(($#));dolabel=${label//$1/$2}shift2donecapitalize"$label"}# modulus function that returns 1..N instead of 0..N-1functionamod{echo$((($1-1)%$2+1))}# convert a compass angle from degrees into a box index (1..32)functioncompass_point{# use bc or dc depending on what's on the system#amod $(dc <<<"$1 5.625 + 11.25 / 1 + p") 32amod$(bc<<<"($1 + 5.625) / 11.25 + 1")32}# Now output the table of test dataheader_format="%-7s | %-18s | %s\n"row_format="%7.2f | %-18s | %2d\n"printf"$header_format""Degrees""Closest Point""Index"foranglein${test_angles[@]};doletindex=$(compass_point$angle)abbr=${compass_points[index-1]}label="$(expand_point$abbr)"printf"$row_format"$angle"$label"$indexdone
Output:
Degrees | Closest Point | Index 0.00 | North | 1 16.87 | North by east | 2 16.88 | North-northeast | 3 33.75 | Northeast by north | 4 50.62 | Northeast | 5 50.63 | Northeast by east | 6 67.50 | East-northeast | 7 84.37 | East by north | 8 84.38 | East | 9 101.25 | East by south | 10 118.12 | East-southeast | 11 118.13 | Southeast by east | 12 135.00 | Southeast | 13 151.87 | Southeast by south | 14 151.88 | South-southeast | 15 168.75 | South by east | 16 185.62 | South | 17 185.63 | South by west | 18 202.50 | South-southwest | 19 219.37 | Southwest by south | 20 219.38 | Southwest | 21 236.25 | Southwest by west | 22 253.12 | West-southwest | 23 253.13 | West by south | 24 270.00 | West | 25 286.87 | West by north | 26 286.88 | West-northwest | 27 303.75 | Northwest by west | 28 320.62 | Northwest | 29 320.63 | Northwest by north | 30 337.50 | North-northwest | 31 354.37 | North by west | 32 354.38 | North | 1
PublicSubbox_the_compass()Dimcompass_pointAsIntegerDimcompass_points_allAsNewCollectionDimtest_points_allAsNewCollectionDimcompass_points(8)AsVariantDimtest_points(3)AsVariantcompass_points(1)=[{"North","North by east","North-northeast","Northeast by north"}]compass_points(2)=[{"Northeast","Northeast by east","East-northeast","East by north"}]compass_points(3)=[{"East","East by south","East-southeast","Southeast by east"}]compass_points(4)=[{"Southeast","Southeast by south","South-southeast","South by east"}]compass_points(5)=[{"South","South by west","South-southwest","Southwest by south"}]compass_points(6)=[{"Southwest","Southwest by west","West-southwest","West by south"}]compass_points(7)=[{"West","West by north","West-northwest","Northwest by west"}]compass_points(8)=[{"Northwest","Northwest by north","North-northwest","North by west"}]test_points(1)=[{0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12}]test_points(2)=[{118.13,135.0,151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25}]test_points(3)=[{253.12,253.13,270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38}]Fori=1To3ForEachtIntest_points(i)test_points_all.AddtNexttNextiFori=1To8ForEachcIncompass_points(i)compass_points_all.AddcNextcNextiFori=1Totest_points_all.Countcompass_point=(WorksheetFunction.Floor(test_points_all(i)*32/360+0.5,1)Mod32)+1Debug.PrintFormat(compass_point,"@@");" ";compass_points_all(compass_point);Debug.PrintString$(20-Len(compass_points_all(compass_point))," ");Debug.Printtest_points_all(i)NextiEndSub
1 North 0 2 North by east 16,87 3 North-northeast 16,88 4 Northeast by north 33,75 5 Northeast 50,62 6 Northeast by east 50,63 7 East-northeast 67,5 8 East by north 84,37 9 East 84,38 10 East by south 101,25 11 East-southeast 118,12 12 Southeast by east 118,13 13 Southeast 135 14 Southeast by south 151,87 15 South-southeast 151,88 16 South by east 168,75 17 South 185,62 18 South by west 185,63 19 South-southwest 202,5 20 Southwest by south 219,37 21 Southwest 219,38 22 Southwest by west 236,25 23 West-southwest 253,12 24 West by south 253,13 25 West 270 26 West by north 286,87 27 West-northwest 286,88 28 Northwest by west 303,75 29 Northwest 320,62 30 Northwest by north 320,63 31 North-northwest 337,5 32 North by west 354,37 1 North 354,38
ModuleBoxingTheCompassDim_points(32)AsStringSubMain()BuildPoints()DimheadingAsDouble=0DForiAsInteger=0To32heading=i*11.25SelectCaseiMod3Case1heading+=5.62Case2heading-=5.62EndSelectConsole.WriteLine("{0,2}: {1,-18} {2,6:F2}°",(iMod32)+1,InitialUpper(GetPoint(heading)),heading)NextEndSubPrivateSubBuildPoints()DimcardinalAsString()=NewString(){"north","east","south","west"}DimpointDescAsString()=NewString(){"1","1 by 2","1-C","C by 1","C","C by 2","2-C","2 by 1"}Dimstr1,str2,strCAsStringForiAsInteger=0To3str1=cardinal(i)str2=cardinal((i+1)Mod4)strC=IIf(str1="north"Orstr1="south",str1&str2,str2&str1)ForjAsInteger=0To7_points(i*8+j)=pointDesc(j).Replace("1",str1).Replace("2",str2).Replace("C",strC)NextNextEndSubPrivateFunctionInitialUpper(ByValsAsString)AsStringReturns.Substring(0,1).ToUpper()&s.Substring(1)EndFunctionPrivateFunctionGetPoint(ByValDegreesAsDouble)AsStringDimtestDAsDouble=(Degrees/11.25)+0.5Return_points(CInt(Math.Floor(testDMod32)))EndFunctionEndModule
Output:
1: North 0.00° 2: North by east 16.87° 3: North-northeast 16.88° 4: Northeast by north 33.75° 5: Northeast 50.62° 6: Northeast by east 50.63° 7: East-northeast 67.50° 8: East by north 84.37° 9: East 84.38°10: East by south 101.25°11: East-southeast 118.12°12: Southeast by east 118.13°13: Southeast 135.00°14: Southeast by south 151.87°15: South-southeast 151.88°16: South by east 168.75°17: South 185.62°18: South by west 185.63°19: South-southwest 202.50°20: Southwest by south 219.37°21: Southwest 219.38°22: Southwest by west 236.25°23: West-southwest 253.12°24: West by south 253.13°25: West 270.00°26: West by north 286.87°27: West-northwest 286.88°28: Northwest by west 303.75°29: Northwest 320.62°30: Northwest by north 320.63°31: North-northwest 337.50°32: North by west 354.37° 1: North 354.38°
constnames=["North","North by east","North-northeast","Northeast by north","Northeast","Northeast by east","East-northeast","East by north","East","East by south","East-southeast","Southeast by east","Southeast","Southeast by south","South-southeast","South by east","South","South by west","South-southwest","Southwest by south","Southwest","Southwest by west","West-southwest","West by south","West","West by north","West-northwest","Northwest by west","Northwest","Northwest by north","North-northwest","North by west","North"]constdegrees=[f32(0),16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,118.13,135,151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38]fnmain(){foridx,degreeindegrees{mutjdx:=ifidx>=32{idx-31}else{idx+1}println("${jdx:2} ${names[jdx]:-18} ${degree:6.2f}")}}
1 North by east 0.00 2 North-northeast 16.87 3 Northeast by north 16.88 4 Northeast 33.75 5 Northeast by east 50.62 6 East-northeast 50.63 7 East by north 67.50 8 East 84.37 9 East by south 84.3810 East-southeast 101.2511 Southeast by east 118.1212 Southeast 118.1313 Southeast by south 135.0014 South-southeast 151.8715 South by east 151.8816 South 168.7517 South by west 185.6218 South-southwest 185.6319 Southwest by south 202.5020 Southwest 219.3721 Southwest by west 219.3822 West-southwest 236.2523 West by south 253.1224 West 253.1325 West by north 270.0026 West-northwest 286.8727 Northwest by west 286.8828 Northwest 303.7529 Northwest by north 320.6230 North-northwest 320.6331 North by west 337.5032 North 354.37 1 North by east 354.38
import"./fmt"forFmt// 'cpx' returns integer index from 0 to 31 corresponding to compass point.// Input heading h is in degrees. Note this index is a zero-based index// suitable for indexing into the table of printable compass points,// and is not the same as the index specified to be printed in the output.varcpx=Fn.new{|h|varx=(h/11.25+0.5).floor%32if(x<0)x=x+32returnx}// printable compass pointsvarcompassPoint=["North","North by east","North-northeast","Northeast by north","Northeast","Northeast by east","East-northeast","East by north","East","East by south","East-southeast","Southeast by east","Southeast","Southeast by south","South-southeast","South by east","South","South by west","South-southwest","Southwest by south","Southwest","Southwest by west","West-southwest","West by south","West","West by north","West-northwest","Northwest by west","Northwest","Northwest by north","North-northwest","North by west"]// function required by taskvardegreesToCompassPoint=Fn.new{|h|compassPoint[cpx.call(h)]}varr=[0.0,16.87,16.88,33.75,50.62,50.63,67.5,84.37,84.38,101.25,118.12,118.13,135.0,151.87,151.88,168.75,185.62,185.63,202.5,219.37,219.38,236.25,253.12,253.13,270.0,286.87,286.88,303.75,320.62,320.63,337.5,354.37,354.38]System.print("Index Compass point Degree")vari=0for(hinr){varindex=i%32+1// printable index computed per pseudocodevard=degreesToCompassPoint.call(h)Fmt.print("$4d $-19s $7.2f°",index,d,h)i=i+1}
Index Compass point Degree 1 North 0.00° 2 North by east 16.87° 3 North-northeast 16.88° 4 Northeast by north 33.75° 5 Northeast 50.62° 6 Northeast by east 50.63° 7 East-northeast 67.50° 8 East by north 84.37° 9 East 84.38° 10 East by south 101.25° 11 East-southeast 118.12° 12 Southeast by east 118.13° 13 Southeast 135.00° 14 Southeast by south 151.87° 15 South-southeast 151.88° 16 South by east 168.75° 17 South 185.62° 18 South by west 185.63° 19 South-southwest 202.50° 20 Southwest by south 219.37° 21 Southwest 219.38° 22 Southwest by west 236.25° 23 West-southwest 253.12° 24 West by south 253.13° 25 West 270.00° 26 West by north 286.87° 27 West-northwest 286.88° 28 Northwest by west 303.75° 29 Northwest 320.62° 30 Northwest by north 320.63° 31 North-northwest 337.50° 32 North by west 354.37° 1 North 354.38°
func Deg2Index(Heading); \Return index from heading in degreesreal Heading;def Sector = 360./32.;return (fix(Heading/Sector) & $1F) + 1;real Headings;int CompassPoint, H, Index;[Headings:= [ 0.0, 16.87, 16.88, 33.75, 50.62, 50.63, 67.5, 84.37, 84.38, 101.25, 118.12, 118.13, 135.0, 151.87, 151.88, 168.75, 185.62, 185.63, 202.5, 219.37, 219.38, 236.25, 253.12, 253.13, 270.0, 286.87, 286.88, 303.75, 320.62, 320.63, 337.5, 354.37, 354.38];CompassPoint:= [ "North", "North by east", "North-northeast", "Northeast by north", "Northeast", "Northeast by east", "East-northeast", "East by north", "East", "East by south", "East-southeast", "Southeast by east", "Southeast", "Southeast by south", "South-southeast", "South by east", "South", "South by west", "South-southwest", "Southwest by south", "Southwest", "Southwest by west", "West-southwest", "West by south", "West", "West by north", "West-northwest", "Northwest by west", "Northwest", "Northwest by north", "North-northwest", "North by west"];Text(0, "Index Heading Compass Point^m^j");for H:= 0 to 33-1 do [Index:= Deg2Index(Headings(H)); Format(3,0); RlOut(0, float(Index)); Format(7,2); RlOut(0, Headings(H)); Text(0, " "); Text(0, CompassPoint(Index-1)); CrLf(0); ];]
Index Heading Compass Point 1 0.00 North 2 16.87 North by east 3 16.88 North-northeast 4 33.75 Northeast by north 5 50.62 Northeast 6 50.63 Northeast by east 7 67.50 East-northeast 8 84.37 East by north 9 84.38 East 10 101.25 East by south 11 118.12 East-southeast 12 118.13 Southeast by east 13 135.00 Southeast 14 151.87 Southeast by south 15 151.88 South-southeast 16 168.75 South by east 17 185.62 South 18 185.63 South by west 19 202.50 South-southwest 20 219.37 Southwest by south 21 219.38 Southwest 22 236.25 Southwest by west 23 253.12 West-southwest 24 253.13 West by south 25 270.00 West 26 286.87 West by north 27 286.88 West-northwest 28 303.75 Northwest by west 29 320.62 Northwest 30 320.63 Northwest by north 31 337.50 North-northwest 32 354.37 North by west 1 354.38 North
dim point$(32) for i =1 to 32 read point$(i)next iprint "Index\tClosest Point\t\tDegrees"print "=====\t=============\t\t=======" for i = 0 to 32 heading = i *11.25 resto=mod(i,3) if resto=1 then heading = heading +5.62 elseif resto=2 then heading = heading -5.62 end if ind = mod(i,32)+1 print ind,"\t",compasspoint$( heading),"\t",headingnext i end sub compasspoint$(h) x = h / 11.25 + 1.5 if (x >= 33.0) x = x - 32.0 return point$(int(x))end sub 10 data "North ", "North by east ", "North-northeast "20 data "Northeast by north", "Northeast ", "Northeast by east ", "East-northeast "30 data "East by north ", "East ", "East by south ", "East-southeast "40 data "Southeast by east ", "Southeast ", "Southeast by south", "South-southeast "50 data "South by east ", "South ", "South by west ", "South-southwest "60 data "Southwest by south", "Southwest ", "Southwest by west ", "West-southwest "70 data "West by south ", "West ", "West by north ", "West-northwest "80 data "Northwest by west ", "Northwest ", "Northwest by north", "North-northwest "90 data "North by west "
conststd=@import("std");
/// Degrees is not constrained to the range 0 to 360fndegreesToCompassPoint(degrees:f32)[]constu8{vard=degrees+comptime(11.25/2.0);while(d<0)d+=360;while(d>=360)d-=360;constindex:usize=@intFromFloat(@divFloor(d,11.25));constpoints:[32][]constu8=comptime.{"North","North by east","North-northeast","Northeast by north","Northeast","Northeast by east","East-northeast","East by north","East","East by south","East-southeast","Southeast by east","Southeast","Southeast by south","South-southeast","South by east","South","South by west","South-southwest","Southwest by south","Southwest","Southwest by west","West-southwest","West by south","West","West by north","West-northwest","Northwest by west","Northwest","Northwest by north","North-northwest","North by west",};returnpoints[index];}
pubfnmain()anyerror!void{conststdout=std.io.getStdOut().writer();trystdout.print("Index Heading Compass point\n",.{});for(0..33)|i|{varheading=@as(f32,@floatFromInt(i))*11.25;heading+=switch(i%3){1=>5.62,2=>-5.62,else=>0,};constindex=i%32+1;trystdout.print(" {d:2} {d:>6.2}° {s}\n",.{index,heading,degreesToCompassPoint(heading)});}}
Index Heading Compass point 1 0.00° North 2 16.87° North by east 3 16.88° Northeast... 31 337.50° Northwest 32 354.37° North by west 1 354.38° North
A:=("X N NbE NNE NEbN NE NEbE ENE EbN E EbS ESE " // one based array "SEbE SE SEbS SSE SbE S SbW SSW SWbS SW SWbW " "WSW WbS W WbN WNW NWbW NW NWbN NNW NbW").split(" "); fcn compassBox(d){ return(( ( (d + 360.0 / 64.0) % 360.0) * 32.0 / 360.0).ceil()); }foreach i in ([0..32]){ heading:=11.25*i; switch(i%3){ // or heading+=5.62*((i+1).divr(3)[1]-1); case(1){ heading+=5.62 } case(2){ heading-=5.62 } } box:=compassBox(heading); println("%6.2f\UB0; : %2d\t%s".fmt(heading,box,A[box]));}0.00 : 1N 16.87 : 2NbE 16.88 : 3NNE 33.75 : 4NEbN 50.62 : 5NE... same as AWK output337.50 : 31NNW354.37 : 32NbW354.38 : 1N
10DATA"North","North by east","North-northeast"20DATA"Northeast by north","Northeast","Northeast by east","East-northeast"30DATA"East by north","East","East by south","East-southeast"40DATA"Southeast by east","Southeast","Southeast by south","South-southeast"50DATA"South by east","South","South by west","South-southwest"60DATA"Southwest by south","Southwest","Southwest by west","West-southwest"70DATA"West by south","West","West by north","West-northwest"80DATA"Northwest by west","Northwest","Northwest by north","North-northwest"90DATA"North by west"100DIMp$(32,18)110FORi=1TO32120READp$(i)130NEXTi140FORi=0TO32150LETh=i*11.25160LETr=FNm(i,3)170IFr=1THENLETh=h+5.62:GOTO190180IFr=2THENLETh=h-5.62190LETind=FNm(i,32)+1200PRINTind;TAB4;210LETx=h/11.25+1.5220IFx>=33THENLETx=x-32230PRINTp$(INTx);TAB25;h240NEXTi250STOP260DEF FNm(i,n)=((i/n)-INT(i/n))*n:REMmodulusfunction