ランレングスCarelyちゃんにPythonで参戦してみるよ! | Dev Driven 開発・デザインチーム ランレングスCarelyちゃんにPythonで参戦してみるよ! | 働くひとと組織の健康を創る iCARE

BLOG

ランレングスCarelyちゃんにPythonで参戦してみるよ!

2022/12/07

はじめに

レアキャラの岩崎です。
少し仕事中にむしゃくしゃしたので、12月4日に投稿されたこちらの記事に挑戦状がついていたのでやってみました。という記事です。
https://dev.icare.jpn.com/dev_cat/run-length-carely-chan

とりあえずソース

なんか縛りがあったわけでもないんですがクドウさんが1ラインで書いてたから私もなんか1ラインで書いてみました。私はRubyがあんまり得意じゃありません(爆弾)というかぜんぜん触れたことがなく、Pythonばっかりの人生だったのでPythonでWindowsのWSLの動作確認も含めて書いてみたってわけ。

for i in "0xc0000000,0x1ffffe00000,0x1ffffffe0000,0xffffffffc000,0x3fffffffff000,0xffffffffffc00,0x3fff00003fff00,0xfff8000007ff80,0x1ffe0000001ffe0,0x3ff800000007ff0,0x7fe000000001ff8,0xffc01c000e007fc,0xff801e001e00000,0x1ff0008000400000,0x3fe0000000000000,0x3fe0000000000000,0x3fe0000000000000,0x3fc0018000400000,0x3fc0007003000000,0x3fc00007f0000000,0x3fc0000000000000,0x3fe0000000008000,0x3fe00000003fff00,0x1ff0000001ffffc0,0x1ff0000007fffff0,0xff800000ffffff8,0xffc00001ffffffc,0x7fe00001ffffffe,0x3ff80001ffffffe,0x1ffe0001ffffffe,0x1fff8001ffffffc,0x1ffff800ffffffc,0x3ffffff87fffff0,0x3ffffffc1fffff0,0x7fefffff07ffff8,0xfc01ffff801e1fc,0xc0000ffff00000c".split(","): print(format(int(i,16), '064b'))

え?これRLEじゃないじゃん?
まぁ、そうなんですよね。RLEじゃないんですが、圧縮符号化というところでまぁ、テクとして使うものとして2進数を16進数にしたりするのも有りだったりするわけで、そんな細かいことは木にしないでください。
で、話を進めると、実はこういうのって分解の仕方で結構状況が変わってきたりもするんですよね。

あのCarelyちゃんを1行ずつ64bitで変換するとこんな感じになって、容量としては656バイトくらいです。

0xc0000000,0x1ffffe00000,0x1ffffffe0000,0xffffffffc000,0x3fffffffff000,0xffffffffffc00,0x3fff00003fff00,0xfff8000007ff80,0x1ffe0000001ffe0,0x3ff800000007ff0,0x7fe000000001ff8,0xffc01c000e007fc,0xff801e001e00000,0x1ff0008000400000,0x3fe0000000000000,0x3fe0000000000000,0x3fe0000000000000,0x3fc0018000400000,0x3fc0007003000000,0x3fc00007f0000000,0x3fc0000000000000,0x3fe0000000008000,0x3fe00000003fff00,0x1ff0000001ffffc0,0x1ff0000007fffff0,0xff800000ffffff8,0xffc00001ffffffc,0x7fe00001ffffffe,0x3ff80001ffffffe,0x1ffe0001ffffffe,0x1fff8001ffffffc,0x1ffff800ffffffc,0x3ffffff87fffff0,0x3ffffffc1fffff0,0x7fefffff07ffff8,0xfc01ffff801e1fc,0xc0000ffff00000c

それを16bit単位で変換すると569バイトになって結構容量が変わってくるわけですね。

0,0,c000,0,0,1ff,ffe0,0,0,1fff,fffe,0,0,ffff,ffff,c000,3,ffff,ffff,f000,f,ffff,ffff,fc00,3f,ff00,3f,ff00,ff,f800,7,ff80,1ff,e000,1,ffe0,3ff,8000,0,7ff0,7fe,0,0,1ff8,ffc,1c0,e0,7fc,ff8,1e0,1e0,0,1ff0,80,40,0,3fe0,0,0,0,3fe0,0,0,0,3fe0,0,0,0,3fc0,180,40,0,3fc0,70,300,0,3fc0,7,f000,0,3fc0,0,0,0,3fe0,0,0,8000,3fe0,0,3f,ff00,1ff0,0,1ff,ffc0,1ff0,0,7ff,fff0,ff8,0,fff,fff8,ffc,0,1fff,fffc,7fe,0,1fff,fffe,3ff,8000,1fff,fffe,1ff,e000,1fff,fffe,1ff,f800,1fff,fffc,1ff,ff80,fff,fffc,3ff,ffff,87ff,fff0,3ff,ffff,c1ff,fff0,7fe,ffff,f07f,fff8,fc0,1fff,f801,e1fc,c00,ff,ff00,c

こんなふうにできたりして圧縮っていう観点で言えば2進数においてはRLEっぽかったりするわけです。(そう?)

エレガントに行こうじゃないか

だけど、よく考えよう。16bitで変換すると処理が重たいんです。「はぁ?何言ってんの?」って思うかもしれませんが、64bitのループ回数は37回ですが、16bitでやるとループ回数は147回、更に8回に1回の分岐処理が必要になって64bitで変換したものを処理するのに比べて相当なリソースを使用することになります。
ここは?容量が少し増えるけれども、処理が単純で早い方を採用するでしょう?
いやね、実のところもう少し小さい感じでも組めたんですが処理がぜんぜんエレガントじゃなかったんでボツですボツ。

という感じでただ暇だったので、Carelyちゃんをいい感じで愛でようっていうブログでした。

ばいばーい