https://www.reddit.com/r/factorio/comments/1t57q1p/another_qr_code_solar_farm_no_urls_used/
![7cea8974abc236a14e81d2b628f175653257331142]()
![7cea8972abc236a14e81d2b628f17c6ea433fe6a]()
이렇게 생겨먹은 태양광 청사진
![2cb3df32edd72aeb7fad9bb619d521706b430f9790f4a53e2402f43e7a7eada9194c1738571f26c4deb3ba3f07c83b724d976e56bd7fe17deedb855242c495bf70be9819709480aeb6]()
줌아웃하면 QR코드 모양을 하고있는데
이걸 스캔하면 루아 스크립트가 나옴
s=[===[N,E,L,G=177,{},{},{}Z=bit32 X=Z.bxor R=Z.rshift K=Z.lshift B=Z.band O=Z.bor
x=1
for i=0,254 do E[i]=x L[x]=i x=K(x,1)if x>255 then x=X(x,285)end end
for i=255,511 do E[i]=E[i-255]end
G={212,246,77,73,195,192,75,98,5,70,103,177,22,217,138,51,181,246,72,25,18,46,228,74,216,195,11,106,130,150}
function rs(d)local r={}for i=1,30 do r[i]=0 end
for i=1,#d do f=X(d[i],r[1])
for j=1,29 do r[j]=r[j+1]end r[30]=0
for j=1,30 do if f~=0 then r[j]=X(r[j],E[L[f]+L[G[j]]])end end end return r end
function enc(z)BT,n={},0
function a(v,l)for i=l-1,0,-1 do n=n+1 BT[n]=B(R(v,i),1)end end
a(4,4)a(#z,16)for i=1,#z do a(z:byte(i),8)end
t=23648-n if t>4 then t=4 end a(0,t)while n%8~=0 do n=n+1 BT[n]=0 end
o,m={},0
for i=1,n,8 do m=m+1 b=0 for j=0,7 do b=O(b,K(BT[i+j],7-j))end o[m]=b end
p=236 while m<2956 do m=m+1 o[m]=p p=253-p end return o end
function mkc(d)D,C={},{}p=1
for b=1,25 do n=b<20 and 118 or 119
l={}for i=1,n do l[i]=d[p]p=p+1 end D[b]=l C[b]=rs(l)end
r,m={},0
for i=1,119 do for b=1,25 do if D[b][i]then m=m+1 r[m]=D[b][i]end end end
for i=1,30 do for b=1,25 do m=m+1 r[m]=C[b][i]end end return r end
g,v={},{}
for y=1,N do g[y]={}v[y]={}for x=1,N do g[y][x]=0 end end
function w(x,y,u)g[y][x]=u v[y][x]=1 end
A=math.abs
for _,p in ipairs{{4,4},{N-3,4},{4,N-3}}do for dy=-4,4 do for dx=-4,4 do
Q,Y=p[1]+dx,p[2]+dy
if Q>=1 and Q<=N and Y>=1 and Y<=N then ax,ay=A(dx),A(dy)
w(Q,Y,ax<=3 and ay<=3 and(ax<=1 and ay<=1 or ax>2 or ay>2)and 1 or 0)
end end end end
for i=9,N-8 do
if not v[7][i]then w(i,7,i%2)end
if not v[i][7]then w(7,i,i%2)end end
H={7,31,59,87,115,143,171}
for _,ay in ipairs(H)do for _,ax in ipairs(H)do
if not(ax<=8 and ay<=8 or ax>=N-7 and ay<=8 or ax<=8 and ay>=N-7)then
for dy=-2,2 do for dx=-2,2 do
ad=A(dx)>A(dy)and A(dx)or A(dy)
w(ax+dx,ay+dy,ad~=1 and 1 or 0)
end end end end end
w(9,N-7,1)
for i=0,7 do v[9][i+1]=1 v[i+1][9]=1 v[9][N-i]=1 v[N-i][9]=1 end
v[9][9]=1
for i=0,5 do for j=0,2 do v[N-10+j][i+1]=1 v[i+1][N-10+j]=1 end end
S="s=[===["..s.."]".."===] load(s)()"
cw=mkc(enc(S))
bt={}for _,c in ipairs(cw)do for i=7,0,-1 do bt[#bt+1]=B(R(c,i),1)end end
bi,col=1,N
while col>=1 do
if col==7 then col=6 end
for ri=0,N-1 do for dc=0,1 do x=col-dc
y=R(N-col,1)%2==0 and N-ri or ri+1
if x>=1 and x<=N and y>=1 and y<=N and not v[y][x]and bi<=#bt then
g[y][x]=bt[bi]bi=bi+1 end end end col=col-2 end
for y=1,N do for x=1,N do
if not v[y][x]and(x-1)*(y-1)%2+(x-1)*(y-1)%3==0 then g[y][x]=X(g[y][x],1)end end end
for i=0,14 do b=B(R(25368,14-i),1)
px=i<6 and i+1 or i<7 and 8 or 9
py=i<8 and 9 or i==8 and 8 or 15-i
g[py][px]=b g[i<7 and N-i or 9][i<7 and 9 or N-14+i]=b end
for i=0,5 do for j=0,2 do b=B(R(167017,i*3+j),1)
g[i+1][N-10+j]=b g[N-10+j][i+1]=b end end
e={}n=0
for y=-3,181 do for x=-3,181 do n=n+1 e[n]={entity_number=n,name=g[y]and g[y][x]==1 and"solar-panel"or"accumulator",position={x*3,3-y*3}}end end
local s=game.player.cursor_stack s.set_stack("blueprint")s.set_blueprint_entities(e)]===] load(s)()
이 스크립트를 콘솔창에 붙여넣고 실행하면??
![1bb4d423ea8368e869b6d09528d527034ad39beb5d80fa65]()
원본 청사진이 나온다
![39a8dd24e9c007a837bbc0a617f33030f7a2ba4363a566af280b47962fec42b628b4f3637bc3f21cdf3e52826de738]()
위와 같이 스스로의 소스코드를 내뱉는 프로그램을 콰인(Quine)이라고 한다더라고
+원본 댓글에 어떻게 만드는지 약간 설명되어있던 부분이 있던데 이해한 만큼만 적어봄
일단 스크립트가 s=[... 로 시작하고 중간에 S="s=[===["..s.."]".."===] load(s)()" 부분이 있어서 S라는 변수 안에 자기 자신이 들어가게 됨
이게 콰인을 가능하게 해주는 부분
루아에서는 스트링을 그냥 실행할 수 있어서 만들기 쉬운 편이라고 함
다음부터는 어떻게 정보를 압축했는지에 대한 내용
팩토리오 청사진은 JSON 형태로 되어있음
![7cea897eabc236a14e81d2b628f1766bc65a42]()
여기서 흰색, 빨간색으로 되어있는 부분은 싹 다 반복되는 부분이라 한번만 적어두면 그 다음부턴 그냥 버릴 수 있음
entity number, position 뒤에 적혀있는 숫자들도 일정한 규칙이 있으니 한두줄로 압축할 수 있고
결국 중요한건 이 부분이 태양판인지 축전지인지 하는 1비트짜리 정보밖에 안 남는다
그래서 입력으로 0에서 255 사이의 숫자들을 받고 이진수로 바꾼 다음 0이 오면 solar-panel을, 1이 오면 accumulator를 넣도록 함
"163"이면 "0b10100011"이 되고
{"entity_number":45,"name":"accumulator","position":{"x":133.0,"y":1.0}}
{"entity_number":46,"name":"solar-panel","position":{"x":136.0,"y":1.0}}
{"entity_number":47,"name":"accumulator","position":{"x":139.0,"y":1.0}}
...
이렇게 변환시켜주는거
또 QR코드에 있는 테두리라든가 인식용 네모들이라든가 일부분이 가려져도 스캔할 수 있도록 하는 오류 수정 알고리즘같은 것들도 당연히 필요없는 부분
코드의 시작 부분에 문자열 -> QR 변환 알고리즘을 그냥 넣어뒀더라고
근데 이렇게 압축해도 스크립트 안에 자기 자신을 온전히 담을 수는 없음
결국 스크립트 입력으로 숫자들이 잔뜩 필요한데 이 숫자들조차 스크립트의 일부니까
콰인을 만드려면 코드 안에 코드에 대한 정보가 온전히 담겨 있어야 하는데 1바이트로 1바이트를 초과하는 정보를 설명하는건 정보이론상 불가능함
이를 위해서 이해하기 힘든... 수학적 기법을 이용해 추가적인 인코딩을 진행한다
for i=9,N-8 do
if not v[7][i]then W(i,7,i%2)end
if not v[i][7]then W(7,i,i%2)end end
H={7,31,59,87,115,143,171}for _,n in I(H)do for _,m in I(H)do
if not(m<=8 and n<=8 or m>=N-7 and n<=8 or m<=8 and n>=N-7)then
for p=-2,2 do for o=-2,2 do
r=A(o)>A(p)and A(o)or A(p)
W(m+o,n+p,r~=1 and 1 or 0)
end end end end end
W(9,N-7,1)for i=0,7 do v[9][i+1]=1 v[i+1][9]=1 v[9][N-i]=1 v[N-i][9]=1 end
v[9][9]=1
for i=0,5 do for j=0,2 do v[N-10+j][i+1]=1 v[i+1][N-10+j]=1 end end
a,b,d,J=1,N,M(F(S)),{}for _,c in I(d)do for i=7,0,-1 do J[#J+1]=B(R(c,i),1)end end
작성자는 '이 코드만을 위한 극히 특수한 압축 알고리즘을 작성하는 것과 같다'고 표현함
비유하자면 그림을 이미지 파일로 저장하는게 아니라 어디에 먹칠을 해라 붓을 어떤 방향으로 휘둘러라 같은 설명서를 적어둔다고 하면 될듯
패턴이 전혀 없는 무작위적인 노이즈가 아닌 이상에야 그림 자체의 용량보다 크기가 작은 설명서를 쓸 수 있을 테니까
다만 콰인의 규칙상 그 설명서조차도 그림의 일부가 되어야 하고, 설명서를 추가하면 결국 그림 전체의 모양이 바뀌게 되니까 설명서를 다시 작성해야 함
언제까지? 될 때까지.
![7cea8971abc236a14e81d2b628f1736cd782c9]()
손으로 하면 한달정도 걸리는 개노가다라서 여기까지 만들고 나머지는 그냥 클로드 돌렸다고 함
어제 올라온 게시글(스캔하면 자기가 올라와있는 factoriobin 링크로 데려다주는 거였음) 보고 만들었다고 하니까 딱 하루가 걸린 셈
![3bb8c235ecdd36906faddfb002c80d3072ac2aa7a3bce1612557f87e20c8c0b677a4]()
QR코드 버전 40은 177 x 177 크기로 2,953바이트를 담을 수 있는데 딱 1바이트 남기고 들어간다고 하더라ㅋㅋ
스스로를 찍은 사진ㄷㄷ
미친 개발자 놈들 이런거 게임으로도 해서 재밌게 놀더라고
이런미친
해석을 봐도 뭔소린지 모르겠네 ㅋㅋㅋ
factoriobin으로 연결하는건 링크를 모르는데 어케하나 했는데 개인 도메인 하나 써서 그거기준으로 만든다음 업로드 후 factoriobin 주소로 리다이렉트한거였네
팩끼야아아악
무친.....공포스럽다
이게임은 괴수가 너무 많아...
이거 이정도면 팩토리오 내 정보저장용 사이버 도서관 만들 수 도 있겠는데...
ㅋㅋㅋㅋ사실상 전구만으로도 그건 가능하지
@ㅇㅇ(112.220) 1000101001010011010010101111010111 이런 식으로 함? ㅋㅋㅋ
이런 ㅅㅂ;;;
도대체가... 이게임이 무서워짐.....ㄷㄷㄷ - dc App
변태
우로보로스ㄷㄷㄷㄷ
굉장히 복잡해보이지만 근본적으로는 유전자 같은거라고 보면 됨 자기자신이 결과물이면서 동시에 청사진이면서 공장인거지
그냥 유전자가 개존나신기한 미친놈처럼 보일뿐인데여
설계도대로 만든 설계도대로 만든 설계도대로만든설계도대로만든..
이론상 '이 코드만을 위한 극히 특수한 압축 알고리즘을 위한 극히 특수한 압축 알고리즘을 위한......' 식으로 용량을 줄일수 있는건가..
아.. QR코드까진 이해했습니다