Run-length encoding: Difference between revisions

m
(→‎Haskell: Added a variant expressed as a fold.)
m (→‎{{header|Wren}}: Minor tidy)
 
(41 intermediate revisions by 20 users not shown)
Line 21:
{{trans|Python}}
 
<langsyntaxhighlight lang="11l">F encode(input_string)
V count = 1
V prev = Char("\0")
Line 44:
V value = encode(‘aaaaahhhhhhmmmmmmmuiiiiiiiaaaaaa’)
print(‘Encoded value is ’value.map(v -> String(v[1])‘’v[0]))
print(‘Decoded value is ’decode(value))</langsyntaxhighlight>
 
{{out}}
Line 55:
Output is in hexadecimal but is otherwise correct.
 
<langsyntaxhighlight lang="asm"> .model small ; 128k .exe file
.stack 1024 ; load SP with 0400h
.data ; no data segment needed
Line 118:
OutputRam byte 256 dup (0)
 
end start</langsyntaxhighlight>
 
{{out}}
Line 131:
 
=={{header|Action!}}==
<langsyntaxhighlight Actionlang="action!">BYTE FUNC GetLength(CHAR ARRAY s BYTE pos)
CHAR c
BYTE len
Line 230:
PrintE("decoded:")
PrintE(decoded)
RETURN</langsyntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Run-length_encoding.png Screenshot from Atari 8-bit computer]
Line 245:
 
=={{header|Ada}}==
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
procedure Test_Run_Length_Encoding is
Line 292:
Put_Line (Encode ("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"));
Put_Line (Decode ("12W1B12W3B24W1B14W"));
end Test_Run_Length_Encoding;</langsyntaxhighlight>
Sample output:
<pre>
Line 307:
 
Note: The following uses iterators, eliminating the need of declaring arbitrarily large CHAR arrays for caching.
<langsyntaxhighlight lang="algol68">STRING input := "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW";
STRING output := "12W1B12W3B24W1B14W";
 
Line 378:
print(c)
# OD # );
print(new line)</langsyntaxhighlight>
Output:
<pre>
Encode input: 12W1B12W3B24W1B14W
Decode output: WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
</pre>
 
=={{header|Amazing Hopper}}==
<syntaxhighlight lang="c">
/*
TASK BASIC-EMBEBIDO de HOPPER
 
onechar("WB",objetivo)
deja un único carcater de todos los que encuentre consecutivamente,
de la lista de caracteres "WB".
índice:=()
copia el valor de la función entre paréntesis en "índice", pero
deja ese valor en el stack de trabajo, para ser asignado a "largo".
poschar(INICIO, v, objetivo)
entrega la posición donde el caracter dado "v" deja de repetirse
(por eso se resta 1 al resultado).
objetivo+=sublargo
borra los primeros sublargo-ésimo caracteres.
#basic{...} / #(...)
BASIC embebido de Hopper.
*/
 
#include <basico.h>
 
#define INICIO 1
#proto codificar(_X_,_Y_,_Z_)
#proto decodificar(_X_,_Y_)
 
principal {
índice="", largo=0, codificado="", decodificado=""
objetivo = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
 
decimales '0', fijar separador 'NULO'
#basic{
largo = len(índice:=( onechar("WB",objetivo) ) )
print ("Original =",objetivo,NL)
 
codificado = codificar(objetivo, índice, largo)
decodificado = decodificar(codificado, índice)
print ("Codificado =",codificado,"\nDecodificado =",decodificado,NL)
}
terminar
}
 
subrutinas
 
codificar( o, i, l)
v="", sublargo=0
para cada caracter ( v, i, l )
/* deja ésto en el stack de trabajo: */
#( sublargo := (poschar(INICIO, v, o) - 1 ) ), 'v'
o+=sublargo
siguiente
unir esto
retornar
 
decodificar(c, i)
v="", posición=0, l=0
#( l=len(i) )
para cada caracter ( v, i, l )
#basic{
posición = find(v, c)-1
/* deja ésto en el stack de trabajo: */
replicate(v, number(copy(posición,1,c)) )
}
++posición,c+=posición
siguiente
unir esto
retornar
 
</syntaxhighlight>
{{out}}
<pre>
Original =WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
Codificado =12W1B12W3B24W1B14W
Decodificado =WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
 
</pre>
 
=={{header|APL}}==
<langsyntaxhighlight APLlang="apl"> ∇ ret←RLL rll;count
[1] count←∣2-/((1,(2≠/rll),1)×⍳1+⍴rll)~0
[2] ret←(⍕count,¨(1,2≠/rll)/rll)~' '
</syntaxhighlight>
</lang>
Sample Output:
<pre>
Line 398 ⟶ 482:
 
=={{header|AppleScript}}==
<langsyntaxhighlight lang="applescript">------------------ RUN-LENGTH ENCODING‎‎ -----------------
 
-- encode :: String -> String
Line 556 ⟶ 640:
end repeat
v
end |until|</langsyntaxhighlight>
{{Out}}
<pre>W12B1W12B3W24B1W14
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
true</pre>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">runlengthEncode: function [s][
join map chunk split s => [&] 'x ->
(to :string size x) ++ first x
]
 
runlengthDecode: function [s][
result: new ""
loop (chunk split s 'x -> positive? size match x {/\d+/}) [a,b] ->
'result ++ repeat first b to :integer join to [:string] a
return result
]
 
str: "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
 
encoded: runlengthEncode str
print ["encoded:" encoded]
 
decoded: runlengthDecode encoded
print ["decoded:" decoded]
 
if decoded=str -> print "\nSuccess!"</syntaxhighlight>
 
{{out}}
 
<pre>encoded: 12W1B12W3B24W1B14W
decoded: WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
 
Success!</pre>
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">MsgBox % key := rle_encode("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW")
MsgBox % rle_decode(key)
 
Line 597 ⟶ 712:
}
Return output
}</langsyntaxhighlight>
 
=={{header|AWK}}==
Line 606 ⟶ 721:
'''Encoding'''
 
<langsyntaxhighlight lang="awk">BEGIN {
FS=""
}
Line 621 ⟶ 736:
}
printf("%d%c", j, cp)
}</langsyntaxhighlight>
 
'''Decoding'''
 
<langsyntaxhighlight lang="awk">BEGIN {
RS="[0-9]+[^0-9]"
final = "";
Line 637 ⟶ 752:
END {
print final
}</langsyntaxhighlight>
 
=={{header|BaCon}}==
<langsyntaxhighlight lang="qbasic">FUNCTION Rle_Encode$(txt$)
 
LOCAL result$, c$ = LEFT$(txt$, 1)
Line 681 ⟶ 796:
encoded$ = Rle_Encode$(rle_data$)
PRINT "Encoded: ", encoded$
PRINT "Decoded: ", Rle_Decode$(encoded$)</langsyntaxhighlight>
{{out}}
<pre>RLEData: WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
Line 694 ⟶ 809:
{{trans|PowerBASIC}}
 
<langsyntaxhighlight lang="qbasic">DECLARE FUNCTION RLDecode$ (i AS STRING)
DECLARE FUNCTION RLEncode$ (i AS STRING)
 
Line 748 ⟶ 863:
outP = outP + tmp2
RLEncode$ = outP
END FUNCTION</langsyntaxhighlight>
 
Sample output (last one shows errors from using numbers in input string):
Line 766 ⟶ 881:
111r
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
==={{header|Applesoft BASIC}}===
 
<syntaxhighlight lang="basic"> 10 I$ = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
20 GOSUB 100ENCODE
30 GOSUB 200DECODE
40 PRINT "INPUT: ";I$
50 PRINT "OUTPUT: ";
60 GOSUB 250 PRINT
70 END
100 O$ = MID$ (I$,1,1):N$ = MID$ ( CHR$ (0),1, LEN (O$)): IF LEN (I$) < 2 THEN RETURN
110 FOR I = 2 TO LEN (I$):C$ = MID$ (I$,I,1): IF C$ < > RIGHT$ (O$,1) THEN O$ = O$ + C$:N$ = N$ + CHR$ (0): NEXT I: RETURN
120 N$ = MID$ (N$,1, LEN (O$) - 1) + CHR$ ( ASC ( MID$ (N$, LEN (O$))) + 1): NEXT I: RETURN
200 I$ = "": IF LEN (O$) THEN FOR I = 1 TO LEN (O$): FOR J = 0 TO ASC ( MID$ (N$,I)):I$ = I$ + MID$ (O$,I,1): NEXT J,I
210 RETURN
250 IF LEN (O$) THEN FOR I = 1 TO LEN (O$): PRINT ASC ( MID$ (N$,I)) + 1; MID$ (O$,I,1);: NEXT I
260 RETURN
</syntaxhighlight>
{{out}}
<pre>INPUT: WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
OUTPUT: 12W1B12W3B24W1B14W</pre>
 
=={{header|BASIC256}}==
<syntaxhighlight lang="basic256">
<lang BASIC256>
function FBString(lon, cad$)
# Definimos la función String en BASIC256
Line 846 ⟶ 981:
print decoded$
end
</syntaxhighlight>
</lang>
{{out}}
La salida es similar a la de [[#BASIC|BASIC]], mostrada arriba.
Line 852 ⟶ 987:
=={{header|BBC BASIC}}==
The run counts are indicated by means of character codes in the range 131 to 255.
<langsyntaxhighlight lang="bbcbasic"> input$ = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
PRINT "Input: " input$
rle$ = FNencodeRLE(input$)
Line 887 ⟶ 1,022:
ENDIF
ENDWHILE
= o$</langsyntaxhighlight>
 
=={{header|Befunge}}==
Line 893 ⟶ 1,028:
Pipe the output of the program-it's more reliable.
{{works with|CCBI|2.1}}
<langsyntaxhighlight Befungelang="befunge"> ~"y"- ~$ v
<temp var for when char changes
format:
Line 918 ⟶ 1,053:
the validity of this program is NOT affected p-
>^
--written by Gamemanj,for Rosettacode</langsyntaxhighlight>
 
=={{header|Bracmat}}==
<langsyntaxhighlight lang="bracmat"> ( run-length
= character otherCharacter acc begin end
. :?acc
Line 942 ⟶ 1,077:
)
& run-length$WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
</syntaxhighlight>
</lang>
<pre> 12W1B12W3B24W1B14W</pre>
 
=={{header|Burlesque}}==
<langsyntaxhighlight lang="burlesque">
"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
=[{^^[~\/L[Sh}\m
</syntaxhighlight>
</lang>
 
=={{header|C}}==
Encoder that can deal with byte streams. Can encode/decode any byte values and any length with reasonable efficiency. Also showing OO and polymophism with structs.
<langsyntaxhighlight Clang="c">#include <stdio.h>
#include <stdlib.h>
 
Line 1,099 ⟶ 1,234:
 
return 0;
}</langsyntaxhighlight>
 
See [[Run-length encoding/C]]
Line 1,106 ⟶ 1,241:
=== Linq ===
<!--Martin Freedman 22/02/2018-->
<langsyntaxhighlight lang="csharp">using System.Collections.Generic;
using System.Linq;
using static System.Console;
Line 1,142 ⟶ 1,277:
}
}
}</langsyntaxhighlight>
Output:
<pre>raw = WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
Line 1,152 ⟶ 1,287:
 
Many solutions do not follow the suggested output guideline in the challenge (not helped by its wording), instead producing a list of tuples or equivalent. This is much simpler (especially for decode) and the following provides an equivalent of those (IMHO deficient) solutions, to make comparisons easier.
<langsyntaxhighlight lang="csharp">using System.Collections.Generic;
using System.Linq;
using static System.Console;
Line 1,181 ⟶ 1,316:
string.Join(",", list.Select(t => $"[{t.i},{t.c}]"));
}
}</langsyntaxhighlight>
Output:
<pre>raw = WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
Line 1,190 ⟶ 1,325:
Stringbuilder version. Might be more performant but mixes output formatting with encoding/decoding logic.
<!--Martin Freedman 22/02/2018-->
<langsyntaxhighlight lang="csharp">using System.Collections.Generic;
using System.Linq;
using static System.Console;
Line 1,225 ⟶ 1,360:
}
}
}</langsyntaxhighlight>
Output:
<pre>raw = WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
Line 1,237 ⟶ 1,372:
This example only works if there are no digits in the string to be encoded and then decoded.
 
<langsyntaxhighlight lang="csharp"> public static void Main(string[] args)
{
string input = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW";
Line 1,285 ⟶ 1,420:
}
return sb.ToString();
}</langsyntaxhighlight>
 
=== RegEx ===
Somewhat shorter, using Regex.Replace with MatchEvaluator (using C#2 syntax only):
<langsyntaxhighlight lang="csharp">using System;
using System.Text.RegularExpressions;
 
Line 1,325 ⟶ 1,460:
});
}
}</langsyntaxhighlight>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <algorithm>
#include <array>
#include <iterator>
Line 1,489 ⟶ 1,624:
std::cout.setf(std::cout.boolalpha);
std::cout << "Round trip works: " << (test_string == decoded_str) << '\n';
}</langsyntaxhighlight>
 
{{libheader|boost}}
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <string>
#include <sstream>
Line 1,544 ⟶ 1,679:
}
return oss.str( ) ;
}</langsyntaxhighlight>
 
=={{header|Ceylon}}==
<langsyntaxhighlight lang="ceylon">shared void run() {
"Takes a string such as aaaabbbbbbcc and returns 4a6b2c"
Line 1,577 ⟶ 1,712:
assert (compress("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW") == "12W1B12W3B24W1B14W");
assert (decompress("24a") == "aaaaaaaaaaaaaaaaaaaaaaaa");
}</langsyntaxhighlight>
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">(defn compress [s]
(->> (partition-by identity s) (mapcat (juxt count first)) (apply str)))
 
Line 1,586 ⟶ 1,721:
(->> (re-seq #"(\d+)([A-Z])" s)
(mapcat (fn [[_ n ch]] (repeat (Integer/parseInt n) ch)))
(apply str)))</langsyntaxhighlight>
 
=={{header|COBOL}}==
{{works with|GNU Cobol|2.0}}
<langsyntaxhighlight lang="cobol"> >>SOURCE FREE
IDENTIFICATION DIVISION.
PROGRAM-ID. run-length-encoding.
Line 1,713 ⟶ 1,848:
END-PERFORM
.
END FUNCTION decode.</langsyntaxhighlight>
 
{{out}}
Line 1,724 ⟶ 1,859:
=={{header|CoffeeScript}}==
 
<langsyntaxhighlight lang="coffeescript">encode = (str) ->
str.replace /(.)\1*/g, (w) ->
w[0] + w.length
Line 1,734 ⟶ 1,869:
console.log s = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
console.log encode s
console.log decode encode s</langsyntaxhighlight>
 
<pre>
Line 1,744 ⟶ 1,879:
The following version encodes the number of ocurrences as an unicode character. You can change the way it looks by rotating the offset.
 
<langsyntaxhighlight lang="coffeescript">encode = (str, offset = 75) ->
str.replace /(.)\1*/g, (w) ->
w[0] + String.fromCharCode(offset+w.length)
Line 1,751 ⟶ 1,886:
str.split('').map((w,i) ->
if not (i%2) then w else new Array(+w.charCodeAt(0)-offset).join(str[i-1])
).join('')</langsyntaxhighlight>
 
<pre>
Line 1,763 ⟶ 1,898:
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun group-similar (sequence &key (test 'eql))
(loop for x in (rest sequence)
with temp = (subseq sequence 0 1)
Line 1,785 ⟶ 1,920:
 
(run-length-encode "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW")
(run-length-decode '((#\W 12) (#\B 1) (#\W 12) (#\B 3) (#\W 24) (#\B 1)))</langsyntaxhighlight>
 
=={{header|D}}==
===Short Functional Version===
<langsyntaxhighlight lang="d">import std.algorithm, std.array;
 
alias encode = group;
Line 1,801 ⟶ 1,936:
"WWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW";
assert(s.encode.decode.equal(s));
}</langsyntaxhighlight>
 
===Basic Imperative Version===
<langsyntaxhighlight lang="d">import std.stdio, std.array, std.conv;
 
// Similar to the 'look and say' function.
Line 1,856 ⟶ 1,991:
writeln("Encoded: ", encoded);
assert(txt == encoded.decode);
}</langsyntaxhighlight>
{{out}}
<pre>Input: WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
Line 1,864 ⟶ 1,999:
D's native string is utf-encoded. This version works for utf string, and uses a [[Variable-length_quantity|Variable-length Quantity]] [[Variable-length_quantity#D|module]].
 
<langsyntaxhighlight lang="d">import std.stdio, std.conv, std.utf, std.array;
import vlq;
 
Line 1,942 ⟶ 2,077:
auto sEncoded = RLE.init.encode(s).encoded ;
assert(s == RLE(sEncoded).decode(), "Not work");
}</langsyntaxhighlight>
 
output from "display.txt":
Line 1,963 ⟶ 2,098:
 
The code looks more complex than the third Python version because this also handles digits by escaping them with #.
<langsyntaxhighlight lang="d">import std.stdio, std.conv, std.array, std.regex, std.utf,
std.algorithm;
 
Line 1,994 ⟶ 2,129:
"11#222##333";
assert(s == reDecode(reEncode(s)));
}</langsyntaxhighlight>
 
=={{header|Déjà Vu}}==
<langsyntaxhighlight lang="dejavu">rle:
if not dup:
drop
Line 2,025 ⟶ 2,160:
rle "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
!. dup
!. rld</langsyntaxhighlight>
{{out}}
<pre>[ & 12 "W" & 1 "B" & 12 "W" & 3 "B" & 24 "W" & 1 "B" & 14 "W" ]
Line 2,031 ⟶ 2,166:
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
<syntaxhighlight lang="delphi">
<lang Delphi>
program RunLengthTest;
 
Line 2,127 ⟶ 2,262:
writeln(Data.Decode);
Readln;
end.</langsyntaxhighlight>
{{out}}
<pre>
Line 2,136 ⟶ 2,271:
=={{header|E}}==
 
<langsyntaxhighlight lang="e">def rle(string) {
var seen := null
var count := 0
Line 2,163 ⟶ 2,298:
}
return result
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="e">? rle("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW")
# value: [[12, 'W'], [1, 'B'], [12, 'W'], [3, 'B'], [24, 'W'], [1, 'B'], [14, 'W']]
 
? unrle(rle("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"))
# value: "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"</langsyntaxhighlight>
 
=={{header|EasyLang}}==
 
<syntaxhighlight lang="easylang">
func$ rlenc in$ .
for c$ in strchars in$
if c$ = c0$
cnt += 1
else
if cnt > 0
out$ &= cnt & c0$ & " "
.
c0$ = c$
cnt = 1
.
.
out$ &= cnt & c0$
return out$
.
func$ rldec in$ .
for h$ in strsplit in$ " "
c$ = substr h$ len h$ 1
for i to number h$
out$ &= c$
.
.
return out$
.
s$ = input
print s$
s$ = rlenc s$
print s$
s$ = rldec s$
print s$
#
input_data
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
 
</syntaxhighlight>
 
=={{header|Elena}}==
ELENA 46.x :
<langsyntaxhighlight lang="elena">import system'text;
import system'routines;
import extensions;
Line 2,185 ⟶ 2,359:
int count := 0;
char current := s[0];
s.forEach::(ch)
{
if (ch == current)
Line 2,209 ⟶ 2,383:
char current := $0;
var a := new StringWriter();
s.forEach::(ch)
{
current := ch;
Line 2,238 ⟶ 2,412:
s := compressor.decompress(s);
console.printLine(s)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,246 ⟶ 2,420:
 
=={{header|Elixir}}==
<langsyntaxhighlight lang="elixir">defmodule Run_length do
def encode(str) when is_bitstring(str) do
to_char_list(str) |> encode |> to_string
Line 2,272 ⟶ 2,446:
|> Run_length.encode |> IO.inspect
|> Run_length.decode |> IO.inspect
end)</langsyntaxhighlight>
 
{{out}}
Line 2,286 ⟶ 2,460:
 
=={{header|Emacs Lisp}}==
<langsyntaxhighlight lang="lisp">(defun run-length-encode (str)
(let (output)
(with-temp-buffer
Line 2,295 ⟶ 2,469:
(count (skip-chars-forward (string char))))
(push (format "%d%c" count char) output))))
(mapconcat #'identity (nreverse output) "")))</langsyntaxhighlight>
 
{{libheader|seq.el}}
<langsyntaxhighlight lang="lisp">(require 'seq)
 
(defun run-length-encode (str)
Line 2,304 ⟶ 2,478:
(apply #'concat (mapcar (lambda (items)
(format "%d%c" (length items) (car items)))
grouped))))</langsyntaxhighlight>
 
=={{header|Erlang}}==
Line 2,310 ⟶ 2,484:
A single-threaded/process version with a simple set of unit test.
 
<langsyntaxhighlight lang="erlang">-module(rle).
 
-export([encode/1,decode/1]).
Line 2,355 ⟶ 2,529:
?_assert(decode(Expected) =:= PreEncoded),
?_assert(decode(encode(PreEncoded)) =:= PreEncoded)
].</langsyntaxhighlight>
 
A version that works on character lists:
 
<langsyntaxhighlight lang="erlang">
-module(rle).
 
Line 2,380 ⟶ 2,554:
decode([{Count, Char}|T], Acc) ->
decode(T, [[Char || _ <- lists:seq(1, Count)]|Acc]).
</syntaxhighlight>
</lang>
 
=={{header|Euphoria}}==
<langsyntaxhighlight lang="euphoria">include misc.e
 
function encode(sequence s)
Line 2,420 ⟶ 2,594:
pretty_print(1,s,{3})
puts(1,'\n')
puts(1,decode(s))</langsyntaxhighlight>
 
Output:
Line 2,427 ⟶ 2,601:
 
=={{header|F Sharp|F#}}==
<langsyntaxhighlight lang="fsharp">
open System
open System.Text.RegularExpressions
Line 2,446 ⟶ 2,620:
|> List.map (fun m -> Int32.Parse(m.Groups.[1].Value), m.Groups.[2].Value)
|> List.fold (fun acc (len, s) -> acc + String.replicate len s) ""
</syntaxhighlight>
</lang>
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: io kernel literals math.parser math.ranges sequences
sequences.extras sequences.repeating splitting.extras
splitting.monotonic strings ;
Line 2,466 ⟶ 2,640:
"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
"12W1B12W3B24W1B14W"
[ encode ] [ decode ] bi* [ print ] bi@</langsyntaxhighlight>
{{out}}
<pre>
Line 2,474 ⟶ 2,648:
 
=={{header|FALSE}}==
<langsyntaxhighlight lang="false">1^[^$~][$@$@=$[%%\1+\$0~]?~[@.,1\$]?%]#%\., {encode}</langsyntaxhighlight>
<langsyntaxhighlight lang="false">[0[^$$'9>'0@>|~]['0-\10*+]#]n:
[n;!$~][[\$][1-\$,]#%%]#%% {decode}</langsyntaxhighlight>
 
=={{header|Fan}}==
<syntaxhighlight lang="fan">**
<lang Fan>**
** Generates a run-length encoding for a string
**
Line 2,525 ⟶ 2,699:
 
override Str toStr() { return "${count}${char.toChar}" }
}</langsyntaxhighlight>
 
=={{header|Forth}}==
<langsyntaxhighlight lang="forth">variable a
: n>a (.) tuck a @ swap move a +! ;
: >a a @ c! 1 a +! ;
Line 2,542 ⟶ 2,716:
i c@ digit? if 10 * i c@ [char] 0 - + else
a @ over i c@ fill a +! 0 then
loop drop a @ over - ;</langsyntaxhighlight>
 
Example:
 
<langsyntaxhighlight lang="forth">s" WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
here 1000 + encode here 2000 + decode cr 3 spaces type
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW</langsyntaxhighlight>
 
=={{header|Fortran}}==
{{works with|Fortran|95 and later}}
<langsyntaxhighlight lang="fortran">program RLE
implicit none
 
Line 2,610 ⟶ 2,784:
end do
end subroutine
end program</langsyntaxhighlight>
 
Output:
Line 2,619 ⟶ 2,793:
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">
Dim As String initial, encoded, decoded
 
Line 2,674 ⟶ 2,848:
Print decoded
End
</syntaxhighlight>
</lang>
{{out}}
La salida es similar a la de [[#BASIC|BASIC]], mostrada arriba.
 
=={{header|FutureBasic}}==
This gives RLE encoding for strings and RLE decoding for strings and arrays, e.g., for [[Conway's_Game_of_Life|Conway's Game of Life]]
<syntaxhighlight lang=FutureBasic>
 
local fn encode( string as CFStringRef) as CFStringRef
CFStringRef ch, s, t
Short i, rl
s = @"" // Initalize the output string
for i = 0 to len( string ) - 1 // Encode string char by char
ch = mid( string, i, 1) // Read character at index
rl = 1 // Start run-length counter
while fn StringIsEqual( mid( string, i + rl, 1), ch )
rl ++ // Same char, so increase counter
wend
if rl == 1 then t = @"" else t = fn StringWithFormat( @"%d", rl ) // Counter as string, don't encode 1's
t = fn StringByAppendingString( t, ch ) // Add character
s = fn StringByAppendingString( s, t ) // Add to already encoded string
i += rl - 1 // Move index
next
print s
end fn
 
 
local fn decode( string as CFStringRef )
CFStringRef ch, s, t // character, outputstring, temporary string
Short i, rl // index, run length
s = @"" // Initalize the output string
for i = 0 to len( string ) - 1 // Decode input string char by char
ch = mid( string, i, 1 ) // Read character at index
if intval( ch ) == 0 // Not a digit
rl = 1
else
rl = intval( mid( string, i ) ) // Read run-length
i += fix( log10( rl ) + 1 ) // Move index past digits
ch = mid( string, i, 1 ) // Read character after run length
end if
t = fn StringByPaddingToLength( ch, rl, ch, 0 ) // Assemble temp string
s = fn StringByAppendingString( s, t ) // Add to decoded string
next
print s
end fn
 
 
local fn decode2D( string as CFStringRef ) // For Conway's Game of Life objects
Boolean a(500, 500) // Or larger to hold bigger life forms
CFStringRef ch
Short i, j, rl, f // Decoded char
Short v = 0, w = 0, x = 0, y = 0 // Temp width, max width, array coordinates
for i = 0 to len( string ) - 2 // Final char is always !
ch = mid( string, i, 1 )
if intval( ch ) == 0
rl = 1
else
rl = intval( mid( string, i ) )
i += fix( log10( rl ) + 1 )
ch = mid( string, i, 1 )
end if
select ch // Decode character as:
case @"$" : f = -1 // - new line
case @"b" : f = 0 // - dead
case @"o" : f = 1 // - live
case else : // Ignore
end select
for j = 1 to rl // Fill array with run of chars
if f = -1
x = 0 : y ++ : v = 0 // New line
else
a(x, y) = f
x ++ : v ++ : if v > w then w = v
end if
next
next
for j = 0 to y : for i = 0 to w - 1
print a(i, j);
next : print : next
end fn
 
fn decode( @"12W1B12W3B24W1B14W" ) // Assignment
fn encode( @"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW" )
fn decode2D( @"bo$2bo$3o!" ) // Glider
 
handleevents // Join Mac event loop
 
</syntaxhighlight>
Output:
<pre>
 
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
12WB12W3B24WB14W
011
001
111
 
</pre>
 
=={{header|Gambas}}==
'''[https://gambas-playground.proko.eu/?gist=b30707043cb64effba91a2edc4d4be94 Click this link to run this code]'''
<langsyntaxhighlight lang="gambas">Public Sub Main()
Dim sString As String = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
Dim siCount As Short = 1
Line 2,702 ⟶ 2,971:
Print sString & gb.NewLine & sHold.Join(", ")
 
End</langsyntaxhighlight>
Output:
<pre>
Line 2,711 ⟶ 2,980:
=={{header|Go}}==
Decoder kind of necessary to demonstrate task requirement that I can recreate the input.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 2,781 ⟶ 3,050:
}
return string(d)
}</langsyntaxhighlight>
Output:
<pre>
Line 2,791 ⟶ 3,060:
 
=={{header|Groovy}}==
<langsyntaxhighlight lang="groovy">def rleEncode(text) {
def encoded = new StringBuilder()
(text =~ /(([A-Z])\2*)/).each { matcher ->
Line 2,805 ⟶ 3,074:
}
decoded.toString()
}</langsyntaxhighlight>
Test code
<langsyntaxhighlight lang="groovy">def text = 'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW'
def rleEncoded = rleEncode(text)
assert rleEncoded == '12W1B12W3B24W1B14W'
Line 2,813 ⟶ 3,082:
 
println "Original Text: $text"
println "Encoded Text: $rleEncoded"</langsyntaxhighlight>
Output:
<pre>Original Text: WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
Line 2,820 ⟶ 3,089:
=={{header|Haskell}}==
===In terms of group===
<langsyntaxhighlight lang="haskell">import Data.List (group)
 
-- Datatypes
Line 2,841 ⟶ 3,110:
encoded = rlencode input
decoded = rldecode encoded
putStrLn $ "Encoded: " <> show encoded <> "\nDecoded: " <> show decoded</langsyntaxhighlight>
{{Out}}
<pre>Encoded: [(12,'W'),(1,'B'),(12,'W'),(3,'B'),(24,'W'),(1,'B'),(14,'W')]
Line 2,847 ⟶ 3,116:
 
Or:
<langsyntaxhighlight Haskelllang="haskell">import Data.Char (isDigit)
import Data.List (group, groupBy)
 
Line 2,872 ⟶ 3,141:
decode = runLengthDecode encode
mapM_ putStrLn [text, encode, decode]
putStrLn $ "test: text == decode => " <> show (text == decode)</langsyntaxhighlight>
{{out}}
<pre>WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
Line 2,880 ⟶ 3,149:
 
===In terms of span===
<langsyntaxhighlight lang="haskell">import Data.Char (isDigit)
import Data.List (span)
 
Line 2,904 ⟶ 3,173:
src = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
encoded = encode src
decoded = decode encoded</langsyntaxhighlight>
{{Out}}
<pre>W12B1W12B3W24B1W14
Line 2,911 ⟶ 3,180:
 
===As a fold===
<syntaxhighlight lang="haskell">----------------------- RUN LENGTHS ----------------------
<lang haskell>import Data.Bifunctor (first)
 
----------------------- RUN LENGTHS ----------------------
 
runLengths :: String -> [(Int, Char)]
runLengths "" = []
runLengths s = uncurry (:) (foldr go ((0, ' '), []) s)
where
let go c ("", xs) = ([c], xs)
go c (cs@(x0, :_), runxs) = ((1, c), xs)
|go c ==((n, x = (c : cs), xs)
| c |== otherwisex = ([c], (lengthsucc csn, x) :, xs)
| otherwise = ((1, c), (n, x) : xs)
in uncurry
(:)
( first
((,) . length <*> head)
(foldr go ("", []) s)
)
 
--------------------------- TEST -------------------------
Line 2,933 ⟶ 3,195:
main = do
let testString =
"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWW"
"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWW"
<> "WWWWWWWWWWBWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
encoded = runLengths testString
putStrLn $ showLengths encoded
print $
print $ concatMap (uncurry replicate) encoded == testString
concatMap (uncurry replicate) encoded == testString
 
------------------------- DISPLAY ------------------------
showLengths :: [(Int, Char)] -> String
showLengths [] = []
showLengths ((n, c) : xs) = show n <> [c] <> showLengths xs</langsyntaxhighlight>
{{Out}}
<pre>12W1B12W3B24W1B14W
Line 2,948 ⟶ 3,211:
 
=={{header|Icon}} and {{header|Unicon}}==
<langsyntaxhighlight Iconlang="icon">procedure main(arglist)
 
s := "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
Line 2,974 ⟶ 3,237:
procedure Repl(n, c)
return repl(c,n)
end</langsyntaxhighlight>
 
Sample output:
Line 2,984 ⟶ 3,247:
=={{header|J}}==
'''Solution:'''
<langsyntaxhighlight lang="j">rle=: ;@(<@(":@(#-.1:),{.);.1~ 1, 2 ~:/\ ])
rld=: ;@(-.@e.&'0123456789' <@({:#~1{.@,~".@}:);.2 ])</langsyntaxhighlight>
 
'''Example:'''
<langsyntaxhighlight lang="j"> rle 'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW'
12W1B12W3B24W1B14W
 
rld '12W1B12W3B24W1B14W'
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW</langsyntaxhighlight>
 
Note that this implementation fails for the empty case. Here's a version that fixes that:
 
<langsyntaxhighlight lang="j">rle=: ;@(<@(":@#,{.);.1~ 2 ~:/\ (a.{.@-.{.),])</langsyntaxhighlight>
 
Other approaches include using <nowiki>rle ::(''"_)</nowiki> or <nowiki>rle^:(*@#)</nowiki> or equivalent variations on the original sentence.
Line 3,004 ⟶ 3,267:
A numeric approach, based on a discussion in the J forums (primarily [http://jsoftware.com/pipermail/programming/2015-June/042139.html Pascal Jasmin] and [http://jsoftware.com/pipermail/programming/2015-June/042141.html Marshall Lochbaum]):
 
<langsyntaxhighlight lang="j"> torle=: (#, {.);.1~ 1,2 ~:/\ ]
frle=: #/@|:</langsyntaxhighlight>
 
Task example:
 
<langsyntaxhighlight lang="j"> torle a.i.'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW'
12 87
1 66
Line 3,018 ⟶ 3,281:
14 87
u: frle torle a.i.'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW'
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW</langsyntaxhighlight>
 
Note that this approach also fails on the empty case.
 
=={{header|Java}}==
This can be achieved using regular expression capturing
<lang java>import java.util.regex.Matcher;
<syntaxhighlight lang="java">
import java.util.regex.Matcher;
import java.util.regex.Pattern;
</syntaxhighlight>
<syntaxhighlight lang="java">
String encode(String string) {
Pattern pattern = Pattern.compile("(.)\\1*");
Matcher matcher = pattern.matcher(string);
StringBuilder encoded = new StringBuilder();
while (matcher.find()) {
encoded.append(matcher.group().length());
encoded.append(matcher.group().charAt(0));
}
return encoded.toString();
}
</syntaxhighlight>
<syntaxhighlight lang="java">
String decode(String string) {
Pattern pattern = Pattern.compile("(\\d+)(.)");
Matcher matcher = pattern.matcher(string);
StringBuilder decoded = new StringBuilder();
int count;
while (matcher.find()) {
count = Integer.parseInt(matcher.group(1));
decoded.append(matcher.group(2).repeat(count));
}
return decoded.toString();
}
</syntaxhighlight>
<pre>
string = WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
encoded = 12W1B12W3B24W1B14W
decoded = WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
string.equals(decoded) = true
 
string = https://www.rosettacode.org/
encoded = 1h2t1p1s1:2/3w1.1r1o1s1e2t1a1c1o1d1e1.1o1r1g1/
decoded = https://www.rosettacode.org/
string.equals(decoded) = true
</pre>
<br />
An alternate demonstration
<syntaxhighlight lang="java">import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RunLengthEncoding {
Line 3,060 ⟶ 3,366:
System.out.println(decode("1W1B1W1B1W1B1W1B1W1B1W1B1W1B"));
}
}</langsyntaxhighlight>
Tests:
 
{{libheader|JUnit}}
<langsyntaxhighlight lang="java">import static org.junit.Assert.assertEquals;
 
import org.junit.Test;
Line 3,095 ⟶ 3,401:
 
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
===ES5===
Here's an encoding method that walks the input string character by character
<langsyntaxhighlight lang="javascript">function encode(input) {
var encoding = [];
var prev, count, i;
Line 3,114 ⟶ 3,420:
encoding.push([count, prev]);
return encoding;
}</langsyntaxhighlight>
 
Here's an encoding method that uses a regular expression to grab the character runs ({{works with|JavaScript|1.6}} for the <code>forEach</code> method)
<langsyntaxhighlight lang="javascript">function encode_re(input) {
var encoding = [];
input.match(/(.)\1*/g).forEach(function(substr){ encoding.push([substr.length, substr[0]]) });
return encoding;
}</langsyntaxhighlight>
 
And to decode (see [[Repeating a string#JavaScript|Repeating a string]])
<langsyntaxhighlight lang="javascript">function decode(encoded) {
var output = "";
encoded.forEach(function(pair){ output += new Array(1+pair[0]).join(pair[1]) })
return output;
}</langsyntaxhighlight>
 
===ES6===
By defining a generic ''group'' function:
<langsyntaxhighlight lang="javascript">(() => {
'use strict';
 
Line 3,182 ⟶ 3,488:
// MAIN ---
return main();
})();</langsyntaxhighlight>
{{Out}}
<pre>From: "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
Line 3,189 ⟶ 3,495:
 
A <code>.reduce()</code> based one-liner
<langsyntaxhighlight lang="javascript">
const rlEncode = (s: string) => s.match(/(.)\1*/g).reduce((result,char) => result+char.length+char[0],"")
const rlValidate = (s: string) => /^(\d+\D)+$/.test(s)
const rlDecode = (s: string) => rlValidate(s) ? s.match(/(\d[a-z\s])\1*/ig).reduce((res,p) => res+p[p.length-1].repeat(parseInt(p)),"") : Error("Invalid rl")
</syntaxhighlight>
</lang>
 
=={{header|jq}}==
Line 3,199 ⟶ 3,505:
 
'''Utility function:'''
<langsyntaxhighlight lang="jq">def runs:
reduce .[] as $item
( [];
Line 3,207 ⟶ 3,513:
else . + [[$item, 1]]
end
end ) ;</langsyntaxhighlight>
'''Run-length encoding and decoding''':
<langsyntaxhighlight lang="jq">def run_length_encode:
explode | runs | reduce .[] as $x (""; . + "\($x[1])\([$x[0]]|implode)");
 
Line 3,217 ⟶ 3,523:
($pair[0:-1] | tonumber) as $n
| $pair[-1:] as $letter
| . + ($n * $letter)) ;</langsyntaxhighlight>
'''Example''':
<langsyntaxhighlight lang="jq">"ABBCCC" | run_length_encode | run_length_decode</langsyntaxhighlight>
{{out}}
<langsyntaxhighlight lang="sh">$ jq -n -f Run_length_encoding.jq
"ABBCCC"</langsyntaxhighlight>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<langsyntaxhighlight lang="julia">using IterTools
 
encode(str::String) = collect((length(g), first(g)) for g in groupby(first, str))
Line 3,236 ⟶ 3,542:
decoded = decode(encoded)
println("Original: $original\n -> encoded: $encoded\n -> decoded: $decoded")
end</langsyntaxhighlight>
 
{{out}}
Line 3,248 ⟶ 3,554:
=={{header|K}}==
 
<langsyntaxhighlight lang="k">rle: {,/($-':i,#x),'x@i:&1,~=':x}</langsyntaxhighlight>
 
{{trans|J}}
 
<langsyntaxhighlight lang="k">rld: {d:"0123456789"; ,/(.(d," ")@d?/:x)#'x _dvl d}</langsyntaxhighlight>
 
'''Example:'''
 
<langsyntaxhighlight lang="k"> rle "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
"12W1B12W3B24W1B14W"
rld "12W1B12W3B24W1B14W"
"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"</langsyntaxhighlight>
 
=={{header|Kotlin}}==
Tail recursive implementation of Run Length Encoding
<langsyntaxhighlight lang="scala">tailrec fun runLengthEncoding(text:String,prev:String=""):String {
if (text.isEmpty()){
return prev
Line 3,276 ⟶ 3,582:
assert(runLengthEncoding("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW")
== "12W1B12W3B24W1B14W")
}</langsyntaxhighlight>
 
=={{header|Lasso}}==
<langsyntaxhighlight Lassolang="lasso">define rle(str::string)::string => {
local(orig = #str->values->asCopy,newi=array, newc=array, compiled=string)
while(#orig->size) => {
Line 3,325 ⟶ 3,631:
 
rlde('12W1B12W3B24W1B14W')
rlde('1d1s1f1k1j2h1k1d1s1j1f1h1d1s1k1h1s1h1d2j1f2h1d1l1s2l1w')</langsyntaxhighlight>
 
{{out}}
Line 3,336 ⟶ 3,642:
 
=={{header|Liberty BASIC}}==
<langsyntaxhighlight lang="lb">mainwin 100 20
 
'In$ ="aaaaaaaaaaaaaaaaaccbbbbbbbbbbbbbbba" ' testing...
Line 3,383 ⟶ 3,689:
next i
Decoded$ =r$
end function</langsyntaxhighlight>
 
=={{header|LiveCode}}==
<langsyntaxhighlight LiveCodelang="livecode">function rlEncode str
local charCount
put 1 into charCount
Line 3,428 ⟶ 3,734:
end repeat
return repStr
end repeatString</langsyntaxhighlight>
 
=={{header|Logo}}==
<langsyntaxhighlight lang="logo">to encode :str [:out "||] [:count 0] [:last first :str]
if empty? :str [output (word :out :count :last)]
if equal? first :str :last [output (encode bf :str :out :count+1 :last)]
Line 3,448 ⟶ 3,754:
make "foo "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
make "rle encode :foo
show equal? :foo decode :rle</langsyntaxhighlight>
 
=={{header|Lua}}==
 
<langsyntaxhighlight lang="lua">local C, Ct, R, Cf, Cc = lpeg.C, lpeg.Ct, lpeg.R, lpeg.Cf, lpeg.Cc
astable = Ct(C(1)^0)
 
Line 3,482 ⟶ 3,788:
end
return ret
end</langsyntaxhighlight>
 
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module RLE_example {
inp$="WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
Line 3,519 ⟶ 3,825:
}
RLE_example
</syntaxhighlight>
</lang>
 
{{out}}
Line 3,532 ⟶ 3,838:
The function
 
<langsyntaxhighlight Mathematicalang="mathematica">RunLengthEncode[input_String]:= (l |-> {First@l, Length@l}) /@ (Split@Characters@input)</langsyntaxhighlight>
 
takes as input an arbitrary string of characters and returns a list of {c, n} pairs, where c is the character and n is the number of repeats. The function
 
<langsyntaxhighlight Mathematicalang="mathematica">RunLengthDecode[input_List]:= ConstantArray @@@ input // Flatten // StringJoin</langsyntaxhighlight>
 
recreates the string.
Line 3,542 ⟶ 3,848:
Example: For the string
 
<langsyntaxhighlight Mathematicalang="mathematica">mystring="WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW";</langsyntaxhighlight>
 
here is the run-length encoding:
 
<langsyntaxhighlight Mathematicalang="mathematica">rle = RunLengthEncode[mystring]
 
{{"W", 12}, {"B", 1}, {"W", 12}, {"B", 3}, {"W", 24}, {"B", 1}, {"W", 14}}</langsyntaxhighlight>
 
Check that the input string is recreated:
 
<langsyntaxhighlight Mathematicalang="mathematica">mystring == RunLengthDecode[rle]
 
True</langsyntaxhighlight>
 
=={{header|Maxima}}==
To encode
<lang maxima>rle(a) := block(
<syntaxhighlight lang="maxima">rle(a) := block(
[n: slength(a), b: "", c: charat(a, 1), k: 1],
for i from 2 thru n do
Line 3,563 ⟶ 3,870:
sconcat(b, k, c)
)$
</syntaxhighlight>
To decode
<syntaxhighlight lang="maxima">
 
/* Function to return a list where all but the last entries are integers */
intbucket(lst):=block(bucket:[],while integerp(first(lst)) do (push(first(lst),bucket),lst:rest(lst)),lst:append(reverse(bucket),[first(lst)]));
 
/* Run-length decoding */
rld(string_list):=block(
coref:map(eval_string,charlist(string_list)),
listcharact:sublist(coref,lambda([x],integerp(x)=false)),
map(intbucket,append([coref],makelist(coref:rest(coref,length(intbucket(coref))),length(listcharact)-1))),
makelist(sublist(%%[i],integerp),i,1,length(%%)),
map(eval_string,makelist(apply(concat,%%[i]),i,1,length(%%))),
makelist(smake(%%[i],string(listcharact[i])),i,1,length(listcharact)),
apply(concat,%%));
</syntaxhighlight>
 
Output
<syntaxhighlight lang="maxima">
rle("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW");
"12W1B12W3B24W1B14W"</lang>
rld(%);
/* "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW" */
</syntaxhighlight>
 
=={{header|MMIX}}==
<langsyntaxhighlight lang="mmix"> LOC Data_Segment
GREG @
Buf OCTA 0,0,0,0 integer print buffer
Line 3,677 ⟶ 4,006:
2H SET $4,#a print NL
GO $127,PChar
TRAP 0,Halt,0 EXIT</langsyntaxhighlight>
Example run encode --> decode:
<pre>~/MIX/MMIX/Rosetta> mmix rle
Line 3,685 ⟶ 4,014:
=={{header|Nim}}==
{{trans|Python}}
<langsyntaxhighlight lang="nim">import parseutils, strutils
 
proc compress(input: string): string =
Line 3,720 ⟶ 4,049:
let compressed = Text.compress()
echo "Compressed: ", compressed
echo "Uncompressed: ", compressed.uncompress()</langsyntaxhighlight>
 
{{out}}
Line 3,728 ⟶ 4,057:
 
=={{header|Objeck}}==
<langsyntaxhighlight lang="objeck">use RegEx;
 
class RunLengthEncoding {
Line 3,779 ⟶ 4,108:
return output;
}
}</langsyntaxhighlight>
 
<pre>encoding: 12W1B12W3B24W1B14W
Line 3,789 ⟶ 4,118:
 
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml">let encode str =
let len = String.length str in
let rec aux i acc =
Line 3,811 ⟶ 4,140:
let decode lst =
let l = List.map (fun (c,n) -> String.make n c) lst in
(String.concat "" l)</langsyntaxhighlight>
 
<langsyntaxhighlight lang="ocaml">let () =
let e = encode "aaaaahhhhhhmmmmmmmuiiiiiiiaaaaaa" in
List.iter (fun (c,n) ->
Line 3,819 ⟶ 4,148:
) e;
print_endline (decode [('a', 5); ('h', 6); ('m', 7); ('u', 1); ('i', 7); ('a', 6)]);
;;</langsyntaxhighlight>
 
;Using regular expressions
<langsyntaxhighlight lang="ocaml">#load "str.cma";;
 
open Str
Line 3,838 ⟶ 4,167:
let () =
print_endline (encode "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW");
print_endline (decode "12W1B12W3B24W1B14W");</langsyntaxhighlight>
 
=={{header|Oforth}}==
 
<langsyntaxhighlight Oforthlang="oforth">: encode(s)
StringBuffer new
s group apply(#[ tuck size asString << swap first <<c ]) ;
Line 3,853 ⟶ 4,182:
loop: i [ c <<c ] 0
]
drop ;</langsyntaxhighlight>
 
{{out}}
Line 3,865 ⟶ 4,194:
</pre>
 
=={{header|Ol}}==
<syntaxhighlight lang="scheme">
(define (RLE str)
(define iter (string->list str))
(let loop ((iter iter) (chr (car iter)) (n 0) (rle '()))
(cond
((null? iter)
(reverse (cons (cons n chr) rle)))
((char=? chr (car iter))
(loop (cdr iter) chr (+ n 1) rle))
(else
(loop (cdr iter) (car iter) 1 (cons (cons n chr) rle))))))
 
(define (decode rle)
(apply string-append (map (lambda (p)
(make-string (car p) (cdr p))) rle)))
</syntaxhighlight>
Test:
<syntaxhighlight lang="scheme">
(define str "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW")
(print str)
 
(define rle (RLE str))
(for-each (lambda (pair)
(print (car pair) " : " (string (cdr pair))))
rle)
(print (decode rle))
</syntaxhighlight>
{{Out}}
<pre>
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
12 : W
1 : B
12 : W
3 : B
24 : W
1 : B
14 : W
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
</pre>
=={{header|Oz}}==
<langsyntaxhighlight lang="oz">declare
fun {RLEncode Xs}
for G in {Group Xs} collect:C do
Line 3,902 ⟶ 4,271:
{System.showInfo Data}
{Show Enc}
{System.showInfo {RLDecode Enc}}</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">rle(s)={
if(s=="", return(s));
my(v=Vec(s),cur=v[1],ct=1,out="");
Line 3,935 ⟶ 4,304:
};
rle("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW")
elr(%)</langsyntaxhighlight>
Output:
<pre>%1 = "12W1B12W3B24W1B14W"
Line 3,942 ⟶ 4,311:
 
=={{header|Pascal}}==
<langsyntaxhighlight lang="pascal">Program RunLengthEncoding(output);
procedure encode(s: string; var counts: array of integer; var letters: string);
Line 3,992 ⟶ 4,361:
decode(s, counts, letters);
writeln(s);
end.</langsyntaxhighlight>
Output:
<pre>:> ./RunLengthEncoding
Line 4,004 ⟶ 4,373:
Simple version using ASCII numerals as length markers, like the example in the task description (won't work correctly on input strings that already contain digits):
 
<langsyntaxhighlight lang="perl">sub encode {
shift =~ s/(.)\1*/length($&).$1/grse;
}
Line 4,010 ⟶ 4,379:
sub decode {
shift =~ s/(\d+)(.)/$2 x $1/grse;
}</langsyntaxhighlight>
 
Modified version that can take arbitrary byte strings as input (produces encoded byte strings that are compatible with the [[#C|C solution]]):
 
<langsyntaxhighlight lang="perl">sub encode {
shift =~ s/(.)\1{0,254}/pack("C", length($&)).$1/grse;
}
Line 4,020 ⟶ 4,389:
sub decode {
shift =~ s/(.)(.)/$2 x unpack("C", $1)/grse;
}</langsyntaxhighlight>
 
Further modified version that supports compact representation of longer non-repeating substrings, just like the [[#C|C solution]] (so should be fully compatible with that solution for both encoding and decoding):
 
<langsyntaxhighlight lang="perl">sub encode {
my $str = shift;
my $ret = "";
Line 4,055 ⟶ 4,424:
}
return $ret;
}</langsyntaxhighlight>
 
Demonstration of the third version:
 
<langsyntaxhighlight lang="perl">use Data::Dump qw(dd);
dd my $str = "XXXXXABCDEFGHIoooooooooooooooooooooooooAAAAAA";
dd my $enc = encode($str);
dd decode($enc);</langsyntaxhighlight>
 
{{out}}
Line 4,072 ⟶ 4,441:
 
=={{header|Phix}}==
CopyBased ofon [[Run-length_encoding#Euphoria|Euphoria]], but uses a few string in place of sequence.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function encode(sequence s)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
sequence out = {}
<span style="color: #008080;">function</span> <span style="color: #000000;">encode</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
integer prev_char,count = 1
<span style="color: #004080;">sequence</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
if length(s) then
<span style="color: #008080;">if</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;">then</span>
prev_char = s[1]
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span>
for i=2 to length(s) do
<span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
if s[i]!=prev_char then
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</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;">do</span>
out &= {count,prev_char}
<span style="color: #008080;">if</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;">ch</span> <span style="color: #008080;">then</span>
prev_char = s[i]
<span style="color: #000000;">r</span> <span style="color: #0000FF;">&=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">count</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">}</span>
count = 1
<span style="color: #000000;">ch</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>
else
<span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
count += 1
end if<span style="color: #008080;">else</span>
<span style="color: #000000;">count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
out &= {count,prev_char}
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end if
<span style="color: #000000;">r</span> <span style="color: #0000FF;">&=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">count</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">}</span>
return out
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">r</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function decode(sequence s)
sequence out = {}
<span style="color: #008080;">function</span> <span style="color: #000000;">decode</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
for i=1 to length(s) by 2 do
<span style="color: #004080;">string</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
out &= repeat(s[i+1],s[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: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">by</span> <span style="color: #000000;">2</span> <span style="color: #008080;">do</span>
end for
<span style="color: #000000;">r</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">repeat</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;">1</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>
return out
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">r</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
sequence s = encode("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW")
pp(s)
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">encode</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"</span><span style="color: #0000FF;">)</span>
?decode(s)</lang>
<span style="color: #0000FF;">?</span><span style="color: #000000;">s</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">decode</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
Note the character hints are desktop/Phix only and don't appear under p2js.
<pre>
{12,87'W',1,66'B',12,87'W',3,66'B',24,87'W',1,66'B',14,87'W'}
Line 4,110 ⟶ 4,483:
 
=={{header|PHP}}==
<langsyntaxhighlight lang="php"><?php
function encode($str)
{
Line 4,127 ⟶ 4,500:
echo encode('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW'), PHP_EOL;
echo decode('12W1B12W3B24W1B14W'), PHP_EOL;
?></langsyntaxhighlight>
 
=={{header|Picat}}==
===While loop===
Quite slow.
<syntaxhighlight lang="picat">rle(S) = RLE =>
RLE = "",
Char = S[1],
I = 2,
Count = 1,
while (I <= S.len)
if Char == S[I] then
Count := Count + 1
else
RLE := RLE ++ Count.to_string() ++ Char.to_string(),
Count := 1,
Char := S[I]
end,
I := I + 1
end,
RLE := RLE ++ Count.to_string() ++ Char.to_string().</syntaxhighlight>
 
===Using positions of different chars===
Much faster than <code>rle/1</code>.
<syntaxhighlight lang="picat">rle2(S) = RLE =>
Ix = [1] ++ [I : I in 2..S.len, S[I] != S[I-1]] ++ [S.len+1],
Diffs = diff(Ix),
RLE = [Diffs[I].to_string() ++ S[Ix[I]].to_string() : I in 1..Diffs.len].join('').</syntaxhighlight>
===Recursive approach===
The fastest version.
<syntaxhighlight lang="picat">rle3(S) = RLE =>
rle3(S.tail(),S[1],1,[],RLE).
 
rle3([],LastChar,Count,RLE1,RLE) =>
RLE = (RLE1 ++ [Count.to_string(),LastChar.to_string()]).join('').
 
rle3([C|T],LastChar,Count,RLE1,RLE) =>
C == LastChar ->
rle3(T,C,Count+1,RLE1,RLE)
;
rle3(T,C,1,RLE1++[Count.to_string()++LastChar.to_string()],RLE).</syntaxhighlight>
 
===Test===
Encode and decode (only using <code>rle3/1</code>):
<syntaxhighlight lang="picat">go =>
S = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWWA",
println(S),
RLE = rle3(S),
println(rle=RLE),
D = rl_decode(RLE),
println(D),
if D == S then
println(ok)
else
println(not_ok)
end,
nl.</syntaxhighlight>
 
{{out}}
<pre>WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWWA
rle = 12W1B12W3B24W1B14W1A
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWWA
ok</pre>
 
===Benchmark on larger string===
A benchmark on a larger string (30_000) clearly shows that rle3/1 is the fastest.
<syntaxhighlight lang="picat">go2 =>
_ = random2(),
Alpha = "AB",
Len2 = Alpha.len,
_ = random2(),
S = [Alpha[random(1,Len2)] : _ in 1..30_000],
if S.len < 200 then println(s=S) end ,
println("rle/1:"),
time(_=rle(S)),
println("rle2/1:"),
time(_=rle2(S)),
println("rle3/1:"),
time(_=rle3(S)),
nl.</syntaxhighlight>
 
{{out}}
<pre>rle/1:
 
CPU time 4.02 seconds.
 
rle3/1:
 
CPU time 2.422 seconds.
 
rle3/1:
 
CPU time 0.812 seconds.</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de encode (Str)
(pack
(make
Line 4,152 ⟶ 4,618:
(prinl "Data: " "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW")
(prinl "Encoded: " (encode @))
(prinl "Decoded: " (decode @)) )</langsyntaxhighlight>
Output:
<pre>Data: WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
Line 4,159 ⟶ 4,625:
 
=={{header|PL/I}}==
<langsyntaxhighlight lang="pli">declare (c1, c2) character (1);
declare run_length fixed binary;
declare input file;
Line 4,196 ⟶ 4,662:
end;
put edit ((c do i = 1 to run_length)) (a);
end;</langsyntaxhighlight>
 
=={{header|PowerBASIC}}==
Line 4,202 ⟶ 4,668:
This version can handle any arbitrary string that doesn't contain numbers (not just letters). (A flag value could be added which would allow the inclusion of ''any'' character, but such a flag isn't in this example.)
 
<langsyntaxhighlight lang="powerbasic">FUNCTION RLDecode (i AS STRING) AS STRING
DIM Loop0 AS LONG, rCount AS STRING, outP AS STRING, m AS STRING
 
Line 4,253 ⟶ 4,719:
'in PB/Win, "?" = MSGBOX; in PB/DOS & PB/CC. "?" = PRINT
? initial & $CRLF & encoded & $CRLF & decoded
END FUNCTION</langsyntaxhighlight>
 
Outputs are similar to those in [[#BASIC|BASIC]], above.
 
=={{header|PowerShell}}==
<langsyntaxhighlight lang="powershell">function Compress-RLE ($s) {
$re = [regex] '(.)\1*'
$ret = ""
Line 4,275 ⟶ 4,741:
}
return $ret
}</langsyntaxhighlight>
Output:
<pre>PS> Compress-RLE "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
Line 4,285 ⟶ 4,751:
Works with SWI-Prolog.<br>
This code is inspired from a code found here : http://groups.google.com/group/comp.lang.prolog/browse_thread/thread/b053ea2512e8b350 (author : Pascal J. Bourguignon).
<langsyntaxhighlight Prologlang="prolog">% the test
run_length :-
L = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW",
Line 4,392 ⟶ 4,858:
 
run(Var,[Other|RRest], [1,Var],[Other|RRest]):-
dif(Var,Other).</langsyntaxhighlight>
Output :
<pre> ?- run_length.
Line 4,404 ⟶ 4,870:
 
=={{header|Pure}}==
<langsyntaxhighlight lang="pure">using system;
 
encode s = strcat $ map (sprintf "%d%s") $ encode $ chars s with
Line 4,418 ⟶ 4,884:
let s = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW";
let r = encode s; // "12W1B12W3B24W1B14W"
decode r;</langsyntaxhighlight>
 
=={{header|PureBasic}}==
{{trans|PowerBasic}} with some optimations to use pointers instead of string functions. According to the task description it works with uppercase A - Z. In this implementation it also functions with all characters that are non-digits and whose value is non-zero.
<langsyntaxhighlight PureBasiclang="purebasic">Procedure.s RLDecode(toDecode.s)
Protected.s repCount, output, currChar, tmp
Protected *c.Character = @toDecode
Line 4,487 ⟶ 4,953:
Input()
CloseConsole()
EndIf</langsyntaxhighlight>
Sample output:
<pre>Type something: WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWW
Line 4,496 ⟶ 4,962:
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">def encode(input_string):
count = 1
prev = None
Line 4,528 ⟶ 4,994:
if value[1] == 0:
print("Encoded value is {}".format(value[0]))
decode(value[0])</langsyntaxhighlight>
 
Functional
{{works with|Python|2.4}}
<langsyntaxhighlight lang="python">from itertools import groupby
def encode(input_string):
return [(len(list(g)), k) for k,g in groupby(input_string)]
Line 4,540 ⟶ 5,006:
 
encode("aaaaahhhhhhmmmmmmmuiiiiiiiaaaaaa")
decode([(5, 'a'), (6, 'h'), (7, 'm'), (1, 'u'), (7, 'i'), (6, 'a')])</langsyntaxhighlight>
 
<br>'''By regular expression'''<br>
The simplified input range of only uppercase characters allows a simple regular expression to be applied repeatedly for encoding, and another for decoding:
<langsyntaxhighlight lang="python">from re import sub
 
def encode(text):
Line 4,565 ⟶ 5,031:
 
textin = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
assert decode(encode(textin)) == textin</langsyntaxhighlight>
 
=={{header|Quackery}}==
Line 4,571 ⟶ 5,037:
<code>lookandsay</code> is defined at [[Look-and-say sequence#Quackery]].
 
<langsyntaxhighlight Quackerylang="quackery"> [ lookandsay ] is encode ( $ --> $ )
 
[ $ "" 0 rot
Line 4,590 ⟶ 5,056:
dup echo$ cr
decode
echo$ cr</langsyntaxhighlight>
 
{{out}}
Line 4,601 ⟶ 5,067:
=={{header|R}}==
R has a built-in function, rle, for run length encoding. This modification allows input and output in the forms specified above.
<langsyntaxhighlight lang="rsplus">runlengthencoding <- function(x)
{
splitx <- unlist(strsplit(input, ""))
Line 4,609 ⟶ 5,075:
 
input <- "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
runlengthencoding(input)</langsyntaxhighlight>
Similarly, inverse.rle provides decompression after a run length encoding.
<langsyntaxhighlight lang="rsplus">inverserunlengthencoding <- function(x)
{
lengths <- as.numeric(unlist(strsplit(output, "[[:alpha:]]")))
Line 4,621 ⟶ 5,087:
 
output <- "12W1B12W3B24W1B14W"
inverserunlengthencoding(output)</langsyntaxhighlight>
 
=={{header|Racket}}==
 
<syntaxhighlight lang="racket">
<lang Racket>
#lang racket
(define (encode str)
Line 4,631 ⟶ 5,097:
(define (decode str)
(regexp-replace* #px"([0-9]+)(.)" str (λ (m n c) (make-string (string->number n) (string-ref c 0)))))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
Line 4,638 ⟶ 5,104:
count from 0, not from 1.
 
<syntaxhighlight lang="raku" perl6line>sub encode($str) { $str.subst(/(.) $0*/, { $/.chars ~ $0 }, :g) }
 
sub decode($str) { $str.subst(/(\d+) (.)/, { $1 x $0 }, :g) }
Line 4,644 ⟶ 5,110:
my $e = encode('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW');
say $e;
say decode($e);</langsyntaxhighlight>
 
Output:
Line 4,661 ⟶ 5,127:
Note that this REXX version (for encoding and decoding) uses a &nbsp; ''replication'' &nbsp; count, not the &nbsp; ''count'' &nbsp; of characters,
<br>so a replication count of &nbsp; '''11''' &nbsp; represents a count of &nbsp; '''12''' &nbsp; characters.
<langsyntaxhighlight lang="rexx">/*REXX program encodes and displays a string by using a run─length encoding scheme. */
parse arg input . /*normally, input would be in a file. */
default= 'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW'
Line 4,698 ⟶ 5,164:
$= $ || copies( substr(x, k, 1), n) /*N: is now the number of characters. */
j= j + # + 1 /*increment the DO loop index by D+1. */
end /*j*/; return $ /*return the decoded string to caller. */</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
<pre>
Line 4,707 ⟶ 5,173:
 
===version 2===
<langsyntaxhighlight lang="rexx">
/*REXX*/
s='WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW'
Line 4,747 ⟶ 5,213:
 
o: ol=ol||arg(1)
Return</langsyntaxhighlight>
{{out}}
<pre> s=WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
Line 4,756 ⟶ 5,222:
===version 3===
No need to output counts that are 1
<langsyntaxhighlight lang="rexx">
/*REXX*/
s='WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW'
Line 4,805 ⟶ 5,271:
 
o: ol=ol||arg(1)
Return</langsyntaxhighlight>
{{out}}
<pre> s=WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
Line 4,813 ⟶ 5,279:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Run-length encoding
 
Line 4,841 ⟶ 5,307:
see dec
next
</syntaxhighlight>
</lang>
Output:
<pre>
12W1B12W3B24W1B14W
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
</pre>
 
=={{header|RPL}}==
≪ DUP 1 DUP SUB → in c
≪ "" 1
2 in SIZE '''FOR''' j
in j DUP SUB
'''IF''' DUP c == '''THEN''' DROP 1 +
'''ELSE'''
ROT ROT
→STR + c +
SWAP 'c' STO 1
'''END'''
'''NEXT'''
→STR + c +
≫ ≫ ‘<span style="color:blue">RLENC</span>’ STO
≪ → in
≪ "" 0
1 in SIZE '''FOR''' j
in j DUP SUB
'''IF''' DUP "A" ≥ '''THEN'''
ROT 1 4 ROLL '''START''' OVER + '''NEXT'''
SWAP DROP 0
'''ELSE''' STR→ SWAP 10 * + '''END'''
'''NEXT''' DROP
≫ ≫ ‘<span style="color:blue">RLDEC</span>’ STO
 
"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW" <span style="color:blue">RLENC</span> DUP <span style="color:blue">RLDEC</span>
{{out}}
<pre>
2: "12W1B12W3B24W1B14W"
1: "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
</pre>
 
Line 4,854 ⟶ 5,353:
Ruby has built-in run-length encoding in the form of <code>chunk</code>, here I provide a thin wrapper around it:
 
<langsyntaxhighlight lang="ruby">
# run_encode("aaabbbbc") #=> [["a", 3], ["b", 4], ["c", 1]]
def run_encode(string)
Line 4,870 ⟶ 5,369:
end
 
</syntaxhighlight>
</lang>
 
<langsyntaxhighlight lang="ruby">def encode(string)
string.scan(/(.)(\1*)/).collect do |char, repeat|
[1 + repeat.length, char]
Line 4,880 ⟶ 5,379:
def decode(string)
string.scan(/(\d+)(\D)/).collect {|length, char| char * length.to_i}.join
end</langsyntaxhighlight>
 
This usage also seems to be idiomatic, and perhaps less cryptic:
<langsyntaxhighlight lang="ruby">def encode(string)
string.scan(/(.)(\1*)/).inject("") do |encoding, (char, repeat)|
encoding << (1 + repeat.length).to_s << char
Line 4,893 ⟶ 5,392:
decoding << char * length.to_i
end
end</langsyntaxhighlight>
 
<br>'''By regular expression'''<br>
The simplified input range of only uppercase characters allows a simple regular expression to be applied repeatedly for encoding, and another for decoding:
<langsyntaxhighlight lang="ruby">def encode(str)
str.gsub(/(.)\1*/) {$&.length.to_s + $1}
end
Line 4,903 ⟶ 5,402:
def decode(str)
str.gsub(/(\d+)(\D)/) {$2 * $1.to_i}
end</langsyntaxhighlight>
 
'''Test:'''
<langsyntaxhighlight lang="ruby">orig = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
p enc = encode(orig)
p dec = decode(enc)
puts "success!" if dec == orig</langsyntaxhighlight>
 
{{out}}
Line 4,919 ⟶ 5,418:
 
=={{header|Run BASIC}}==
<langsyntaxhighlight lang="runbasic">string$ = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
beg = 1
i = 1
Line 4,944 ⟶ 5,443:
beg = i
if i < len(press$) then goto [expand]
print " Expanded:";expand$</langsyntaxhighlight>Output:
<pre>Compressed:12W1B12W3B24W1B14W
Expanded:WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW</pre>
 
=={{header|Rust}}==
<langsyntaxhighlight lang="rust">fn encode(s: &str) -> String {
s.chars()
// wrap all values in Option::Some
Line 5,004 ⟶ 5,503:
assert_eq!(text, decoded);
}
</syntaxhighlight>
</lang>
{{out}}
<pre>original: WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
Line 5,014 ⟶ 5,513:
Care is taken to use StringBuilder for performance reasons.
 
<langsyntaxhighlight lang="scala">def encode(s: String) = (1 until s.size).foldLeft((1, s(0), new StringBuilder)) {
case ((len, c, sb), index) if c != s(index) => sb.append(len); sb.append(c); (1, s(index), sb)
case ((len, c, sb), _) => (len + 1, c, sb)
Line 5,026 ⟶ 5,525:
for (Code(len, c) <- Code findAllIn s) sb.append(c * len.toInt)
sb.toString
}</langsyntaxhighlight>
 
A simpler (?) encoder:
<langsyntaxhighlight lang="scala">def encode(s:String) = {
s.foldLeft((0,s(0),""))( (t,c) => t match {case (i,p,s) => if (p==c) (i+1,p,s) else (1,c,s+i+p)})
match {case (i,p,s) => s+i+p}
}</langsyntaxhighlight>
 
To make it faster (it's also faster than the longer implementation above) just replace '''""''' with '''new StringBuilder''' and '''s+i+p''' with '''{s.append(i);s.append(p)}'''
 
A simpler (?) decoder (that can handle a string like "2AB", producing "AAB"):
<langsyntaxhighlight lang="scala">def decode(s: String, Code: scala.util.matching.Regex = """(\d+)?([a-zA-Z])""".r) =
Code.findAllIn(s).foldLeft("") { case (acc, Code(len, c)) =>
acc + c * Option(len).map(_.toInt).getOrElse(1)
}</langsyntaxhighlight>
 
=={{header|Scheme}}==
<langsyntaxhighlight lang="scheme">(define (run-length-decode v)
(apply string-append (map (lambda (p) (make-string (car p) (cdr p))) v)))
 
Line 5,057 ⟶ 5,556:
; ((12 . #\W) (1 . #\B) (12 . #\W) (3 . #\B) (24 . #\W) (1 . #\B) (14 . #\W))
(run-length-decode '((12 . #\W) (1 . #\B) (12 . #\W) (3 . #\B) (24 . #\W) (1 . #\B) (14 . #\W)))
; "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"</langsyntaxhighlight>
 
=={{header|sed}}==
The encode script:
<langsyntaxhighlight lang="sed">
/^$/ b
:start
Line 5,088 ⟶ 5,587:
s/^([0-9]+.)(.*)/\2\1/
b start
</syntaxhighlight>
</lang>
 
The decode script:
<langsyntaxhighlight lang="sed">
/^$/ b
:start
Line 5,113 ⟶ 5,612:
s/^0+//
b loop }
</syntaxhighlight>
</lang>
 
Example (assuming the scripts reside in the files <code>encode.sed</code> and <code>decode.sed</code>):
<langsyntaxhighlight lang="bash">
sed -rf encode.sed <<< "foo oops"
# 1f2o1 2o1p1s
Line 5,125 ⟶ 5,624:
(sed -rf decode.sed | sed -rf encode.sed) <<< 1000.
# 1000.
</syntaxhighlight>
</lang>
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "scanstri.s7i";
 
Line 5,163 ⟶ 5,662:
writeln(letterRleEncode("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"));
writeln(letterRleDecode("12W1B12W3B24W1B14W"));
end func;</langsyntaxhighlight>
 
=={{header|SETL}}==
<syntaxhighlight lang="setl">program rle;
test := "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW";
 
print("Input:");
print(test);
print("Encoded:");
print(enc := rlencode(test));
print("Decoded:");
print(rldecode(enc));
 
proc rlencode(s);
loop while s /= "" do
part := span(s, s(1));
r +:= str #part + part(1);
end loop;
return r;
end proc;
 
proc rldecode(s);
loop while s /= "" do
num := span(s, "0123456789");
item := notany(s, "");
r +:= val num * item;
end loop;
return r;
end proc;
end program;</syntaxhighlight>
{{out}}
<pre>Input:
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
Encoded:
12W1B12W3B24W1B14W
Decoded:
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW</pre>
 
=={{header|Sidef}}==
First solution:
<langsyntaxhighlight lang="ruby">func encode(str) {
str.gsub(/((.)(\2*))/, {|a,b| "#{a.len}#{b}" });
}
Line 5,173 ⟶ 5,708:
func decode(str) {
str.gsub(/(\d+)(.)/, {|a,b| b * a.to_i });
}</langsyntaxhighlight>
{{out}}
<pre>12W1B12W3B24W1B14W</pre>
 
Second solution, encoding the length into a byte:
<langsyntaxhighlight lang="ruby">func encode(str) {
str.gsub(/(.)(\1{0,254})/, {|a,b| b.len+1 -> chr + a});
}
Line 5,189 ⟶ 5,724:
}
return r;
}</langsyntaxhighlight>
{{out}}
<pre>"\fW\1B\fW\3B\30W\1B\16W"</pre>
Line 5,199 ⟶ 5,734:
{{works with|Smalltalk/X}} (and others)
 
<langsyntaxhighlight lang="smalltalk">|compress decompress|
compress := [:string |
String streamContents:[:out |
Line 5,232 ⟶ 5,767:
]
].
].</langsyntaxhighlight>
 
<langsyntaxhighlight lang="smalltalk">compress value:'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW'
-> '12W1B12W3B24W1B14W'
 
decompress value:'12W1B12W3B24W1B14W'
-> 'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW'</langsyntaxhighlight>
 
Most Smalltalk dialects include a class named "RunArray", which can be used as:
{{works with|Smalltalk/X}}
{{works with|VisualWorks}}
<langsyntaxhighlight lang="smalltalk">compress := [:string |
String streamContents:[:out |
string asRunArray runsDo:[:count :char |
count printOn:out. out nextPut:char]]].</langsyntaxhighlight>
 
=={{header|SNOBOL4}}==
Line 5,254 ⟶ 5,789:
{{works with|CSnobol}}
 
<langsyntaxhighlight SNOBOL4lang="snobol4">* # Encode RLE
define('rle(str)c,n') :(rle_end)
rle str len(1) . c :f(return)
Line 5,272 ⟶ 5,807:
str = rle(str); output = str
str = elr(str); output = str
end</langsyntaxhighlight>
 
Output:
Line 5,278 ⟶ 5,813:
12W1B12W3B24W1B14W
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW</pre>
 
=={{header|SparForte}}==
As a structured script.
<syntaxhighlight lang="ada">#!/usr/local/bin/spar
pragma is
annotate( summary, "rle" );
annotate( description, "Given a string containing uppercase characters (A-Z)," );
annotate( description, "compress repeated 'runs' of the same character by" );
annotate( description, "storing the length of that run, and provide a function to" );
annotate( description, "reverse the compression. The output can be anything, as" );
annotate( description, "long as you can recreate the input with it." );
annotate( description, "" );
annotate( description, "Example:" );
annotate( description, "Input: WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW" );
annotate( description, "Output: 12W1B12W3B24W1B14W" );
annotate( see_also, "http://rosettacode.org/wiki/Run-length_encoding" );
annotate( author, "Ken O. Burtch" );
license( unrestricted );
restriction( no_external_commands );
end pragma;
 
procedure rle is
 
function to_rle( s : string ) return string is
begin
if strings.length( s ) = 0 then
return "";
end if;
declare
result : string;
code : character;
prefix : string;
first : natural := 1;
index : natural := 1;
begin
while index <= strings.length( s ) loop
first := index;
index := @+1;
code := strings.element( s, positive(first) );
while index <= strings.length( s ) loop
exit when code /= strings.element( s, positive(index) );
index := @+1;
exit when index-first = 99;
end loop;
prefix := strings.trim( strings.image( index - first ), trim_end.left );
result := @ & prefix & code;
end loop;
return result;
end;
end to_rle;
 
function from_rle( s : string ) return string is
begin
if strings.length( s ) = 0 then
return "";
end if;
declare
result : string;
index : positive := 1;
prefix : string;
code : character;
begin
loop
prefix := "" & strings.element( s, index );
index := @+1;
if strings.is_digit( strings.element( s, index ) ) then
prefix := @ & strings.element( s, index );
index := @+1;
end if;
code := strings.element( s, index );
index := @+1;
result := @ & ( numerics.value( prefix ) * code );
exit when natural(index) > strings.length( s );
end loop;
return result;
end;
end from_rle;
 
begin
? to_rle( "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW" );
? from_rle( "12W1B12W3B24W1B14W");
end rle;</syntaxhighlight>
 
=={{header|SQL}}==
Line 5,283 ⟶ 5,900:
<br>
* RLE encoding
<syntaxhighlight lang="sql">
<lang SQL>
-- variable table
drop table if exists var;
Line 5,331 ⟶ 5,948:
where noWithinGroup = 1
) Rle_Compressed
</syntaxhighlight>
</lang>
 
* RLE decoding
<syntaxhighlight lang="sql">
<lang SQL>
-- variable table
DROP TABLE IF EXISTS var;
Line 5,397 ⟶ 6,014:
string_agg(replicated_Letter, '' ORDER BY group_no) decoded_string
FROM lettersReplicated
</syntaxhighlight>
</lang>
 
=={{header|Standard ML}}==
<langsyntaxhighlight lang="sml">fun encode str =
let
fun aux (sub, acc) =
Line 5,416 ⟶ 6,033:
 
fun decode lst =
concat (map (fn (c,n) => implode (List.tabulate (n, fn _ => c))) lst)</langsyntaxhighlight>
Example:
<pre>
Line 5,428 ⟶ 6,045:
=={{header|Swift}}==
Using array as the internal representation of the encoded input:
<langsyntaxhighlight lang="swift">import Foundation
 
// "WWWBWW" -> [(3, W), (1, B), (2, W)]
Line 5,442 ⟶ 6,059:
return encoded.reduce("") { $0 + String(count: $1.0, repeatedValue: $1.1) }
}
</syntaxhighlight>
</lang>
 
'''Usage:'''
 
<langsyntaxhighlight lang="swift">
let input = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
let output = decode(encode(input))
print(output == input)
</syntaxhighlight>
</lang>
 
{{Out}}
Line 5,458 ⟶ 6,075:
Converting encoded array into the string and then decoding it using NSScanner:
 
<langsyntaxhighlight lang="swift">// "3W1B2W" -> "WWWBWW"
func decode(encoded: String) -> String {
let scanner = NSScanner(string: encoded)
Line 5,473 ⟶ 6,090:
return out
}
</syntaxhighlight>
</lang>
 
<langsyntaxhighlight lang="swift">let encodedString = encode(input).reduce("") { $0 + "\($1.0)\($1.1)" }
print(encodedString)
let outputString = decode(encodedString)
print(outputString == input)
</syntaxhighlight>
</lang>
 
{{Out}}
Line 5,489 ⟶ 6,106:
=={{header|Tcl}}==
The encoding is an even-length list with elements <tt>{count char ...}</tt>
<langsyntaxhighlight lang="tcl">proc encode {string} {
set encoding {}
# use a regular expression to match runs of one character
Line 5,503 ⟶ 6,120:
}
return $decoded
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="tcl">set str "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
set enc [encode $str] ;# ==> {12 W 1 B 12 W 3 B 24 W 1 B 14 W}
set dec [decode $enc]
if {$str eq $dec} {
puts "success"
}</langsyntaxhighlight>
 
=={{header|TMG}}==
Unix TMG is designed to process and generate ''files'' rather than process text in memory. Therefore encoding and decoding parts can be done in separate programs.
 
Encoding:
<langsyntaxhighlight UnixTMGlang="unixtmg">loop: ordcop [lch?]\loop;
ordcop: ord/copy;
ord: char(ch)/last [ch!=lch?]\new [cnt++] fail;
Line 5,523 ⟶ 6,140:
last: parse(out) [lch=0];
copy: smark any(!<<>>);
 
ch: 0;
lch: 0;
cnt: 0;</langsyntaxhighlight>
 
Decoding:
<langsyntaxhighlight UnixTMGlang="unixtmg">loop: readint(n) copy\loop;
copy: smark any(!<<>>)
repeat: [n?] parse(( scopy )) [--n>0?]\repeat;
 
/* Reads decimal integer */
readint: proc(n;i) ignore(<<>>) [n=0] inta
int1: [n = n*12+i] inta\int1;
inta: char(i) [i<72?] [(i =- 60)>=0?];
 
i: 0;
n: 0;</langsyntaxhighlight>
 
=={{header|TSE SAL}}==
<syntaxhighlight lang="tsesal">
STRING PROC FNStringGetDecodeStringCharacterEqualCountS( STRING inS )
STRING s1[255] = ""
STRING s2[255] = ""
STRING s3[255] = ""
STRING s4[255] = ""
INTEGER I = 0
INTEGER J = 0
INTEGER K = 0
INTEGER L = 0
K = Length( inS )
I = 1 - 1
REPEAT
J = 1 - 1
s3 = ""
REPEAT
I = I + 1
J = J + 1
s1 = SubStr( inS, I, 1 )
s3 = s3 + s1
s4 = SubStr( inS, I + 1, 1 )
UNTIL ( NOT ( s4 IN '0'..'9' ) )
FOR L = 1 TO Val( s3 )
s2 = s2 + s4
ENDFOR
I = I + 1
UNTIL ( I >= ( K - 1 ) )
RETURN( s2 )
END
//
STRING PROC FNStringGetEncodeStringCharacterEqualCountS( STRING inS )
STRING s1[255] = ""
STRING s2[255] = ""
INTEGER I = 0
INTEGER J = 0
INTEGER K = 0
K = Length( inS )
I = 1 - 1
REPEAT
J = 1 - 1
REPEAT
I = I + 1
J = J + 1
s1 = SubStr( inS, I, 1 )
UNTIL ( NOT ( SubStr( inS, I + 1, 1 ) == s1 ) )
s2 = s2 + Str( J ) + s1
UNTIL ( I >= ( K - 1 ) )
RETURN( s2 )
END
//
STRING PROC FNStringGetEncodeDecodeStringCharacterEqualCountS( STRING inS )
STRING s1[255] = FNStringGetEncodeStringCharacterEqualCountS( inS )
STRING s2[255] = FNStringGetDecodeStringCharacterEqualCountS( s1 )
RETURN( s2 )
END
//
PROC Main()
STRING s1[255] = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
STRING s2[255] = ""
IF ( NOT ( Ask( "string: get: encode: decode: string: character: equal: count: inS = ", s1, _EDIT_HISTORY_ ) ) AND ( Length( s1 ) > 0 ) ) RETURN() ENDIF
s2 = FNStringGetEncodeDecodeStringCharacterEqualCountS( s1 )
Warn( "equal strings if result is 1", ",", " ", "and the result is", ":", " ", s1 == s2 )
END
</syntaxhighlight>
 
=={{header|TUSCRIPT}}==
<langsyntaxhighlight lang="tuscript">
$$ MODE TUSCRIPT,{}
input="WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW",output=""
Line 5,552 ⟶ 6,235:
PRINT input
PRINT output
</syntaxhighlight>
</lang>
Output:
<pre>
Line 5,561 ⟶ 6,244:
=={{header|UNIX Shell}}==
{{works with|bash}}
<langsyntaxhighlight lang="bash">encode() {
local phrase=$1
[[ -z $phrase ]] && return
Line 5,605 ⟶ 6,288:
# replace spaces with the char
echo "${result// /$char}"
}</langsyntaxhighlight>
Demo
<langsyntaxhighlight lang="bash">str="WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
enc=$(encode "$str")
dec=$(decode "$enc")
declare -p str enc dec
[[ $str == "$dec" ]] && echo success || echo failure</langsyntaxhighlight>
Output
<pre>declare -- str="WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
Line 5,622 ⟶ 6,305:
which is a second order function taking a binary predicate that decides
when consecutive items of an input list belong to the same run.
<langsyntaxhighlight Ursalalang="ursala">#import std
#import nat
 
Line 5,637 ⟶ 6,320:
<
encode test_data,
decode encode test_data></langsyntaxhighlight>
The output shows an encoding of the test data, and a decoding of the encoding, which
matches the original test data.
Line 5,644 ⟶ 6,327:
 
=={{header|VBA}}==
<syntaxhighlight lang="vb">
<lang vb>
Option Explicit
 
Line 5,681 ⟶ 6,364:
Next
length_decoding = a
End Function</langsyntaxhighlight>
{{out}}
<pre>12W1B12W3B24W1B14W
Line 5,692 ⟶ 6,375:
Newlines are not converted (the regular expression does not count newlines).
This methods supports any type of input.
<langsyntaxhighlight lang="vedit">:RL_ENCODE:
BOF
While (!At_EOF) {
Line 5,722 ⟶ 6,405:
}
}
Return</langsyntaxhighlight>
 
=={{header|V (Vlang)}}==
<syntaxhighlight lang="Zig">
const test = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
 
fn main() {
encoded := encode(test)
println(encoded)
println(decode(encoded))
}
 
fn encode(data string) string {
mut encode :=""
mut temp := []u8{}
for key, value in data {
if key > 1 && value != data[key - 1] {
encode += temp.len.str() + temp[0].ascii_str()
temp.clear()
}
temp << value
}
encode += temp.len.str() + temp[0].ascii_str()
temp.clear()
return encode
}
 
fn decode(data string) string {
mut decode :=""
mut temp := []u8{}
for value in data {
if value.is_digit() == false {
decode += value.repeat(temp.bytestr().int())
temp.clear()
}
else {temp << value}
}
return decode
}
</syntaxhighlight>
 
{{out}}
<pre>
12W1B12W3B24W1B14W
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
</pre>
 
=={{header|Wren}}==
{{libheader|Wren-pattern}}
<langsyntaxhighlight ecmascriptlang="wren">import "./pattern" for Pattern
 
var p = Pattern.new("/u") // match any upper case letter
Line 5,770 ⟶ 6,498:
System.print("Original = decoded : %(s == d)\n")
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 5,791 ⟶ 6,519:
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">include c:\cxpl\codes; \intrinsic 'code' declarations
string 0; \use zero-terminated strings, instead of MSb terminated
 
Line 5,831 ⟶ 6,559:
CrLf(0);
Expand("W11BW11B2W23BW13"); CrLf(0);
]</langsyntaxhighlight>
 
Output (with slightly better compression than the example):
Line 5,837 ⟶ 6,565:
W11BW11B2W23BW13
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
</pre>
 
=={{header|Zig}}==
<syntaxhighlight lang="zig">const std = @import("std");
 
fn Run(comptime T: type) type {
return struct {
value: T,
length: usize,
};
}
 
fn encode(
comptime T: type,
input: []const T,
allocator: std.mem.Allocator,
) ![]Run(T) {
var runs = std.ArrayList(Run(T)).init(allocator);
defer runs.deinit();
 
var previous: ?T = null;
var length: usize = 0;
 
for (input) |current| {
if (previous == current) {
length += 1;
} else if (previous) |value| {
try runs.append(.{
.value = value,
.length = length,
});
previous = current;
length = 1;
} else {
previous = current;
length += 1;
}
}
 
if (previous) |value| {
try runs.append(.{
.value = value,
.length = length,
});
}
 
return runs.toOwnedSlice();
}
 
test encode {
const input =
"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW";
 
const expected = [_]Run(u8){
.{ .length = 12, .value = 'W' },
.{ .length = 1, .value = 'B' },
.{ .length = 12, .value = 'W' },
.{ .length = 3, .value = 'B' },
.{ .length = 24, .value = 'W' },
.{ .length = 1, .value = 'B' },
.{ .length = 14, .value = 'W' },
};
 
const allocator = std.testing.allocator;
const actual = try encode(u8, input, allocator);
defer allocator.free(actual);
 
try std.testing.expectEqual(expected.len, actual.len);
for (expected, actual) |e, a| {
try std.testing.expectEqual(e.length, a.length);
try std.testing.expectEqual(e.value, a.value);
}
}
 
fn decode(
comptime T: type,
runs: []const Run(T),
allocator: std.mem.Allocator,
) ![]T {
var values = std.ArrayList(T).init(allocator);
defer values.deinit();
for (runs) |r|
try values.appendNTimes(r.value, r.length);
return values.toOwnedSlice();
}
 
test decode {
const runs = [_]Run(u8){
.{ .length = 12, .value = 'W' },
.{ .length = 1, .value = 'B' },
.{ .length = 12, .value = 'W' },
.{ .length = 3, .value = 'B' },
.{ .length = 24, .value = 'W' },
.{ .length = 1, .value = 'B' },
.{ .length = 14, .value = 'W' },
};
 
const allocator = std.testing.allocator;
const decoded = try decode(u8, &runs, allocator);
defer allocator.free(decoded);
 
try std.testing.expectEqualStrings(
"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW",
decoded,
);
}
 
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer std.debug.assert(gpa.deinit() == .ok);
 
const allocator = gpa.allocator();
var input = std.ArrayList(u8).init(allocator);
defer input.deinit();
 
const stdout = std.io.getStdOut().writer();
const stdin = std.io.getStdIn().reader();
try stdout.print("Input: ", .{});
try stdin.streamUntilDelimiter(input.writer(), '\n', null);
 
const runs = try encode(u8, input.items, allocator);
defer allocator.free(runs);
 
try stdout.print("Encoded:\n", .{});
for (runs) |r|
try stdout.print(" {}\n", .{r});
 
const decoded = try decode(u8, runs, allocator);
defer allocator.free(decoded);
 
try stdout.print("Decoded: {s}\n", .{decoded});
}</syntaxhighlight>
{{out}}
<pre>
Input: WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
Encoded:
run_length_encoding.Run(u8){ .value = 87, .length = 12 }
run_length_encoding.Run(u8){ .value = 66, .length = 1 }
run_length_encoding.Run(u8){ .value = 87, .length = 12 }
run_length_encoding.Run(u8){ .value = 66, .length = 3 }
run_length_encoding.Run(u8){ .value = 87, .length = 24 }
run_length_encoding.Run(u8){ .value = 66, .length = 1 }
run_length_encoding.Run(u8){ .value = 87, .length = 14 }
Decoded: WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
</pre>
 
=={{header|zkl}}==
A byte stream to byte stream codec, the streams hard coded for ease. Character '\1' is used as a sentinel and there are limits on the run length to avoid byte overflow.
<langsyntaxhighlight lang="zkl">const MAX_LEN=250, MIN_LEN=3;
fcn compress(text){ // !empty byte/text stream -->Data (byte stream)
sink:=Data(); cnt:=Ref(0);
Line 5,858 ⟶ 6,730:
},text[0]) : write(_,cnt.value);
sink;
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">fcn inflate(data){ //-->String
data.howza(3).pump(String,
fcn(c){ // if c==1, read n,c2 and expand, else write c
if(c=="\x01") return(Void.Read,2) else return(Void.Write,c) },
fcn(_,n,c){ c*n.toAsc() })
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">text:="WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW";
d:=compress(text);
d.bytes().println();
println(text.len()," bytes --> ",d.len()," bytes");
println(text==inflate(d));</langsyntaxhighlight>
{{out}}
<pre>
9,476

edits