를 작성하는 방법을 자기 재현하는 코드(인쇄 소스에 exec)?
-
01-07-2019 - |
문제
나는 많이 보았 C/C++기반 솔루션이 이 문제가 어디 우리를 작성해야 하는 프로그램에 따라 실행 인쇄 자신의 소스입니다.
일부 솔루션
http://www.cprogramming.com/challenges/solutions/self_print.html
더 많은 솔루션이 인터넷에서 각각 다릅니다.나는 경 우리는 어떻게 접근하여 이러한 문제를,무엇인가 내부에 마음의 하나를 해결합니다.빌려 저에게 어떤 통찰력으로 이 문제는...동 솔루션에서 해석한 언어 perl,php,ruby,etc.할 수 있는...나는 방법을 알고 싶은 한 가지에 대한 디자인에서 컴파일한 언어
해결책
고객께서는 cheating1 사이에는 차이가 없이 컴파일되고 해석되는 언어입니다.
의 일반적인 접근 방식을 quines 는 것은 매우 쉽습니다.첫째,어떤 프로그램처럼,어떤 점에서 그것을 인쇄할 수:
print ...
그러나 무엇을 해야 그것을 인쇄?자체입니다.그래서 그것을 인쇄 할 필요가 있다"print"command:
print "print ..."
어떻게 해야 그것을 인쇄 다음은?음,한 시간에 프로그램이 성장,그래서 그것을 인쇄가 필요한 문자열로 시작하는 인도
print "print \"print ...\""
지금 프로그램을 다시 성장,그래서 거기에 다시 더 프린트:
print "print \"print \\\"...\\\"\""
그래서.모든 추가 코드가 더 코드를 인쇄합니다.이 방법은 없고, 하지만 그는 흥미로운 패턴문자열"인쇄\""이 반복되고 다시.그것은 좋은 것을 넣어 반복되는 부분 으로 변:
a = "print \"" print a
그러나,프로그램을 다만,변경 그래서 우리는 우리 조정할 필요가 있:
a = "a = ...\nprint a" print a
면 우리가 지금 시도해를 채우기에서"...", 우리는 실행으로 동일한 문제를 전하고 있습니다.궁극적으로,우리는 뭔가를 작성하는 다음과 같다:
a = "a = " + (quoted contents of a) + "\nprint a" print a
하지만,가능
는 경우에도 있기 때문에 우리는 이런 기능 quoted()
을 위해 인용,
가 여전히 문제는 우리 정의 a
의 관점에서 자체:
a = "a = " + quoted(a) + "\nprint a" print a
그래서 우리가 할 수 있는 퍼팅 장소를 홀더로 a
:
a = "a = @\nprint a" print a
든다!다른 것은 지금은 명확하다.단순히 교체하는 장소 홀더
과 인용된 내용의 a
:
a = "a = @\nprint a" print a.replace("@", quoted(a))
때문에 우리가 변경된 코드 우리는 조정이 필요한 문자열:
a = "a = @\nprint a.replace(\"@\", quoted(a))" print a.replace("@", quoted(a))
니다.모든 quines 모든 언어로 작동하는 방법 (제외하고 부정하는 사람).
잘하는지 확인해야 합를 교체할만 첫 번째 발생 장소의 홀더입니다.고 사용할 경우 두 번째 장소는 홀더 피할 수 있습니다 필요를 인용하는 문자열입니다.
그러나 사람들은 사소한 문제
고 해결하기 쉽습니다.는 경우,사실의 실현 quoted()
고 replace()
만 내용에는 다양한 quines 정말 차이가 있습니다.
1 함으로써 프로그램으로 읽어의 소스 파일
다른 팁
의 몇 가지 서로 다른 전략을 쓰 quines.분명 하나은 코드를 작성하는 코드를 출력합니다.그러나 더 많은 흥미로운 것들을 포함한 언어할 수 있는 기능을 위해 자기 포함,다음과 같이%s-style printf 기능에 여러 언어를 사용할 수 있습니다.당신은 그게 뭔가를 포함하도록 그것을 끝까지 해결하는 요청을 포함합니다.생각처럼,회문에,많은 시험과 오류가가 참여했다.
또한할 수 있는 방법을 연구한 핵심 전쟁 게임 작동합니다.그것은 좋은 예를 들어,나는 생각한다.
일반적인 접근 방식(할 수 없는 경우 속임수*)은 뭔가를 쓰는 것이 인코딩 소스에서 문자열을 일정한 다음 출력하는 일정한 두:한 번으로 문자열과 한 번 코드입니다.가는"내가 쓰는 모든 시간을 줄의 코드를 작성해야 다른 인쇄하다."문제입니다.
'부정 행위'포함됩니다:-사용하여 해석되어 단순히 선적 원본 및 인쇄 -0 바이트 길이 파일에 유효와 같은 일부 언어 C.
에 대한 재미있는,내가 가진 중 하나에 계획하는 나는 아주 자랑스럽게 생각하고의 약 5 분 전까지 발견 발견되었다.어쨌든,거기에 약간 수정하"규칙"게임의 더 나은 계산에 대한 이중성의 데이터 및 코드에서는 Lisp:인쇄하는 대신 소스 프로그램의 it's S-식 반환하는 자체:
((lambda (x) (list x `',x)) '(lambda (x) (list x `',x)))
이 하키 같은 개념이지만,약간 다른(더 자세한 정보)메커니즘에 대한 인용.나는 내 같은 발견하였습니다.
하나의 아이디어에 대해 생각하는 인코딩하는 방법을 제공 무언가를 두 가지 의미할 수 있도록 사용하여 출력에서 뭔가 몇 가지의 형태입니다.또한 cavaet 는 이러한 유형의 문제를 제공한 제한을 어렵게 만들로 없이 어떤 규칙이 이외의 다른 프로그램 출력을 자체,빈 프로그램은 솔루션입니다.
당신이 찾을 수있는 꽤 몇 가지 솔루션이 여기: http://forums.thedailywtf.com/forums/p/5232/147528.aspx
는 방법에 대해 실제로 읽고 인쇄 소스 코드?그 어렵지 않습니다.Heres 에서 하나 php:
<?php
{
header("Content-Type: text/plain");
$f=fopen("5.php","r");
while(!feof($f))
{
echo fgetc($f);
}
fclose($f);
}
?>
Python 에서 작성할 수 있습니다:
s='c=chr(39);print"s="+c+s+c+";"+s';c=chr(39);print"s="+c+s+c+";"+s
에서 영감이 자기는 인쇄 의사 코드:
Print the following line twice, the second time with quotes.
"Print the following line twice, the second time with quotes."
I've done a a s3 를 들어에 관심있는 사람들을 위해 이
var program = "var program = @; function main(){trace(program.replace('@',
String.fromCharCode(34) + program + String.fromCharCode(34)))} main()";
function main(){
trace(program.replace('@', String.fromCharCode(34) + program + String.fromCharCode(34)))
}
main()
루비에서는:
을 둔 파일입니다.읽기(__파일__)