Skip to content

Instantly share code, notes, and snippets.

@alphaKAI
Last active July 7, 2020 13:31
Show Gist options
  • Save alphaKAI/c3cab592452356a435d3164d1e65579b to your computer and use it in GitHub Desktop.
Save alphaKAI/c3cab592452356a435d3164d1e65579b to your computer and use it in GitHub Desktop.
赤ちゃん語に変換するやつ (v3はv2のUTF-8化。v2は「ば」「ぶ」「マ」「!」の4値をつかって変換, 無印(original)は「ばぶばぶ!」と「ママ!」の2値で変換)
import std;
enum int[dchar] BabyTerm = [
'ば' : 0b0000,
'ぶ' : 0b0001,
'マ' : 0b0010,
'!' : 0b0011,
];
enum dchar[int] BabyTerm_R = [
0b0000 : 'ば',
0b0001 : 'ぶ',
0b0010 : 'マ',
0b0011 : '!',
];
string encode(string input) {
string encoded;
foreach (i, c; input) {
foreach (j; 0..char.sizeof * 4) {
auto x = (c >> (j * 2)) & 0b11;
encoded ~= BabyTerm_R[x];
}
}
return encoded;
}
string decode(string encoded) {
dstring d_encoded = encoded.to!dstring;
immutable(char)[] decoded;
char c = 0x00;
size_t count; // 何bitみたか
size_t bytes; // ある文字が何byteか
for (size_t i; i < d_encoded.length; i) {
const d = d_encoded[i++];
const x = BabyTerm[d];
c |= (x << (count++ * 2));
if (count == 4) { // read 1 bytes
if ((c >> 7) == 0) { // 1
bytes = 1;
} else if ((c >> 5) == 0b110) {
bytes = 2;
} else if ((c >> 4) == 0b1110) {
bytes = 3;
} else {
bytes = 4;
}
count = 0;
}
if (bytes) {
size_t j = i;
immutable(char)[] buf = [c];
c = 0x00;
while (--bytes) {
foreach (t; 0..4) {
c |= (BabyTerm[d_encoded[j++]] << (t * 2));
}
buf ~= c;
c = 0x00;
}
decoded ~= buf;
i = j;
}
}
return decoded;
}
string compress(string s) {
string ret;
dstring d_s = s.to!dstring;
dchar previous_char = 0;
size_t chain = 1;
for (size_t i = 0; i < d_s.length; i++) {
const d = d_s[i];
if (i == 0) {
previous_char = d;
continue;
}
if (previous_char == d) {
chain++;
} else if (previous_char != d) {
if (chain > 2) {
ret ~= "%s:%d".format(previous_char, chain);
} else {
if (chain) {
foreach (_; 0..chain) {
ret ~= previous_char;
}
} else {
ret ~= previous_char;
}
}
previous_char = d;
chain = 1;
}
}
if (chain > 3) {
ret ~= "%s:%d".format(previous_char, chain);
} else {
if (chain) {
foreach (_; 0..chain) {
ret ~= previous_char;
}
} else {
ret ~= previous_char;
}
}
return ret;
}
string decompress(string s) {
dstring ret;
dstring d_s = s.to!dstring;
auto s_sp = d_s.split(":");
dchar last_char;
foreach (i, e; s_sp) {
if (i == 0) {
ret ~= e;
last_char = e[$-1];
} else {
size_t num_len;
size_t idx;
for (dchar c = e[idx++]; num_len < e.length && '0' <= c && c <= '9'; c = e[idx++], num_len++) {}
const size_t repeat = e[0..num_len].to!int - 1;
auto rem = e[num_len..$];
foreach (_; 0..repeat) {
ret ~= last_char;
}
ret ~= rem;
last_char = e[$-1];
}
}
return ret.to!string;
}
void main(string[] args) {
args = args[1..$];
string line, input;
while ((line = readln()) !is null) {
input ~= line.chomp;
}
if (args.length) {
bool encode_mode = true;
bool compress_flag;
bool decompress_flag;
foreach (arg; args) {
if (arg == "--to-baby") {
encode_mode = true;
} else if (arg == "--to-adult") {
encode_mode = false;
} else if (arg == "--compress") {
compress_flag = true;
} else if (arg == "--decompress") {
decompress_flag = true;
}
}
if (encode_mode) {
if (compress_flag) {
writeln(encode(input).compress);
} else {
writeln(encode(input));
}
} else {
if (decompress_flag) {
writeln(decode(input.decompress));
} else {
if (input.find(':')) {
writeln(decode(input.decompress));
} else {
writeln(decode(input));
}
}
}
} else {
writeln(encode(input));
}
}
import std;
enum BabyTerm {
babubabu = "ばぶばぶ!", mama = "ママ!"
}
BabyTerm from_int(int v) {
if (v == 0) {
return BabyTerm.babubabu;
} else if (v == 1) {
return BabyTerm.mama;
}
throw new Exception("should not reach here");
}
BabyTerm[][] encode(string input) {
BabyTerm[][] encoded;
encoded.length = input.length;
foreach (i, c; input) {
foreach (j; 0..char.sizeof * 8) {
encoded[i] ~= from_int((c >> j) & 1);
}
}
return encoded;
}
string show_encoded(BabyTerm[][] encoded) {
string s;
foreach (i, e; encoded) { foreach (x; e) { s ~= x; } if (i != encoded.length - 1) s ~= "\n"; }
return s;
}
string decode(BabyTerm[][] encoded) {
immutable(char)[] decoded;
foreach (e; encoded) {
char c = 0x00;
foreach (i, x; e) {
c |= ((x == BabyTerm.babubabu ? 0 : 1) << i);
}
decoded ~= c;
}
return decoded;
}
string decode(string encoded) {
BabyTerm[][] tokenized;
tokenized.length = 1;
for (size_t i; i < encoded.length;) {
auto e = encoded[i];
auto sub = encoded[i..$];
if (startsWith(sub, cast(string)BabyTerm.babubabu)) {
tokenized[tokenized.length - 1] ~= BabyTerm.babubabu;
i += BabyTerm.babubabu.length;
} else if (startsWith(sub, cast(string)BabyTerm.mama)) {
tokenized[tokenized.length - 1] ~= BabyTerm.mama;
i += BabyTerm.mama.length;
} else if (e == '\n') {
tokenized.length++;
i++;
}
}
return decode(tokenized);
}
void test() {
string input = "ばーか!";
auto encoded = encode(input);
auto decoded = decode(encoded);
auto x = "ママ!ママ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ママ!ママ!ママ!
ママ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ママ!
ばぶばぶ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ママ!ママ!ばぶばぶ!ママ!
ママ!ママ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ママ!ママ!ママ!
ママ!ママ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ママ!
ばぶばぶ!ばぶばぶ!ママ!ママ!ママ!ママ!ばぶばぶ!ママ!
ママ!ママ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ママ!ママ!ママ!
ママ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ママ!
ママ!ママ!ばぶばぶ!ママ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ママ!
ママ!ママ!ママ!ママ!ばぶばぶ!ママ!ママ!ママ!
ばぶばぶ!ばぶばぶ!ママ!ママ!ママ!ママ!ばぶばぶ!ママ!
ママ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ばぶばぶ!ママ!";
writeln("input: ", input);
writeln("encoded: \n", show_encoded(encoded));
writeln("decoded: ", decoded);
writeln("decoded(2): ", decode(x));
}
void main(string[] args){
args = args[1..$];
string line, input;
while ((line = readln()) !is null) {
input ~= line;
}
if (args.length) {
if (args[0] == "--to-baby") {
writeln(encode(input).show_encoded);
} else if (args[0] == "--to-adult") {
writeln(decode(input[0..$-1]));
}
} else {
writeln(encode(input).show_encoded);
}
}
import std;
enum int[dchar] BabyTerm = [
'ば' : 0b0000,
'ぶ' : 0b0001,
'マ' : 0b0010,
'!' : 0b0011,
];
enum dchar[int] BabyTerm_R = [
0b0000 : 'ば',
0b0001 : 'ぶ',
0b0010 : 'マ',
0b0011 : '!',
];
string encode(string input) {
string encoded;
foreach (i, c; input.to!dstring) {
foreach (j; 0..dchar.sizeof * 4) {
auto x = (c >> (j * 2)) & 0b11;
encoded ~= BabyTerm_R[x];
}
}
return encoded;
}
string decode(string encoded) {
immutable(dchar)[] decoded;
dchar c = 0x00;
foreach (i, e; encoded.to!dstring) {
const auto j = i % 16;
if (i > 0 && j == 0) {
decoded ~= c;
c = 0x00;
}
auto x = (BabyTerm[e] << (j * 2));
c |= x;
}
if (c) {
decoded ~= c;
}
return decoded.to!string;
}
void main(string[] args) {
args = args[1..$];
string line, input;
while ((line = readln()) !is null) {
input ~= line.chomp;
}
if (args.length) {
if (args[0] == "--to-baby") {
writeln(encode(input));
} else if (args[0] == "--to-adult") {
writeln(decode(input));
}
} else {
writeln(encode(input));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment