Last active
May 20, 2024 08:40
-
-
Save tompng/a4ca6eca4836014afe8a68227fdd7cac to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
⠁⠠⠐⢀⢀⠄⠁⠄⠐⠂⠁⢀⠁⢀⠈⢀⢀⠈ | |
⠠⠈⠈⠄⠁⡁⡁⠃⢅⡤⠴⡔⢉⢄⢁⡄⠙⡐⢃⠬⠎⢁⡠⠢⡂⠌⠈⢀⢀⠈ | |
⠁⠠⠐⡈⠆⢁⢅⢅⡰⣐⠔⡖⠍⢑⢕⢩⡲⠃⠌⡆⡊⠴⣔⠔⣐⠢⡜⡜⠠⠏⢀⠁⠆⠢⠊⠁⠐⡀ | |
⠐⢀⡀⠰⠦⠉⢆⠖⠞⢸⠅⢒⢑⠺⡜⢴⣖⡞⢈⠏⡯⣚⠰⠃⣄⡻⢮⢞⣖⠿⢈⢸⡏⡨⠾⡬⠒⢐⡅⢠⠃⢁⡂⠑⠁⠐ | |
⠐⢀⠤⠨⢁⠏⠛⠤⠏⠸⡂⠝;BEGIN{->s{eval((a="⡉⢐⡊⡕⢹⢨⡃⢚⣀⢃⠂⠠⠂⠜⠩⠄⠄⠠ | |
⠄⢀⠑⠋⠅⠫⠄⠒⠏⡪⡕";s.gsub(/[^!-~]/,'')))}.[]"⠩⡖⡶⠹⢳⠄⢪⣇⣌⡪⡐⠃⠕⠜⠒⠈⠈ | |
⠈⠂⠂⠊⢅⡍⡄⡗⣌⡴⠁⡒$s=[⡙⠭⣐⢚];⢧⡸de⢴f⡨(⠮⢵s⠷e⢗⠙⠏lf).⠖⢀⢤⣾⢱⢍⡰⠆⡔⠏⢑⠣⢈⡃⢀⡂⠐⡀ | |
⠁⠁⠆⡢⢈⡡⠔⠛⡪⡲⢂⢊⣏met⣄⠂⣰hod⢭⠱_⢳mi⣷ssin⡫g⡓(a⠴⢸⡲)=$⠝⡎⣓⢵⣏⡢⢼⡐⢸⣋⣁⡰⠮⢤⡨⠤⡀⠂ | |
⠄⠠⣀⡒⡋⠣⢌⠑⣇⡖⠧⣙⡙⣻⡌s<<⡾⡾a⡳.⢸to⢯_⡌s;⢟⣣⡾at_⠞e⡡x⠷⢒it{⢆⡝⣆⢛⠋⢮⡻⡖⡵⣍⡤⢑⡢⣡⠂⠭⠡⠙⠂⢀ | |
⠠⠂⢂⢐⢀⡒⡋⡋⡱⣢⠋⡂⣕⢋⢪⠳⢁a,b⣃⢾=⣯⡆a.sp⡼l⡣it;⢼⡌c,*⣺⠰⢇d,e⢦⠧⡏⣪⣃⢯⢗⠶⣠⠦⠝⡲⠩⣃⢶⡮⠧⠱⡨⠒⠂⠈ | |
⠂⠄⠰⡑⠁⠴⡬⠳⠍⢦⢘⠠⢺⣣⣈⢩⢆⣪⣲=s⠸⢉⡲.⠪⡀⠺⠙⡐⠐⠵⣛⢥⠫⠖⠊⣐⣕⣏⡥⢫⢟⠭spl⡆⡃⡽⢻⡍⡈⢲⢐⡠⠥⡒⢸⣾⣤⡝⡒⡀⢡⠱⠔⠚⠈⠠ | |
⠠⠠⠡⡰⡘⡜⡴⣁⢮⠕⣸⡑⠋⣉⡓⢬⠮⡭⠓⣬it⢉⡻⣋⣇;$s[⡑⢓4]+=?x⠒⡅*20+a;$s[⡧⣿⣝⣔⣦⣿⣻⡡⠠⢣⣭⠔⢡⠙⠔⣂⢠⢌⠃⡂⠜⠠⠁ | |
⠈⡀⠎⠐⡕⢄⢼⢖⣇⢰⣈⢒⠈⠖⣏⣺⣠⡈⣉⢊5]⠄⡮=e+?⡲⢒x*3+⢇⡜⣦⡏$s[5⠞⡹⡘⠗];$s[⣂⡗⡋⣭⢽⢎⡠⣏⢦⡓⣴⠽⢵⣠⠶⡮⡭⢈⠰⢈⠠⠈⠂ | |
⠁⠂⠜⠎⠌⡑⠰⡪⠪⠵⣩⢃⢴⡇⢍⡉⢚⡾⠻⢮⢩5,0]=⣄⠣⠺⠣⣀⠿[b⡔⣚⢪⣻⡴⡖+?x⡬⡲⢿⣰⣉⡥*⢼28⣯⠡⡒⠾⠻⠳⠠⡨⣚⣠⡛⢟⣀⠃⠗⠭⢀⠋⢕⠦⠒⠠⠂ | |
⠂⢀⠁⡂⠭⣢⠜⡹⡻⢶⣝⢕⡺⡂⡪⠮⢖⣠⣊⢉⣊+c]⡟⡮⢚⡾⣢⠯⡧⠹+d⣻⢘⠒⠊⣟⣂;n=⣝⢗⡙⡥⢛⡬0⣲;a⢖⠙⠪⡧⡗⡞⢃⠳⠡⢍⡨⣑⡄⠨⡖⡍⣈⡅⠡⠠⠬⢀⠠ | |
⠠⠁⡀⠩⠧⡡⢁⣅⠴⢴⣈⣶⡔⢩⣻⠤⢙⢍⢛⢶⠚⢖⡝=(1⠨⡫⠺⣌⣷⠰⣟..2⡒⣜⢰⡫⠲⣲55)⡥⠡⣺⠂⡣⡬.⣾so⢮⣼⡚⠅⢯⣗⠼⣜⡑⣀⣲⣾⠹⢎⢇⠱⢇⢣⢂⡊⢈⡀⠐ | |
⠁⠄⠓⣀⠨⡮⣁⡬⢷⣀⡬⡘⡥⢟⠓⡨⣯⢓⠻⢾⠠⢳⠻r⢄t⢛⠈⣼⢈⣹⡏⣠_⢵b⡮⡴⢼⢧⢷⢭y⣖{(⠿⡇⠌⠴⠢⣃'%b⣏⡰⠿⣛⡝⠦⣑⠷⢳⢀⠣⡀⣆⡶⣑⠌⡤⢓⠰⡀⡄⠠⠂ | |
⢀⠁⡁⢅⠌⣠⠾⠘⣎⠽⡼⢦⡮⣣⣢⣓⣓⠝⠐⢵⢁⠎⠳⣆⣟'%⣾⢋⡬⣱⢙⡶⠌⠼_1)⢛⣱⠔⠹⢒.⣯c⣏o⢇⠎⣈⢎⠜unt⡶⡝⢪⢶⣿⠢⠄⡱⣤⣰⠞⢗⡘⠒⣕⠿⣬⠮⠼⠮⠈⠜⠁⠄ | |
⡀⠐⠐⠂⡐⠽⠵⡓⢫⡈⢭⠺⠽⢨⢍⡳⠻⢼⡡⠺⠞⣢⡩⡤⡄(⠪?⢉⠹⠫⠧⡓⡳⠷1⠊)⢲⡿⢆⣕⡝⣦<⡒<⢮1⡴⣕⠏⣡⠩0|_⠐⢰⢍⢞⠑⢭⡤⣻⡪⣢⢑⢙⡨⡼⡥⢖⣖⡑⠏⠕⠂⡀⠐ | |
⠁⢀⠆⠡⣠⠶⡼⣘⡗⣠⡫⢴⢹⣭⡅⣳⡺⡮⠩⢐⢔⠂⢯⣠⣮⢟1};⡧⠥⢊⡤⠞⠊⠃$s.⡋⢗⣁⡱⠶m⣂⡗ap⣅⢝⡿⢬⡻⢌{|⡡⣓⣒⢝⠊⡐⠧⠽⢵⣧⠋⢂⢻⢤⣜⡍⢏⣆⠊⠣⠄⠂⠁ | |
⠠⠂⡈⡐⢅⠇⡊⢄⣲⠂⡆⠱⢍⠓⣸⠰⡻⣦⣟⣮⡩⠭⣔⡷⣤⠢s|(⣲⢖⣇⡲⣆⡜⣕m⡐=⠓⣩⣠⣠⣮s⢪⡥.⡅s⣙⢙⣍⠗⣨iz⣝⣸⠝⡀⢐⢪⠻⠝⣤⡟⢆⡢⡉⠓⣓⡄⠕⠹⡂⠬⡁⠂⠂ | |
⢀⠐⠥⠂⢦⠨⡭⢒⣶⢶⠉⢆⡷⢆⡘⡗⠦⢘⠰⡄⠣⠬⠧⢆⣩⠜e)⣫.⠫⢩⡭⣏⠯⣻⠻tim⢍⢬⢵⣄e⣛⡔⢱s⡐{⣏⣕⢅⣎|i⣴⢟⢰⣷⣣⠢⢂⣖⣊⢶⣙⢿⠙⣄⠚⣠⢬⡙⡊⠘⢠⠂⢀ | |
⡀⠠⠌⠝⠍⣃⠩⢹⢴⡅⢯⣴⡶⣩⣘⢨⡖⣏⡂⢂⡴⡜⡻⠞⠿⣰⠽|⣔⣜r⢌⢌⠃⡴⣐⠨=⡂4⢜⢴⠂⡾0⡮⣺⡜⠗-⡏i⡶⢌⢬*(m⡕⡣⢄⡑⣿⡴⣫⠙⣃⣔⢩⢜⣞⢌⣫⡆⢲⠳⠙⠙⠁⢀ | |
⠠⠈⡈⢢⠡⡛⢁⠡⡂⡃⡍⡟⡬⣄⢄⢎⡩⡖⡷⢼⢎⡌⣞⢮⢁⣗+⢈⡬~⡢⠎⣰⢸⢶⠘⡮i)/⠥⢆⣮4⣨⢙⠳⢖0⣶⢢;⣐⡃s[i⡠⡋⣕⡝⣳⣳⠫⣦⡞⠱⡶⠤⢾⠈⡲⠁⢈⠗⠢⢀⠄ | |
⠐⠄⠂⢤⠪⢬⠖⠑⣋⠱⡆⠍⠠⡵⡓⣤⢹⣥⣉⣗⢺⡗⢥⠖⣬⡹]⢦⠲>⢌⢥⢭⠂⣽⣀⠠?⠼~⣩⢰⢓&⢠⡚⢤⠓⢽&⡸⢧n⣮=a.⡃⣗⡒⡕⢍⣰⣣⢌⡑⡃⢤⣞⡔⠕⣔⠭⠭⠬⠢⠐⠈ | |
⢀⢀⠆⣄⠈⣤⣎⣄⢋⢗⡹⢊⠑⠢⡥⢡⠅⢿⡐⡁⡌⠹⢟⡂⢱in⡩⣫d⡒⣃⢑⣘⠑⣗e⣉x(⠡⣇⢾s⢷⣮⢔⢺⡆[⢜i⠫].⡞o⢴⡶⣄⠽⣷⠗⡃⣃⣊⢜⡑⠊⠮⠖⠔⠄⠈⠠⠐ | |
⠠⠂⠇⢅⡦⢚⢳⢱⣸⡼⣏⣃⠞⠪⠙⡤⡇⠪⣍⢠⣓⠃⡕⠹⡚rd⣥⣭&⢯⢗⢖⣯⠈⢻0⣶xf⢐⠁⡒f⣣⠗⢤⣵⡬)⢈+⣃n*⡿(⡉⢮⡛⡬⠭⡢⠌⡤⡽⠇⣇⣈⠟⢖⢜⠬⠆⠂⠈ | |
⠠⡀⠩⢂⢤⢋⠲⢶⠁⢺⢻⠼⣡⡐⢚⡽⡮⢒⡋⢏⣂⠓⡵⣆8+⣜(⠡⣚⠔⢓⠰⢤⣧3⡅⠻9-⢣⡃r⣤⣆⣗⢪⣧)⣭*⡖22⣬)⡗⣭⠈⡤⢶⠇⠢⠝⣖⡞⡟⠎⢌⠝⠗⠘⠈⠈ | |
⠠⡀⠨⡢⡖⡩⡎⡖⢀⢒⠲⣨⡷⠛⣡⠢⢷⣛⢇⢄⣫⡸⠐⠄.ro⡚⡉⢠⣲⠒⣑⡌u⢙⠟n⣃d⡕⢴.⡚⠽⣞⢇⢌cl⢵am⠴p⡦⠙⡀⢙⠱⣓⡜⠖⠲⣂⠬⣡⡅⢆⠖⠄⠁ | |
⠂⠁⡀⡈⠍⠗⠮⢆⠖⢯⡄⢳⣋⠹⠑⢐⠡⠽⡌⠊⡛⡴⣂(8,⠲⣑⢀⢭⢵⡒⠶2⣁⡍5⢛5⠫⢽)⡴⡣⣻⣻⡌}}⢥⡸;⢓r⠖⢄⢈⣋⡻⠒⣘⢝⠮⡖⡸⡘⠢⠠⠈⠈ | |
⠠⠐⠡⠙⡕⠈⠴⢂⡚⡓⡯⣘⠔⡕⠢⠟⠧⠊⣖⢥⠥⢃eq⡜⣉⣹⣑⠳⢇⡹⢬u⣧⢼i⡦⠕r⡝⡒e⠨⢻⢳⡝'⠿⡘⠬zl⡫⠈⣋⡴⠪⠯⡌⢰⣖⠡⡪⢊⣀⠪⠂⠁ | |
⠠⢀⠍⠦⠝⠔⡈⢂⡭⡦⠦⠠⡣⠆⢿⡞⢦⣊⣨⣫⡟ib'⠤⢶⠧⢰⣋⣚⠟;⣌⣟e⡄⢾v⣡⣐a⡏⣴⢠l(⢰⡐⠪Zl⠱⡱⡊⠒⢔⣏⠽⠝⠜⠇⣐⡃⠪⠈⠁ | |
⠈⠐⠨⠢⡃⠬⡈⡂⢩⢺⠰⠅⡧⡐⣩⡻⡔⠋⣭ib.⡓⡃⣻⠞⣿⠦⢡⣎⢮⢅i⣌⢋n⣘⠤⠘f⡛l⢈a⣇⡽⡄te⣪⠴⣬⡌⡢⠨⢥⡩⠚⠜⡀⠁⠁ | |
⡀⠠⠨⠜⢨⣀⠎⠭⣍⠜⡚⡽⣠⣪⣡⠸⣧(⠉⢸n⣨⣉⣽⣪⢒⠮⢹⠝⡃.⡂⢃⡙⣴d⠮⢡⠩i⢖⡫g⣯⡱⢏it⢿⢆⠩⠦⡣⠦⠬⡄⠉⠌⠁⠠ | |
⡀⠐⠢⣀⠔⢔⠖⣰⠪⣎⡐⢯⠓⣑s⣊⣵⢲(2⣽⡞⢆⠴⣴⡕⠺⢻5⣀⢬⢛⡄6⣷⢶)⡻.p⢁⡝⠖a⢴c⢪⡆⠙⡚⠜⠰⠢⠡⠁⠄ | |
⠐⠂⡂⠘⠄⠁⠗⢑⢩⢣⠐⢁⡌⠚k⡾'⣚⢦⣶⣀⢋⠥⢶c⠝⠉⣔⣞⡫⡽*'⡤⠉⡓)⠐⡐⢏)⠆⡸⠨⢤⡢⡄⠄⠠⡀ | |
⠠⠐⠒⠔⡂⠂⠇⡆⡨⠧⠑⡎⡝⣊⡄⢘⡲⢘⣳⠮⢝}⢜⠌⡃⢙⡸⠈⢦"};⡞⡈⠤⣉⡘⡊⠖⡑⠪⠖⢁⠄⠄⠈ | |
⠠⡀⠂⠑⡐⡉⠎⡡⠐⠵⠊⠏⠳⢦⣈⢆⡌⠩⠢⡓⠗⡃⢣⡬⡘⡢⡘⠸⠈⠰⠔⡰⠎⠈⠡⠠⡀⠁ | |
⠁⠄⠄⠁⢁⠂⢀⠑⡉⠁⢂⠸⠤⠍⢄⡉⠩⡒⠰⡄⠬⡢⠩⠓⠉⡄⠈⠈⠐⠈ | |
⠐⠈⠈⠐⢀⠠⢀⠠⠄⢀⠐⠠⠈⠠⠠⠂⢀⠁ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# rubocop:disable all | |
class KurageString | |
def initialize(n, len, p0, dir) | |
@n = n | |
@l = len.fdiv @n | |
@px, @py, @vx, @vy = (@n + 1).times.map { [*(p0 + _1 * @l * dir).rect, 0, 0] }.transpose | |
@arrays = 8.times.map{[]} | |
end | |
def update(p0, ff, dt) | |
p0x = p0.real | |
p0y = p0.imag | |
n = @n | |
px,py,vx,vy = @px,@py,@vx,@vy | |
fx,fy,dx,dy,a,b,r,ts = @arrays | |
(n+1).times { |i| | |
f = ff[@py[i]%1*19.9][@px[i]%1*19.9] | |
fx[i] = -1.7*@vx[i] + f.real/10 | |
fy[i] = -1.7*@vy[i] + f.imag/10 | |
} | |
# d[i] = ps[i+1] - ps[i] | |
# v_next[i] = v[i] + (fs[i] + d[i+1] * ts[i+1] - d[i] * ts[i]) * dt | |
# dot(v_next[i] - v_next[i - 1]), a[i]) = 0 | |
# first: | |
# v0 = (p0_next - ps[0]) / dt | |
# ll*ts[i] - dot(a[i],d[i+1])*ts[i+1] = dot(a[i],(v[i]+fs[i]*dt) - v0)/dt | |
# normal: | |
# 2*ll*ts[i] - dot(d[i],d[i+1])*ts[i+1] - dot(d[i],d[i-1])*ts[i-1] = dot(d[i],(v[i]+fs[i]*dt) - (v[i-1]+fs[i-1]*dt))/dt | |
# last: | |
# 2*ll*ts[i] - dot(d[i],d[i-1])*ts[i-1] = dot(a[i],(v[i]+fs[i]*dt) - (v[i-1]+fs[i-1]*dt))/dt | |
n.times { |i| | |
dx[i] = px[i + 1] - px[i] | |
dy[i] = py[i + 1] - py[i] | |
vx[i] += fx[i] * dt | |
vy[i] += fy[i] * dt | |
} | |
vx[0] = (p0x - px[0]) / dt | |
vy[0] = (p0y - py[0]) / dt | |
(n - 1).times { a[_1] = dx[_1] * dx[_1 + 1] + dy[_1] * dy[_1 + 1] } | |
n.times{|i| | |
b[i] = 2 * (dx[i]**2+dy[i]**2) | |
r[i] = (dx[i] * (vx[i + 1] - vx[i]) + dy[i] * (vy[i + 1] - vy[i])) / dt | |
} | |
b[0] /= 2 | |
(n - 1).times {|i| | |
b[i + 1] -= a[i] * c = a[i] / b[i] | |
r[i + 1] += r[i] * c | |
} | |
(n - 2).downto(0) { |i| r[i] += r[i + 1] * a[i] / b[i + 1] } | |
n.times { ts[_1] = r[_1] / b[_1] } | |
px[0] = p0x | |
py[0] = p0y | |
(1..n).each { |i| | |
qx = px[i] + vx[i] * dt + ((i < n ? dx[i] * ts[i] : 0) - dx[i - 1] * ts[i - 1]) * dt * dt - p0x | |
qy = py[i] + vy[i] * dt + ((i < n ? dy[i] * ts[i] : 0) - dy[i - 1] * ts[i - 1]) * dt * dt - p0y | |
qn = [@l / (qx**2+qy**2)**0.5, 1].min | |
vx[i] = -(px[i] - px[i] = p0x += qx * qn) / dt | |
vy[i] = -(py[i] - py[i] = p0y += qy * qn) / dt | |
} | |
(dx[0] + dy[0].i) * ts[0] | |
end | |
def render | |
hash = Hash.new(0) | |
lines(@px, @py, hash) | |
hash | |
end | |
end | |
def line(ax, ay, bx, by, h) | |
s = 160 | |
n=[s*(ax-bx).abs, s*(ay-by).abs].max.ceil | |
(n+1).times { |i| | |
x = ((ax*i+(n-i)*bx)*s/n).round % s | |
y = ((ay*i+(n-i)*by)*s/n).round % s | |
h[x/2+y/4*s/2]|=1<<(x%2*4+y%4) | |
} | |
end | |
def lines(xs, ys, h) | |
(xs.size-1).times { |i| | |
line xs[i], ys[i], xs[i+1], ys[i+1], h | |
} | |
end | |
def stroke(ps, h) | |
lines ps.map(&:real), ps.map(&:imag), h | |
end | |
def draw(hashes) | |
lines = 40.times.map{[' '] * 80} | |
chars = 256.times.map{((_1&135)+(_1>>1&56)+(160+_1[3]<<6)).chr'utf-8'} | |
{}.merge(*hashes) { _2 | _3 }.each{ | |
lines[_1 / 80][_1 % 80] = chars[_2] | |
} | |
print "\e[H" + lines.map { "#{_1.join.rstrip}\e[K\r\n" }.join | |
end | |
class Kurage | |
def initialize | |
@p = 0.5 + 0.5i | |
@v = 0 | |
@r = 0 | |
@dir = 1 | |
end | |
def update(dt, phase, fs, ff) | |
rf=vf=0 | |
ps(phase).zip(fs).each { |p, f| | |
vf += f / 1000 | |
rf += (p - @p).rect.zip((f*-1i).rect).sum{_1*_2} / 10 | |
} | |
t=trans(phase) | |
4.times { |i| | |
p = t[1i**i] | |
f = ff[p.imag%1*19.9][p.real%1*19.9] / 10 | |
vf += f / 16 | |
rf += (p - @p).rect.zip((f*-1i).rect).sum{_1*_2} | |
} | |
@v += (-@v + 0.05 * @dir * (1 + Math.sin(phase)) + vf) * dt | |
@p += @v * dt | |
@r += (-2 * @r + rf) * dt | |
@dir *= 1i ** @r | |
end | |
def trans(phase) | |
->z{x,y=z.rect;@p+@dir*0.1*(z+Math.sin(phase+x)*(1-x)*y/8i)} | |
end | |
def render(phase) | |
t=trans(phase) | |
hash = Hash.new(0) | |
stroke -1.4.step(1.4,0.02).map{t[(1i**_1)*(1+_1**16/1000-(1i.**4*_1).real/16)]},hash | |
(-1..1).each{|a| | |
stroke -1.2.step(1.2,0.2).map{x,y=(1i**_1).rect;t[x/6-0.7+(y/4+0.62*a).i]},hash | |
} | |
stroke 0.step(2*Math::PI,0.1).map{|u|t[0.3*(0.3+Math.sin(3*u-phase/27)-Math.cos(5*u)+Math.sin(4*u-phase/35).i+Math.sin(5*u).i)]},hash | |
hash | |
end | |
def ps(phase) | |
t=trans(phase) | |
[-3,9.5,-9.5,3].flat_map{|y|[-1,0,1].map{t[-0.8+(y+_1)*0.1i]}} | |
end | |
end | |
kurage = Kurage.new | |
strings = kurage.ps(0).map { |p0| | |
Ractor.new(p0) { |p0| | |
q = rand(30..40) | |
string = KurageString.new(q, q.fdiv(80), p0, -1) | |
loop { | |
f = string.update(*Ractor.receive) | |
Ractor.yield [f, string.render] | |
} | |
} | |
} | |
require 'io/console' | |
STDIN.raw do | |
$><<"\e[K\e[2J\e[?1000h" | |
buf = +'' | |
ff = (0..20).map { [0] * 20 } | |
dt = 0.1 | |
(1..).each { |i| | |
t=Time.now | |
buf += STDIN.read_nonblock(1000) rescue '' | |
break if buf.include? ?\C-c | |
events = buf.scan(a=/\e\[M.../) | |
buf=buf.split(a).last.to_s | |
events.each { |ev| | |
x=(ev[-2].ord-31)/4 | |
y=(ev[-1].ord-31)/2 | |
next if x>20||y>20 | |
type = ev[3] # mousedown: ' ', mouseup: '#', scrollup: 'a', scrolldown: '`' | |
a,b=type=='a'?[-1i,0]:type=='`'?[1i,0]:[0,6] | |
20.times { |iy| | |
dy = (iy-y+10)%20-10 | |
20.times { |ix| | |
dx = (ix-x+10)%20-10 | |
r2=(dx*dx+dy*dy)/64.0 | |
ff[iy][ix]+=(1-r2)**2*(a+b*(dx+dy.i)) if r2<1 | |
} | |
} | |
} | |
f=Ractor.make_shareable(ff.map{|l|l.map!{_1*0.9}.dup}) | |
phase = i*0.2 | |
strings.zip(kurage.ps(phase)).each { _1.send [_2, f, dt] } | |
fs, hashes = strings.map(&:take).transpose | |
kurage.update(dt, phase, fs, f) | |
hashes << kurage.render(phase) | |
draw(hashes) | |
s=t-Time.now+0.03 | |
sleep s if s>0 | |
} | |
ensure | |
$><<"\e[?1000l" | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# rubocop:disable all | |
def embed_constants(code) | |
code.gsub(/[A-Z][A-Z0-9_]*/){ | |
Object.const_get(_1) rescue _1 | |
} | |
end | |
HEADER1_LINES = 4 | |
HEADER2_LINES = HEADER1_LINES + 1 | |
RADIUS = 40 | |
RADIUS1 = 39 | |
RPARAM = 22 | |
HEADER1 = ';BEGIN{->s{eval((a="' | |
HEADER2 = '";s.gsub(/[^!-~]/,\'\')))}.[]"' | |
FOOTER = '"};' | |
BODY = embed_constants(<<~RUBY).split.join + FOOTER | |
$s=[]; | |
def(self).method_missing(a)=$s<<a.to_s; | |
at_exit{ | |
a,b=a.split; | |
c,*d,e=s.split; | |
$s[HEADER1_LINES]+=?x*20+a; | |
$s[HEADER2_LINES]=e+?x*3+$s[HEADER2_LINES]; | |
$s[HEADER2_LINES,0]=[b+?x*28+c]+d; | |
n=0; | |
a=(1..255).sort_by{('%b'%_1).count(?1)<<10|_1}; | |
$s.map{|s| | |
(m=s.size).times{|i| | |
r=RADIUS-i*(m+~i)/RADIUS; | |
s[i]>?~&&n=a.index(s[i].ord&0xff)+n*(8+(RADIUS1-r)*RPARAM).round.clamp(8,255) | |
} | |
}; | |
require'zlib';eval(Zlib.inflate(n.digits(256).pack'c*')) | |
} | |
RUBY | |
def normalize_sexp(sexp) | |
case sexp | |
in [*rest, Integer, Integer] | |
rest.map{normalize_sexp(_1)} | |
in Array | |
sexp.map{normalize_sexp(_1)} | |
else | |
sexp | |
end | |
end | |
def remove_spaces(code) | |
require 'ripper' | |
normalized = normalize_sexp(Ripper.sexp(code)) | |
chars = code.chars | |
chars.each_with_index do |c, i| | |
next if c !~ /\s/ | |
chars[i] = '' | |
unless normalize_sexp(Ripper.sexp(chars.join)) == normalized | |
chars[i] = c | |
end | |
end | |
p [chars.join.size, code.size] | |
puts chars.join | |
chars.join | |
end | |
require 'zlib' | |
data = Zlib.deflate(remove_spaces(File.read('kurage_base.rb').gsub(/(^| +)#.+/, '')), Zlib::BEST_COMPRESSION) | |
number = data.bytes.reverse.reduce{|a,b|a*256+b} | |
puts number.bit_length / 8 | |
mark = 0x28ff.chr('utf-8') | |
lines = (RADIUS).times.map do |y| | |
w = 2 * Math.sqrt(4.0 * (y + 0.5) * (RADIUS - 0.5 - y)).round | |
' ' * (RADIUS - w / 2) + mark * w | |
end | |
pattern_lines = DATA.read.lines | |
entrypoint_chars = (HEADER1 + HEADER2 + BODY).chars | |
p entrypoint_chars.size | |
(HEADER1_LINES...lines.size).each do |y| | |
pattern = pattern_lines[y - HEADER1_LINES] | |
next unless pattern | |
pattern.chars.each_with_index do |c, i| | |
next unless c == '#' | |
lines[y][i + 22] = entrypoint_chars.shift || '$' | |
end | |
end | |
chars = (1..255).sort_by{('%b'%_1).count(?1)<<10|_1}.map{(10240 + _1).chr 'utf-8'} | |
srand 0 | |
lines = lines.reverse.map do |line| | |
spaces = line[/^ */] | |
content = line.delete(' ') | |
m = content.size | |
spaces + content.chars.reverse.each_with_index.map do |c, i| | |
next c unless c == mark | |
r=RADIUS-i*(m+~i)/RADIUS | |
n=(8+(RADIUS1-r)*RPARAM).round.clamp(8,255) | |
c = chars[number % n] | |
number /= n | |
c | |
end.join.reverse | |
end.reverse | |
output = lines.join("\n") + "\n" | |
puts output | |
File.write 'kurage.rb', output | |
p BODY.size | |
puts number.bit_length / 8 | |
p [DATA.read.count('#'), HEADER1.size + HEADER2.size + BODY.size] | |
__END__ | |
#################### | |
############################ | |
#### ## ## # # # # #### | |
### ### # ## #### # ## ### | |
### # # ## # ## ### # # ### | |
### # #### # ### ### ### | |
## # ### | |
## #### ###### ######### | |
## #### #### #### ##### | |
##### ## ### # ## | |
### ## ### # ## | |
### ### ### # ## | |
# # # # # ## ### | |
## ### # # # ### | |
# # # # # # # ### | |
### ### # ## ## | |
### # # # # # ## | |
## # ### # # # ## | |
# # # # # # # ### | |
# # ### # # # ### | |
# # # # # # # ### | |
## # # ## # # # ## # | |
## # # ## # # # ## # | |
## # # ## # # # ## # | |
### # # # # ## ## # | |
### # # # # ## # # | |
## # # # # # ## | |
### # # # # ## ## | |
### # # # # # ## | |
# # # # # # ## | |
# ## # # # ## # # | |
# # # ## # # | |
# ### |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment