Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料
Search
Yusuke Endoh
March 18, 2022
Programming
91
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料
https://cookpad.connpass.com/event/238257/
Yusuke Endoh
March 18, 2022
More Decks by Yusuke Endoh
See All by Yusuke Endoh
Practical TypeProf: Lessons from Analyzing Optcarrot
mame
1
2.8k
型システムを知りたい人のための型検査器作成入門
mame
15
5.3k
TRICK 2025 Results
mame
0
5.6k
Writing Ruby Scripts with TypeProf
mame
1
1.4k
An Invitation to TRICK: How to write weird Ruby programs
mame
1
1.3k
TypeProf進捗
mame
0
120
12年前の『型システム入門』翻訳の思い出話
mame
14
2.8k
Good first issues of TypeProf
mame
4
10k
Revisiting TypeProf - IDE support as a primary feature
mame
1
3.7k
Other Decks in Programming
See All in Programming
AIとASP.NET Coreで雑Webアプリを作った話
mayuki
0
520
Spec Driven Development | AI Summit Lisbon
danielsogl
PRO
0
190
生成AI時代にこそ効くGo | Why Go Works in the Age of Generative AI
mom0tomo
8
3.2k
キャリア迷子上等 ─ "ない道"は自分で作ればいい
16bitidol
3
2k
過去最大のMCPアップデート! 2026-07-28 RC版の謎に迫る
licux
6
280
3Dシーンの圧縮
fadis
1
760
OSもどきOS
arkw
0
560
AI時代の仕事技芸論 — ソフトウェア開発で「遊ぶように働く」職人的熟達のすすめ
kuranuki
2
670
AI時代のUIはどこへ行く?その2!
yusukebe
21
7.1k
気づいたらRubyで100作品 ー クリエイティブコーディングが生活の一部になるまで / 100 Ruby Sketches Later: How Creative Coding Became Part of My Life
chobishiba
3
570
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
utgwkk
3
730
JJUG CCC 2026 Spring: JSpecify で実現する Kotlin フレンドリーな Java API 設計
ternbusty
1
160
Featured
See All Featured
A Soul's Torment
seathinner
6
2.9k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
65
56k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
310
The SEO identity crisis: Don't let AI make you average
varn
0
490
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
390
YesSQL, Process and Tooling at Scale
rocio
174
15k
Crafting Experiences
bethany
1
180
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
420
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
410
Odyssey Design
rkendrick25
PRO
2
690
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
230
Transcript
クックパッド 春の超絶技巧パンまつり 超絶技巧プログラミング編 講師:遠藤 侑介(@mametter) 1
講師:遠藤 侑介(@mametter) •プログラミング言語Rubyの開発が仕事です • ちょっと変なプログラムを書きます 2
TA:茂呂 智大 (@slightair) • エンジニア統括マネージャー 兼 モバイル基盤部 部長 • エンジニア組織づくり、採用、社内のモバイルアプリ
開発基盤の環境改善が仕事です • Ruby の開発はしていませんが Ruby はよく書きます、 大好きです • 変なプログラムは書けませんが、それがどうして動く のか考えるのは好きです 3
4
5 eval$s=%q(;eval" "+%w(z=?¥s;t=z+?¥n;$><<( t*5+"eval$s=%q(#{$s.gsub(/#.*/){ $&.tr(z,?¥x21)}})¥n"+t+(0..6).map{|y |(0..47).map{"co@@@@@@okpad¥x21".upcas e["h7sam@@@@@@b@@ @@jw@@@@@@@24yz3n dq4vk3q@@ @
@@ @@tzcro eg26ut5@ @ @2xbkt rzzvizj@ @j1uy1 ubzk8xhw@ @ @fj3q33 0".to_i(3@@ @@@@@@6)[_1*7 +y]>0?_1/7:@@@ @7]}<<?¥n}*""+ t*5).gsub(/.@ @+/){$&.strip .center(66)@ @@@@@@@@@@@@@@@}.gsub(/./){t =?¥x21==$&@ @;u=$`.size>1 800;"¥e[@ @48;2;#{u&&t| |z==$&?"@@@@@@@@@@@@@@@@@@255;255;255" :u||$&==?¥x40?"64;28;0":"255;153;51" }m#{(t)?z:$&}¥e[0m"};exit).join. ## (C) 2022 Cookpad Inc. gsub(?¥x40,"")) https://gist.github.com/mame/97d352962539d5065e97487d287e74aa
6
クックパッドロゴのQuine •Quine:ソースコード自身を 出力するプログラム ※特別な許可をもらって作ってます! 会社のロゴは大切な知的財産なので、 他者のロゴを勝手にQuineにするのはやめましょう 7 eval$s=%q(;eval" "+%w(z=?¥s;t=z+?¥n;$><<( t*5+"eval$s=%q(#{$s.gsub(/#.*/){
$&.tr(z,?¥x21)}})¥n"+t+(0..6).map{|y |(0..47).map{"co@@@@@@okpad¥x21".upcas e["h7sam@@@@@@b@@ @@jw@@@@@@@24yz3n dq4vk3q@@ @ @@ @@tzcro eg26ut5@ @ @2xbkt rzzvizj@ @j1uy1 ubzk8xhw@ @ @fj3q33 0".to_i(3@@ @@@@@@6)[_1*7 +y]>0?_1/7:@@@ @7]}<<?¥n}*""+ t*5).gsub(/.@ @+/){$&.strip .center(66)@ @@@@@@@@@@@@@@@}.gsub(/./){t =?¥x21==$&@ @;u=$`.size>1 800;"¥e[@ @48;2;#{u&&t| |z==$&?"@@@@@@@@@@@@@@@@@@255;255;255" :u||$&==?¥x40?"64;28;0":"255;153;51" }m#{(t)?z:$&}¥e[0m"};exit).join. ## (C) 2022 Cookpad Inc. gsub(?¥x40,""))
今日のテーマ:超絶技巧プログラミング •あえて実用性のないプログラムを書いて遊ぼう • ふつうのRubyコードの話はしません • クックパッドの業務の話もしません 8
超絶技巧プログラミングで得られるもの •コンピュータ科学の理論にふれるきっかけ •プログラミング言語についての深い理解 9
今日の流れ •13:15~14:15:講義 •14:15~17:00:実習 • 17:00~18:00:発表会 •超絶技巧プログラミングコンテストに投稿を! • TRICK 2022(締切:2022/07/31) •
https://github.com/tric/trick2022 10
講義内容 •➔超絶技巧プログラミングの事例紹介 • 基本テクニック3点 • プログラムをアスキーアートにする • ターミナルで遊ぶ • Quineを書く
11
Quineリレー • 自分自身を出力する REXXプログラム、を出力する rcプログラム、を出力する … Scalaプログラム、を出力する Rustプログラム、を出力する Rubyプログラム https://github.com/mame/quine-relay/blob/master/QR.rb
12
Green-square Quine • https://github.com/mame?from=1970-01-01&to=1970-12-31 eval s=%q"n=t • https://github.com/mame/green-square-quine 13
もっと見たい人は •参考書をみてください 14
講義内容 •超絶技巧プログラミングの事例紹介 •➔基本テクニック3点 • プログラムをアスキーアートにする • ターミナルで遊ぶ • Quineを書く 15
Tip 1: アスキーアートプログラム 1. 好きなRubyプログラムを書く 2. 空白と改行と円マーク ¥ を避ける 3.
おまじないで囲む 16 puts "Hello world!" puts("Hello"+32.chr+"world!") eval(%w( puts("Hello"+32.chr+"world!") )*"") この範囲を自由に整形できる
たとえば 17 eval(%w(put s("Hello"+3 2.chr+"worl d!"))*"") eval(%w(puts( "H el lo
"+ 32 .c hr +" world!"))*"") eval(%w(p ut s( "H el lo "+ 32 .c hr +" wo rl d!"))*"") つぶしたり 四角にしたり 円にしたり メソッド名や数字の途中で 改行してもOK 文字列の途中に スペースいれてもOK
仕組み •Rubyの%w記法は「文字列の配列」を返す • 配列を掛け算すると連結した文字列になる • evalは文字列をコードとして実行する 18 %w(pu ts( 42))
#=> ["pu", "ts(", "42)"] %w(pu ts( 42))*"" #=> "puts(42)" eval(%w(pu ts( 42))*"") #=> 42
練習問題(5分) • 自己紹介を出力するプログラムを イニシャル形状にしてみましょう • 余分はコメント(#)などで埋める • 別のメッセージ・形状でも可 •gistに置いてSlackへ提出ください 19
eval(%w( pu ts ("Yusu Ke -E nd oh,h obby:w al ki ng ") ###### ## ).join) eval(%w(puts("YusuKe -E nd oh,h ob by :w alki ng")## ### ##### ## #### ###### ###### #### ## ## ## #############).join)
解説 •正解はありません、動けばOK! •手編集が面倒くさいなあと思ったら→自動化 20 code = %q(puts("YusuKe-Endoh,hobby:walking")).chars puts <<END.gsub("#") {
code.shift || "#" } ## ## ###### ## ## ## #### ###### ## ## ## ## ###### ## END
Tip 2: ターミナルで色の表示 • "¥e[数字m"で色を指定、"¥e[m" で指定解除する • 最近は"¥e[38;2;R;G;Bm"でRGB指定もできる • 注:cmd.exeやTerminal.appでは動かない
• Windows TerminalやiTerm2を使ってください 21 puts "¥e[31mfoo¥e[m" #=> foo(赤い字になる) puts "¥e[41mfoo¥e[m" #=> foo(背景が赤くなる) puts "¥e[38;2;255;0;0mfoo¥e[m" #=> foo puts "¥e[48;2;255;0;0mfoo¥e[m" #=> foo 30黒 40黒 31赤 41赤 32緑 42緑 33黄 43黄 34青 44青 35紫 45紫 36水 46水 37白 47白
練習問題(5分) •好きな色付きメッセージを出してみましょう •発展:コードをアスキーアート化しましょう • おまじない eval(%w( ... )*"") で囲む •
ヒント:"¥e[数字m" のかわりに 27.chr+"[数字m" 22 $ ruby color-message.rb Hello, world!
解説 •たとえば • アスキーアート化するには 23 puts "¥e[37;46mHello¥e[m ¥e[33;41mworld!¥e[m" eval(%w( e
= 27.chr; puts(e+"[37;46mHello"+e+"[m"+32.chr+e+"[33;41mworld!"+e+"[m") )*"")
なぜ円マークは使えない? •¥ と e の間に空白や改行が入ると動かなくなる • 興味があったら実習時に試してみてください 24 eval(%w( puts("¥
e[37;46mHello¥e[m") )*"") ここに空白が入ると意味が変わる
Tip 3: Quine •自分自身を出力するプログラム • 哲学者Willard van Orman Quineに由来 25
$ ruby quine.rb > quine2.rb $ diff –s quine.rb quine2.rb ファイル quine.rb と quine2.rb は同一です
間違ったQuineの書き方 • …を出力するプログラム • それを出力するプログラム • それを出力するプログラム • この方針は明らかにきりがない 26
puts "..." puts "puts ¥"...¥"" puts "puts ¥"puts ¥¥¥"...¥¥¥"¥""
ただしいQuineの書き方(1) •…を出力するプログラム • このコードを eval で包む • %q[...] は文字列リテラル "..."
とほぼ同じ 27 puts "..." s = %q[puts "..."]; eval s
ただしいQuineの書き方(2) • … の代わりになるべく↑を出力するようにする 28 s = %q[puts "s =
%q[...]; eval s"]; eval s s = %q[puts "..."]; eval s
ただしいQuineの書き方(3) •… の位置に入るべき文字列は、変数 s そのもの •答え: 29 s = %q[puts
"s = %q[" + s + "]; eval s"]; eval s #=> s = %q[puts "s = %q[" + s + "]; eval s"]; eval s s = %q[puts "s = %q[...]; eval s"]; eval s
練習問題(10分) • Quineを実際に動かしてみましょう • ちょっと違う形式でQuineを書いてみましょう • 【やや難】自分自身を反転して出力してみましょう • 【難】自分自身を赤字で出力するようにしましょう •
ヒント:%q[...] は %q{...} などに置き換えよう 30 eval(s = %q[puts "...ここを埋める..."]) s = %q[puts "s = %q["+s+"]; eval s"]; eval s
解説 •答え: • 文字列内の式展開を使ってもいいです •赤字Quine: 31 eval(s = %q[puts "eval(s
= %q[" + s + "])"]) eval(s = %q[puts "eval(s = %q[#{ s }])"]) eval(s = %q{puts 27.chr+"[31meval(s = %q{"+s+"})"+27.chr+"[m"})
講義はここまで 32
実習 • 好きなプログラムを自由に書いてください • 講義内容を参考にしても、しなくてもよいです • 次ページのネタ案も参考に • 15:30ごろから講師とzoom雑談(1人3分くらい) •
何を作ろうとしてるか講師に聞かせてください! • 17時ごろから発表 • githubに置いてSlack提出してください(gistでも可) 33
ネタ案:へんな見た目のプログラム •アスキーアートの形をしたQuine • アスキーアート+色+Quine • 今回の講義内容の組み合わせでできる(はず) • ヒント:Quineの中にアスキーアート化のおまじないをうまく混ぜる • 【難】色がついたまま
実行可能なQuine • ヒント:コード中にエスケープ シーケンスを混ぜる 34 $ ruby quine.rb eval(...色つきコード...) $ ruby quine.rb | ruby eval(...色つきコード...)
ネタ案:エンコードQuineを極める • 自分自身を難読化して出力するQuine • ヒント:putsの前にBase64.encode64を通せばよい • 【やや難】自分自身を出力するPythonプログラムを 出力するRubyプログラム • ヒント:Pythonの"""文字列リテラルを使うとちょっと簡単かも
35 $ ruby base64-quine.rb | base64 –d > base64-quine2.rb $ ruby base64-quine.rb | python3 > base64-quine2.rb
ネタ案:Quineを進化させる •実行のたびに長くなるQuine風コード • ヒント:普通のQuineにコメント # を足すだけでできます •【難】実行のたびに1増えるQuine風コード 36 eval(s=%q[...ここを埋める...]) #=>
eval(s=%q[...ここを埋める....])# #=> eval(s=%q[...ここを埋める.....])## n=1;eval(s=%q[...ここを埋める...]) #=> n=2;eval(s=%q[...ここを埋める...]) #=> n=3;eval(s=%q[...ここを埋める...])
ネタ案:アスキーアートを極める •【やや難】コードより大きいアスキーアートを 表示する • 300文字のコードで横40 x 縦20(800文字)の アスキーアートを表示するなど • 圧縮を実装する必要がある
• ランレングス圧縮、Byte Pair Encodingあたりが簡単 • 基本的な構造→ 37 data = "アスキーアートを圧縮したデータ" print(展開(data))
ネタ案:形状を変化させるQuine •【激難】"A"形状と"B"形状を行き来するQuine • 初期状態は"A"形状 • 実行すると自分自身を"B"の形にして出力する • "B"の形を実行すると"A"に戻る • ヒント:アスキーアート化プログラム+圧縮+Quine
全部組み合わせる必要がある 38
ネタ案:アニメーション •端末に何回も上書きする •エスケープシーケンスを使う • ¥e[H • カーソルを画面左上に移動する • ¥e[2J •
画面の内容を全部消す • 参考:https://en.wikipedia.org/wiki/ANSI_escape_code 39 print "¥e[H¥e[2J" (0..).each do |i| print "." * (i%10) print ":" print "." * (9-i%10) print "¥e[H" sleep 0.1 end
ネタ案:その他 • 【難?】今日の内容をRuby以外の言語で再現する • evalや%w()がとても便利なことがわかる • 【?】自分の得意な技術と今日の内容を組み合わせる • アスキーアート ×
競技プログラミングのアルゴリズム • Quine × Next.js、Quine × Unity、Quine × AI • うまくできたら → https://github.com/tric/trick2022 40
余談:哲学者QuineとプログラムQuine(1) •命題: • この命題は真とも偽とも言えない •「この命題」で命題自身を参照してるのが肝 • 次のQuineと同じ構造 41 この命題は偽である puts
File.read(__FILE__)
余談:哲学者QuineとプログラムQuine(2) •哲学者Quineが研究した間接的自己言及の命題 • 「この命題」みたいなインチキなしで 同じ構造を作り出している • expr => v は
v = expr と(ほぼ)同じ意味 • s.dumpは文字列を引用形式にする 42 「は、自身の引用を前置されると偽になる」は、 自身の引用を前置されると偽になる " => s; puts s.dump + s" => s; puts s.dump + s
余談:哲学者QuineとプログラムQuine(3) • 自己言及は計算機の理論分野でわりと登場する • 停止性問題 • プログラムが有限時間で停止するかどうかを判定するアルゴ リズムは書けない • クリーネの再帰定理
• チューリング完全な言語では自己言及が構成できる • ゲーデルの不完全性定理 • よくわかりません • 興味があったら→理論計算機科学、数理論理学 43
おわり •超絶技巧プログラミングとは、 おもしろい理論・技術をおもしろく実践する遊び •作ったものはぜひ発信していきましょう • 感想記事でも、YouTubeでも、GitHubの肥やしでも • うまくできたら → https://github.com/tric/trick2022
44