Data update

This commit is contained in:
Ingy döt Net 2026-04-30 12:34:36 -04:00
parent 4bb20c9b71
commit cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions

View file

@ -0,0 +1,4 @@
enc {⎕IO0 0=: (c),(c,~c)1}
dec {⎕IO0 0=:0 c,(c,~c())1}
show {az⎕C⎕A eaz enc daz dec e d:,' → ',(e),' → ',d 'Error'⎕SIGNAL 16}
show¨ 'broood' 'bananaaa' 'hiphophiphop'

View file

@ -0,0 +1,82 @@
with Ada.Text_IO;
procedure Move_To_Front is
subtype Lower_Case is Character range 'a' .. 'z';
subtype Index is Integer range 0 .. 25;
type Table is array (Index) of Lower_Case;
Alphabet: constant Table := "abcdefghijklmnopqrstuvwxyz";
type Number_String is array(Positive range <>) of Natural;
function Encode(S: String) return Number_String is
Key: Table := Alphabet;
function Encode(S: String; Tab: in out Table) return Number_String is
procedure Look_Up(A: in out Table; Ch: Lower_Case; Pos: out Index) is
begin
for I in A'Range loop
if A(I) = Ch then
Pos := I;
A := A(Pos) & A(A'First .. Pos-1) & A(Pos+1 .. A'Last);
return;
end if;
end loop;
raise Program_Error with "unknown character";
end Look_Up;
Empty: Number_String(1 .. 0);
Result: Natural;
begin
if S'Length = 0 then
return Empty;
else
Look_Up(Tab, S(S'First), Result);
return Result & Encode(S(S'First+1 .. S'Last), Tab);
end if;
end Encode;
begin
return Encode(S, Key);
end Encode;
function Decode(N: Number_String) return String is
Key: Table := Alphabet;
function Decode(N: Number_String; Tab: in out Table) return String is
procedure Look_Up(A: in out Table; Pos: Index; Ch: out Lower_Case) is
begin
Ch := A(Pos);
A := A(Pos) & A(A'First .. Pos-1) & A(Pos+1 .. A'Last);
end Look_Up;
Result: String(N'Range);
begin
for I in N'Range loop
Look_Up(Tab, N(I), Result(I));
end loop;
return Result;
end Decode;
begin
return Decode(N, Key);
end Decode;
procedure Encode_Write_Check(S: String) is
N: Number_String := Encode(S);
T: String := Decode(N);
Check: String := (if S=T then "Correct!" else "*WRONG*!");
begin
Ada.Text_IO.Put("'" & S & "' encodes to");
for Num of N loop
Ada.Text_IO.Put(Integer'Image(Num));
end loop;
Ada.Text_IO.Put_Line(". This decodes to '" & T & "'. " & Check);
end Encode_Write_Check;
begin
Encode_Write_Check("broood");
Encode_Write_Check("bananaaa");
Encode_Write_Check("hiphophiphop");
end Move_To_Front;

View file

@ -0,0 +1,31 @@
10 DEFINT C,L: DIM C(128)
20 AL$="abcdefghijklmnopqrstuvwxyz"
30 READ W$: IF W$="" THEN END
40 PRINT W$;" -> ";
50 S$=W$: GOSUB 1000
60 FOR I=1 TO L: PRINT C(I);: NEXT I
70 GOSUB 1100
80 PRINT " -> ";S$
90 IF S$<>W$ THEN PRINT "Not equal"
100 GOTO 30
110 END
120 DATA broood,bananaaa,hiphophiphop,""
1000 REM ENCODE
1010 Z$=AL$
1020 FOR I=1 TO LEN(S$)
1030 J=INSTR(Z$,MID$(S$,I,1))
1040 C(I)=J-1
1050 Z$=MID$(Z$,J,1) + LEFT$(Z$,J-1) + RIGHT$(Z$,LEN(Z$)-J)
1060 NEXT I
1070 L=LEN(S$)
1080 RETURN
1100 REM DECODE
1110 Z$=AL$
1120 S$=""
1130 FOR I=1 TO L
1140 C$=MID$(Z$,C(I)+1,1)
1150 S$=S$+C$
1160 J=INSTR(Z$,C$)
1170 Z$=MID$(Z$,J,1) + LEFT$(Z$,J-1) + RIGHT$(Z$,LEN(Z$)-J)
1180 NEXT I
1190 RETURN

View file

@ -0,0 +1,65 @@
get "libhdr"
let indexof(ch, s) = valof
for i = 0 to s%0 do
if s%i = ch resultis i
let copy(sin, sout) be
for i = 0 to sin%0 do
sout%i := sin%i
let streq(a, b) = valof
$( for i = 0 to a%0 do
unless a%i = b%i resultis false
resultis true
$)
let movetofront(s, ch) be
$( let i = indexof(ch, s)
for j = i to 2 by -1 do
s%j := s%(j-1)
s%1 := ch
$)
let encode(s, alph, v) be
$( let a = vec 1+256/BYTESPERWORD
copy(alph, a)
for i = 1 to s%0
$( let c = indexof(s%i, a)
v!(i-1) := c-1
movetofront(a, s%i)
$)
$)
let decode(v, n, alph, s) be
$( let a = vec 1+256/BYTESPERWORD
copy(alph, a)
s%0 := n
for i = 0 to n-1
$( let c = a%(v!i+1)
s%(i+1) := c
movetofront(a, c)
$)
$)
let show(s) be
$( let enc = vec 256
let dec = vec 1+256/BYTESPERWORD
let alph = "abcdefghijklmnopqrstuvwxyz"
writes(s)
writes(" -> ")
encode(s, alph, enc)
for i = 0 to s%0-1 do writef("%N ", enc!i)
writes("-> ")
decode(enc, s%0, alph, dec)
writes(dec)
test streq(s, dec)
writes(" (ok)*N") or writes(" (fail)*N")
$)
let start() be
$( show("broood")
show("bananaaa")
show("hiphophiphop")
$)

View file

@ -0,0 +1,54 @@
movetofront = proc (s: string, c: char) returns (string) signals (not_found)
if string$indexc(c, s) = 0 then signal not_found end
next: array[char] := array[char]$[c]
for sc: char in string$chars(s) do
if sc = c then continue end
array[char]$addh(next, sc)
end
return(string$ac2s(next))
end movetofront
encode = proc (s, alph: string) returns (sequence[int]) signals (not_found)
encoded: array[int] := array[int]$[]
for c: char in string$chars(s) do
array[int]$addh(encoded, string$indexc(c, alph) - 1)
alph := movetofront(alph, c) resignal not_found
end
return(sequence[int]$a2s(encoded))
end encode
decode = proc (data: sequence[int], alph: string) returns (string) signals (not_found)
decoded: array[char] := array[char]$[]
for n: int in sequence[int]$elements(data) do
c: char := alph[n + 1]
array[char]$addh(decoded, c)
alph := movetofront(alph, c) resignal not_found
end
return(string$ac2s(decoded))
end decode
print_seq = proc (seq: sequence[int], s: stream)
for n: int in sequence[int]$elements(seq) do
stream$puts(s, int$unparse(n) || " ")
end
end print_seq
start_up = proc ()
po: stream := stream$primary_output()
words: sequence[string] := sequence[string]$["broood", "bananaaa", "hiphophiphop"]
alph: string := "abcdefghijklmnopqrstuvwxyz"
for word: string in sequence[string]$elements(words) do
stream$puts(po, word || " -> ")
encoded: sequence[int] := encode(word, alph)
print_seq(encoded, po)
stream$puts(po, "-> ")
decoded: string := decode(encoded, alph)
stream$puts(po, decoded)
if word = decoded
then stream$putl(po, " ok")
else stream$putl(po, " fail")
end
end
end start_up

View file

@ -0,0 +1,167 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. MTF-ENCODE-DECODE.
DATA DIVISION.
WORKING-STORAGE SECTION.
*> Initial alphabet reference
01 ALPHABET-INIT PIC X(26) VALUE
"abcdefghijklmnopqrstuvwxyz".
*> Dynamic character list (simulates the JS charList array)
01 CHAR-TABLE.
05 CHAR-ITEM PIC X OCCURS 26 TIMES.
*> Variables for processing
01 WORK-AREAS.
05 INPUT-WORD PIC X(20) VALUE SPACES.
05 WORD-LEN PIC 99 VALUE 0.
05 I PIC 99 VALUE 0.
05 J PIC 99 VALUE 0.
05 K PIC 99 VALUE 0.
05 TEMP-CHAR PIC X VALUE SPACE.
05 CHAR-INDEX PIC 99 VALUE 0.
*> Storage for algorithm outputs
01 ENCODED-DATA.
05 ENCODED-NUMBERS PIC 99 OCCURS 20 TIMES.
01 DECODED-DATA.
05 DECODED-WORD PIC X(20) VALUE SPACES.
*> Variables for console logging/displaying
01 DISPLAY-AREAS.
05 DISPLAY-LINE PIC X(120) VALUE SPACES.
05 DISP-POS PIC 99 VALUE 1.
05 DISP-NUM PIC Z9.
*> Equivalent to JS: var words = ['broood', ...]
01 TEST-DATA.
05 TEST-WORDS.
10 FILLER PIC X(20) VALUE "broood".
10 FILLER PIC X(20) VALUE "bananaaa".
10 FILLER PIC X(20) VALUE "hiphophiphop".
05 TEST-WORD-REDEF REDEFINES TEST-WORDS.
10 TEST-WORD-ARR PIC X(20) OCCURS 3 TIMES.
05 TEST-IDX PIC 9 VALUE 1.
PROCEDURE DIVISION.
MAIN-LOGIC.
DISPLAY "Testing Move-To-Front (MTF) Algorithm".
DISPLAY "=====================================".
*> Equivalent to: words.map(...)
PERFORM VARYING TEST-IDX FROM 1 BY 1 UNTIL TEST-IDX > 3
MOVE TEST-WORD-ARR(TEST-IDX) TO INPUT-WORD
PERFORM GET-WORD-LENGTH
DISPLAY "Original Word : " INPUT-WORD(1:WORD-LEN)
*> Encode
PERFORM ENCODE-MTF
PERFORM PRINT-ENCODED
*> Decode
PERFORM DECODE-MTF
PERFORM PRINT-DECODED
DISPLAY "-------------------------------------"
END-PERFORM.
STOP RUN.
*> ==========================================
*> ENCODE ALGORITHM
*> ==========================================
ENCODE-MTF.
PERFORM INIT-CHAR-LIST.
PERFORM VARYING I FROM 1 BY 1 UNTIL I > WORD-LEN
MOVE INPUT-WORD(I:1) TO TEMP-CHAR
MOVE 0 TO CHAR-INDEX
*> Simulate JS: charList.indexOf(char)
PERFORM VARYING J FROM 1 BY 1
UNTIL J > 26 OR CHAR-INDEX > 0
IF CHAR-ITEM(J) = TEMP-CHAR
MOVE J TO CHAR-INDEX
END-IF
END-PERFORM
*> JS arrays are 0-indexed, COBOL is 1-indexed.
*> Subtract 1 to match exact JS numeric output.
COMPUTE ENCODED-NUMBERS(I) = CHAR-INDEX - 1
*> Simulate JS: splice(charNum, 1) and unshift()
PERFORM MOVE-TO-FRONT
END-PERFORM.
*> ==========================================
*> DECODE ALGORITHM
*> ==========================================
DECODE-MTF.
PERFORM INIT-CHAR-LIST.
MOVE SPACES TO DECODED-WORD.
PERFORM VARYING I FROM 1 BY 1 UNTIL I > WORD-LEN
*> Convert JS 0-based index back to COBOL 1-based index
COMPUTE CHAR-INDEX = ENCODED-NUMBERS(I) + 1
MOVE CHAR-ITEM(CHAR-INDEX) TO TEMP-CHAR
*> Append character to decoded string
MOVE TEMP-CHAR TO DECODED-WORD(I:1)
*> Simulate JS: splice(num, 1) and unshift()
PERFORM MOVE-TO-FRONT
END-PERFORM.
*> ==========================================
*> SHARED HELPER FUNCTIONS
*> ==========================================
*> Moves item at CHAR-INDEX to position 1, shifting rest right
MOVE-TO-FRONT.
IF CHAR-INDEX > 1
PERFORM VARYING K FROM CHAR-INDEX BY -1 UNTIL K = 1
COMPUTE J = K - 1
MOVE CHAR-ITEM(J) TO CHAR-ITEM(K)
END-PERFORM
MOVE TEMP-CHAR TO CHAR-ITEM(1)
END-IF.
*> Resets the array back to "a" through "z"
INIT-CHAR-LIST.
PERFORM VARYING I FROM 1 BY 1 UNTIL I > 26
MOVE ALPHABET-INIT(I:1) TO CHAR-ITEM(I)
END-PERFORM.
*> Trims whitespace to find true length of current input word
GET-WORD-LENGTH.
MOVE 0 TO WORD-LEN.
PERFORM VARYING I FROM 20 BY -1
UNTIL I < 1 OR INPUT-WORD(I:1) NOT = SPACE
CONTINUE
END-PERFORM.
MOVE I TO WORD-LEN.
*> ==========================================
*> DISPLAY/LOGGING FORMATTERS
*> ==========================================
PRINT-ENCODED.
MOVE SPACES TO DISPLAY-LINE.
MOVE 1 TO DISP-POS.
STRING "Encoded Array : [" DELIMITED BY SIZE
INTO DISPLAY-LINE WITH POINTER DISP-POS.
PERFORM VARYING I FROM 1 BY 1 UNTIL I > WORD-LEN
MOVE ENCODED-NUMBERS(I) TO DISP-NUM
IF I = WORD-LEN
STRING DISP-NUM DELIMITED BY SIZE
"]" DELIMITED BY SIZE
INTO DISPLAY-LINE WITH POINTER DISP-POS
ELSE
STRING DISP-NUM DELIMITED BY SIZE
", " DELIMITED BY SIZE
INTO DISPLAY-LINE WITH POINTER DISP-POS
END-IF
END-PERFORM.
DISPLAY DISPLAY-LINE(1:DISP-POS).
PRINT-DECODED.
DISPLAY "Decoded Word : " DECODED-WORD(1:WORD-LEN).

View file

@ -0,0 +1,100 @@
include "cowgol.coh";
include "strings.coh";
sub CheckCharError(ptr: [uint8]) is
if ptr == 0 as [uint8] then
print("Character not found.\n");
ExitWithError();
end if;
end sub;
sub FindChar(chr: uint8, str: [uint8]): (loc: [uint8]) is
loc := 0 as [uint8];
var begin := str;
while [str] != 0 and [str] != chr loop
str := @next str;
end loop;
if [str] == chr then
loc := str;
end if;
end sub;
sub FindCharIdx(chr: uint8, str: [uint8]): (idx: intptr) is
var locptr := FindChar(chr, str);
CheckCharError(locptr);
idx := locptr - str;
end sub;
sub MoveToFront(sym: uint8, symtab: [uint8]) is
var symptr := FindChar(sym, symtab);
CheckCharError(symptr);
while symptr > symtab loop
[symptr] := [@prev symptr];
symptr := @prev symptr;
end loop;
[symtab] := sym;
end sub;
sub Encode(string: [uint8], symtab: [uint8], result: [uint8]) is
var symtab_buffer: uint8[256];
var st := &symtab_buffer[0];
CopyString(symtab, st);
while [string] != 0 loop
[result] := FindCharIdx([string], st) as uint8;
MoveToFront([string], st);
string := @next string;
result := @next result;
end loop;
end sub;
sub Decode(codes: [uint8], size: intptr, symtab: [uint8], result: [uint8]) is
var symtab_buffer: uint8[256];
var st := &symtab_buffer[0];
CopyString(symtab, st);
while size > 0 loop
[result] := [st + [codes] as intptr];
MoveToFront([result], st);
codes := @next codes;
result := @next result;
size := size - 1;
end loop;
[result] := 0;
end sub;
sub Test(string: [uint8]) is
sub PrintArr(codes: [uint8], size: intptr) is
while size > 0 loop
print_i8([codes]);
print_char(' ');
codes := @next codes;
size := size - 1;
end loop;
end sub;
var symtab := "abcdefghijklmnopqrstuvwxyz";
var encoded_buf: uint8[256];
var decoded_buf: uint8[256];
var encoded := &encoded_buf[0];
var decoded := &decoded_buf[0];
var size := StrLen(string);
print(string);
print(" -> ");
Encode(string, symtab, encoded);
PrintArr(encoded, size);
print("-> ");
Decode(encoded, size, symtab, decoded);
print(decoded);
if StrCmp(string, decoded) == 0 then
print(" (ok)\n");
else
print(" (fail)\n");
end if;
end sub;
Test("broood");
Test("bananaaa");
Test("hiphophiphop");

View file

@ -0,0 +1,33 @@
class Array
# useful method to work on parts of the array in-place
def slice (start, length)
start = size - start if start < 0
raise "Out of bounds" unless start >= 0 && length >= 0 && start + length <= size
Slice.new(to_unsafe + start, length)
end
end
def encode (message, symbols)
symbols = symbols.dup
message.chars.map {|ch|
idx = symbols.index! ch
symbols.slice(0, idx+1).rotate! -1
idx
}
end
def decode (message, symbols)
symbols = symbols.dup
message.map {|idx|
ch = symbols[idx]
symbols.slice(0, idx+1).rotate! -1
ch
}.join
end
symbols = ('a'..'z').to_a
["broood", "bananaaa", "hiphophiphop"].each do |word|
encoded = encode(word, symbols)
decoded = decode(encoded, symbols)
printf "%-12s -> %-38s -> %s\n", word, encoded, decoded
end

View file

@ -0,0 +1,114 @@
! Move-to-front algorithm
! tested with Intel ifx (IFX) 2025.2.1 20250806 on Kubuntu 25.10
! GNU Fortran (Ubuntu 15.2.0-4ubuntu4) 15.2.0 on Kubuntu 25.10
! VSI Fortran x86-64 V8.7-001 on OpenVMS x86_64 V9.2-3
! No Non-standard features used, should compile on any fairly recent Fortran.
! U.B., February 2026
!=========================================================================================
program FrontMove
implicit none
! Starting sequence in the local symbol tables in 2 subroutines
character (len=26), parameter :: startSymbolTab = 'abcdefghijklmnopqrstuvwxyz'
! The test cases of the task description:
call EncodeAndCrossCheck ('broood')
call EncodeAndCrossCheck ('bananaaa')
call EncodeAndCrossCheck ('hiphophiphop')
! Two more tests: What happens in MoveToFront() if char appears at the beginning ('a')
! or at the end ('z') of the symbol table?
call EncodeAndCrossCheck ('anton')
call EncodeAndCrossCheck ('zwareshagz')
contains
! =========================================================================
! Encode a given text string using the Move-to-fromt algorithm, then
! decode the resultant sequence of numbers, to be compared to the original.
! =========================================================================
subroutine EncodeAndCrossCheck (text)
character (len=*), intent(in) :: text ! Input: the text to encode
integer, dimension(len(text)) :: code ! Resultant numeric array
character (len=26) :: SymTab ! The symbol table to work with
integer :: l ! LEngth of input text
integer :: ii, idx ! Loop index, Pos of a char inside Symbol Table
! Initialize work table
SymTab = startSymbolTab
l = len (text)
write (*,'(A, T13, A)', advance='no') text, ' ->'
! Encoding Algorithm:
! for each symbol of the input sequence:
! output the index of the symbol in the symbol table
! move that symbol to the front of the symbol table
do ii=1, l
idx = index (SymTab, text(ii:ii))
code (ii) = idx-1 ! Code muss be null-based
write (*, '(I3)', advance='no') code(ii)
call moveToFront (SymTab, idx)
end do
do ii=3*l,36
write (*,'(x)', advance='no') ! some space to format output
enddo
write (*,'(A)', advance='no') ' -> '
! Now decode the resultant code and hope to see again the original text.
call decodeAndCheck (code, l, text)
end subroutine EncodeAndCrossCheck
! =====================================================================================
! Decode a given array of numbers and check if the rtesult matches the given input text
! =====================================================================================
subroutine decodeAndCheck (code, l, text)
integer , intent(in) ::l
integer, dimension(l), intent(in) :: code
character (len=*), intent(in) :: text ! the text to compare to the decode result.
character (len=26) :: SymTab
integer :: ii, idx
logical :: mismatch
! # Using the same starting symbol table
SymTab = startSymbolTab
mismatch = .false.
! Decoding Algorithm:
! for each index of the input sequence:
! output the symbol at that index of the symbol table
! move that symbol to the front of the symbol table
do ii=1, l
idx = code(ii) + 1
write (*, '(A1)', advance='no') SymTab (idx:idx)
if (SymTab (idx:idx) .ne. text (ii:ii)) mismatch = .true.
call moveToFront (SymTab, idx)
end do
if (.not. mismatch) then
write (*,*) '(Success)'
else
write (*,*) 'ERROR.'
endif
end subroutine decodeAndCheck
! =========================================================================
! Move the character found at index 'ind' in the string "'txt' to the front
! =========================================================================
subroutine moveToFront (txt, ind)
character (len=*), intent(inout) :: txt
integer, intent(in) :: ind
! Rearrange txt: character at ind, then everything in front of ind, then everything behind.
txt = txt(ind:ind) // txt(:ind-1) // txt (ind+1:)
end subroutine moveToFront
end program FrontMove

View file

@ -0,0 +1,30 @@
main :: [sys_message]
main = [Stdout (lay (map test ["broood", "bananaaa", "hiphophiphop"]))]
test :: [char]->[char]
test str = str ++ " -> " ++ show encoded ++ " -> " ++ decoded ++ result
where alph = "abcdefghijklmnopqrstuvwxyz"
encoded = enc alph str
decoded = dec alph encoded
result = " (ok)", if str == decoded
result = " (fail)", otherwise
enc :: [*]->[*]->[num]
enc symtab [] = []
enc symtab (x:xs) = find x symtab : enc (movetofront x symtab) xs
dec :: [*]->[num]->[*]
dec symtab [] = []
dec symtab (x:xs) = c : dec (movetofront c symtab) xs where c = symtab ! x
movetofront :: *->[*]->[*]
movetofront x xs = x:remove x xs
remove :: *->[*]->[*]
remove x [] = []
remove x (x:xs) = remove x xs
remove x (y:xs) = y:remove x xs
find :: *->[*]->num
find x (x:xs) = 0
find x (y:xs) = 1 + find x xs

View file

@ -0,0 +1,119 @@
100H:
BDOS: PROCEDURE (FN,ARG); DECLARE FN BYTE, ARG ADDRESS; GO TO 5; END BDOS;
EXIT: PROCEDURE; GO TO 0; END EXIT;
PRINT: PROCEDURE (STR); DECLARE STR ADDRESS; CALL BDOS(9, STR); END PRINT;
PRINT$NUM: PROCEDURE (N);
DECLARE N ADDRESS, I BYTE;
DECLARE S (6) BYTE INITIAL ('.....$');
I = 5;
DIGIT: DO;
S(I := I-1) = '0' + N MOD 10;
IF (N := N/10) > 0 THEN GO TO DIGIT;
END;
CALL PRINT(.S(I));
END PRINT$NUM;
FIND: PROCEDURE (STR, CHR) ADDRESS;
DECLARE STR ADDRESS, CHR BYTE;
DECLARE S BASED STR BYTE, I ADDRESS;
I = 0;
DO WHILE S(I) <> CHR; I = I+1; END;
RETURN I;
END FIND;
MOVE$TO$FRONT: PROCEDURE (SYMTAB, SYM);
DECLARE SYMTAB ADDRESS, SYM BYTE, TMP BYTE;
DECLARE S BASED SYMTAB BYTE, I ADDRESS;
I = FIND(SYMTAB, SYM);
DO WHILE I>0; S(I) = S(I := I-1); END;
S(0) = SYM;
END MOVE$TO$FRONT;
COPY$STRING: PROCEDURE (INSTR, OUTSTR);
DECLARE (INSTR, OUTSTR) ADDRESS;
DECLARE (I BASED INSTR, O BASED OUTSTR) BYTE;
DO WHILE I <> '$';
O = I;
INSTR = INSTR + 1;
OUTSTR = OUTSTR + 1;
END;
O = '$';
END COPY$STRING;
STR$LEN: PROCEDURE (STR) ADDRESS;
DECLARE STR ADDRESS;
RETURN FIND(STR, '$');
END STR$LEN;
STR$EQ: PROCEDURE (STR1, STR2) BYTE;
DECLARE (STR1, STR2) ADDRESS;
DECLARE (S1 BASED STR1, S2 BASED STR2) BYTE;
DECLARE I ADDRESS;
I = 0;
DO WHILE S1(I) = S2(I) AND S1(I) <> '$'; I=I+1; END;
RETURN S1(I) = S2(I);
END STR$EQ;
ENCODE: PROCEDURE (STR, SYMTAB, RESULT);
DECLARE (STR, SYMTAB, RESULT) ADDRESS;
DECLARE S BASED STR BYTE, R BASED RESULT BYTE, I ADDRESS;
DECLARE TEMP$SYMTAB (256) BYTE;
CALL COPY$STRING(SYMTAB, .TEMP$SYMTAB);
DO I=0 TO STR$LEN(STR) - 1;
R(I) = FIND(.TEMP$SYMTAB, S(I));
CALL MOVE$TO$FRONT(.TEMP$SYMTAB, S(I));
END;
END ENCODE;
DECODE: PROCEDURE (ARR, SZ, SYMTAB, RESULT);
DECLARE (ARR, SZ, SYMTAB, RESULT) ADDRESS;
DECLARE N BASED ARR BYTE, R BASED RESULT BYTE, I ADDRESS;
DECLARE TEMP$SYMTAB (256) BYTE;
CALL COPY$STRING(SYMTAB, .TEMP$SYMTAB);
DO I=0 TO SZ-1;
R(I) = TEMP$SYMTAB(N(I));
CALL MOVE$TO$FRONT(.TEMP$SYMTAB, R(I));
END;
R(SZ) = '$';
END DECODE;
PRINT$ARR: PROCEDURE (ARR, SZ);
DECLARE (ARR, SZ) ADDRESS;
DECLARE N BASED ARR BYTE, I ADDRESS;
DO I=0 TO SZ-1;
CALL PRINT$NUM(N(I));
CALL PRINT(.' $');
END;
END PRINT$ARR;
TEST: PROCEDURE (STR);
DECLARE STR ADDRESS, SZ ADDRESS;
DECLARE ENC$ARR (256) BYTE;
DECLARE SYMTAB (27) BYTE INITIAL ('ABCDEFGHIJKLMNOPQRSTUVWYXZ$');
DECLARE DEC$STR (256) BYTE;
SZ = STR$LEN(STR);
CALL PRINT(STR);
CALL PRINT(.' -> $');
CALL ENCODE(STR, .SYMTAB, .ENC$ARR);
CALL PRINT$ARR(.ENC$ARR, SZ);
CALL PRINT(.'-> $');
CALL DECODE(.ENC$ARR, SZ, .SYMTAB, .DEC$STR);
CALL PRINT(.DEC$STR);
IF STR$EQ(STR, .DEC$STR)
THEN CALL PRINT(.' (OK)$');
ELSE CALL PRINT(.' (FAIL)$');
CALL PRINT(.(13,10,'$'));
END TEST;
CALL TEST(.'BROOOD$');
CALL TEST(.'BANANAAA$');
CALL TEST(.'HIPHOPHIPHOP$');
CALL EXIT;
EOF

View file

@ -0,0 +1,53 @@
local fmt = require "fmt"
require "table2"
local function encode(s)
if s == "" then return {} end
local symbols = "abcdefghijklmnopqrstuvwxyz":split("")
local result = table.rep(#s, 0)
for i = 1, #s do
local c = s[i]
local index = symbols:findindex(|ch| -> ch == c)
if !index then error($"{s} contains a non-alphabetic character") end
result[i] = index
if index > 1 then
for k = index - 1, 1, -1 do symbols[k + 1] = symbols[k] end
symbols[1] = c
end
end
return result
end
local function decode(a)
if #a == 0 then return "" end
local symbols = "abcdefghijklmnopqrstuvwxyz":split("")
local result = table.rep(#a, "")
local i = 1
for a as n do
if n < 1 or n > 26 then error($"{fmt.format("%,s", a)} contains an invalid number") end
result[i] = symbols[n]
if n > 1 then
for j = n - 1, 1, -1 do symbols[j + 1] = symbols[j] end
symbols[1] = result[i]
end
i += 1
end
return result:concat("")
end
local strings = {"broood", "bananaaa", "hiphophiphop"}
local encoded = table.create(#strings)
for i, s in strings do
encoded[i] = encode(s)
fmt.print("%-12s -> %,s", s, encoded[i])
end
print()
local decoded = table.create(#encoded)
i = 1
for encoded as a do
decoded[i] = decode(a)
local correct = (decoded[i] == strings[i]) ? "correct" : "incorrect"
fmt.print("%,-38s -> %-12s -> %s", a, decoded[i], correct)
i += 1
end

View file

@ -0,0 +1,75 @@
Function Test-MTF
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true,Position=0)]
[string]$word,
[Parameter(Mandatory=$false)]
[string]$SymbolTable = 'abcdefghijklmnopqrstuvwxyz'
)
Begin
{
Function Encode
{
Param
(
[Parameter(Mandatory=$true,Position=0)]
[string]$word,
[Parameter(Mandatory=$false)]
[string]$SymbolTable = 'abcdefghijklmnopqrstuvwxyz'
)
foreach ($letter in $word.ToCharArray())
{
$index = $SymbolTable.IndexOf($letter)
$prop = [ordered]@{
Input = $letter
Output = [int]$index
SymbolTable = $SymbolTable
}
New-Object PSobject -Property $prop
$SymbolTable = $SymbolTable.Remove($index,1).Insert(0,$letter)
}
}
Function Decode
{
Param
(
[Parameter(Mandatory=$true,Position=0)]
[int[]]$index,
[Parameter(Mandatory=$false)]
[string]$SymbolTable = 'abcdefghijklmnopqrstuvwxyz'
)
foreach ($i in $index)
{
#Write-host $i -ForegroundColor Red
$letter = $SymbolTable.Chars($i)
$prop = [ordered]@{
Input = $i
Output = $letter
SymbolTable = $SymbolTable
}
New-Object PSObject -Property $prop
$SymbolTable = $SymbolTable.Remove($i,1).Insert(0,$letter)
}
}
}
Process
{
#Encoding
Write-Host "Encoding $word" -NoNewline
$Encoded = (Encode -word $word).output
Write-Host -NoNewline ": $($Encoded -join ',')"
#Decoding
Write-Host "`nDecoding $($Encoded -join ',')" -NoNewline
$Decoded = (Decode -index $Encoded).output -join ''
Write-Host -NoNewline ": $Decoded`n"
}
End{}
}

View file

@ -0,0 +1,28 @@
encodeMTF <- function(str, symtable = letters) {
encode <- function(ch) {
r <- which(symtable == ch)
symtable <<- c(ch, symtable[-r])
return(r)
}
sapply(strsplit(str, "")[[1]], encode)
}
decodeMTF <- function(arr, symtable = letters) {
decode <- function(i) {
r <- symtable[i]
symtable <<- c(r, symtable[-i])
return(r)
}
paste(sapply(arr, decode), collapse = "")
}
testset <- c("broood", "bananaaa", "hiphophiphop")
encoded <- lapply(testset, encodeMTF)
decoded <- mapply(decodeMTF, encoded)
for (i in seq_along(testset)) {
cat("Test string:", testset[i], "\n -> Encoded:", paste(encoded[[i]], collapse = ", "), "\n -> Decoded:", decoded[i], "\n\n")
}
# Test if decoded strings equal original
all(sapply(seq_along(testset), function(i) identical(testset[i], decoded[i])))

View file

@ -0,0 +1,41 @@
$ENTRY Go {
= <Show 'broood'>
<Show 'bananaaa'>
<Show 'hiphophiphop'>;
};
Alph {
= 'abcdefghijklmnopqrstuvwxyz';
};
Show {
e.X, <Encode (<Alph>) e.X>: e.Enc,
<Decode (<Alph>) e.Enc>: e.X
= <Prout e.X ' -> ' e.Enc ' -> ' e.X>;
e.X = <Prout 'Result of decode not equal to input'>;
};
Encode {
(e.Alph) = ;
(e.Alph) s.C e.X =
<Lookup s.C e.Alph>
<Encode (<MoveToFront s.C e.Alph>) e.X>;
};
Decode {
(e.Alph) = ;
(e.Alph) s.I e.X, <Item s.I e.Alph>: s.C =
s.C <Decode (<MoveToFront s.C e.Alph>) e.X>;
};
Lookup {
s.C e.X s.C e.Y, <Lenw e.X>: s.L e.X = s.L;
};
Item {
s.N e.X, <First <Add 1 s.N> e.X>: (e.Y s.C) e.Z = s.C;
};
MoveToFront {
s.C e.X s.C e.Y = s.C e.X e.Y;
};

View file

@ -0,0 +1,31 @@
program move_to_front;
tests := ["broood", "bananaaa", "hiphophiphop"];
alph := "abcdefghijklmnopqrstuvwxyz";
loop for test in tests do
e := encode(test, alph);
d := decode(e, alph);
v := if test = d then "(ok)" else "(fail)" end;
print(test,"->",e,"->",d,v);
end loop;
proc encode(s, alph);
enc := [];
loop for c in s do
[i, j] := mark(alph, c);
alph := c + alph(..i-1) + alph(j+1..);
enc with:= i-1;
end loop;
return enc;
end proc;
proc decode(ls, alph);
s := "";
loop for i in ls do
c := alph(i + 1);
s +:= c;
alph := c + alph(..i) + alph(i+2..);
end loop;
return s;
end proc;
end program;

View file

@ -0,0 +1,49 @@
Function mtf_encode(s)
'create the array list and populate it with the initial symbol position
Set symbol_table = CreateObject("System.Collections.ArrayList")
For j = 97 To 122 'a to z in decimal.
symbol_table.Add Chr(j)
Next
output = ""
For i = 1 To Len(s)
char = Mid(s,i,1)
If i = Len(s) Then
output = output & symbol_table.IndexOf(char,0)
symbol_table.RemoveAt(symbol_table.LastIndexOf(char))
symbol_table.Insert 0,char
Else
output = output & symbol_table.IndexOf(char,0) & " "
symbol_table.RemoveAt(symbol_table.LastIndexOf(char))
symbol_table.Insert 0,char
End If
Next
mtf_encode = output
End Function
Function mtf_decode(s)
'break the function argument into an array
code = Split(s," ")
'create the array list and populate it with the initial symbol position
Set symbol_table = CreateObject("System.Collections.ArrayList")
For j = 97 To 122 'a to z in decimal.
symbol_table.Add Chr(j)
Next
output = ""
For i = 0 To UBound(code)
char = symbol_table(code(i))
output = output & char
If code(i) <> 0 Then
symbol_table.RemoveAt(symbol_table.LastIndexOf(char))
symbol_table.Insert 0,char
End If
Next
mtf_decode = output
End Function
'Testing the functions
wordlist = Array("broood","bananaaa","hiphophiphop")
For Each word In wordlist
WScript.StdOut.Write word & " encodes as " & mtf_encode(word) & " and decodes as " &_
mtf_decode(mtf_encode(word)) & "."
WScript.StdOut.WriteBlankLines(1)
Next