Data update
This commit is contained in:
parent
5150844a7d
commit
4bb20c9b71
7735 changed files with 38060 additions and 199180 deletions
|
|
@ -20,6 +20,6 @@ def ibwt:
|
|||
| length as $len
|
||||
| reduce range(0;$len) as $i ([];
|
||||
reduce range(0; $len) as $j (.;
|
||||
.[$j] = $r[$j:$j+1] + .[$j]) | sort)
|
||||
.[$j] = $r[$j:$j+1] + .[$j]) | sort)
|
||||
| first( .[] | select(endswith("\u0003")))
|
||||
| .[1:-1] ;
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
# Burrows–Wheeler transform
|
||||
|
||||
# # Variables:
|
||||
# # Variables:
|
||||
#
|
||||
export LC_COLLATE=POSIX
|
||||
|
||||
STX=\^ # start marker
|
||||
ETX=\| # end marker
|
||||
STX=\^ # start marker
|
||||
ETX=\| # end marker
|
||||
|
||||
typeset -a str
|
||||
str[0]='BANANA'
|
||||
|
|
@ -17,75 +17,75 @@ str[3]='TO BE OR NOT TO BE OR WANT TO BE OR NOT?'
|
|||
str[4]='SIX.MIXED.PIXIES.SIFT.SIXTY.PIXIE.DUST.BOXES'
|
||||
str[5]='|ABC^'
|
||||
|
||||
# # Functions:
|
||||
# # Functions:
|
||||
#
|
||||
|
||||
# # Function _bwt(str, arr, lc) - sort all circular shifts of arr, return last col
|
||||
# # Function _bwt(str, arr, lc) - sort all circular shifts of arr, return last col
|
||||
#
|
||||
function _bwt {
|
||||
typeset _str ; _str="$1"
|
||||
typeset _arr ; nameref _arr="$2"
|
||||
typeset _lastcol ; nameref _lastcol="$3"
|
||||
typeset _i _j _newstr ; integer _i _j
|
||||
typeset _str ; _str="$1"
|
||||
typeset _arr ; nameref _arr="$2"
|
||||
typeset _lastcol ; nameref _lastcol="$3"
|
||||
typeset _i _j _newstr ; integer _i _j
|
||||
|
||||
[[ ${_str} == *+("$STX"|"$ETX")* ]] && return 1
|
||||
|
||||
_str="$STX${_str}$ETX"
|
||||
for ((_i=0; _i<${#_str}; _i++)); do
|
||||
_newstr=${_str:${#_str}-1:1}
|
||||
for ((_j=0; _j<${#_str}-1; _j++)); do
|
||||
_newstr+=${_str:${_j}:1}
|
||||
done
|
||||
_arr+=( "${_newstr}" )
|
||||
_str="${_newstr}"
|
||||
done
|
||||
[[ ${_str} == *+("$STX"|"$ETX")* ]] && return 1
|
||||
|
||||
set -sA arr # Sort arr
|
||||
_str="$STX${_str}$ETX"
|
||||
for ((_i=0; _i<${#_str}; _i++)); do
|
||||
_newstr=${_str:${#_str}-1:1}
|
||||
for ((_j=0; _j<${#_str}-1; _j++)); do
|
||||
_newstr+=${_str:${_j}:1}
|
||||
done
|
||||
_arr+=( "${_newstr}" )
|
||||
_str="${_newstr}"
|
||||
done
|
||||
|
||||
for ((_i=0; _i<${#_arr[*]}; _i++)); do
|
||||
_lastcol+=${_arr[_i]:${#_arr[_i]}-1:1}
|
||||
done
|
||||
set -sA arr # Sort arr
|
||||
|
||||
for ((_i=0; _i<${#_arr[*]}; _i++)); do
|
||||
_lastcol+=${_arr[_i]:${#_arr[_i]}-1:1}
|
||||
done
|
||||
}
|
||||
|
||||
# # Function _ibwt(str) - inverse bwt
|
||||
# # Function _ibwt(str) - inverse bwt
|
||||
#
|
||||
function _ibwt {
|
||||
typeset _str ; _str="$1"
|
||||
typeset _arr _vec _ret _i ; typeset -a _arr _vec ; integer _i
|
||||
typeset _str ; _str="$1"
|
||||
typeset _arr _vec _ret _i ; typeset -a _arr _vec ; integer _i
|
||||
|
||||
_intovec "${_str}" _vec
|
||||
for ((_i=1; _i<${#_str}; _i++)); do
|
||||
_intoarr _vec _arr
|
||||
set -sA _arr
|
||||
done
|
||||
_intovec "${_str}" _vec
|
||||
for ((_i=1; _i<${#_str}; _i++)); do
|
||||
_intoarr _vec _arr
|
||||
set -sA _arr
|
||||
done
|
||||
|
||||
for ((_i=0; _i<${#arr[*]}; _i++)); do
|
||||
[[ "${arr[_i]}" == ${STX}*${ETX} ]] && echo "${arr[_i]}" && return
|
||||
done
|
||||
for ((_i=0; _i<${#arr[*]}; _i++)); do
|
||||
[[ "${arr[_i]}" == ${STX}*${ETX} ]] && echo "${arr[_i]}" && return
|
||||
done
|
||||
}
|
||||
|
||||
# # Function _intovec(str, vec) - trans str into vec[]
|
||||
# # Function _intovec(str, vec) - trans str into vec[]
|
||||
#
|
||||
function _intovec {
|
||||
typeset _str ; _str="$1"
|
||||
typeset _vec ; nameref _vec="$2"
|
||||
typeset _i ; integer _i
|
||||
typeset _str ; _str="$1"
|
||||
typeset _vec ; nameref _vec="$2"
|
||||
typeset _i ; integer _i
|
||||
|
||||
for ((_i=0; _i<${#_str}; _i++)); do
|
||||
_vec+=( "${_str:${_i}:1}" )
|
||||
done
|
||||
for ((_i=0; _i<${#_str}; _i++)); do
|
||||
_vec+=( "${_str:${_i}:1}" )
|
||||
done
|
||||
}
|
||||
|
||||
# # Function _intoarr(i, vec, arr) - insert vec into arr
|
||||
# # Function _intoarr(i, vec, arr) - insert vec into arr
|
||||
#
|
||||
function _intoarr {
|
||||
typeset _vec ; nameref _vec="$1"
|
||||
typeset _arr ; nameref _arr="$2"
|
||||
typeset _j ; integer _j
|
||||
typeset _vec ; nameref _vec="$1"
|
||||
typeset _arr ; nameref _arr="$2"
|
||||
typeset _j ; integer _j
|
||||
|
||||
for ((_j=0; _j<${#_vec[*]}; _j++)); do
|
||||
_arr="${_vec[_j]}${_arr[_j]}"
|
||||
done
|
||||
for ((_j=0; _j<${#_vec[*]}; _j++)); do
|
||||
_arr="${_vec[_j]}${_arr[_j]}"
|
||||
done
|
||||
}
|
||||
|
||||
######
|
||||
|
|
@ -93,14 +93,14 @@ function _intoarr {
|
|||
######
|
||||
|
||||
for ((i=0; i<${#str[*]}; i++)); do
|
||||
unset arr lastcol result ; typeset -a arr
|
||||
unset arr lastcol result ; typeset -a arr
|
||||
|
||||
print -- "${str[i]}"
|
||||
_bwt "${str[i]}" arr lastcol
|
||||
(( $? )) && print "ERROR: string cannot contain $STX or $ETX" && continue
|
||||
print -- "${str[i]}"
|
||||
_bwt "${str[i]}" arr lastcol
|
||||
(( $? )) && print "ERROR: string cannot contain $STX or $ETX" && continue
|
||||
|
||||
print -- "${lastcol}"
|
||||
result=$(_ibwt "${lastcol}")
|
||||
print -- "${result}"
|
||||
echo
|
||||
print -- "${lastcol}"
|
||||
result=$(_ibwt "${lastcol}")
|
||||
print -- "${result}"
|
||||
echo
|
||||
done
|
||||
|
|
|
|||
|
|
@ -1,147 +1,145 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #000080;font-style:italic;">-- demo\rosetta\burrows_wheeler.exw
|
||||
--/*
|
||||
The traditional method:
|
||||
-- demo\rosetta\burrows_wheeler.exw
|
||||
--/*
|
||||
The traditional method:
|
||||
|
||||
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"
|
||||
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
|
||||
rotations of "banana$", sorting it, and then extracting the right-hand column.
|
||||
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.
|
||||
|
||||
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
|
||||
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.
|
||||
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
|
||||
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 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 $).
|
||||
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
|
||||
the characters that we want.
|
||||
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 $).
|
||||
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
|
||||
the characters that we want.
|
||||
|
||||
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.
|
||||
--*/</span>
|
||||
<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>
|
||||
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.
|
||||
--*/
|
||||
with javascript_semantics
|
||||
constant terminator = '$'
|
||||
|
||||
<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>
|
||||
<span style="color: #000080;font-style:italic;">-- i,j are indexes of the last character, so bump before first compare.
|
||||
-- eg/ie rot_sort(i,j,s) should yield compare(rotate(s,i),rotate(s,j)),
|
||||
-- as in rot_sort(7,6,"banana$") == compare("banana$","$banana")
|
||||
-- - but one character at a time rather than constructing both.</span>
|
||||
<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: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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 rot_sort(integer i,j, sequence s)
|
||||
-- i,j are indexes of the last character, so bump before first compare.
|
||||
-- eg/ie rot_sort(i,j,s) should yield compare(rotate(s,i),rotate(s,j)),
|
||||
-- as in rot_sort(7,6,"banana$") == compare("banana$","$banana")
|
||||
-- - but one character at a time rather than constructing both.
|
||||
integer l = length(s)
|
||||
while true do
|
||||
i = mod(i,l)+1
|
||||
j = mod(j,l)+1
|
||||
integer c = compare(s[i],s[j])
|
||||
if c!=0 then return c end if
|
||||
end while
|
||||
end function
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<span style="color: #000000;">s</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">terminator</span>
|
||||
<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: #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>
|
||||
<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: #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>
|
||||
<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>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
function burrows_wheeler_transform(string s)
|
||||
if find(terminator,s) then return "error" end if
|
||||
s &= terminator
|
||||
integer l = length(s)
|
||||
sequence t = custom_sort(routine_id("rot_sort"),tagset(l),{s})
|
||||
string res = repeat(' ',l)
|
||||
for i=1 to l do
|
||||
res[i] = s[t[i]]
|
||||
end for
|
||||
return res
|
||||
end function
|
||||
|
||||
<span style="color: #000080;font-style:italic;">--/*
|
||||
Inversion. The traditional method is add column and sort, seven times,
|
||||
to reconstruct the table above, then pick the entry that ends with the
|
||||
marker. Showing that technique in full detail here is not helpful, and
|
||||
like above that would be hideously inefficient for large strings.
|
||||
--/*
|
||||
Inversion. The traditional method is add column and sort, seven times,
|
||||
to reconstruct the table above, then pick the entry that ends with the
|
||||
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
|
||||
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
|
||||
$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
|
||||
character pairings of the original message. The trick is in figuring
|
||||
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
|
||||
the $banan,na$ban,nana$b parts are sorted in the same order, whether
|
||||
they are prefixed with a or not. That is, the middle (parenthesised)
|
||||
matching numbers are both 123, not 123 and say 231. It is quite hard
|
||||
to see that being useful, but eventually the penny should drop. The
|
||||
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.
|
||||
However, we already have the last column, and the first is just that
|
||||
sorted alphabetically, and with just those two, we have all possible
|
||||
character pairings of the original message. The trick is in figuring
|
||||
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
|
||||
the $banan,na$ban,nana$b parts are sorted in the same order, whether
|
||||
they are prefixed with a or not. That is, the middle (parenthesised)
|
||||
matching numbers are both 123, not 123 and say 231. It is quite hard
|
||||
to see that being useful, but eventually the penny should drop. The
|
||||
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.
|
||||
|
||||
In other words the first a in l always corresponds to the first in f,
|
||||
the second to the second, and so on, and that (amazingly) forms the
|
||||
order in which the pairings need to be daisy-chained together.
|
||||
In other words the first a in l always corresponds to the first in f,
|
||||
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) then
|
||||
we pop {2,3,4} into those slots in t as we find 'a' in f, likewise
|
||||
for all other letters, forming the links for each pairing as shown.
|
||||
See the trivial step 3 scan below, then go back and stare at f and
|
||||
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>
|
||||
The code below builds a queue of 'a' ({1,6,7}, built backwards) then
|
||||
we pop {2,3,4} into those slots in t as we find 'a' in f, likewise
|
||||
for all other letters, forming the links for each pairing as shown.
|
||||
See the trivial step 3 scan below, then go back and stare at f and
|
||||
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 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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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)</span>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000080;font-style:italic;">-- Step 2. reform/pop char queues into pairing links</span>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000080;font-style:italic;">-- Step 3. rebuild (backwards)</span>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
function inverse_burrows_wheeler(string s)
|
||||
if find('\0',s) then ?9/0 end if -- (doable, but needs some +1s)
|
||||
integer l = length(s), c
|
||||
string f = sort(s)
|
||||
sequence q = repeat(0,256), -- queue heads (per char)
|
||||
x = repeat(0,l), -- queue links
|
||||
t = repeat(0,l) -- reformed/pairing links
|
||||
-- Step 1. discover/build queues (backwards)
|
||||
for i=l to 1 by -1 do
|
||||
c = s[i]
|
||||
x[i] = q[c]
|
||||
q[c] = i
|
||||
end for
|
||||
-- Step 2. reform/pop char queues into pairing links
|
||||
for i=1 to l do
|
||||
c = f[i]
|
||||
t[q[c]] = i
|
||||
q[c] = x[q[c]]
|
||||
end for
|
||||
-- Step 3. rebuild (backwards)
|
||||
c = find(terminator,f)
|
||||
if c=0 then return "error" end if
|
||||
string res = repeat(' ',l-1)
|
||||
for i=l-1 to 1 by -1 do
|
||||
c = t[c] -- (first time in, skip the end marker)
|
||||
res[i] = f[c]
|
||||
end for
|
||||
return res
|
||||
end function
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
procedure test(string src)
|
||||
string enc = burrows_wheeler_transform(src),
|
||||
dec = inverse_burrows_wheeler(enc)
|
||||
src = shorten(src,"characters")
|
||||
enc = shorten(enc,"characters")
|
||||
dec = shorten(dec,"characters")
|
||||
printf(1,"original: %s --> %s\n inverse: %s\n",{src,enc,dec})
|
||||
end procedure
|
||||
|
||||
<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>
|
||||
<!--
|
||||
test("banana")
|
||||
test("dogwood")
|
||||
test("TO BE OR NOT TO BE OR WANT TO BE OR NOT?")
|
||||
test("SIX.MIXED.PIXIES.SIFT.SIXTY.PIXIE.DUST.BOXES")
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ class BurrowsWheelerTransform{
|
|||
_assert_(not str.holds(special), "String cannot contain char \"%s\"".fmt(special) );
|
||||
str=str.append(special);
|
||||
str.len().pump(List().merge,'wrap(n){ String(str[n,*],str[0,n]) })
|
||||
.pump(String,T("get",-1)); // last char of each "permutation"
|
||||
.pump(String,T("get",-1)); // last char of each "permutation"
|
||||
}
|
||||
fcn decode(str){
|
||||
table:=List.createLong(str.len(),""); // ("",""..), mutable
|
||||
table:=List.createLong(str.len(),""); // ("",""..), mutable
|
||||
do(str.len()){
|
||||
foreach n in (str.len()){ table[n]=str[n] + table[n] }
|
||||
table.sort();
|
||||
foreach n in (str.len()){ table[n]=str[n] + table[n] }
|
||||
table.sort();
|
||||
} // --> ("$dogwood","d$dogwoo","dogwood$",...)
|
||||
table.filter1("%s*".fmt(special).glob)[1,*]; // str[0]==$, often first element
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue