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


> heading 11.25

North by East

> heading 22.7

North Northeast

> heading 44.99


> heading 91


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!

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

5 Answers 5


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

        float heading = Float.parseFloat(aaarrrgs[0]);

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



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)));}}
  • 3
    \$\begingroup\$ I'm sure that didn't help me on the "shortest code wins" rule, but since I'm using Java anyway... \$\endgroup\$ Commented Jan 4, 2014 at 12:52
  • \$\begingroup\$ 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? ;) \$\endgroup\$ Commented Jan 5, 2014 at 0:30
  • \$\begingroup\$ @Jeen, can ye show me wha' ye could get if ye really honker down and reduce tha' code there? \$\endgroup\$ Commented Jan 5, 2014 at 0:35
  • 2
    \$\begingroup\$ @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. \$\endgroup\$ Commented Jan 5, 2014 at 7:54
  • \$\begingroup\$ Arrr, fair 'nuff, matey... \$\endgroup\$ Commented Jan 5, 2014 at 22:15

Perl 5.10 using substitution, 231 228 226 224

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

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

  • 1
    \$\begingroup\$ Arrr, that be a clever use of a function there... \$\endgroup\$ Commented 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

  • \$\begingroup\$ I be a little confused here @AsksAnyway, what be th' use of tha' there leviathan of a string? ... Arrr... \$\endgroup\$ Commented Jan 5, 2014 at 0:34
  • \$\begingroup\$ It "calculates" the names of the compass points. It's a way of reducing the code size. \$\endgroup\$
    – AsksAnyway
    Commented Jan 5, 2014 at 10:02

Perl 5.10, 262 257 254

Somewhat similar to one of the Python solutions:

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])}
say$a==int$a&&'Between '.p($a-1).' and ',p$a

Four newlines added for readability.

Edit: Three bytes less thanks to @Dom Hastings

  • \$\begingroup\$ 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. \$\endgroup\$ Commented Jan 5, 2014 at 19:45
  • \$\begingroup\$ @nwellhoff I didn't know Perl could accept strings without them being in quotes? (re: line 1) \$\endgroup\$ Commented Jan 5, 2014 at 22:17
  • 1
    \$\begingroup\$ @Eliseod'Annunzio Perl accepts strings without quotes in non-strict mode if they don't clash with function names or reserved words. \$\endgroup\$
    – nwellnhof
    Commented Jan 5, 2014 at 22:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.