512바이트 계산기에서 1024바이트 Python으로
def buzz() , for n in range(101) , 중첩 if · else , print 와 함수 호출로 구성됨 def , 콜론, 들여쓰기, 괄호 없는 if 조건식이 Python다운 형태를 만듦 1 + 2 에서 x = 1 + 2 * 3 , if x > y: z = 3 순으로 확장했지만, 결과는 목표와 달리 계산기에 가까웠고 이미 512바이트를 넘었음소스를 직접 실행하는 파서
char src[999] 에 대부분의 공백을 제거한 소스를 보관함 int vars[256] 하나에 변수와 함수 이름에 대응하는 값을 저장함 pos , ch , line_start 로 다음 문자 위치, 현재 문자, 현재 줄 시작 위치를 추적함 for 에서는 or 와 inrange( 를, while 에서는 hile 을, if 에서는 f 를 건너뜀 vars 의 인덱스로 직접 사용함들여쓰기와 소스 위치로 구현한 제어 흐름
while 과 for 는 조건식의 소스 위치를 저장하고, 본문 실행 후 그 위치로 돌아가 매 반복마다 다시 파싱 함코드 골프로 1024바이트에 맞추기
libc 를 링크한다고 가정함 int 선언과 함수 반환형을 이용함 e(){for(z=t();c-43u<3;)y=44-c,z+=y*t();return z;} 로 압축함 Y(){c&&c-10&&Y(G());} 로 줄임 c 로 소스 끝을, c-10 으로 줄바꿈 여부를 검사하고 && 로 if 를 대체함 G();Y(); 대신 Y(G()); 를 사용해 한 바이트를 더 절약함 if n%15: 처럼 정수의 참·거짓 판정은 가능함최종 지원 기능과 제약
+ , - , * , % 의 연산자 우선순위를 처리함 + · - 는 표현식 시작에서만 동작함 < , > , <= , >= , == 를 지원하며, 비교는 표현식당 하나만 가능함 if · else 를 지원함 while 과 for x in range(y) 는 각각 else 블록도 사용할 수 있음 print 는 문자열 리터럴 하나 또는 정수 표현식 하나를 출력함공개 코드와 압축 과정의 부담
Hacker News 의견들
이 “Python”은 첫 글자만으로 키워드를 판별 함. f 는 무조건 for [x] in range[y] 형태이고 다른 for 문은 지원하지 않으며, w 는 while , i 는 if , d 는 def , p 는 print( 로 간주함.
게다가 글에 실린 코드가 GitHub의 “읽기 쉬운” 버전보다 주석이 많아서, 동작을 이해하려면 글까지 읽어야 함. Tiny Python이라기엔 너무 단순 한 듯함. 몇 KB만 더 허용해서 최소한 리스트와 딕셔너리는 지원하면 좋겠음. Lisp도 가능한 기능임!
w = 4 처럼 단순한 코드도 실패한다는 뜻인가? 내 취향에는 너무 과한 편법임. 내가 택할 방식은 아니지만, 들인 노력과 읽기 쉬운 글은 높이 평가함. 내가 최근 몇 달간 직접 작성한 코드보다도 사람이 쓴 코드가 더 많기도 함!https://www.a1k0n.net/2006/09/15/obfuscated-c-donut.html
더 큰 규모를 보고 싶다면 https://phoboslab.org/log/2021/09/q1k3-making-of 도 있음. 개인적으로는 여전히 https://www.pouet.net/prod.php?which=1221 에 애착이 감.
반복문은 소스의 앞부분으로 돌아가 매번 다시 파싱하는 방식인데, DOS의 .bat 처리도 이렇게 작동함. Unix 계열 셸에서도 같은지는 그 “기능”을 활용할 일이 없어 모르겠음.
C4 외에 살펴볼 만한 고밀도 인터프리터로 J Incunabulum 도 있음. 의도적으로 코드 골프를 한 것은 아니라 크기는 조금 더 큼. https://www.jsoftware.com/ioj/iojATW.htm .
더 넓게 보면 배열 프로그래밍 문화에서는 이 정도 코드 밀도를 평범하게 여기는 듯함. https://news.ycombinator.com/item?id=45800777 .
https://news.ycombinator.com/item?id=36102460
SectorLisp 같은 것을 생각하고 있음. https://justine.lol/sectorlisp/ .
물론 자원이 극히 제한된 임베디드 시스템은 예외이며, 그곳에서는 C와 어셈블리에 사실상 적수가 없음.
https://prog21.dadgum.com/116.html
1 + 2 로 시작했다”는 대목부터 납득하기 어려움. 그걸 어떻게 512~1,024바이트 안에 넣었다는 것인가? print(3 * * 1000) 도 해봤는가?그래도 내가 작고 투박한 장난감 Python 구현을 만든다면 임의 정밀도 정수나 거듭제곱 연산자 는 아마 구현하지 않을 것 같음. 적어도 첫 버전에서는 제외할 듯함.
https://justine.lol/sectorlisp/
덧붙여, sectorC로 python1024를 컴파일할 수 있을지 궁금함.