/* Box the compass in Picat. From Rosetta Code http://rosettacode.org/wiki/Box_the_compass """ Avast me hearties! 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). """ This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ % import util. % import cp. main => go. % % This is based on the Prolog solution. % go => 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]). % % inspired by the Nim solution % go2 => 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. index(-,-,-,-) 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). compassangle2(Index , Name, Heading, Angle) => nonvar(Angle), resolveindex(Angle, Index), compassangle(Index,Name, Heading, _). resolveindex(Angle, Index) => N = Angle / 11.25 + 0.5, I = floor(N), Index = (I mod 32) + 1. printTableRow(Angle) => compassangle2(Index, Name, _, Angle), printf("%2d %-20s %6.2f", Index,Name, Angle). printTable([X|Xs]) => printTableRow(X), nl, printTable(Xs). printTable([]) => true.