Three word location: Difference between revisions

→‎{{header|Raku}}: 10 times the accuracy, same space
No edit summary
(→‎{{header|Raku}}: 10 times the accuracy, same space)
Line 519:
=={{header|Raku}}==
{{works with|Rakudo|2020.07}}
===The task===
In large part due to the complete lack of specification, reference implementation, or guidance from the task creator, came up with my own bespoke synthetic word list.
 
Line 618 ⟶ 619:
 
(Ok, I admit I manipulated that second to last one, but it '''is''' a correct and valid 3-word location in this implementation. There is less than 1 chance in 5000 that it will produce that specific word group though.)
 
===A thought experiment===
A little thought experiment... Latitude, longitude to four decimal places is accurate to about 11.1 meters at the equator, smaller the further from the equator you get.
What would it take to support five decimal places? (Accurate to 1.11 meters.)
 
<code>360 * 100000 == 36000000;
ceiling 36000000.log(2) == 26;</code>
 
So we need 26 bits to cover 360.00000; half of that for 180.00000, or <code>26 bits + 25 bits == 51 bits</code>. <code>51 / 3 == 17</code>. <code>2**17 == 131072</code> indices. The previous synthetics routine provides much more than enough.
 
How many sylabics will we need to minimally cover it?
 
<code>∛131072 == 50.7968...</code>
 
So at least 51. The synthetics routine provide sylabics in blocks of 5, so we would need
at least 11 consonants.
 
Capriciously and somewhat randomly cutting down the list we arrive at this.
 
10 times better accuracy in the same three, 6-letter word space.
 
<lang perl6># SYNTHETICS HANDLING
my @synth = flat < b d f j k n p r s t w > X~ < a e i o u >;
my %htnys = @synth.antipairs;
my $exp = @synth.elems;
my $prec = 100_000;
 
 
sub synth (Int $v) { @synth[$v.polymod($exp xx *).reverse || 0].join }
 
sub thnys (Str $v) { sum %htnys{$v.comb(2).reverse} Z× 1, $exp, $exp² }
 
 
# ENCODE / DECODE
sub w-encode ( Rat(Real) $lat, Rat(Real) $lon, :&f = &synth ) {
$_ = (($lat + 90) × $prec).round.fmt('%025b') ~ (($lon + 180) × $prec).round.fmt('%026b');
(:2(.substr(0,17)), :2(.substr(17,17)), :2(.substr(34)))».&f
}
 
sub w-decode ( *@words, :&f = &thnys ) {
my $bin = @words».&f.map({.fmt('%017b')}).join;
(:2($bin.substr(0,25))/$prec) - 90, (:2($bin.substr(25))/$prec) - 180
}
 
 
# TESTING
for 51.43372, -0.21412, # Wimbledon center court
21.25976,-157.81173, # Diamond Head summit
-55.96525, -67.22557, # Monumento Cabo De Hornos
28.3852, -81.5638, # Walt Disney World
89.99999, 179.99999, # test some
-89.99999,-179.99999 # extremes
-> $lat, $lon {
my @words = w-encode $lat, $lon;
printf "Coordinates: %s, %s\n To Index: %s\n To 3-word: %s\nFrom 3-word: %s, %s\n\n",
$lat, $lon, w-encode($lat, $lon, :f({$_})).Str, @words.Str, w-decode(@words);
}</lang>
{{out}}
<pre>Coordinates: 51.43372, -0.21412
To Index: 55247 71817 21724
To 3-word: jofuni kosasi diduwu
From 3-word: 51.43372, -0.21412
 
Coordinates: 21.25976, -157.81173
To Index: 43460 110608 121675
To 3-word: fukafa repebo safija
From 3-word: 21.25976, -157.81173
 
Coordinates: -55.96525, -67.22557
To Index: 13294 108118 5251
To 3-word: bukeru rasaso besane
From 3-word: -55.96525, -67.22557
 
Coordinates: 28.3852, -81.5638
To Index: 46244 28747 13220
To 3-word: jajasu duniri bukaka
From 3-word: 28.3852, -81.5638
 
Coordinates: 89.99999, 179.99999
To Index: 70312 65298 86271
To 3-word: kofoki kepifo nonope
From 3-word: 89.99999, 179.99999
 
Coordinates: -89.99999, -179.99999
To Index: 0 512 1
To 3-word: ba duji be
From 3-word: -89.99999, -179.99999</pre>
 
=={{header|Symsyn}}==
10,327

edits