June 2018 Update

This commit is contained in:
Ingy döt Net 2018-06-22 20:57:24 +00:00
parent ba8067c3b7
commit 22f33d4004
5278 changed files with 84726 additions and 14379 deletions

View file

@ -0,0 +1,76 @@
CONST lzw_data$ = "TOBEORNOTTOBEORTOBEORNOT"
PRINT "LZWData: ", lzw_data$
encoded$ = Encode_LZW$(lzw_data$)
PRINT "Encoded: ", encoded$
PRINT "Decoded: ", Decode_LZW$(encoded$)
'----------------------------------------------------------
FUNCTION Encode_LZW$(sample$)
LOCAL dict ASSOC int
LOCAL ch$, buf$, result$
LOCAL nr, x
FOR nr = 0 TO 255
dict(CHR$(nr)) = nr
NEXT
FOR x = 1 TO LEN(sample$)
ch$ = MID$(sample$, x, 1)
IF dict(buf$ & ch$) THEN
buf$ = buf$ & ch$
ELSE
result$ = APPEND$(result$, 0, STR$(dict(buf$)))
dict(buf$ & ch$) = nr
INCR nr
buf$ = ch$
END IF
NEXT
result$ = APPEND$(result$, 0, STR$(dict(buf$)))
RETURN result$
END FUNCTION
'----------------------------------------------------------
FUNCTION Decode_LZW$(sample$)
LOCAL list$ ASSOC STRING
LOCAL old$, ch$, x$, out$, result$
LOCAL nr
FOR nr = 0 TO 255
list$(STR$(nr)) = CHR$(nr)
NEXT
old$ = TOKEN$(sample$, 1)
ch$ = list$(old$)
result$ = ch$
FOR x$ IN LAST$(sample$, 1)
IF NOT(LEN(list$(x$))) THEN
out$ = list$(old$)
out$ = out$ & ch$
ELSE
out$ = list$(x$)
END IF
result$ = result$ & out$
ch$ = LEFT$(out$, 1)
list$(STR$(nr)) = list$(old$) & ch$
INCR nr
old$ = x$
NEXT
RETURN result$
END FUNCTION

View file

@ -1,72 +1,95 @@
package main
import "fmt"
import (
"fmt"
"log"
"strings"
)
// Compress a string to a list of output symbols.
func compress(uncompressed string) []int {
// Build the dictionary.
dictSize := 256
dictionary := make(map[string]int)
for i := 0; i < 256; i++ {
dictionary[string(i)] = i
}
// Build the dictionary.
dictSize := 256
// We actually want a map of []byte -> int but
// slices are not acceptable map key types.
dictionary := make(map[string]int, dictSize)
for i := 0; i < dictSize; i++ {
// Ugly mess to work around not having a []byte key type.
// Using `string(i)` would do utf8 encoding for i>127.
dictionary[string([]byte{byte(i)})] = i
}
w := ""
result := make([]int, 0)
for _, c := range []byte(uncompressed) {
wc := w + string(c)
if _, ok := dictionary[wc]; ok {
w = wc
} else {
result = append(result, dictionary[w])
// Add wc to the dictionary.
dictionary[wc] = dictSize
dictSize++
w = string(c)
}
}
var result []int
var w []byte
for i := 0; i < len(uncompressed); i++ {
c := uncompressed[i]
wc := append(w, c)
if _, ok := dictionary[string(wc)]; ok {
w = wc
} else {
result = append(result, dictionary[string(w)])
// Add wc to the dictionary.
dictionary[string(wc)] = dictSize
dictSize++
//w = []byte{c}, but re-using wc
wc[0] = c
w = wc[:1]
}
}
// Output the code for w.
if w != "" {
result = append(result, dictionary[w])
}
return result
if len(w) > 0 {
// Output the code for w.
result = append(result, dictionary[string(w)])
}
return result
}
// Decompress a list of output ks to a string.
func decompress(compressed []int) string {
// Build the dictionary.
dictSize := 256
dictionary := make(map[int]string)
for i := 0; i < 256; i++ {
dictionary[i] = string(i)
}
type BadSymbolError int
w := string(compressed[0])
result := w
for _, k := range compressed[1:] {
var entry string
if x, ok := dictionary[k]; ok {
entry = x
} else if k == dictSize {
entry = w + w[:1]
} else {
panic(fmt.Sprintf("Bad compressed k: %d", k))
}
func (e BadSymbolError) Error() string {
return fmt.Sprint("Bad compressed symbol ", int(e))
}
result += entry
// Decompress a list of output symbols to a string.
func decompress(compressed []int) (string, error) {
// Build the dictionary.
dictSize := 256
dictionary := make(map[int][]byte, dictSize)
for i := 0; i < dictSize; i++ {
dictionary[i] = []byte{byte(i)}
}
// Add w+entry[0] to the dictionary.
dictionary[dictSize] = w + entry[:1]
dictSize++
var result strings.Builder
var w []byte
for _, k := range compressed {
var entry []byte
if x, ok := dictionary[k]; ok {
//entry = x, but ensuring any append will make a copy
entry = x[:len(x):len(x)]
} else if k == dictSize && len(w) > 0 {
entry = append(w, w[0])
} else {
return result.String(), BadSymbolError(k)
}
result.Write(entry)
w = entry
}
return result
if len(w) > 0 {
// Add w+entry[0] to the dictionary.
w = append(w, entry[0])
dictionary[dictSize] = w
dictSize++
}
w = entry
}
return result.String(), nil
}
func main() {
compressed := compress("TOBEORNOTTOBEORTOBEORNOT")
fmt.Println(compressed)
decompressed := decompress(compressed)
fmt.Println(decompressed)
compressed := compress("TOBEORNOTTOBEORTOBEORNOT")
fmt.Println(compressed)
decompressed, err := decompress(compressed)
if err != nil {
log.Fatal(err)
}
fmt.Println(decompressed)
}

View file

@ -0,0 +1,50 @@
function compressLZW(decompressed::String)
dictsize = 256
dict = Dict{String,Int}(string(Char(i)) => i for i in range(0, dictsize))
result = Vector{Int}(0)
w = ""
for c in decompressed
wc = string(w, c)
if haskey(dict, wc)
w = wc
else
push!(result, dict[w])
dict[wc] = dictsize
dictsize += 1
w = string(c)
end
end
if !isempty(w) push!(result, dict[w]) end
return result
end
function decompressLZW(compressed::Vector{Int})
dictsize = 256
dict = Dict{Int,String}(i => string('\0' + i) for i in range(0, dictsize))
result = IOBuffer()
w = string(Char(shift!(compressed)))
write(result, w)
for k in compressed
if haskey(dict, k)
entry = dict[k]
elseif k == dictsize
entry = string(w, w[1])
else
error("bad compressed k: $k")
end
write(result, entry)
dict[dictsize] = string(w, entry[1])
dictsize += 1
w = entry
end
return String(result)
end
original = ["0123456789", "TOBEORNOTTOBEORTOBEORNOT", "dudidudidudida"]
compressed = compressLZW.(original)
decompressed = decompressLZW.(compressed)
for (word, comp, decomp) in zip(original, compressed, decompressed)
comprate = (length(word) - length(comp)) / length(word) * 100
println("Original: $word\n-> Compressed: $comp (compr.rate: $(round(comprate, 2))%)\n-> Decompressed: $decomp")
end

View file

@ -1,31 +1,29 @@
/*REXX program compresses text using the LZW (Lempel─Ziv─Welch), and reconstitutes it.*/
parse arg x /*get an optional argument from the CL.*/
if x=='' then x= '"There is nothing permanent except change." Heraclitus [540-475 BC]'
say 'original text=' x
if x='' then x= '"There is nothing permanent except change." Heraclitus [540-475 BC]'
say 'original text=' x
cypher=LZWc(x) /*compress text using the LZW algorithm*/
say; say 'reconstituted=' LZWd(cypher) /*display the original cypher text. */
say; say ' LZW integers=' cypher /*also display the LZW integers used.*/
say 'reconstituted=' LZWd(cypher)
say ' LZW integers=' cypher
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
LZWc: procedure; parse arg y,,w $ @.; #=256 /*the LZW compress algorithm.*/
do j=0 for #; _=d2c(j); @._=j; end /*j*/
do j=0 for #; _=d2c(j); @._=j; end /*j*/
do k=1 for length(y); _=w || substr(y, k, 1)
if @._=='' then do; $=$ @.w; @._=#; #=#+1
w=substr(y, k, 1)
do k=1 for length(y); _=w || substr(y, k, 1)
if @._=='' then do; $=$ @.w; @._=#; #=#+1; w=substr(y,k,1)
end
else w=_
end /*k*/
return strip($ @.w) /*remove any superfluous blanks*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
LZWd: procedure; parse arg w y,,@.; #=256 /*the LZW decompress algorithm.*/
do j=0 for #; @.j=d2c(j); end /*j*/
do j=0 for #; @.j=d2c(j); end /*j*/
$=@.w; w=$
do k=1 for words(y); _=word(y, k)
if @._\=='' | @.k==" " then ?=@._
else if _=# then ?=w || left(w, 1)
else if _==# then ?=w || left(w, 1)
$=$ || ?
@.#=w || left(?, 1); #=#+1
w=?
@.#=w || left(?, 1); #=#+1; w=?
end /*k*/
return $

View file

@ -0,0 +1,81 @@
# Project : LZW compression
# Date : 2018/04/07
# Author : Gal Zsolt (~ CalmoSoft ~)
# Email : <calmosoft@gmail.com>
plaintext = "TOBEORNOTTOBEORTOBEORNOT"
result = []
encode = encodelzw(plaintext)
for i = 1 to len(encode) step 2
add(result,ascii(substr(encode,i,1)) + 256*ascii(substr(encode,i+1,1)))
next
showarray(result)
see decodelzw(encode)
func encodelzw(text)
o = ""
dict = list(4096)
for i = 1 to 255
dict[i] = char(i)
next
l = i
i = 1
w = left(text,1)
while i < len(text)
d = 0
while d < l
c = d
if i > len(text)
exit
ok
for d = 1 to l
if w = dict[d]
exit
ok
next
if d < l
i = i + 1
w = w + substr(text,i,1)
ok
end
dict[l] = w
l = l + 1
w = right(w,1)
o = o + char(c % 256) + char(floor(c / 256))
end
return o
func decodelzw(text)
o = ""
dict = list(4096)
for i = 1 to 255
dict[i] = char(i)
next
l = i
c = ascii(left(text,1)) + 256*ascii(substr(text,2,1))
w = dict[c]
o = w
if len(text) < 4
return o
ok
for i = 3 to len(text) step 2
c = ascii(substr(text,i,1)) + 256*ascii(substr(text,i+1,1))
if c < l
t = dict[c]
else
t = w + left(w,1)
ok
o = o + t
dict[l] = w + left(t,1)
l = l + 1
w = t
next
return o
func showarray(vect)
svect = ""
for n = 1 to len(vect)
svect = svect + vect[n] + " "
next
svect = left(svect, len(svect) - 1)
see svect + nl