Run-length encoding: Difference between revisions

Updated two D versions
(Updated two of the four D versions)
(Updated two D versions)
Line 724:
 
=={{header|D}}==
===Short Functional Version===
<lang d>import std.stdio, std.algorithm, std.conv, std.array;
 
alias group encode;
 
string decode(Range)Group!(Range"a == b", string) renc) {
return join(map!(t => replicate(""~cast(char)t[0], t[1]))(renc));
 
void main() {
auto s = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW";
assert(decode(encode(s)) == s);
}</lang>
===Basic Imperative Version===
<lang d>import std.stdio, std.array, std.conv;
Line 774 ⟶ 787:
writeln("Encoded: ", encoded);
assert(txt == decode(encoded));
}</lang>
===Short Functional Version===
<lang d>import std.stdio, std.algorithm, std.conv, std.array;
 
alias group encode;
 
string decode(Range)(Range r) {
return join(map!(t => replicate(""~cast(char)t[0], t[1]))(r));
 
void main() {
auto s = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW";
assert(decode(encode(s)) == s);
}</lang>
===UTF String Version===
D's native string is utf-encoded. This version work for utf string. This code use a [[Variable-length_quantity|Variable-length Quantity]] [[Variable-length_quantity#D|module]].
 
<lang d>import std.stdio, std.conv, std.utf, std.string;
import std.conv vlq;
import std.utf ;
import std.string ;
 
import vlq ;
 
struct RLE { // for utf string
ubyte[] encoded ;
 
RLE encode(const string s) {
validate(s) ; // check if s is well-formed utf, throw if not
encoded.length = 0 ; // reset
if (s.length == 0) return this ; // empty string
string last ;
VLQ count ; // init value 0
for (int i = 0 ; i < s.length ; ) {
auto k = s.stride(i) ;
auto ucode = cast(string)s[i .. i+k] ;
if (i == 0) last = ucode ;
if (ucode == last)
count++ ;
else {
encoded ~= count.toVLQ ~ cast(ubyte[]) last ;
last = ucode ;
count = 1 ;
}
i += k ;
}
encoded ~= VLQ(count).toVLQ ~ cast(ubyte[]) last ;
return this ;
}
 
int opApply(int delegate(ref ulong c, ref string u) dg) {
VLQ count ;
string ucode ;
 
for(int i = 0 ; i < encoded.length ;) {
for (int i = auto0; ki =< count.extract(encoded[i..$]length; ) ;{
iauto k += kcount.extract(encoded[i .. $]);
if(i >+= encoded.length)k;
if throw new Exception("noti valid>= encoded string".length) ;
k = stride(cast throw new Exception(string)"not valid encoded[i..$], 0string") ;
if(k == 0xffstride(cast(string) //encoded[i not.. valid utf code point$], 0);
if (k == 0xff) throw// new Exception("not valid encodedutf string")code point ;
ucode = cast throw new Exception(string)"not valid encoded[i..i+k].dup string");
dg(count.value, ucode = cast(string)encoded[i .. i+k].dup;
i += kdg(count.value, ucode);
} i += k;
return 0 ;}
 
}
return 0;
}
 
string toString() {
string res ;
foreach (ref i, s ; this)
if (indexOf(`"0123456789#`", s) == -1)
res ~= to!stringtext(i) ~ s ;
else
res ~= to!stringtext(i) ~` '#`' ~ s ;
return res ;
}
string decode() {
string res ;
foreach (ref i, s ; this)
res ~= repeat(s, cast(uint)i) ;
return res ;
}
}
 
void main() {
RLE r ;
auto s = "尋尋覓覓冷冷清清淒淒慘慘戚戚\nWWWWWWWWWWWWBWWWWWWWWWWW" ~
"WBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW\n" ~
"11#222##333" ;
auto f = File("display.txt", "w") ;
f.writeln(s) ;
r.encode(s) ;
f.writefln("-----\n%s\n-----\n%s", r, r.decode) ;
auto sEncoded = RLE.init.encode(s).encoded ;
assert(s == RLE(sEncoded).decode , "Not work") ;
}</lang>
 
Anonymous user