자신의 언어를 해석하지만 자신은 해석하지 않습니까?


21

X는 간단한 언어 인 "X 해석"이라는 많은 과제가 있습니다. 제 생각에는 너무 지루합니다. 인터넷에있는 모든 미련한 사람들에게 흥미로운 일을하기 위해 다음과 같은 도전을 시도 할 수 있습니다.

도전

언어를 선택하십시오 $LANG. $LANG튜링 완료 프로그래밍 언어 또는 프로그래밍 언어의 튜링 완료 하위 집합 일 수 있습니다. $LANG통역 을 위해 귀하의 언어 기능을 생략하는 경우 , 귀하의 제출물도로 작성되어야하므로 귀하의 프로그램에도 사용해서는 안됩니다 $LANG.

컴파일러 / 인터프리터를 $LANG작성하십시오 $LANG. eval이 컴파일러를 작성할 수있는 언어의 모든 기능 ( 및 친구 포함 )을 사용할 수 있습니다. 작업을 더욱 어렵게하려면 한 가지 제한이 있습니다. 프로그램은 $LANG인터프리터 / 컴파일러 자체 를 제외한 모든 유효한 프로그램을 해석 / 컴파일 할 수 있어야 합니다. 해석 / 컴파일 할 프로그램이 파일 이름에 관계없이 인터프리터 또는 컴파일러 자체 인 경우 프로그램은 인터프리터 또는 컴파일러의 기능 (예 : 바핑 또는 인쇄 Hello, world!) 과 완전히 관련이없는 작업을 수행해야합니다 .

이 작업을 더욱 복잡하게하려면 프로그램을 컴파일하거나 해석 할 때 자체 소스를 읽지 않아야합니다.

명세서

  • 이 작업은 코드 골프입니다. 가장 적은 문자로 제출하면 이깁니다. 동점 인 경우 먼저 제출 된 솔루션이 우선합니다.
  • 프로그램 / 스크립트는 파일에서 해석 할 프로그램을 읽어야합니다. 경로와 이름을 하드 코딩 할 수 있습니다. 파일을 읽을 때 파일을 다른 파일로 컴파일하거나 (시스템에서 실행 가능해야 함) 직접 실행할 수 있습니다. $LANG파일 읽기 기능이 부족한 경우 적합한 코드를 읽는 다른 방법을 선택할 수 있습니다 $LANG. $LANG다른 언어의 하위 집합으로 선택할 수 없지만 파일 읽기 기능을 제거 할 수 있습니다.
  • 일반적인 코드 골프 규칙이 적용됩니다. 즉, 해결책을 사용하여 솔루션이 사소한 경우 (솔루션을 정확하게 구현하는 단일 문자 프로그램을 정의하는 경우)이 문제를 해결하기 위해 작성한 개인 애완 동물 언어는 금지됩니다. 규칙의 남용이 권장됩니다.

튜링이 완료되는 한 언어를 정의 할 수 있습니까?
Cruncher

@Cruncher 그렇습니다. 자세한 내용은 사양의 마지막 글 머리표를 참조하십시오.
FUZxxl

답변:


8

루비, 63

b=$<.read
t="b=$<.read\nt=%p\nb!=t%%t&&eval(b)"
b!=t%t&&eval(b)

더 작은 솔루션이 없으면 대답이 허용됩니다.
FUZxxl

11

펄, 89 자, 부정 행위 없음

$_=q($_=q(Q);s/Q/$_/;($q=join"",<>)eq$_?die:eval$q);s/Q/$_/;($q=join"",<>)eq$_?die:eval$q

이 코드는 "자체"로 간주되는 항목에 대해 매우 까다 롭습니다. 특히, 입력에 후행 줄 바꿈이나 다른 추가 공백이 있으면 자체 인식되지 않습니다. 테스트하려면 파일 (예 :)로 저장하고 다음을 unquine.pl수행하십시오.

$ perl unquine.pl unquine.pl
Died at unquine.pl line 1, <> line 1.

기억하지 unquine.pl파일이 있어야합니다 정확히 덜, 더 이상 긴 89 바이트. 다른 Perl 스크립트를 입력으로 실행하면 다른 스크립트가 다음과 같이 실행됩니다.

$ perl unquine.pl hello.pl
Hello, world!

이름에서 알 수 있듯이 구현은 퀴네를 기반으로합니다.

$_=q($_=q(Q);s/Q/$_/);s/Q/$_/

이 코드는 $_자신과 동일하게 설정 됩니다. 나머지 프로그램 (물론 내부에 복제해야 함 $_) $_은 입력 과 비교 하고 입력과 일치하면 죽고 그렇지 않으면 입력을 평가합니다.


&&/ ;쌍을 삼항으로 바꿀 수 있습니다 (한 번의 char off, quining으로 두 배). 좋은 아이디어와 구현!
JB

@JB : 잘 잡아! 이제 89 자까지 줄었습니다.
Ilmari Karonen

5

GolfScript, 30 자

{`".~"+"#{$<.read}".@=!{~}*}.~

이 프로그램은 명령 행에 이름이 지정된 파일의 내용을 읽고 위의 코드와 정확히 일치하지 않으면 GolfScript로 해석합니다. 입력 값이 위의 코드와 정확히 동일하면 변경없이 그대로 인쇄됩니다 (끝에 추가 된 줄 바꿈 제외).

이것은 이 자체 식별 프로그램에 대한 아주 간단한 적응입니다 . 구체적으로 :

  • { } GolfScript의 코드 블록 리터럴입니다.
  • .~코드 블록에 적용되어 블록을 복제하고 사본을 실행합니다.

코드 블록 내부 :

  • ` 코드 블록의 사본을 문자열 화합니다.
  • ".~"+문자 .~를 추가하여 프로그램의 소스 코드가 포함 된 문자열을 생성합니다.
  • "#{$<.read}"GolfScript 내에서 Ruby 코드를 실행할 수 있는 문서화 된 핵 입니다. 이 경우 명령 줄에 지정된 파일의 내용을 읽고 반환하는 Ruby 문 $<.read( Lowjacker의 Ruby 솔루션 에서 훔친 )을 실행합니다. 이 해킹은 GolfScript 자체가 명시적인 파일 I / O 기능을 제공하지 않기 때문에 필요합니다.
  • .@ 스택에 파일 내용의 사본 두 개와이 프로그램의 소스 코드가 포함되도록 스택 위에 요소를 복제하고 섞습니다.
  • =! 스택의 상위 2 개 항목 (예 : 파일 내용 및 소스)을 비교하여 서로 다르면 1을, 동일하면 0을 반환합니다.
  • {~}*파일 내용의 나머지 사본을 GolfScript 코드로 평가하지만 비교 결과가 1 인 경우에만 해당됩니다 (기술적으로 {~}스택의 숫자로 지정된 횟수만큼 코드 블록 을 실행합니다 ( 예 : 0 또는 1 회). 블록 ~은 GolfScript 평가 연산자입니다.)

추신. stdin에서 실행할 코드를 읽는 것이 허용되면 Ruby에 쉘을 적용하지 않고도 21 개의 문자 로이 문제를 해결할 수 있습니다 .

{`".~"+1$=!{""\~}*}.~

이 프로그램은 stdin에서 입력 문자열을 읽고 자신의 소스와 일치하지 않으면 빈 입력으로 실행합니다. 위의 프로그램과 마찬가지로 소스와 일치하는 입력은 단순히 에코됩니다.


좋아 보이지만 파일에서 입력을 읽는 것처럼 보이지 않습니다.
FUZxxl

Lowjacker 솔루션과 같은 파일에서 정확하게 읽습니다.
Ilmari Karonen

5

파이썬 167 130 118 바이트

이것은 골프에 대한 나의 첫 번째 시도이므로 여기에 간다! 자체를 제외한 모든 프로그램을 해석합니다.

개선 된 버전 :

i=open(raw_input()).read();q='i=open(raw_input()).read();q=%s;i==q%%repr(q)and a;exec(i)\n';i==q%repr(q)and a;exec(i)

그것이 스스로 얻는다면 :

Traceback (most recent call last):
  File "pygolf.py", line 1, in <module>
    i=open(raw_input()).read();q='i=open(raw_input()).read();q=%s;i==q%%repr(q)and a;exec(i)\n';i==q%repr(q)and a;exec(i)
NameError: name 'a' is not defined

이 솔루션이 Ilmari Karonen과 거의 같은 방식으로 작동한다고 생각합니다. 기본 아이디어는 다음과 같습니다.

input = read_some_file()
if input == some_quine()
    barf()
interpret(input)

내가 사용한 quine은 다음 중 하나를 기반으로했습니다.

(lambda x: x + repr((x,)))('(lambda x: x + repr((x,)))',)

그러나 그 이후로 훨씬 짧은 퀴인은 다음과 같습니다.

q='q=%s;q%%repr(q)';q%repr(q)

대화식 파이썬 쉘을 허용하면 더 짧을 수 있습니다.이 경우 다음을 수행 할 수 있습니다.

'%s;_%%repr(_)';_%repr(_)

파이썬에는 명령 줄 인수를 얻을 수있는 짧은 방법이 없기 때문에 raw_input ()으로갔습니다 (여전히 길지만 길지는 않습니다)

import sys;sys.argv[1]

사용법은 :

echo "foobar.py" | python quinterpretter.py

또는

python quinterpretter.py
<type filename and hit enter>

나는 사용하기 위해 더 짧은 quine을 찾았지만 여기에 내 구 버전 (후손을 위해)이 있습니다.

i=open(raw_input()).read();a if i==(lambda x,y:x+repr((x,y))+y)('i=open(raw_input()).read();a if i==(lambda x,y:x+repr((x,y))+y)', ' else 1;exec(i)\n') else 1;exec(i)

% s를 % r로 바꾸고 repr을 제거하십시오. % r은 raw를 의미하며 기본적으로 그는 같은 것입니다.
Loovjo

4

Javascript를 사용하여 파일에서 정확하게 읽을 수는 없습니다 (HTML5 FileReader를 사용할 수는 있지만 필요한 것보다 훨씬 복잡합니다). 따라서 이것은 자바 스크립트 프로그램을 문자열로 받아 실행하는 함수입니다.

이것은 아마도 골프처럼 될 수는 없지만 어쨌든 여기 있습니다.

자바 스크립트, 252

function c(p){q='\"';s='\\';a="function c(p){q='\"';s='\\';a=%;a=a.slice(0,17)+s+a.slice(17,24)+a[23]+a.slice(24);a=q+a.replace('%',q+a+q)+q;alert(a);}";a=a.slice(0,17)+s+a.slice(17,24)+a[23]+a.slice(24);a=a.replace('%',q+a+q);alert(a);if(p!=a)eval(p)}

Javascript에서 quine을 형성하는 더 좋은 기술을 아는 사람이 있으면 알려주세요.


1
귀하의 코드와 내 Perl 솔루션에 따라 135 문자 JS 솔루션을 아래에 게시했습니다. 영감을 얻기 위해 +1!
Ilmari Karonen

2
read p<p;read c<c;[ "$p" = "$c" ]||. ./c

sh의 45 자 (POSIX 쉘). 실행할 코드는 파일에 있어야합니다 ./c.

인터프리터 자체의 코드는 파일에 있어야 ./p하므로 도전이 그것을 금지하지는 않지만 속이는 것 같습니다. 아니면 이것이 나의 "언어"가 "완벽한 프로그래밍 언어"가되지 못하게 하는가?

일반적으로 외부 실행 파일이지만 이론적으로 셸에 내장 된 도구를 사용하면 코드를 단축 할 수 있습니다.

cmp -s p c||. ./c

그것은 18 자이며, -s비트는 그렇지 않으면 유효한 (자체가 아닌) 프로그램을 위해 항상 인쇄되는 줄을 억제하는 것입니다.

그리고 더 간결한 구문으로 위의 작업을 수행하는 셸 언어 버전을 항상 빌드 할 수 있습니다.

그리고 입력이 단일 '.'로 구성된 경우 항상 프로그램을 작성할 수 있습니다. 또는 빈 문자열 인 hell은 다른 파일의 내용을 일반 코드로 평가하고이를 프로그래밍 언어라고합니다. 따라서 빈 문자열은 사용자가 구축 한 언어로 해결해야 할 솔루션입니다. 실제로 다음은 그러한 언어에 대한 통역사입니다.

read code; if [ "$code" ]; then eval "$code"; else . ./othercode; fi

위의 스크립트가 해석하는 언어를 사용하면 솔루션은 빈 문자열입니다. 그리고 코드 위치를 더 이상 하드 코딩 할 필요가 없습니다.

문제?


2
문제는 "프로그램이 자체 소스를 읽지 말아야한다"고 말합니다.
Ilmari Karonen

다 니트, 그때 시간 낭비. 그리고 나는 당신이 당신이 생략 할 기능을 사용해서는 안된다고 말합니다. 이것은 빈 문자열 기능에 위배됩니다. 그런 다음 컴파일러 / 인터프리터 자체의 코드가 새 언어에서 다른 동작을 일으키는 경우 인터프리터 기능을 생략 / 변경 해야합니다 . 어쨌든, 나는 글쓰기 오류가 재미있었습니다.
TaylanUB

@TaylanUB 글쎄, 실제로 통역사를 제외한 모든 유효한 $ lang 프로그램을 해석해야합니다.
FUZxxl

@FUZxxl 예는 "SH + 빈 문자열"언어 (코드가 빈 문자열이 아닌 경우), 또한 해석 쉬 코드 (에 넣어되어야하는 그 안에 기록 된 빈 문자열 프로그램 쉬에, 그렇지 않으면 동일하다 ./othercode), 및 수행 코드가 빈 문자열이면 아무것도 없습니다. 파일 ./othercode를 호출해서는 안됩니다. 빈 문자열 언어로 작성된 인터프리터가 해석하는 코드 일뿐입니다.
TaylanUB

2

자바 스크립트, 135 자

function c(p){q='function c(p){q=%27Q%27;p!=unescape(q).replace(/Q/,q)?eval(p):alert()}';p!=unescape(q).replace(/Q/,q)?eval(p):alert()}

Peter Olson의 JavaScript 솔루션은 Perl 솔루션을 JS로 이식하려고 영감을주었습니다. 그의 솔루션과 마찬가지로이 코드는 c문자열을 수락하고 위의 코드와 같지 않으면 회피 하는 함수 를 정의합니다 .

뒷이야기에서 명백한 해결책이 무엇인지 알 때까지 JavaScript에 균형 잡힌 문자열 구분 기호가없는 것을 처리하는 좋은 방법을 찾는 데 시간이 걸렸습니다 unescape().

편리하게도 내 코드에는 백 슬래시 또는 큰 따옴표가 포함되어 있지 않으므로 큰 따옴표로 묶은 문자열에 안전하게 저장할 수 있습니다. 이를 통해 쉽게 테스트 할 수 있습니다.

e = "function c(p){q='function c(p){q=%27Q%27;p!=unescape(q).replace(/Q/,q)?eval(p):alert()}';p!=unescape(q).replace(/Q/,q)?eval(p):alert()}"
h = "alert('Hello, world!')"

eval(e)  // defines the function c()

c(h)     // evaluates h
c(e)     // does not evaluate e, alerts "undefined" instead

당신은 대체 할 수 alert()0대신 경고의 아무것도 할 수 있도록하는 undefined13 개 문자 저장합니다.
피터 올슨

@PeterOlson : 네,하지만이 프로그램은 "프로그램 자체가 감지되면 전혀 관련이없는 작업을 수행해야합니다"라고 말합니다. 나는 그것이 무언가를 해야한다는 것을 의미한다고 해석합니다 . 게다가, 나는이 방법이 더 좋아. :) (
Py

1
@Ilmari 아무것도하지 않는 것은 Javascript IMHO 해석과 관련이 없습니다.
FUZxxl

p=>...대신에 갈 수 있습니다function c(p)
FireCubez

2

커먼 리스프, 59

#+~ #.(#:a)(defun L(p)(compile-file p))(push :~ *features*)
  • 새로운 Lisp REPL에서 파일을 컴파일하십시오 (예 : sbcl --load )
  • 이제 L공통 Lisp 파일을 컴파일 할 수 있는 기능 이 있습니다.
  • (L <your file>)그러나을 호출 하면 파일 을 읽는 동안 오류가 발생 합니다.

왜?

처음으로 :~키워드를 (으)로 푸시했습니다 *features*. 이제 사용자 환경은 ~기능 에 대해 알고 #+있으며 ~ 기능 표현식 을 평가할 때 독자 매크로 가 성공했을 때 다음과 같이 처음으로 건너 뛰지 않고 다음 양식을 읽습니다. 파일에 다음과 같은 형식입니다 #.(#:a), 평가 묻는 (#:a)에서 읽기 시간 과 코드를 읽을로 결과 값을 사용합니다. 그러나 (#:a)uninterned symbol과 관련된 함수를 호출합니다 #:a. 이후 #:auninterned되고, 어떤 기능 (즉,하지에 바인딩되지 않은 신선한 상징이다 fboundp). 오류.


1

구성표, 48 자 또는 51 자

체계는 다양한 구현을 가진 언어입니다. 최신 RnRS를 준수해야하는 구현에도 불구하고 최신 작업 표준 (R6RS)은 미니멀리즘이 없기 때문에 인기가 없었습니다. R7RS는 곧 구제책으로 출시 될 예정입니다. 언어는 2로 나뉘어 있습니다. 첫 번째 언어는 강력하고 최소한이며 두 번째 언어는 구현 간 상호 운용성을위한 기능 확장을 제공하기위한 첫 번째 언어입니다. 그때까지 우리는 일반적인 작업을 이식 가능하게 수행 할 수있는 수단 (호스트 구현에서 구현되거나 수동으로 (구성에서 공통으로))을 제공하는 SRFI (Scheme Requests For Implementation)에 의존합니다. 말할 것도없이 첫 번째 코드 조각 (51 자)은 가능한 한 이식성이 뛰어나면서 SRFI-22 (UNIX의 실행 스크립트 실행)를 사용하여 명령 줄 인수에 액세스합니다.

(define(main x y)(case y(x => error)(else => load)))

더 읽기 쉽게 :

(define (main current-file arg)
  (case arg
    [current-file => error]
    [else => load]))

두 번째 (48 자)는 (널 환경에서) 자체를 평가할 수없는 파일이없는 해석 방법입니다.

(define(e)(write(eval(read)null-environment))(e))

더 읽기 쉽게 :

(define (interpret)
  (write (eval (read) null-environment))
  (interpret))

통역사를 복사하면 코드가 작동하지 않습니다.
FUZxxl

1
그것의 산문에 중첩 괄호를 포함하기 위해 계획 답변으로 남겨 두십시오.
Cyoce

1

그루비, 13 바이트

{Eval.me(it)}

이것은 Groovy의 서브 세트를 해석해야합니다.

테스트 사례 :

p={Eval.me(it)}

p'''
    (0..37).each{println"1234567890JIHGFEDCBAKLMNOPQRST!?,.ZYXWVU"[it..it+2]}
'''

p'''
    {Eval.me(it)}
'''

불행히도 그것은 명백히 방해하지만, 완전히 통역사와 같은 방식으로 수행하며 많은 입력을 위해 수행합니다.


어떤 줄에서 해석 할 프로그램을 읽습니까? 이 작업에 대한 올바른 제출이 아니지만 코드가 흥미 롭습니다.
FUZxxl

오류가 "재귀 한계를 초과했습니다"와 같은 것으로 가정합니까?
Ilmari Karonen

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.