September Morn Update

This commit is contained in:
Ingy döt Net 2019-09-12 10:33:56 -07:00
parent 4e2d22a71d
commit aac6731f2c
6856 changed files with 141342 additions and 21127 deletions

View file

@ -26,7 +26,7 @@ defmodule LZW do
defp decode([], _, _, _, l), do: Enum.reverse(l) |> to_string
defp decode([h|t], old, free, d, l) do
val = d[h]
val = if h == free, do: old ++ [List.first(old)], else: d[h]
add = [List.last(val) | old]
d1 = Map.put(d, free, add)
decode(t, val, free+1, d1, val++l)

View file

@ -0,0 +1,110 @@
' version 22-02-2019
' compile with: fbc -s console
Type dict
prefix As Integer
B As String
End Type
Sub init(dictionary() As dict, ByRef last As ULong)
For i As ULong = 0 To 255
dictionary(i).prefix = -1
dictionary(i).B = Chr(i)
Next
last = 255
End Sub
Function encode_LZW(dictionary() As dict, last_entry As ULong, input_str As String) As String
If Len(input_str) < 2 Then
Print "input string is to short"
Return ""
End If
Dim As String word, output_str, char
Dim As ULong i = 1, index, j, len_input = Len(input_str)
Do
If i > len_input Then
output_str = output_str + " " + Str(index)
Return output_str ' no more chars to process. we are done
End If
char = Mid(Input_str, i, 1)
i += 1
For j = 0 To last_entry
If dictionary(j).B = word + char Then
word += char
index = j
Continue Do
End If
Next
output_str = output_str + " " + Str(index)
last_entry = last_entry +1
dictionary(last_entry).B = word + char
dictionary(last_entry).prefix = index
word = char : index = Asc(char)
Loop
End Function
Function decode_LZW(dictionary() As dict, last_entry As ULong, input_str As String) As String
Dim As String temp, word, output_str
Dim As ULong i, i1 = 1, j, index
input_str = Trim(input_str)
Dim As ULong len_input = Len(input_str)
input_str = input_str + " "
i = InStr(i1, input_str, " ")
index = Val(Mid(Input_str, i1, i - i1))
word = dictionary(index).B
output_str = word
i1 = i +1
Do
i = InStr(i1, input_str, " ")
If i >= len_input Then
index = Val(Mid(input_str, i1))
output_str = output_str + dictionary(index).B
Return output_str
End If
index = Val(Mid(Input_str, i1, i - i1))
i1 = i +1
If index <= last_entry Then
temp = dictionary(index).B
Else
temp = word + Left(word, 1)
End If
output_str = output_str + temp
last_entry = last_entry +1
dictionary(last_entry).B = word + Left(temp, 1)
word = temp
Loop
End Function
' ------=< MAIN >=------
Dim As ULong last_entry, max_bit = 9
Dim As ULong dict_max = 1 Shl max_bit -1
Dim As String output_str, input_str = "TOBEORNOTTOBEORTOBEORNOT"
Dim As dict dictionary()
Print " input str: ";input_str
ReDim dictionary(dict_max +1)
init(dictionary(), last_entry)
output_str = encode_LZW(dictionary(), last_entry, input_str)
Print "encoded str: ";output_str
ReDim dictionary(dict_max +1)
init(dictionary(), last_entry)
output_str = decode_LZW(dictionary(), last_entry, output_str)
Print "decoded str: "; output_str
' empty keyboard buffer
While InKey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End

View file

@ -0,0 +1,38 @@
import Data.List (elemIndex, tails)
import Data.Maybe (fromJust)
doLZW :: Eq a => [a] -> [a] -> [Int]
doLZW _ [] = []
doLZW as (x:xs) = lzw (return <$> as) [x] xs
where
lzw a w [] = [fromJust $ elemIndex w a]
lzw a w (x:xs)
| w_ `elem` a = lzw a w_ xs
| otherwise = fromJust (elemIndex w a) : lzw (a ++ [w_]) [x] xs
where
w_ = w ++ [x]
undoLZW :: [a] -> [Int] -> [a]
undoLZW _ [] = []
undoLZW a cs =
cs >>=
(!!)
(foldl
((.) <$> (++) <*>
(\x xs -> return (((++) <$> head <*> take 1 . last) ((x !!) <$> xs))))
(return <$> a)
(take2 cs))
take2 :: [a] -> [[a]]
take2 xs = filter ((2 ==) . length) (take 2 <$> tails xs)
main :: IO ()
main = do
print $ doLZW ['\0' .. '\255'] "TOBEORNOTTOBEORTOBEORNOT"
print $
undoLZW
['\0' .. '\255']
[84, 79, 66, 69, 79, 82, 78, 79, 84, 256, 258, 260, 265, 259, 261, 263]
print $
((==) <*> ((.) <$> undoLZW <*> doLZW) ['\NUL' .. '\255'])
"TOBEORNOTTOBEORTOBEORNOT"

View file

@ -1,7 +1,7 @@
function compressLZW(decompressed::String)
dictsize = 256
dict = Dict{String,Int}(string(Char(i)) => i for i in range(0, dictsize))
result = Vector{Int}(0)
dict = Dict{String,Int}(string(Char(i)) => i for i in 0:dictsize)
result = Vector{Int}(undef, 0)
w = ""
for c in decompressed
wc = string(w, c)
@ -20,9 +20,9 @@ end
function decompressLZW(compressed::Vector{Int})
dictsize = 256
dict = Dict{Int,String}(i => string('\0' + i) for i in range(0, dictsize))
dict = Dict{Int,String}(i => string('\0' + i) for i in 0:dictsize)
result = IOBuffer()
w = string(Char(shift!(compressed)))
w = string(Char(popfirst!(compressed)))
write(result, w)
for k in compressed
if haskey(dict, k)
@ -37,7 +37,7 @@ function decompressLZW(compressed::Vector{Int})
dictsize += 1
w = entry
end
return String(result)
return String(take!(result))
end
original = ["0123456789", "TOBEORNOTTOBEORTOBEORNOT", "dudidudidudida"]
@ -46,5 +46,5 @@ 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")
println("Original: $word\n-> Compressed: $comp (compr.rate: $(round(comprate, digits=2))%)\n-> Decompressed: $decomp")
end

View file

@ -0,0 +1,25 @@
(define (compress str)
(let loop ((dc (fold (lambda (f x) ; dictionary (simplest, not optimized), with reversed codes
(cons (list x) (cons x f)))
'() (iota 256)))
(w '()) ; output sequence (reversed)
(s 256) ; maximal dictionary code value + 1
(x '()) ; current sequence
(r (str-iter str))); input stream
(cond
((null? r)
(reverse (cons (cadr (member x dc)) w)))
((pair? r)
(let ((xy (cons (car r) x)))
(if (member xy dc)
(loop dc w s xy (cdr r))
(loop (cons xy (cons s dc)) ; update dictionary with xy . s
(cons (cadr (member x dc)) w) ; add code to output stream
(+ s 1) ; increase code
(list (car r)) ; new current sequence
(cdr r))))) ; next input
(else
(loop dc w s x (r)))))
)
(print (compress "TOBEORNOTTOBEORTOBEORNOT")) ; => (84 79 66 69 79 82 78 79 84 256 258 260 265 259 261 263)

View file

@ -0,0 +1,27 @@
(define (decompress str)
(let loop ((dc (fold (lambda (f x) ; dictionary (simplest, not optimized), with reversed codes
(cons x (cons (list x) f)))
'() (iota 256)))
(w '()) ; output sequence (reversed)
(s 256) ; maximal dictionary code value + 1
(x '()) ; current symbols sequence
(r (str-iter str))); input stream
(cond
((null? r)
(reverse w))
((pair? r)
(let*((y (cadr (member (car r) dc)))
(xy (append y x)))
(if (member xy dc)
(loop dc (append y w) s xy (cdr r)) ; вряд ли такое будет...
(loop (cons s (cons xy dc)) ; update dictionary with xy . s
(append y w) ; add phrase to output stream
(+ s 1)
y ; new initial code
(cdr r))))) ; next input
(else
(loop dc w s x (r))))))
(print (runes->string
(decompress (runes->string '(84 79 66 69 79 82 78 79 84 256 258 260 265 259 261 263)))))
; => TOBEORNOTTOBEORTOBEEORNOT

View file

@ -38,7 +38,7 @@ Do i=1 To length(uncompressed)
Else Do
res=res||dict.w', '
dict.wc=dict_size
dict_size+=1
dict_size=dict_size+1
w=c
End
End
@ -61,7 +61,7 @@ w=d.w
Do i=1 To words(compressed)
k=word(compressed,i)
Select
When d.k<>'' | d.k=='20'x then /* allow for blank */
When d.k<>'' | d.k==' ' then /* allow for blank */
entry=d.k
When k=dict_size Then
entry=w||substr(w,1,1)
@ -70,7 +70,7 @@ Do i=1 To words(compressed)
End
res=res||entry
d.dict_size=w||substr(entry,1,1)
dict_size+=1
dict_size=dict_size+1
w=entry
End
Return res

View file

@ -1,29 +1,25 @@
/*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
cypher=LZWc(x) /*compress text using the LZW algorithm*/
say 'reconstituted=' LZWd(cypher)
say ' LZW integers=' cypher
parse arg x; if x=='' then /*get an optional argument from the CL.*/
x= '"There is nothing permanent except change." Heraclitus [540-475 BC]'
say 'original text=' x /* [↑] Not specified? Then use default*/
cypher= LZWc(x) /*compress text using the LZW algorithm*/
say 'reconstituted=' LZWd(cypher) /*display the reconstituted string. */
say ' LZW integers=' cypher /* " " LZW integers used. */
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 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*/
LZWc: procedure; parse arg y,,w $ @.; #= 256 /*LZW compress algorithm.*/
do j=0 for #; _= d2c(j); @._= j; end /*j*/
do k=1 for length(y)+1; z= w || substr(y, k, 1)
if @.z=='' then do; $= $ @.w; @.z= #; #= # + 1; w= substr(y, k, 1); end
else w= z
end /*k*/; return substr($, 2) /*del leading blank.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
LZWd: procedure; parse arg w y,,@.; #=256 /*the LZW decompress algorithm.*/
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)
$=$ || ?
@.#=w || left(?, 1); #=#+1; w=?
end /*k*/
return $
LZWd: procedure; parse arg x y,,@.; #= 256 /*LZW decompress algorithm.*/
do j=0 for #; @.j= d2c(j); end /*j*/
$= @.x; w= $ /*#: is the dictionay size*/
do k=1 for words(y); z= word(y, k)
if @.z\=='' | @.k==" " then ?= @.z
else if z==# then ?= w || left(w, 1)
$= $ || ?
@.#= w || left(?, 1); #= # + 1; w= ?
end /*k*/; return $

View file

@ -0,0 +1,105 @@
Function compress(str as String) As String
Dim i as integer
Dim w as String = ""
Dim c as String
Dim strLen as Integer
Dim wc as string
Dim dic() as string
Dim result() as string
Dim lookup as integer
Dim startPos as integer = 0
Dim combined as String
strLen = len(str)
dic = populateDictionary
for i = 1 to strLen
c = str.mid(i, 1)
wc = w + c
startPos = getStartPos(wc)
lookup = findArrayPos(dic, wc, startPos)
if (lookup <> -1) then
w = wc
Else
startPos = getStartPos(w)
lookup = findArrayPos(dic, w, startPos)
if lookup <> -1 then
result.Append(lookup.ToText)
end if
dic.append(wc)
w = c
end if
next i
if (w <> "") then
startPos = getStartPos(w)
lookup = findArrayPos(dic, w, startPos)
result.Append(lookup.ToText)
end if
return join(result, ",")
End Function
Function decompress(str as string) As string
dim comStr() as string
dim w as string
dim result as string
dim comStrLen as integer
dim entry as string
dim dic() as string
dim i as integer
comStr = str.Split(",")
comStrLen = comStr.Ubound
dic = populateDictionary
w = chr(val(comStr(0)))
result = w
for i = 1 to comStrLen
entry = dic(val(comStr(i)))
result = result + entry
dic.append(w + entry.mid(1,1))
w = entry
next i
return result
End Function
Private Function findArrayPos(arr() as String, search as String, start as integer) As Integer
dim arraySize as Integer
dim arrayPosition as Integer = -1
dim i as Integer
arraySize = UBound(arr)
for i = start to arraySize
if (strcomp(arr(i), search, 0) = 0) then
arrayPosition = i
exit
end if
next i
return arrayPosition
End Function
Private Function getStartPos(str as String) As integer
if (len(str) = 1) then
return 0
else
return 255
end if
End Function
Private Function populateDictionary() As string()
dim dic() as string
dim i as integer
for i = 0 to 255
dic.append(Chr(i))
next i
return dic
End Function