ランレングス符号化した文字列からCarelyちゃんを描いてみた | Dev Driven 開発・デザインチーム ランレングス符号化した文字列からCarelyちゃんを描いてみた | 働くひとと組織の健康を創る iCARE

BLOG

ランレングス符号化した文字列からCarelyちゃんを描いてみた

2022/12/03

はいどうもー。iCAREのクドウマサヤ(@masaya_dev)です。
これはiCARE Dev Advent Calendar 2022の第1レーン3日目の記事です。

はじめに

早速ですが、お手元のirbで以下のコードを実行してみてください。

print "031,102,030,n01,022,120,021,n01,018,128,017,n01,015,134,014,n01,013,138,012,n01,011,142,010,n01,009,114,018,114,008,n01,007,113,024,112,007,n01,006,112,028,112,005,n01,005,111,032,111,004,n01,004,110,036,110,003,n01,003,110,009,103,014,103,010,109,002,n01,003,109,010,104,012,104,021,n01,002,109,012,101,016,101,022,n01,001,109,053,n01,001,109,053,n01,001,109,053,n01,001,108,013,102,016,101,022,n01,001,108,015,103,010,102,024,n01,001,108,019,107,028,n01,001,108,054,n01,001,109,037,101,015,n01,001,109,031,114,008,n01,002,109,027,119,006,n01,002,109,025,123,004,n01,003,109,023,125,003,n01,003,110,021,127,002,n01,004,110,020,128,001,n01,005,111,018,128,001,n01,006,112,016,128,001,n01,006,114,014,127,002,n01,006,118,011,126,002,n01,005,127,004,123,004,n01,005,128,005,121,004,n01,004,110,001,120,005,120,003,n01,003,106,009,118,010,104,004,107,002,n01,003,102,018,116,020,102,002,n01,063,n01".split(',').map(&:chars).map { |e| e[0] * e[1..2].join.to_i }.join.gsub('n', "\n")

え、スマホで読んでいてirbが動かせない?そもそもirbって何?
そんなあなたの為に、あらかじめご用意しておいたものがこちらになります(キューピー3分クッキング風)

ワンライナーCarelyちゃん

はい、なんと弊社でお馴染みのCarelyちゃん(@iCARE4U_info)ロゴがコンソールに描かれます!パチパチパチ〜。

というわけで、今回はこのコードについてお話したいと思います。

きっかけ

私は今年9月、弊社がスポンサードをしたことがきっかけで、RubyKaigiというテックカンファレンスに参加させてもらいました。(参加レポ)

そのイベントの中で、TRICK(超絶技巧Ruby意味不明コンテスト in RubyKaigi)と呼ばれる、Rubyで特に役に立たないけど面白いプログラムを書いて競うという、ユニークなコンテストが行われることを事前に知りました。

RubyKaigi参加直前の休日に、過去の入賞作品眺めて刺激を受け、自分でも何かRubyでそれっぽいもの書けないかなと、遊んでみた結果が上述のコードとなります。

ざっくりコード解説

なるべく短いコードでCarelyちゃんを描きたいというのが今回の目的でした。
最初にだーっと続いている謎の文字列には、ランレングス符号化という、データ圧縮に用いる符号化方式によって、Carelyちゃんをどう描くかという情報が詰まっています。

例えば冒頭の031,102,030,n01が出力されたCarelyちゃんの1行目に該当するものでして

031→0を31文字
102→1を2文字
030→0を30文字
n01→改行を1回

という情報を込めています。それをsplitやmap、joinなどでごにょごにょすることで

000000000000000000000000000000011000000000000000000000000000000

が1行目に表示されるようにしています。
改行用のコードを除いて1行目の情報量を比較すると、圧縮前が63バイト、圧縮後が11バイトとなっていて、圧縮によりソースコードをより短くすることに成功しています。

ランレングス符号化は画像データの圧縮によく用いられている方式なんですが、自分でコードに落として効果を確かめてみるのは面白いなと感じました。

挑戦者求む

このコードは2時間くらいで書き上げたものなので、より短くしたり、美しくしたり、まだまだ改善の余地があるのではないかと感じています。

もっとこう書いたら面白くなる!というアイデアをお持ちのiCAREメンバーや野生のRubyistの方々、ぜひアドバイスください。一緒に遊びましょう。そして一緒に働いてくださるプログラマも絶賛募集中です。

久しぶりにこういうお遊びコードを書きましたが、やっぱりプログラミングは楽しいですね。ではでは!