# Thar she blows!

Arrr... Ahoy there, me maties! Unfurl tha' mainsail! Full to starboard! Ah, feel th' wind in yer hair!

Right, me hearties... I be needin' a bit of yer codin' skills! Me crew are a li'l more modernized than meself... I still be preferrin' th' points of th' compass (see here for more info, Arrr...) while me crew are always usin' a headin'... I be wantin' an easy way of convertin' this twaddle they call a headin' into what I be able to understand, Arrr!

What I be needin' is code tha' be takin' input of a number (decimals are okay) such tha' 0 <= the headin' < 360 and it be spittin' out th' answer as th' closest compass point! Arrr!

Here be some examples:

> heading 0.1

North

> heading 11.25

North by East

> heading 22.7

North Northeast

> heading 44.99

Northeast

> heading 91

East

Now, if'n th' headin' ye be givin' be such that it falls exactly in th' middle of two compass points, don' ye be frettin', me hearties... I be expectin' th' code to spit out Between <point 1> and <point 2>, e.g. heading 5.625 will say Between North and North by East This only be happenin' for a headin' tha' be satisfyin' the equation H = 5.625 + 11.25(N) where H be th' headin' and N be an integer between 0 and 31 inclusive...

Two restrictions tho'...

1) I not be wantin' ye to use arrays for storin' yer data for the points or th' headin's... Tha' be cheatin', sir, an' ye be gettin' a taste of me blunderbuss... This has t' be calculated, jus' like th' old days! Arrr!

2) Shortest code wins, or I'll be makin' ye walk th' plank... Arrr!

• 50 '(Apostrophe) in a single question. Hats off! :D
– Wasi
Jan 4, 2014 at 11:33
• Is using an object in javascript with numeric keys cheating? I mean yaarrr! be it cheatin', ya landlubber? Jan 5, 2014 at 20:35
• Shouldn't this be "N be an integer between 0 and 31 inclusive"? Jan 5, 2014 at 21:01
• @nwellnhof You're right! Updated... :) Jan 5, 2014 at 22:14
• I think you should launch a code golf where the goal is to translate your question to orthographically correct English! Jan 4, 2017 at 21:03

I be spendin' way too much time on this here treasure hunt, but here's a solution in Java:

public class Aaaaarrrr {

public static void main(String[] aaarrrgs) {

final List<String> points = Arrays.asList("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");

float cp = heading / 360.0f * 32.0f;
if (cp % 1 == 0.5f)
System.out.print("Between " + points.get((int)Math.floor(cp)) + " and ");

System.out.println(points.get(Math.round(cp)));

}
}


edit If I minimize the above code and make it real ugly it would become this:

## Java, 770 chars

import java.util.*;class A{public static void main(String[] r){List<String> l=Arrays.asList("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");float c=Float.parseFloat(r[0])/360.0f*32.0f;if (c%1==0.5f) System.out.print("Between "+l.get((int)Math.floor(c))+" and ");System.out.println(l.get(Math.round(c)));}}

• I'm sure that didn't help me on the "shortest code wins" rule, but since I'm using Java anyway... Jan 4, 2014 at 12:52
• I admire the approach, though you're using the Arrays.asList command, pardon me here for my Java ignorance, but isn't that using a storage array? Or is this a sneaky way of introducing the array in the form of a list? ;) Jan 5, 2014 at 0:30
• @Jeen, can ye show me wha' ye could get if ye really honker down and reduce tha' code there? Jan 5, 2014 at 0:35
• @Eliseod'Annunzio wrt the array, I thought you only meant I couldn't use it to store a mapping between names and heading intervals. This array (list) only stores the actual names. But if that is beyond the rules, I imagine it could be changed to use a switch statement instead (with a few extra chars, unfortunately). Oh and condensed version of same code added. I'll have a think about further whittling it down by actually changing how it works. Jan 5, 2014 at 7:54
• Arrr, fair 'nuff, matey... Jan 5, 2014 at 22:15

## Perl 5.10 using substitution, 231228226 224

@c=(north,east,south,west);
@q=qw(P PbR P-Q QbP Q QbR R-Q RbP);
sub p{$j=$_[0]>>3&3;$_=$q[7&pop];s/P/$c[$j]/;s/Q/$c[$j+1&2]$c[$j|1]/;s/R/$c[$j+1&3]/;s/b/ by /;ucfirst}
$a=<>/11.25+.5; say$a==int$a&&'Between '.p($a-1).' and ',p$a  Four newlines added for readability. Edit: Golfed 2 more bytes using pop. Thanks @Dom Hastings Edit: 2 bytes less using qw() ## Python, 264 n='north' e='east' s='south' w='west' b=' by ' def f(H):x,y,z=(n,e,s,w,e,s,w,n,n+e,s+e,s+w,n+w)[int(H%360/90)::4];return(x,x+b+y,x+'-'+z,z+b+x,z,z+b+y,y+'-'+z,y+b+x)[int(H%90*4/45)].capitalize() h=input()+5.625 print h%11.25and f(h)or'Between '+f(h-1)+' and '+f(h)  This uses capitalisation as per the wikipedia page and should work for any number. • Arrr, that be a clever use of a function there... Jan 5, 2014 at 0:31 ### Arrr Python, 336 A,R,r=int,input()/360.*32,' by #South#north#West#East#south#North#west#east#-#/#Between#and'.split('#') a=''.join(r[A(c,16)]for c in'6A608A6928A6802A68A6808A4928A402A4A405A4958A1808A18A1805A1958A108A1A107A1957A1705A17A1707A3957A305A3A302A3927A6707A67A6702A6927A607').split('/') if R%1==.5:print r[11],a[A(R)],r[12], print a[A(round(R))]  Thanks @Jeen • I be a little confused here @AsksAnyway, what be th' use of tha' there leviathan of a string? ... Arrr... Jan 5, 2014 at 0:34 • It "calculates" the names of the compass points. It's a way of reducing the code size. Jan 5, 2014 at 10:02 ## Perl 5.10, 262257 254 Somewhat similar to one of the Python solutions: $n=north;$e=east;$s=south;$w=west; @d=($n,$n.$e,$e,$s.$e,$s,$s.$w,$w,$n.$w,$n);
sub p{$j=pop;$i=$j>>2;ucfirst(($d[$i],"$d[$i] by$d[$i+2&~1]","$d[$i+1&~1]-$d[$i|1]","$d[$i+1] by$d[$i&~1]")[$j&3])}
$a=<>/11.25+.5; say$a==int$a&&'Between '.p($a-1).' and ',p\$a


• Hey @nwellnhof, Looks pretty comprehensive! You can save a few more chars, removing the ; at the end of sub p and switch shift to pop. Jan 5, 2014 at 19:45