Quine은 자기 자신을 복사하는 프로그램이다. 즉, 인수를 취하지 않으며, 실행시 자신의 소스코드를 그대로 출력한다.
문제: 당신이 선호하는 언어를 이용해 Quine 프로그램을 작성하라.
위키백과 설명(스포일러이므로 문제를 도저히 못 풀 때만 보세요): http://en.wikipedia.org/wiki/Quine_(computing)
45개의 풀이가 있습니다.
#include <stdio.h>
char S[] = "#include <stdio.h>%cchar S[] = %c%s%c;%cint main() { printf(S, 10, 34, S, 34, 10); return 0; }";
int main() { printf(S, 10, 34, S, 34, 10); return 0; }
using System; namespace ConsoleApplication { class Program { static void Main(string[] args) { string s = "using System; namespace ConsoleApplication {2} class Program {2} static void Main(string[] args) {2} string s = {0}{1}{0}; Console.WriteLine(s, (char)34, s, (char)123, (char)125); {3}{3}{3}"; Console.WriteLine(s, (char)34, s, (char)123, (char)125); }}}
위에 코드를 실행화면 아래와 같이 출력됨.
using System; namespace ConsoleApplication { class Program { static void Main(st
ring[] args) { string s = "using System; namespace ConsoleApplication {2} class
Program {2} static void Main(string[] args) {2} string s = {0}{1}{0}; Console.Wr
iteLine(s, (char)34, s, (char)123, (char)125); {3}{3}{3}"; Console.WriteLine(s,
(char)34, s, (char)123, (char)125); }}}
winmerge로 비교시 완벽히 일치 즉, 소스코드를 실행하면 실행화면이 소스코드랑 동일한 quine이다.
자바스크립트의 재밌는 특징 두가지를 이용했습니다.
IIFE 즉시실행함수
인자로 넘길 수 있는 function 일급객체
javascript
(function foo() {
console.log('(' + foo + ')();')
})();
C#으로 작성했습니다. 만들고도 긴가민가 하네요.
using System;
public void GenerateQuine()
{
var quine =
"public static void GenerateQuine()" +
"{{\n var quine = {0}{1}{0};" +
"Console.Write(quine, (char)34, quine); }}";
Console.Write(quine, (char)34, quine);
}
Perl
$_는 명시 되지 않으면 기본으로 주어지는 값이고 eval은 string을 실행시킵니다.
""만으로는 백슬래시 지옥을 빠져 나올 수 없는데 다행히 q//를 쓸 수 있습니다.
$_=q/print"\$_=q\/$_\/;eval"/;eval
%r 은 python 에서 문자열 출력시 single quote가 추가되어 출력됩니다.
이를 이용해서 Quine 프로그램을 작성할수 있습니다.
coding by python beginner
bar = 'bar = %r; print(bar %% bar)'; print(bar % bar)
#Python 3.5
q = 'q = %r;import os;os.system("dir>echo");print(str(q %% q))';import os;os.system("dir>echo");print(str(q % q))
Ruby
eval quine="print 'eval quine=';p quine"
다른 방식
quine = "\nputs \"quine = \" + inspect + quine"
puts "quine = " + quine.inspect + quine
Cheat Quine
$><<IO.read($0) #=> puts IO.read('file')
Python 2.7
a = '''print 'a = ' + "''""'" + a + "''""'"
print a'''
print 'a = ' + "''""'" + a + "''""'"
print a
? 그냥 이런식으로 하면 되는것인가?? ㅋㅋㅋㅋㅋ
#include <iostream>
#include <string>
using namespace std;
int main(){
string s = "call me";
cout << "#include <iostream>\n#include <string>\nusing namespace std;\n\nint main(){\n\tstring s = \"call me\";\n}\n";
}
Haskell로 작성하였습니다. ghci 에서 아래와 같이 실행하면 됩니다.
(\s -> putStr s >> print s) "(\\s -> putStr s >> print s) "
(\s -> putStr s >> print s) "(\\s -> putStr s >> print s) "
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class FIO {
public static void main(String args[]) {
String input = "C:/Users/woo/Documents/Visual Studio 2010/Projects/20160927/20160927/20160927.cpp";
try {
BufferedReader in = new BufferedReader(new FileReader(input));
String s;
while ((s = in.readLine()) != null) {
System.out.println(s);
}
in.close();
} catch (IOException e) {
System.err.println(e); // 에러가 있다면 메시지 출력
System.exit(1);
}
}
}
import java.util.ArrayList;
public class Quine {
public static ArrayList
{
PrintFirst();
PrintMiddle(blist) ;
PrintMiddle(alist);
}
public static void PrintMiddle(ArrayList
}
public static void PrintParser(String str)
{
if(str.contains("PrintMiddle(blist);"))
{
blist.add("PrintParser(\""+str + "\");");
PrintMiddle(alist);
alist.clear();
PrintMiddle(blist) ;
blist.clear();
}else{
alist.add(str);
blist.add("PrintParser(\""+str + "\");");
}
}
public static void PrintFirst()
{
PrintParser("import java.util.ArrayList;");
PrintParser("import java.util.List;");
PrintParser("public class Quine {");
PrintParser("public static ArrayList<String> alist = new ArrayList<String>();");
PrintParser("public static ArrayList<String> blist = new ArrayList<String>();");
PrintParser("public static void PrintMiddle(ArrayList<String> plist)");
PrintParser("{");
PrintParser("PrintFirst();");
PrintParser("PrintMiddle(blist) ;");
PrintParser("PrintMiddle(alist);");
PrintParser("}");
PrintParser("public static void PrintMiddle(ArrayList<String> plist)");
PrintParser("{");
PrintParser("for(String tmp:plist)");
PrintParser("{");
PrintParser("System.out.print(tmp+\"\\r\\n\");");
PrintParser("}");
PrintParser("}");
PrintParser("public static void PrintParser(String str)");
PrintParser("{");
PrintParser("if(str.contains(\"PrintMiddle(blist)\"))");
PrintParser("{");
PrintParser("blist.add(\"PrintParser(\\\"\"+str + \"\\\");\");");
PrintParser("PrintMiddle(alist);");
PrintParser("alist.clear()");
PrintParser("PrintMiddle(blist) ;");
PrintParser("blist.clear();");
PrintParser("}else{");
PrintParser("alist.add(str);");
PrintParser("blist.add(\"PrintParser(\\\"\"+str + \"\\\");\");");
PrintParser("}");
PrintParser("}");
PrintParser("public void PrintFirst()");
PrintParser("{");
PrintParser("PrintMiddle(blist);");
PrintParser("}");
PrintParser("}");
}
}
int main() {
char str = "#include
return 0;
}
밣밤바밤밣밣밤바밤밣받받발밦밣밠밠밡밦밣밣밤밠밤밣밡바받밣밣받바받밤밣밦바바발밣밦밤받받밡받바밣바밣밡밡반밤밣밡바받밣밣바바받밤밣밦바바발밣밦밤받받밡받바밣바밣밤밣반밤밣밡바받밣밣바밡반밤밣밦바바발밣밦밤받받밡받바밣바밣밤밣반밤밣밡바받밣밣밤밣반밤밣밦바바발밣밦바바발밣밡받밣발밣받밣반밤밣받밣반밤밣반반바바바밠발밠밤밣발발받받밣밣밤밣발밣반밠밣밤밣밡발바밤밣밠발바밤밣밣밦밦바밣밠발바밤밣밣밦밦바밣반밠밣밤밣밣밦밦바밣밡발바밤밣밦밦바밤밣발밤밣밡밠밣밠받반밡밡반발밦밣받받발밦밣밡밡밦발밣반바반받밡밡발바밤밣밣밦밦바밣반바반받밡반밠밣밤밣밤밡발밤밣발밤밣밡밠밦발밦받밡반밠밣밤밣밡발바밤밣밡반밦밣밣발바밣밦밣반반바바바밣밠받반밡밠밤밠밤밣발밦받밤밣밦바밣밦밣밣밦밦바밣반바반받밡반밠밣밤밣발밦바밤밣발밠바밣밣밡밤바밤밣밣밦밦바밣반바반받밡반밠밣밤밣밠발바밤밣발밠바밣밣밡발바밤밣밣밦밦바밣반바반받밡반밠밣밤밣밣발바밤밣발밠바밣밣밣발바밤밣받반반반밣발밠바밣밣밠발밦반밡밡밤바밤밣밤반반바밣발반밦받밡반받밠밡밣밤밡발받밣반반바바바반바밦밤밣반반반밤밣밠밤밡바밣밡밣받바밣반발바바밣바바받밤밣밦바바발밣받바밣바밣밤밡반밤밣밤밡반밤밣밡밠밡밡밠밡밠밡밡밠밡밠밡밡밠밡밠밡밡밠밡밠밡밡밠받반발반밡밡밠밡밡밠밡밠밡밡밠받바밣바밣바밡반밤밣밡바받밣밣밤밡반밤밣밦밤받받밡밦밣밦밤밡발발받받밣밠밤밣발밣반반바바바바밤밠바밣밠밤밡바밣밤밤밡밤밣밣발받바밣밣밦밦바밣발밦바밤밣발밤밣밡밠밣발바밤밣밣밦밦바밣밡밤바밤밣발밤밣밡밠발밦바밤밣밣밦밦바밣반밠밣밤밣발발받받밣밠발바밤밣밡밤바밤밣밣밦밦바밣발발받받밣발발받받밣밦밡밦발밣밡밣밤받밣밠발바밤밣밡밤바밤밣밣밦밦바밣밤받밦받밣우
우어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어어
바바싼쑨뷺저벖뻐퍼떠벓저범뻐퍼떠벅저벋뻐퍼떠벅저벅뻐뻐서버버
븂맣설빠밞발따발따빠따밞밤다타싹싼산파밞따파빠북다푸빠밞주쏟
타뷹볅쏠따파빠밣자박따파빠발자밞따파빠밝자밝뚜자토박도표차모
불뱍또두뎌범뻐떠벎벎더더더더더터더더떠벋저벎퍼희맣섣
땨또뺘됴따밣다밝따박다밣따빠맣발박따맣맣삭멓발박따뫃
아희입니다. GitHub repo
Swift입니다.
따옴표가 번번이 발목을 잡았는데, debugDescription이 따옴표를 같이 넘겨주는것을 다른 Swift Quine구현에서 발견했습니다. debugDescription을 못찾았으면 Quine을 못풀었을겁니다.
let a = "func b(){print(\"let a = \\(a.debugDescription)\\n\\(a)\")};b()"
func b(){print("let a = \(a.debugDescription)\n\(a)")};b()
별로 존경받지 못하는 외부파일에서 읽어오기 자바소스입니다.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
public class main4 {
public static void main(String[] args) {
File file = new File(".\\src\\main4.java");
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(file));
String output = "";
while((output = br.readLine()) != null){
System.out.println(output);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
using System;
class A
{
static void Main()
{
string s = @"using System;
class A{{static void Main()
{{string s=@{0}{1}{0};
Console.Write(s,'{0}',s);}}}}";
Console.WriteLine(s, '"', s);
}
}
C#
구글링 끝에 문제는 풀었지만... 쉽지 않네요 :)
using System;
class P
{
static void Main()
{
string s = @"using System;
class P
{{
static void Main()
{{
string s=@{0}{1}{0};
Console.Write(s, '{0}', s);
}}
}}
}}";
Console.Write(s, '"', s);
}
}
def func():
up ='"'
well = "'"
codes=["""
def func():
up =""",""" well = """,
""" codes=[""",
""" ]
print(codes[0],well+up+well)
print(codes[1],up+well+up)
print(codes[2]+up*3,end = "")
print(codes[0]+up*3+","+up*3,end = "")
print(codes[1]+up*3+",")
print(up*3+codes[2]+up*3,",")
print(up*3+codes[3]+up*3,end ="")
print(codes[3])
func()
""" ]
print(codes[0],well+up+well)
print(codes[1],up+well+up)
print(codes[2]+up*3,end = "")
print(codes[0]+up*3+","+up*3,end = "")
print(codes[1]+up*3+",")
print(up*3+codes[2]+up*3,",")
print(up*3+codes[3]+up*3,end ="")
print(codes[3])
func()
## 1. 실행시 자신의 소스코드를 그대로 출력하는 Quine 작성
v = '## 1. 실행시 자신의 소스코드를 그대로 출력하는 Quine 작성\n\nv = %r\nprint(v %% v)'
print(v % v)