Skip to content

Instantly share code, notes, and snippets.

@tompng
Last active August 26, 2023 08:43
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tompng/509296fe288f37457bebbe35ad4db01d to your computer and use it in GitHub Desktop.
Save tompng/509296fe288f37457bebbe35ad4db01d to your computer and use it in GitHub Desktop.
福岡rubyist会議Quine
require'irb/color'
code = File.read(ARGV[0] || 'fukuokark.rb')
def hoge(s)
s.gsub("eval(s*'')","$a=s*''")
end
eval code.gsub('then{;eval', 'then{eval hoge')
w = 132
ended = false
colored = IRB::Color.colorize_code(code.lines[0].dup+'%').gsub(/\n.+/,"\n")
code.lines[1..].join.delete("\n").chars.zip($a.chars).map do |a,b|
ended = true if a == '%'
if ended || (a != ' ' && a.ord < 128) # || true
a
else
"\e[38;5;59m#{b}\e[m"
end
end.each_slice(w){|l|
colored << l.join.gsub(/\e\[m\e\[38;5;59m/, '').gsub(/@![^@]+!@@/){"\e[31m#{_1}\e[m"} + "\n"
}
puts colored.gsub(/%\. then(.|\n)+\z/){
"\e[31m%\e[m"+_1[1...6]+IRB::Color.colorize_code(_1[6..])
}
s = 54.times.map{132.times.map{rand(10)}.join}.join.chars
#CODE
hh = 54
ww = 132
code = [[?%] * ww] + [*(s*2).each_slice(ww)]
width = 80
height = 80
include(Math)
shape = ->x,y{[(x+y-0.6).abs,(x-y+0.6).abs,1-y].max<1}
$><<"\e[H\e[2J"
51.times do |time|
time *= 0.02
a = 0.6
t = [time/a, 1].min
u = [0, (time - a) / (1 - a)].max
rot = (1 - u)*1.4
cs = cos(rot)
sn = sin(rot)
canvas = height.times.map{[0] * width}
scale = height * 0.3
dot=->p,f=!1{
canvas[height / 2 + scale * p.imag][width / 2 + scale * p.real] = 1 if(!f||p.imag<0||p.real**2+(p.imag/cs)**2<1)
}
draw_line = ->a,b,f=!1{
c=(a+b)/2.0
if (a-b).abs*scale>1
draw_line[a,c,f]
draw_line[c,b,f]
else
dot[c,f]
end
}
stroke = ->n,t=!1,&b{n.times.map(&b).each_cons(2){draw_line[*_1,t]}}
tt=[2*(1-time), 1].min
y=[tt*(3*tt-2)-(E**(-16*tt)-1)/8,0.6].min
stroke[6,1]{
y.i+[-4-5i,4-5i,7-2i,5i,-7-2i,-4-5i][_1]*0.08
}
b = (y-0.4-3*[(t+0.2)*(0.9-t),0].max).i-0.2*(1-t**2)
l=1.2-time**2*0.6
draw_line[b, b+E**(-0.4-(PI/2-0.4)*time**2).i*l]
draw_line[b, b+c=E**(-0.6-(PI/2-0.6)*time**2).i*l]
t<1&&3.times{|j|stroke[15,1]{b+c*(1+j)*0.1+_1*0.1i-0.03*cos(0.4*_1)}}
n=100
stroke[n+1]{
c=u<0.5?0:(u-0.5)/3
d=2*(PI-c)
a=E**(d*_1/n+c).i
a.imag-a.real.i*cs
}
n.times{|i|
x=2.0*i/n-1
w=x.abs**2.5-1
y=sn*(w+w/3*([1-(4*x)**8,0].max*[rot/1.6-0.5,0].max))
x*x+(y/cs)**2>1&&dot[x-y.i]
}
u>0.5&&[-1,0,1].map{
x=_1*0.56
y=(1-x*x)**0.5*cs
draw_line[z=x+y.i,z+(y-0.4+x.abs)*(1-2*u).i]
}
rot = 0.2*sin(3*PI*time)
e=[4,0,8].map{(9600+_1).chr'utf-8'}
lines = hh.times.map{|iy|
ww.times.map do |ix|
yy = 2*iy
xx = ix-(ww-width)/2
if 0<yy&&yy+1<height&&0<xx&&xx<width
v=canvas[yy][xx]*2+canvas[yy+1][xx]
next e[v-1] if v>0
end
y = (iy+0.5) * 2.0 / hh
x = (ix - ww / 2.0) / hh
x*=0.88;y*=0.88
base = 0.4 * (rot<0?-1:1)
x,y=((x-base+y.i)*E**rot.i+base).rect
shape[x,y] ? '?' : ' '
end.join+$/
}
m=(4-(2+l=lines[0].count(??))%4)%4
rot.abs<0.02 ? lines[0] = ' '*((ww-k=50)/2+1)+??*k+' '*(ww-(ww-k)/2-k-1)+$/ : lines[0].gsub!(rot < 0 ? /\? {#{m}}/ : / {#{m}}\?/,??*(m+1))
hoge = <<'A'.split($/)
??????????????
?? ??
?? ??????????????
?? ?? ????
?? ?? ?????????? ??
?? ?? ?? ??
?? %. then{;eval (#
(+ s= _1 )#
). +@ &&s.scan(( 20
23 && 2/ 18
/@!([^ @]+)!@@/))*''}
A
11.times{
l=hoge[~_1]
lines[~_1][16,l.size]=l
}
$><< "\e[H"+lines.zip(code).map{|a,b|
a.chars.zip(b).map{_1==?? ? _2 : _1}.join
}*''
sleep 0.1
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
zmzgUftevUHrBkkAC4cu6LdjpQ2e2O7MzfVdZD8YkqCHYE3AMsb2/fY
BN00JvGOJgHqMj1bdH0tK6ycr/Jyd9pU1BUF+nOuOSL1uuOirRuxwMxoyJd
GTA7KSPzUwxLc6QrtDS/wMLEWHKcU+5hIS9mA6GFr7CxrT5kUE5TVwMi2NQERbK
cPHIcDdmzG8E/o+vU1UD/Nb2UOelompGtY35OrmdOrVo8BQRshY6JKe6Wc1hWUkKTqj
nZoPKivNqA+Hq5mF718eqvAYiec76WF0wI8566KxsW9UkpMeLW7aSXpOcz6hpYhUyIrkxoy
/7gofbgyS1hBYlayYRBZ81hC2vTG6ZrJ3zMFGmgY0PKSCA+8YZ6gW0hKjQo9DkC1BSVsRShzReW
P7vH06zTsW07NxsEF5Of+opCOdFfSPEzWwZiZTocMAHAKcFexDIJnzCrX▄JbF+ygQ02XwmezBZEp9aO
tN+xSU6xK1tNRaKKSy7uK4YObgHf8yIkpxMWAsNPB+wZgqOoS8BB0jkG▄▄▀Wta6pBt6fQE4mE6EASN0AqH3
nt+8C1yZLTa1Dtqe9/36EmBYwc2LMfny3paEoj9UEQs77kOTTLAgAey▄▄▀mG0b274fHRGJowdKMWrYXLS3Qkm84
1wZ9bPFcYKobR2nbSOrhx7jYfZ0XaLaNoFp8cKAihsWqvK2wbl65DK▄▄▀MfF4E9▄▄▄▀0WZwTynMIigjTKeiQK3ltzBE
nGE9wR8QEbgWjYTCnDPoKFODEGhaFbsqa/k5RoJvgJR4tR/gzHuGR▄▄▀82ur▄▄▄▀▀Qe5jAmcrdMvYogujWWTbfdWQ5ZLSjx
F0u2Z1rBcC3MhDwO5g0EBBSeAlzW+/XV2ZbOMIB+PV/LvHx/fH+f▄▄▀/kD▄▄▄▀▀uCT34JsiVGxvDSZRNPo6EvWu1A354FO0/O0D
UeXX8kj+mJcbkPSIuxnV80VxJjOl7REHTvcbYcWoBl0VFCMZhgMK▄█Q▄▄▄▀▀kHPnXV0T9g/F14tKr62ufUjaCI/AVyeGKP8LsNGiof2
iO8c62WeNI7Yt5gaH9+4G47wRzKivShl617wUrGMexwiVch1GMl▄███▀▀nyQHWZ5zvoTGk7/T8Y6YTf'.unpack1(?m))#wS6(Mbi=;et?o
U(&lNMNQ,lw8rhr'TD@!s=s.lines!@@u_y#kpA*lQ7>m95uis▄█▀▀█X█l'L6J2@+[|;VOT[bJmcrx@![1..].join!@@#L*b.EXdE}Y}}`.>>m
a]hIA@:-8tu'Ztm-Xf@!.chars-[$/!@@1pZUrx#9RQXhYHp)/vA>█:g█z█▄UH7`Ego#sNOM($m(SP}D>@!];eval'cla!@@BeZEiGQa6S?0Exy5l>T
+]lneulM7`oe?|Ao|K.@!ss_Integer;!@@<Xbm?h9ka=lP4puO_De▄▄█▄█▄▄█▄▄Md'A6=|xKgrL1.u?zKd@!def_quo(a)=(!@@wR!7SZYYYuYXw.fAE]<
@(:.k9TJ<:D.e:lKnMSR@!self*a.pow(8!@@h*r▄▄▄▄█▀▀▀▀▀▀▀▀▀▀▀▀{█u█#v█w▀▀▀▀▀▀▀▀▀▀▀▀█▄▄▄▄R{0@!7,89)).modulo!@@hd&[<kw*4yEE**6pt[nN
('DsbvQj`KK`:G@AW@!(89);def_abs(!@@█▀▀bI|cUMn<Q8E-HleDDo█wd█+█t6Iv_RJ[3y${bId$l.▀▀█@!)=modulo(89);e!@@F:l>p(Bm}?o8uHh$+
8v5QL+Yh-+.uY@!nd'.tr(?_,32.ch!@@█▄▄rjH=;a<{{O&tJXEm/t█xj█O█xyn-{s]LL/TKvL=Pa<▄▄█@!r);require'matri!@@CFQY}:cw|@G,<
I`>-lv9qxD@!x';70.times{|i,*!@@▀▄2▀▀▀▀█▄▄▄▄▄▄▄▄▄▄▄▄I█▄B█J█6▄▄▄▄▄▄▄▄▄▄▄▄█▀▀▀▀v▄▀@!v|z=[?!,*?#,?$,*?!@@B,O?EB|s[?
#*Mekp4@!&..?[,*?],*?_..?}!@@z▀▄&v0B3FiHw+k]|Tmu▀▀▀▀▀▀▀▀▀▀?*.!}(/<vPYSs,Z-▄▀f@!];a=(0..101).map{z!@@+Pkp_j$
50]@!.index(s[i+70*_1])}!@@&f▀▄WKN|>gc'(pM)UZA$]0c#gt|0dZOer=q,Z2vdL6:5▄▀ZV@!;w=*Matrix[*(0..61).!@@:k=
@!map{|i,*b|v<<a.zip(0.!@@s8▀▄CA{?)as&u@c&`QXE$kj$kX5e6;AuMZXfs0_0md▄▀[|@!.).sum{|j,k|-(p=(i+k).!@@
@!pow(i+k,88)+1)*(j||(!@@tX▀█N,Do7JsnU.A2tx7y-Y9/T-4:t1MI_T(Tq(v{█▀WG@!b<<p;0))};b}].lup.sol!@@
@!ve(v);102.times{s[i!@@!RF█▄du5Q1[kA;*sQUT6&V$8>@!N{QYHZl|0q▄█YLt@!+70*_1]=z[a[_1]||w.s!@@
@!hift]}};eval(s*'')!@@Yqi▀▄Ul@b0vOyiyx7Up0s.-?+7su4=M>w'{▄▀e5:O6aQ4a{iA>OxF#:5GPhAp$Ck
-(`j$UOytHW)mH[w,(dJ|vixCs█▄,9(3I<!nOsWXVM7?E@j#8RpZ;r▄█CpkutdJL&c[D/Qrq!@CVF@OwGKR
(=*;o#g@J`+f1@UUSG&=BxUD3▀█▄CAH]8/|O&z8w[G{_'901Wy▄█▀+@qMy_sMoF<[k/P2y!5*Z$pVly
:Cxw$KP`0JbJ0,E.qx7F*ZOe]▀▀▄▄4[!e?qtUn-O:V*(A▄▄▀▀aVhBAZSK[-!qcYD|&j1G&cpR]M
;!AU{I4A'f}0+Mv)KFR7(&}y1u▀▀▀▄x24qc-16-Q▄▀▀▀{<<OKs+neRC$79xHFx&eKW?FKk<
?l>lNj_xe67zJgEX1gq&eyk9?x&▀▄I?xwy>W{▄▀JKL](zMFgwI2_Y(rO||$!e*wiNH'
=PkgN,!j=O0c84#A&]j<po5njr▀▀▀▀▀▀▀▀▀▀.wwH];pm=p!w67N5G*1d7bab;6N
3x,6HEyUbQaqO!=$}7R&ZzO-TJ<<*dktB#o5QTHkwl[+bhRvd>25uOSg<{[
||SVge#SH,Kz@|dDAC1;No$s.Gj5O#YB=tE?<zoX!]2gjfI}3`TJPuX
ZP$]>S2aCd?LS&Djluhm-G}Xdlu=a({U+9sD?}LGx;9b/Xslq,|
]=2UHb>q$]H6PA;[r0D>k.IvK*8@b]]#XjnL{[Hnf}>QPa]
sm19W[4(9OWQmg0X{_].4y-=<z0|AVf,jGox@YwEPFv
{(?,{SKfV/=ZyP/jM]c|[cHXzP[*H1JH@z`d./6
4b>*UCA2oiX$v]|6>:UR`,7G2bXa!0J({=_
vt)]&VFUC;j;Ku8s'-W0/D(D/jF8<zb
+1j6dRz#QKIkZU(wusf$Q,UC@aH
>7CB2a{zq#c@N# (}VzBy8x|$=5hV&TL-oHMow
+c N6 s:A$-i6a>]o|zv$4}WI
>y IkNogqre?2h[S$ |`7>r,.Kev*$0>7
K3 AT MI$E b;MeGSS-(o$
W{ Mv i/#Sfxg:uk <f n!Yu5Pa
wk ,B Nq LB I[F
l8 %. then{;eval (#
(+ s= _1 )#
). +@ &&s.scan(( 20
23 && 2/ 18
/@!([^ @]+)!@@/))*''}
require'zlib'
require'./restore'
srand 6 # change this to avoid #{ #@ #$ in output code
original_code = File.read('fukuoka.rb')
embedded_code = original_code.gsub(/(.|\n)*#CODE/, '').gsub(/^ +/,'')
base64 = [Zlib.deflate(embedded_code,5)].pack('m').delete("=\n")
WIDTH = original_code[/ww = \d+/][/\d+/].to_i
HEIGHT = original_code[/hh = \d+/][/\d+/].to_i
code = "require'zlib';eval(Zlib.inflate'#{base64}'.unpack1(?m))#"
code += '♪'*(WIDTH*HEIGHT-code.size)
code = code.chars.each_slice(WIDTH).map(&:join).join($/)
puts code
def sleep(*);end
$>.singleton_class.prepend Module.new{
def output; @output; end
def <<(a); (@output||=[])<<a; super(a); end
}
s = code.delete($/).chars
code_was = s.dup
eval s.join
frames = $>.output.drop(1).map{_1.gsub(/\e\[\d?[a-zA-Z]/, '')}
union = (frames[0].chars).zip(*frames[1..].map(&:chars)).map{|a|
cs = a.uniq
cs == ["\n"] ? "\n" : cs == ["♪"] ? "♪" : ' '
}.join
params = [36+4,66-4,70]
restore_code = "s=s.lines[1..].join.chars-[$/];#{correction_code(*params,'s')};eval(s*'')".chars
puts restore_code.join
puts union.gsub!(/♪{12,}/){|s|
if restore_code.size > 0
x = '@!'+restore_code.shift(s.size-5).join+'!@@'
s[0,x.size] = x
end
s
}
code = code_was.zip(union.lines[1...HEIGHT-2].join.delete($/).chars).map{|a,b|
" ♪"[b] ? a : b rescue nil
}.join.tr('♪█▄▀', ' ')[0,(params[0]+params[1])*params[2]]
# 2334 8880
puts union
hoge = encode_all2(code, *params)
binding.irb
# validate
stripes = hoge.each_slice(params[2]).to_a.transpose.map{|s|s.map{CHARS.index _1}}
matrix = Matrix[*params[1].times.map{|i|(params[0]+params[1]).times.map{param(i,_1)}}]
p stripes.map{|s|(matrix*Vector[*s]).map{_1%89}.max} # all zero
out = frames[0].lines.zip([[]]+hoge.each_slice(WIDTH).to_a).map do |f, c|
next f if c==[] # header
f.chars.zip(c||[]).map{|a,b|
a=='♪' ? b : (a == ' '&&rand<0&&f[16]==' ') ? b : a
}.join
end.join
foo = out.scan(/% +(([^%]|\n)+)%/)[0][0].delete($/).chars.map{_1.ord>128 ? ' ' : _1}
# validate2
bar = foo.dup;eval correction_code(*params, 'bar');p bar==hoge
File.write 'fukuokark.rb', out
binding.irb
%%%%%%%%%%
D8YkqCHYE3AMsb2/fY8E
9pU1BUF+nOuOSL1uuOirRuxwMxoyJd1x5
MLEWHKcU+5hIS9mA6GFr7CxrT5▄▄▀5TVwMi2NQERbKKCVa
o+vU1UD/Nb2UOelompGtY35OrmdOrVo8B▄▄▀▀Y6JKe6Wc1hWUkKTqjzUN6W
Hq5mF718eqvAYiec76WF0wI8566KxsW9Uk▄▄▀▀W7aSXp▄cz6hpYhUyIrkxoy+F7WLV
YlayYRBZ81hC2vTG6ZrJ3zMFGmgY0PKSC▄▄▀YZ6gW▄▀▀▀Qo9DkC1BSVsRShzReWzLTmZV9
NxsEF5Of+opCOdFfSPEzWwZiZTocMAHA▄▄▀▀xD▄▄▀▀▀rXYJbF+ygQ02XwmezBZEp9aOUY9vvjO8
aKKSy7uK4YObgHf8yIkpxMWAsNPB+wZ▄▀▀o▄▄▀▀0jkGX+KWta6pBt6fQE4mE6EASN0AqH3C1B2HMWlF
qe9/36EmBYwc2LMfny3paEoj9UEQs▄█▀▄█▀▀AgAeyqy4mG0b274fHRGJowdKMWrYXLS3Qkm84VjZ59uT6jr
nbSOrhx7jYfZ0XaLaNoFp8cKAihs▄████▀bl65DKBKYMfF4E91CY60WZwTynMIigjTKeiQK3ltzBE4T7xDZ8OAhY
CnDPoKFODEGhaFbsqa/k5RoJvgJ▀██R█g▀▄uGRyU382urK/eBDQe5jAmcrdMvYogujWWTbfdWQ5ZLSjxP4mpqZSkbmBg
5g0EBBSeAlzW+/XV2ZbOMIB+PV/LvH█/█H+█DZq/kD/XPoeuCT34JsiVGxvDSZRNPo6EvWu1A354FO0/O0DS/zqMzD+R+e13
uxnV80VxJjOl7REHTvcbYcWoBl0VFCMZ█g█▄x█QHpXyzkHPnXV0T9g/F14tKr62ufUjaCI/AVyeGKP8LsNGiof2EG90fDkkrOvFLU
9+4G47wRzKivShl617wUrGMexwiVch1GM█z7█r█BnyQHWZ5zvoTGk7/T8Y6YTf'.unpack1(?m))#wS6(Mbi=;et?or)'j71F'Mz.k
@!s=s.lines!@@u_y#kpA*lQ7>m95uisxo█u9█w█'L6J2@+[|;VOT[bJmcrx@![1..].join!@@#L*b.EXdE}Y}}`.>>mshB0.jU``$
@!.chars-[$/!@@1pZUrx#9RQXhYHp)/vA>y:█*█n▀█H7`Ego#sNOM($m(SP}D>@!];eval'cla!@@BeZEiGQa6S?0Exy5l>TO@iQm&]G
@!ss_Integer;!@@<Xbm?h9ka=lP4puO_De▄▄▄█▄█▄▄█▄Md'A6=|xKgrL1.u?zKd@!def_quo(a)=(!@@wR!7SZYYYuYXw.fAE]<|w=G
@!self*a.pow(8!@@h*r▄▄▄▄█▀▀▀▀▀▀▀▀▀▀▀▀{]█n█v=█▀▀▀▀▀▀▀▀▀▀▀▀█▄▄▄▄R{0@!7,89)).modulo!@@hd&[<kw*4yEE**6pt[nN_
W@!(89);def_abs(!@@█▀▀bI|cUMn<Q8E-HleDDoD█d█+c█6Iv_RJ[3y${bId$l.▀▀█@!)=modulo(89);e!@@F:l>p(Bm}?o8uHh$+w'
@!nd'.tr(?_,32.ch!@@█▄▄rjH=;a<{{O&tJXEm/tw█j█O▄█yn-{s]LL/TKvL=Pa<▄▄█@!r);require'matri!@@CFQY}:cw|@G,<Sh
@!x';70.times{|i,*!@@▀▄2▀▀▀▀█▄▄▄▄▄▄▄▄▄▄▄▄I0█B█J█6▄▄▄▄▄▄▄▄▄▄▄▄█▀▀▀▀v▄▀@!v|z=[?!,*?#,?$,*?!@@B,O?EB|s[?xVw
4@!&..?[,*?],*?_..?}!@@z▀▄&v0B3FiHw+k]|Tmu▀▀▀▀▀▀▀▀▀▀?*.!}(/<vPYSs,Z-▄▀f@!];a=(0..101).map{z!@@+Pkp_j$wAV3
@!.index(s[i+70*_1])}!@@&f▀▄WKN|>gc'(pM)UZA$]0c#gt|0dZOer=q,Z2vdL6:5▄▀ZV@!;w=*Matrix[*(0..61).!@@:k=hzKi
@!map{|i,*b|v<<a.zip(0.!@@s8▀▄CA{?)as&u@c&`QXE$kj$kX5e6;AuMZXfs0_0md▄▀[|@!.).sum{|j,k|-(p=(i+k).!@@K9Rd=
{Mk`@!pow(i+k,88)+1)*(j||(!@@tX▀█N,Do7JsnU.A2tx7y-Y9/T-4:t1MI_T(Tq(v{█▀WG@!b<<p;0))};b}].lup.sol!@@+*Tg0N
/K4uVW}@!ve(v);102.times{s[i!@@!RF█▄du5Q1[kA;*sQUT6&V$8>@!N{QYHZl|0q▄█YLt@!+70*_1]=z[a[_1]||w.s!@@F#OkKv
LP6?jo@!hift]}};eval(s*'')!@@Yqi▀▄Ul@b0vOyiyx7Up0s.-?+7su4=M>w'{▄▀e5:O6aQ4a{iA>OxF#:5GPhAp$Ck*YlpJh>
;cor=-(`j$UOytHW)mH[w,(dJ|vixCs█▄,9(3I<!nOsWXVM7?E@j#8RpZ;r▄█CpkutdJL&c[D/Qrq!@CVF@OwGKR$_kzPf4@
AXk-(=*;o#g@J`+f1@UUSG&=BxUD3▀█▄CAH]8/|O&z8w[G{_'901Wy▄█▀+@qMy_sMoF<[k/P2y!5*Z$pVlyolcrjuG]
2Il:Cxw$KP`0JbJ0,E.qx7F*ZOe]▀▀▄▄4[!e?qtUn-O:V*(A▄▄▀▀aVhBAZSK[-!qcYD|&j1G&cpR]M&E,>9>t[+
F';!AU{I4A'f}0+Mv)KFR7(&}y1u▀▀▀▄x24qc-16-Q▄▀▀▀{<<OKs+neRC$79xHFx&eKW?FKk<&+&oy>wW=9
x?l>lNj_xe67zJgEX1gq&eyk9?x&▀▄I?xwy>W{▄▀JKL](zMFgwI2_Y(rO||$!e*wiNH'<@;M`U>l<q
=PkgN,!j=O0c84#A&]j<po5njr▀▀▀▀▀▀▀▀▀▀.wwH];pm=p!w67N5G*1d7bab;6N$2)TkvlNXNv
x,6HEyUbQaqO!=$}7R&ZzO-TJ<<*dktB#o5QTHkwl[+bhRvd>25uOSg<{[]c4(B0oYi.T&
SVge#SH,Kz@|dDAC1;No$s.Gj5O#YB=tE?<zoX!]2gjfI}3`TJPuXFBRzi|I_VE?s
]>S2aCd?LS&Djluhm-G}Xdlu=a({U+9sD?}LGx;9b/Xslq,|bIQl$KQ*>xmAH
Hb>q$]H6PA;[r0D>k.IvK*8@b]]#XjnL{[Hnf}>QPa]?|I/7k;`pkWN0M
[4(9OWQmg0X{_].4y-=<z0|AVf,jGox@YwEPFv|uJP:*Lx@|W6{X
KfV/=ZyP/jM]c|[cHXzP[*H1JH@z`d./6&=86,h?RxZL'aTw
2oiX$v]|6>:UR`,7G2bXa!0J({=_dh}R|h$vpy{+??F/
C;j;Ku8s'-W0/D(D/jF8<zb*x(&tlqPx4Cpe]Y0
KIkZU(wusf$Q,UC@aHyzcjL/&QE!#iM:O-2
>7CB2a{zq#c@N# =5hV&TL-oHMowxIU0k`6uyI?rgeTkAA
+c N6 |zv$4}WIy34Mu0Z79x&,z=@}W6
>y IkNogqre?2h[S$ 0>7l=d$&1A|zuTpFGvW0Jx
K3 AT MI$E `d=z)6i,=L0-dbPl;T
W{ Mv i/#Sfxg:uk <f j5'p,O5Yz{uUY
wk ,B Nq LB J|Do)_'zJ
l8 %. then{;eval (# YiKGu
(+ s= _1 )#
). +@ &&s.scan(( 20
23 && 2/ 18
/@!([^ @]+)!@@/))*''}
require'matrix'
MOD=89
class Integer
def quo(a)=self*a.pow(MOD-2,MOD)%MOD
def abs()=[a=self%MOD,MOD-a].min
end
def param(a,b)=(a+b).pow(a+b,MOD-1)+1
def encode(data,n)
data+=Matrix[*n.times.map{|i|
n.times.map{param(i,data.size+_1)}
}].lup.solve(n.times.map{|i|data.map.with_index{-_1*param(i,_2)}.sum%MOD}).to_a
end
def restore(data, n)
v=[]
[*Matrix[*(0..n-1).map{|i,*a|
v<<data.zip(0..).sum{p=param(i,_2);-p*(_1||(a<<p;0))};a
}].lup.solve(v)]
end
CHARS_CODE = "[?!,*?#,?$,*?&..?[,*?],*?_..?}]"
CHARS = eval(CHARS_CODE)
def encode_all(code_chars, code_size, correction_size, lines)
result = code_chars.dup
lines.times{|i|
l = code_size.times.map do
c = code_chars[i+lines*_1]
idx = CHARS.index c
raise "cannot encode: #{c.inspect}" unless idx
idx
end
encoded = encode l, correction_size
(code_size + correction_size).times do
result[i+lines*_1] = CHARS[encoded[_1]]
end
}
result
end
def correction_code(code_size, correction_size, stripe_size, datavar)
code = <<~RUBY
eval'class_Integer;def_quo(a)=(self*a.pow(87,89)).modulo(89);def_abs()=modulo(89);end'.tr(?_,32.chr);
require'matrix';
STRIPE.times{|i,*v|
z=#{CHARS_CODE};
a=(0..SUMPRED).map{z.index(DATAVAR[i+STRIPE*_1])};
w=*Matrix[*(0..#{correction_size-1}).map{|i,*b|
v<<a.zip(0..).sum{|j,k|-(p=(i+k).pow(i+k,88)+1)*(j||(b<<p;0))};b
}].lup.solve(v);
SUM.times{DATAVAR[i+STRIPE*_1]=z[a[_1]||w.shift]}
}
RUBY
code.gsub('STRIPE', stripe_size.to_s)
.gsub('SUMPRED', (code_size + correction_size - 1).to_s)
.gsub('SUM', (code_size + correction_size).to_s)
.gsub(/^ +/, '').gsub(/\n/, '')
.gsub('DATAVAR', datavar)
end
def encode_all2(original_data, code_size, correction_size, stripe_size)
data = original_data.dup
data = data.chars if data.is_a?(String)
data = data.dup
data += [nil] * ((code_size + correction_size) * stripe_size - data.size)
stripe_size.times do |i|
all_indices = (code_size + correction_size).times.filter_map{stripe_size * _1 + i}
indices = all_indices.reject{CHARS.include?(data[_1])}.shuffle
next if indices.size == 0
p indices.size - correction_size
raise "too large: #{indices.size} #{correction_size}" if indices.size < correction_size
data[indices.pop] = CHARS.sample while indices.size > correction_size
end
data_was = data.dup
eval correction_code(code_size, correction_size, stripe_size, 'data')
raise unless stripe_size.times.all? do |i|
all_indices = (code_size + correction_size).times.filter_map{stripe_size * _1 + i}
values = all_indices.map{CHARS.index data[_1]}
ans = Matrix[*correction_size.times.map{|i|
(code_size+correction_size).times.map{param(i,_1)}
}]*Vector[*values]
ans.all?{_1%89==0}
end
data
rescue => e
p e
p :retry
retry
end
if (File.realpath(__FILE__) == File.realpath($0) rescue nil)
data = (80*19).times.map { CHARS.sample }
data2 = encode_all2(data, 80, 35, 19)
data = encode_all data, 80, 35, 19
p data == data2
corrupt = data.dup
500.times{corrupt[rand corrupt.size]='■'}
code = correction_code(80,35,19,'c')
puts code
c = corrupt.dup
eval code
p c == data
end
def sleep(*);end
frames = `ruby fukuokark.rb`
frames = frames.split("\e\[H").map{_1.gsub(/\e\[\d*[a-zA-Z]/,'')}.reject(&:empty?)
require'open3'
def test(frame)
code = "class Array;def each_slice(n);puts join;exit;end;end;" + frame
Open3.capture3('ruby', '-e', code)[0]
end
ref = test frames[0]
(1...frames.size).each do |num|
p running: num
res = test(frames[num])
if res == ref
puts :OK
else
binding.irb
end
end
binding.irb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment