in reply to Re^3: chapters,sentences, and arrays
in thread chapters,sentences, and arrays

It is interesting to see that there seem to be no way around a loop/compare- or table-lookup-stage to cope with the discrete non-linearity of this problem.

The example below shows two alternatives that seem to compute the chapter from a given valid section directly without an algorithmic (loop/compare) stage:

However, it is only obfuscation. The Heavyside function implements the comparison (non-linearity) and the lookup is hidden in the offsets (3.5, 8.5, etc.). The Fourier synthesis only transforms the table lookup into a new table of coefficients and the comparison (non-linearity) is hidden well in the int() function. Loops are unfolded - not to speak of the iterations done within the math-library (or FPU) to compute the trigonometric functions. No information lost, only transformed (but probably redundancy added?).

Other creative math solutions might involve neural networks (coefficients again) or series employing the si(x) function (coefficients again)... could be fun ... and impractical too ;-)

use strict; sub reference_mapping { # look-up table for verification purpose return substr("111222223333444444",$_[0]-1,1); } sub sentence2chapter_fa { # Fourier approximation my $t = shift; die "$t not in range [1..18]" if ($t<1 || $t>18); return int ( 3.3 + -0.210463 * cos(0.31 * $t) -1.319957 * sin(0.31 * $t) + -0.165006 * cos(0.63 * $t) -0.475488 * sin(0.63 * $t) + -0.018111 * cos(0.94 * $t) -0.365714 * sin(0.94 * $t) + 0.143325 * cos(1.26 * $t) -0.368175 * sin(1.26 * $t) ); } sub heavyside { return $_[0] <= 0 ? 0 : 1; } sub sentence2chapter_hs { # Heavyside approach my $t = shift; die "$t not in range [1..18]" if ($t<1 || $t>18); return heavyside($t ) + heavyside($t - 3.5) + heavyside($t - 8.5) + heavyside($t - 12.5); } print "Sentence Interpolation (delta) Comment\n"; print "---------FA-(d)---HS-(d)---------------\n"; for my $sentence ( 1..18 ) { # verification loop my $ref_chapter = reference_mapping($sentence); my $fa = sentence2chapter_fa($sentence); my $hs = sentence2chapter_hs($sentence); my $comment = $ref_chapter == $fa && $ref_chapter == $hs ? "o +k" : "err"; printf("%4d -> %2d (%d) %2d (%d) %s\n", $sentence, $fa, $fa - $ref_chapter, $hs, $hs - $ref_chapter, $comment); } __END__ Sentence Interpolation (delta) Comment ---------FA-(d)---HS-(d)--------------- 1 -> 1 (0) 1 (0) ok 2 -> 1 (0) 1 (0) ok 3 -> 1 (0) 1 (0) ok 4 -> 2 (0) 2 (0) ok 5 -> 2 (0) 2 (0) ok 6 -> 2 (0) 2 (0) ok 7 -> 2 (0) 2 (0) ok 8 -> 2 (0) 2 (0) ok 9 -> 3 (0) 3 (0) ok 10 -> 3 (0) 3 (0) ok 11 -> 3 (0) 3 (0) ok 12 -> 3 (0) 3 (0) ok 13 -> 4 (0) 4 (0) ok 14 -> 4 (0) 4 (0) ok 15 -> 4 (0) 4 (0) ok 16 -> 4 (0) 4 (0) ok 17 -> 4 (0) 4 (0) ok 18 -> 4 (0) 4 (0) ok