There be many a land lubber that knows naught of the pirate ways and gives direction by degree!
They know not how to box the compass!



Task description

 Create a function that takes a heading in degrees and returns the correct 32-point compass heading.
 Use the function to print and display a table of Index, Compass point, and Degree; rather like the corresponding columns from, the first table of the wikipedia article, but use only the following 33 headings as input:
[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).


Notes;
 The headings and indices can be calculated from this pseudocode:
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
 The column of indices can be thought of as an enumeration of the thirty two cardinal points (see talk page)..


Red []
 
d:  charset [#"N"  #"E" #"S" #"W"]                                                ;; main directions
hm: #()                                                                           ;; hm = hashmap - key= heading, value = [box , compass point]
 
compass-points: [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 N ]
 
expand: func [cp repl][                                                         ;; expand compass point to words
  parse cp [ copy a thru d ahead 2 d insert "-" ]                               ;; insert "-" after first direction, if followed by 2 more
  foreach [src dst ] repl  [ replace/all cp to-string src to-string dst ]       ;; N -> north ...
  uppercase/part cp 1                                                           ;; convert first letter to uppercase
]
 
print-line: does [ print [pad/left hm/:heading/1 3   pad  hm/:heading/2 20  heading ] ]
 
forall compass-points [
 i: (index? compass-points) - 1                                                       ;; so i = 0..33
 heading: i * 11.25 + either 1 = rem: i % 3  [ 5.62]                                  ;; rem = remainder
                                             [ either  rem = 2 [-5.62] [0.0] ]
  hm/:heading:  reduce [ (i % 32 + 1 ) expand to-string compass-points/1 [N north b " by " S south E east W west] ]  
  print-line heading
]