Burrows–Wheeler transform: Difference between revisions
Content added Content deleted
No edit summary |
m (→{{header|Phix}}: added syntax colouring, marked p2js compatible) |
||
Line 1,942: | Line 1,942: | ||
An efficient implementation, based mainly on http://spencer-carroll.com/an-easy-to-understand-explanation-of-the-burrows-wheeler-transform/ <br> |
An efficient implementation, based mainly on http://spencer-carroll.com/an-easy-to-understand-explanation-of-the-burrows-wheeler-transform/ <br> |
||
Takes around about ten seconds to transform and invert a 100K string. Note: requires 0.8.0+ |
Takes around about ten seconds to transform and invert a 100K string. Note: requires 0.8.0+ |
||
<lang Phix>-- |
<!--<lang Phix>(phixonline)--> |
||
<span style="color: #000080;font-style:italic;">-- demo\rosetta\burrows_wheeler.exw |
|||
--/* |
|||
--/* |
|||
The traditional method: |
|||
The traditional method: |
|||
7 banana$ $banana 6 |
|||
7 banana$ $banana 6 |
|||
6 $banana ===> a$banan 5 |
|||
5 a$banan ana$ban 3 |
|||
4 na$bana sort anana$b 1 |
|||
3 ana$ban banana$ 7 |
|||
2 nana$ba ===> na$bana 4 |
|||
1 anana$b nana$ba 2 |
|||
^ desired answer == "annb$aa" |
|||
First ignore the numbers: the desired answer is found by creating a table of all |
|||
First ignore the numbers: the desired answer is found by creating a table of all |
|||
rotations of "banana$", sorting it, and then extracting the right-hand column. |
|||
rotations of "banana$", sorting it, and then extracting the right-hand column. |
|||
However, there is no need to actually create such a table, which could be very |
|||
However, there is no need to actually create such a table, which could be very |
|||
expensive for long strings, instead just number them logically (admittedly that |
|||
expensive for long strings, instead just number them logically (admittedly that |
|||
was somewhat arbitrarily chosen to get the indexes to work out nicely, I picked |
|||
was somewhat arbitrarily chosen to get the indexes to work out nicely, I picked |
|||
the original index of the last character), and perform a custom sort on those. |
|||
the original index of the last character), and perform a custom sort on those. |
|||
The latter effectively just recreates the rotations one character at a time until |
|||
The latter effectively just recreates the rotations one character at a time until |
|||
there is a mismatch (which there always will be since there is only one $). |
|||
there is a mismatch (which there always will be since there is only one $). |
|||
The left hand column is my arbitrary numbering scheme and the right hand column |
|||
The left hand column is my arbitrary numbering scheme and the right hand column |
|||
is those sorted into order, which is also the indexes to the original string of |
|||
is those sorted into order, which is also the indexes to the original string of |
|||
the characters that we want. |
|||
the characters that we want. |
|||
The code below uses $ as the terminator, but eg 1 (== '\#01') should be fine, |
|||
The code below uses $ as the terminator, but eg 1 (== '\#01') should be fine, |
|||
except of course for the display of that on a console. |
|||
except of course for the display of that on a console. |
|||
--*/ |
|||
--*/</span> |
|||
constant terminator = '$' |
|||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">terminator</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'$'</span> |
|||
function rot_sort(integer i,j, sequence s) |
|||
-- i,j are indexes of the last character, so bump before first compare. |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">rot_sort</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> |
|||
-- eg/ie rot_sort(i,j,s) should yield compare(rotate(s,i),rotate(s,j)), |
|||
<span style="color: #000080;font-style:italic;">-- i,j are indexes of the last character, so bump before first compare. |
|||
-- as in rot_sort(7,6,"banana$") == compare("banana$","$banana") |
|||
-- eg/ie rot_sort(i,j,s) should yield compare(rotate(s,i),rotate(s,j)), |
|||
-- - but one character at a time rather than constructing both. |
|||
-- as in rot_sort(7,6,"banana$") == compare("banana$","$banana") |
|||
integer l = length(s) |
|||
-- - but one character at a time rather than constructing both.</span> |
|||
while true do |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> |
|||
i = mod(i,l)+1 |
|||
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span> |
|||
j = mod(j,l)+1 |
|||
<span style="color: #000000;">i</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span> |
|||
integer c = compare(s[i],s[j]) |
|||
<span style="color: #000000;">j</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">j</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span> |
|||
if c!=0 then return c end if |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">compare</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span> |
|||
end while |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">c</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
end function |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
function burrows_wheeler_transform(string s) |
|||
if find(terminator,s) then ?9/0 end if |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">burrows_wheeler_transform</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> |
|||
s &= terminator |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">terminator</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #008000;">"error"</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
integer l = length(s) |
|||
<span style="color: #000000;">s</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">terminator</span> |
|||
sequence t = custom_sort(routine_id("rot_sort"),tagset(l),{s}) |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> |
|||
string res = repeat(' ',l) |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">custom_sort</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"rot_sort"</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">l</span><span style="color: #0000FF;">),{</span><span style="color: #000000;">s</span><span style="color: #0000FF;">})</span> |
|||
for i=1 to l do |
|||
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">)</span> |
|||
res[i] = s[t[i]] |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">l</span> <span style="color: #008080;">do</span> |
|||
end for |
|||
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]</span> |
|||
return res |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end function |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
--/* |
|||
Inversion. The traditional method is add column and sort, seven times, |
|||
<span style="color: #000080;font-style:italic;">--/* |
|||
to reconstruct the table above, then pick the entry that ends with the |
|||
Inversion. The traditional method is add column and sort, seven times, |
|||
marker. Showing that technique in full detail here is not helpful, and |
|||
to reconstruct the table above, then pick the entry that ends with the |
|||
like above that would be hideously inefficient for large strings. |
|||
marker. Showing that technique in full detail here is not helpful, and |
|||
like above that would be hideously inefficient for large strings. |
|||
$banana 1 $ (1 ) a 2 |
|||
a$banan 2 a ( 1) n 6 |
|||
$banana 1 $ (1 ) a 2 |
|||
a$banan 2 a ( 1) n 6 |
|||
ana$ban 3 a ( 2) n 7 |
|||
anana$b 4 a ( 3) b 5 |
|||
banana$ 5 b $ 1 |
|||
na$bana 6 n (2 ) a 3 |
|||
nana$ba 7 n (3 ) a 4 |
|||
^ ^ ^ ^ ^ |
|||
f l f l t |
|||
However, we already have the last column, and the first is just that |
|||
sorted alphabetically, and with just those two, we have all possible |
|||
However, we already have the last column, and the first is just that |
|||
character pairings of the original message. The trick is in figuring |
|||
sorted alphabetically, and with just those two, we have all possible |
|||
out how to stitch them together in the right order. If you carefully |
|||
character pairings of the original message. The trick is in figuring |
|||
study the three that end in a, and the three that start in a, notice |
|||
out how to stitch them together in the right order. If you carefully |
|||
study the three that end in a, and the three that start in a, notice |
|||
they are prefixed with a or not. That is, the middle (parenthesised) |
|||
the $banan,na$ban,nana$b parts are sorted in the same order, whether |
|||
matching numbers are both 123, not 123 and say 231. It is quite hard |
|||
they are prefixed with a or not. That is, the middle (parenthesised) |
|||
to see that being useful, but eventually the penny should drop. The |
|||
matching numbers are both 123, not 123 and say 231. It is quite hard |
|||
right-hand 1 with an a rotated right gives the left-hand 1, and the |
|||
to see that being useful, but eventually the penny should drop. The |
|||
same goes for 2 and 3: they are in fact links to the prior pairing. |
|||
right-hand 1 with an a rotated right gives the left-hand 1, and the |
|||
same goes for 2 and 3: they are in fact links to the prior pairing. |
|||
the second to the second, and so on, and that (amazingly) forms the |
|||
In other words the first a in l always corresponds to the first in f, |
|||
order in which the pairings need to be daisy-chained together. |
|||
the second to the second, and so on, and that (amazingly) forms the |
|||
order in which the pairings need to be daisy-chained together. |
|||
Try following (1->)2a->6n->3a->7n->4a->5b->$, == reverse("banana"), |
|||
in the above f and t tables. |
|||
Try following (1->)2a->6n->3a->7n->4a->5b->$, == reverse("banana"), |
|||
in the above f and t tables. |
|||
The code below builds a queue of 'a' ({1,6,7}, built backwards) from |
|||
l (aka s), into which we pop into t the {2,3,4} of the 'a' in f, and |
|||
The code below builds a queue of 'a' ({1,6,7}, built backwards) then |
|||
likewise for all other letters, forming the links for each pairing. |
|||
we pop {2,3,4} into those slots in t as we find 'a' in f, likewise |
|||
See the trivial step 3 scan below, then go back and stare at f and |
|||
for all other letters, forming the links for each pairing as shown. |
|||
t as shown above, and once again, eventually the penny should drop. |
|||
See the trivial step 3 scan below, then go back and stare at f and |
|||
I will admit I had to read ten or so explanations before I got it. |
|||
t as shown above, and once again, eventually the penny should drop. |
|||
I will admit I had to read ten or so explanations before I got it. |
|||
--*/ |
|||
--*/</span> |
|||
function inverse_burrows_wheeler(string s) |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">inverse_burrows_wheeler</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> |
|||
if find('\0',s) then ?9/0 end if -- (doable, but needs some +1s) |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'\0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- (doable, but needs some +1s)</span> |
|||
integer l = length(s), c |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">c</span> |
|||
string f = sort(s) |
|||
<span style="color: #004080;">string</span> <span style="color: #000000;">f</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> |
|||
sequence q = repeat(0,256), -- queue heads (per char) |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">q</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">256</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- queue heads (per char)</span> |
|||
x = repeat(0,l), -- queue links |
|||
<span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- queue links</span> |
|||
t = repeat(0,l) -- reformed/pairing links |
|||
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- reformed/pairing links |
|||
-- Step 1. discover/build queues (backwards) |
|||
-- Step 1. discover/build queues (backwards)</span> |
|||
for i=l to 1 by -1 do |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">l</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> |
|||
c = s[i] |
|||
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
x[i] = q[c] |
|||
<span style="color: #000000;">x</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">q</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span> |
|||
q[c] = i |
|||
<span style="color: #000000;">q</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span> |
|||
end for |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
-- Step 2. reform/pop char queues into pairing links |
|||
<span style="color: #000080;font-style:italic;">-- Step 2. reform/pop char queues into pairing links</span> |
|||
for i=1 to l do |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">l</span> <span style="color: #008080;">do</span> |
|||
c = f[i] |
|||
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
t[q[c]] = i |
|||
<span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">q</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span> |
|||
q[c] = x[q[c]] |
|||
<span style="color: #000000;">q</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">[</span><span style="color: #000000;">q</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]]</span> |
|||
end for |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
-- Step 3. rebuild (backwards) |
|||
<span style="color: #000080;font-style:italic;">-- Step 3. rebuild (backwards)</span> |
|||
c = find(terminator,f) |
|||
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">terminator</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">)</span> |
|||
string res = repeat(' ',l-1) |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #008000;">"error"</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
for i=l-1 to 1 by -1 do |
|||
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> |
|||
c = t[c] -- (first time in, skip the end marker) |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">l</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> |
|||
res[i] = f[c] |
|||
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span> <span style="color: #000080;font-style:italic;">-- (first time in, skip the end marker)</span> |
|||
end for |
|||
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span> |
|||
return res |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end function |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
procedure test(string src) |
|||
string enc = burrows_wheeler_transform(src), |
|||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">src</span><span style="color: #0000FF;">)</span> |
|||
dec = inverse_burrows_wheeler(enc) |
|||
<span style="color: #004080;">string</span> <span style="color: #000000;">enc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">burrows_wheeler_transform</span><span style="color: #0000FF;">(</span><span style="color: #000000;">src</span><span style="color: #0000FF;">),</span> |
|||
printf(1,"original: %s --> %s\n inverse: %s\n",{src,enc,dec}) |
|||
<span style="color: #000000;">dec</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">inverse_burrows_wheeler</span><span style="color: #0000FF;">(</span><span style="color: #000000;">enc</span><span style="color: #0000FF;">)</span> |
|||
end procedure |
|||
<span style="color: #000000;">src</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">shorten</span><span style="color: #0000FF;">(</span><span style="color: #000000;">src</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"characters"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">enc</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">shorten</span><span style="color: #0000FF;">(</span><span style="color: #000000;">enc</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"characters"</span><span style="color: #0000FF;">)</span> |
|||
test("banana") |
|||
<span style="color: #000000;">dec</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">shorten</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dec</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"characters"</span><span style="color: #0000FF;">)</span> |
|||
test("dogwood") |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"original: %s --> %s\n inverse: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">src</span><span style="color: #0000FF;">,</span><span style="color: #000000;">enc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dec</span><span style="color: #0000FF;">})</span> |
|||
test("TO BE OR NOT TO BE OR WANT TO BE OR NOT?") |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
test("SIX.MIXED.PIXIES.SIFT.SIXTY.PIXIE.DUST.BOXES")</lang> |
|||
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"banana"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"dogwood"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"TO BE OR NOT TO BE OR WANT TO BE OR NOT?"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"SIX.MIXED.PIXIES.SIFT.SIXTY.PIXIE.DUST.BOXES"</span><span style="color: #0000FF;">)</span> |
|||
<!--</lang>--> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |