알파벳 만 사용하여“그녀는 '하지만 그 사람입니다.'라는 문구를 인쇄하십시오.


50

And she said, 'But that's his.'다음 문자 만 사용 하여 문구 를 인쇄하십시오 . abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 문장 부호가 없거나 알파벳이 아닌 문자는 사용하지 마십시오. 원하는 프로그래밍 언어를 사용할 수 있습니다. 공백이 완전히 허용됩니다. 최단 프로그램이 이깁니다.


출력의 공백은 어떻습니까? (리딩 / 트레일 링?)
attinat

2
단, 내 esolang은으로 만 출력을 생성 할 수 없으므로 완료 할 수 없습니다 a-zA-Z. 이론적으로 나는 write와 Eval을 사용하여 필요한 명령어를 만들 +-*,%'"수 있지만 (적어도) 중 하나를 사용하지 않고는 아무것도 만들 수 없습니다 +-*,%'"0-9.
Draco18s

10
(programmer-of (language 'lisp))이것을 싫어합니다.
MatthewRock

4
인정해야합니다. 이것이 처음에는 특히 흥미 롭지 않다고 생각했지만 반복적이고 독특한 문자의 조합은 실제로 (특히 스택 언어에서) 최적화하기가 정말 재미있었습니다. 아주 좋아요
brhfl

1
출력에 추가 공백 이 허용되는지 확인할 수 있습니까? 추가 줄 바꿈처럼? 또는 소스에 공백 과 영문자를 추가하십시오. 추가 줄 바꿈으로 인쇄 되는 Befunge 답변 이 있습니다.
Peter Cordes

답변:


75

공백 , 417 414 349 265 바이트

Kevin Cruijssen 덕분에 265 바이트

  							
  				   
   		 	
   		
   	 
  		   		 
 	  		
 	  		 
   			 
  		 	
   	 
 	  	 
 	  		 
 	  	
   				
  		  	  
  							
 	  	  
  				 	 
  		 
   		
  		 	
   		 	
 	  	 	
  		
   	 
 	  		
 	  		
  		 
   	   
  		  	 	

  
   		  		 
	   	
  
 


온라인으로 사용해보십시오!

설명 :

[S S T  T   T   T   T   T   T   N
_Push_-63_'][S S T  T   T   T   S S S N
_Push_-53_.][S S S T    T   S T N
_Push_13_s][S S S T T   N
_Push_3_i][S S S T  S N
_Push_2_h][S S T    T   S S S T T   S N
_Push_-70_space][S T    S S T   T   N
_Copy_0-based_3rd_s][S T    S S T   T   S N
_Copy_0-based_6th_'][S S S T    T   T   S N
_Push_14_t][S S T   T   S T N
_Push_-5_a][S S S T S N
_Push_2_h][S T  S S T   S N
_Copy_0-based_2nd_t][S T    S S T   T   S N
_Copy_0-based_6th_space][S T    S S T   N
_Copy_0-based_1st_t][S S S T    T   T   T   N
_Push-15_u][S S T   T   S S T   S S N
_Push_-36_B][S S T  T   T   T   T   T   T   N
_Push_-63_'][S T    S S T   S S N
_Copy_0-based_4th_space][S S T  T   T   T   S T S N
_Push_-58_,][S S T  T   S N
_Push_-2_d][S S S T T   N
_Push_3_i][S S T    T   S T N
_Push_-5_a][S S S T T   S T N
_Push-13_s][S T S S T   S T N
_Copy_0-based_3rd_space][S S T  T   N
_Push_-1_e][S S S T S N
_Push_2_h][S T  S S T   T   N
_Copy_0-based_3rd_s][S T    S S T   T   N
_Copy_0-based_3rd_space][S S T  T   S N
_Push_-2_d][S S S T S S S N
_Push_8_n][S S T    T   S S T   S T N
_Push_-37_A][N
S S N
_Create_Label_LOOP][S S S T T   S S T   T   S N
_Push_102][T    S S S _Add][T   N
S S _Print_as_character][N
S N
N
_Jump_to_Label_LOOP]

100
Whitespace is completely allowed.나는 당신이 말 그대로 이것을 보았습니다.
Benjamin Urquhart

3
당신은 저를 이겼습니다. 그래도 꽤 많은 것들이 골프를 칠 수 있습니다. :) NNNprint_char 앞에 추가를 할 때 이미 오류가 발생하여 종료 하기 위해 후행 을 제거 할 수 있으므로 Jump_to_Label 이후에는 나오지 않습니다. 또한 왜 63시작에 저장 하고 루프에서 검색합니까? 대신 추가하기 전에 밀어 넣을 수 있습니다. 그리고 왜 Label-nr TTSSSSTN입니까? 레이블은 비어있을 수도 있으므로 NSSN레이블 NSNN을 하나만 사용하는 경우 레이블을 만들고 레이블로 이동하는 것으로 충분합니다.
케빈 크루이 센

1
위에서 제안한 변경 사항이있는 318 바이트 . 강조 표시가 추가 된 동일한 프로그램이 있습니다. 그리고 상수 값을 63어떻게 공제 했 습니까? 나는 그것이 가능한 가장 짧은 상수인지 100 % 확신하지 못한다. 만약 그렇다면, 이전의 도전을 위해 작성한 저의 지속적인 생성 프로그램에 문제가 있습니다. :)
Kevin Cruijssen

1
그렇습니다. 상수 102가 가장 효율적입니다. 281 바이트 (또는 강조 표시 사용 ). (참고 : 또한 사이에있는 공간에서 ehs dnA복사 된 공간 사이에 4 바이트를 절약하기 위해 하나의 사본을 사용했습니다 dias ehs.
Kevin Cruijssen

3
좋아, 이제 끝났어. :) 265 바이트 (또는 여기에서 강조 표시 ). 추가 사본이 추가되었습니다. ( 여기 관련 공백 팁 )
Kevin Cruijssen

62

펄 (5) , 133 (102) 95 바이트

s qqAnd she saidZ ZBut thatZs hisZZGjGGfq x
s qZqchr oct oct oct ord chopqge x
y qGjfqqdx
print

온라인으로 사용해보십시오!

설명:

정규식, 인쇄 및 절단 $_은 기본적으로 변수 에 적용됩니다 .

s qqAnd she saidZ ZBut thatZs hisZZGjGGfq

빈 문자열을로 바꿉니다 And she saidZ ZBut thatZs hisZZGjGGf.

s qZqchr oct oct oct ord chopqge

Z회피 결과로 각각 대체합니다 chr oct oct oct ord chop. 이렇게하면의 마지막 문자가 제거되고 $_키 코드가 8 진수로 해석되어 다시 문자로 변환됩니다. 예를 들어 j→ 106 → 70 → 56 → 46 → ..

방식으로 인해 교체 작품에 수정 $_손실 교체를 평가하는 동안 그 때문에, 일이 $_지금이다 And she said, 'But that's his.'GjGGf.

y qGjfqqd

모두 삭제 G, jf$_.


26
펄을 알지
못한다면

2
이것은 내가 본 웹 사이트에 기록 된 것 중 가장 아름다운 코드 일 수 있으며, Perl을 아는 사람이라고합니다.
Silvio Mayolo

1
관련,하지만 당신은 대체 할 수 printsay-2 문자. 현재 메타 합의에 따르면 명령 줄 플래그는 -M5.010바이트 수에 포함되지 않습니다.
Silvio Mayolo

34

> <> , 916 (915) 903 바이트

처음에는> <>의 해결책이 불가능하다고 생각했지만 조건부 또는 논리 제어가 필요한 사람은 누구입니까? :디

fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffloffffffffffffffffffffffffffffffffffffffffffffflopppgloppppppppppppppppppppppggloffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffflopppggloploppppppppppppppppppppppploffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffflopppppplofffffffflopggloppppppppppppppppppgglopppplofffffffloffffffffffffffffffffffffffflofffffffffffffffffffffffffffffffffffffffffffffffffffloglopppppppppppppppppppppppppppplofffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffflopppploppgloffffffffffffffffffflopppppppppppppppppppppppppgglofffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffflopppppppppppppppppppppppppppgglofffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffflofloffffffffffloppppppppppppppppppppppploppgloio

온라인으로 사용해보십시오

반복해서 숫자 (숫자 15)를 스택에 넣은 다음 스택 길이를 밀어 해당 ASCII 값으로 문자를 인쇄합니다. 스택의 길이를 줄여야 할 경우을 사용하여 한 번에 세 개의 값을 줄이거 pg대상의 세 개 내에 있으면 한 번에 하나씩 값을 줄 입니다. 프로그램은 i(입력) 을 호출하여 종료되며 , -1입력이 없으므로 a를 누른 다음 오류를 발생시키기 위해 인쇄합니다.

이 방법을 생각하면 솔루션을 만드는 데 사용한 Python 3 프로그램입니다.

s = "And she said, 'But that's his.'"
L = [0]+[ord(c) for c in s]
#print(L)
M = L[1:]+[0]
D = [x[1]-x[0] for x in zip(L,M)]
#print(D)
while D:
	n=D.pop(0)
	if not D:print('io',end='');exit()
	if n>0:print('f'*n,end='lo')
	else:
		while n<-2:print('p',end='');n+=3
		print('g'*-n,end='lo')

온라인으로 사용해보십시오


5
이것이 공백 솔루션에 대한 적절한 대응점입니다! 나에게 +1을 해주셔서 감사합니다.
Francesco

마지막 섹션은 신중하게 사용하여 완전히 제거 할 수 있습니다 p받는 공간에서 위로 이동하면서 스택에 59을 만듭니다 s에서 것은 said, 그때부터 내리막 길에 코드에 배치 d하는 ,. (이 시점에서 (15,15)는 15입니다.)
Nitrodon

사실, 당신은 남용 수 lp(10,10)에 몇 가지 유용한 문자를 넣어 - 그들을 다음, (15,15) 직사각형 검색하는 g곳은 더 편리.
Nitrodon

정말 좋은 생각입니다. 이런 식으로> <>를 생각하기가 너무 어렵습니다. BF로 코딩하는 것과 같습니다.
mbomb007

나는 내 자신의 답변을 게시했다 : codegolf.stackexchange.com/a/186916/69059
Nitrodon

28

IBM PC에서 8086 어셈블리, 1463 845 664 바이트

설명 : 실제 어셈블리 언어 소스는 생성 된 기계 코드가 아닌 항목입니다.

어려움은 대부분의 x86 명령어 (예 : ADD, SUB, JMP, 조건부 점프, 메모리 액세스)가 두 개의 인수를 가지므로 쉼표가 필요하거나 메모리 주소가 필요하다는 것입니다. 따라서 더하기, 빼기, if 또는 루프를 사용할 수 없습니다!

처음 시도하는 동안 증분, 감소, 곱셈, 나누기, 바이트-트릭 및 애매한 BCD 명령어 (예 : AAA, DAS)의 조합을 사용하여 숫자를 "구성"할 수있었습니다. 그 후,이 아이디어는 자체 검사 및 자체 수정 코드를 작성하는 데 사용될 수 있음을 깨달았습니다.

  • 시도 1입니다. (1463 바이트)

    사용 가능한 명령어를 사용하여 ASCII 코드와 스크린 버퍼의 0xb800 주소를 구성했습니다. 시퀀스에서 각 캐릭터의 계산은 수작업으로 진행되었습니다.

  • 시도 2 (완료되지 않음)

    0x40-0x5f 범위의 모든 정수에 대한 opcode가 있음을 인식했습니다. 이 범위에는 AZ가 포함됩니다. 예를 들어 INC CX는 0x41 = 'A'에 해당합니다. 이 opcode 테이블 은 매우 편리합니다.

    3 개의 "데이터"문자열을 구성하고 서로의 위에 레이어를 만들려고했습니다. 첫 번째는 그대로 (대문자), 두 번째는 0x60-0x7f 영역으로 옮겼고 (소문자) 마지막은 0x20-0x3f 영역으로 옮겼습니다 (구두).

    자체 수정 코드는 데이터를 반복하기 위해 루프 또는 3을 생성합니다.

  • 시도 3. (845 바이트)

    이전 접근 방식과 마찬가지로 데이터를 줄이려면 문자열을 한 번만 인코딩하면 "제어 문자"가 혼합되어 문자 세트가 전환됩니다.

  • 시도 4. (664 바이트)

    분기를 처리하기 위해 많은 패치 명령이 필요한 제어 문자를 제거하는 방법은 무엇입니까? 두 개의 대문자 만 사용한다고 가정하면 0x40-0x4f 범위를 사용하여 소문자를 인코딩하고 0x90-0x9f 범위를 사용하여 문장 부호를 0xc0에서 빼서 opcode 테이블을 "플립"할 수 있는지 궁금했습니다. "A"와 "B"는 별도로 넣을 수 있습니다.

    그러나 0x90-0x9f 범위에서 opcode의 절반 만 사용할 수 있으며 필요한 opcode와 일치하지 않습니다. 그런 다음 XOR을 사용하여 셔플 할 수 있다고 생각했는데 효과가있는 것을 발견했습니다. 그리고 여기 있습니다.

골프 :

REP LODSB
PUSH CX
PUSH CX
POP AX
INC CH
PUSH CX
POP DI
DEC AX
DEC AX
REPNE SCASB
REPNE SCASB
PUSH DI
REPNE SCASB
PUSH DI
REPNE SCASB
PUSH DI
POP SI
POP DI
DEC DI
LODSB
NOT AL
STOSB
POP CX
DEC CH
LODSB
NOT AL
STOSB
LODSB
AAA
STOSB
INC DI
LODSB
NEG AL
STOSB
LODSB
NOT AL
PUSH AX
PUSH AX
INC SP
POP ES
INC SP
POP DI
LODSB
NOT AL
PUSH AX
POP BX
NEG AL
STOSB
INC DI
LODSB
DEC AL
NEG AL
DIV BH
PUSH AX
POP DI
LODSB
STOSB
RET
DEC BL
PUSH CS
STOSB
PUSH DS
INC DI
INC AX
POP SI
PUSH SP
NOP
INC BP
POP AX
PUSH DI
NOP
INC BP
PUSH BX
POP BX
PUSH SP
PUSHF
NOP
CWD
PUSH DX
INC DI
INC SP
NOP
INC SP
POP AX
PUSH BX
INC SP
CWD
INC BP
NOP
POP AX
POP BX
INC BP
SAHF
CWD
SCASB
INC DX

와 조립

nasm golf.asm -o golf.com

DOSBOX에서 실행하십시오 (먼저 CLS 실행). 다음과 같습니다 :

샘플 출력

댓글 :

; ASSUME DS = ES = CS
; ASSUME IP = 0x0100
; true for .COM file

; We treat 0xFE as a special marker that we scan for
; This marks our patch zone and the start of our data

; We also use it as a cheap trick to get a constant 0x1f
; into CX

; 0xFE is the first byte of INC or DEC instructions
; that operate on half-word registers (AL, BL, CH etc.)
; WATCH OUT! Adding these breaks the scan


; Can't assume any register contains zero
; so use this trick to zero out CX
REP LODSB

PUSH CX ; needed later

; zero AX
PUSH CX
POP AX

INC CH
PUSH CX
POP DI ; 0x100, where our code starts

DEC AX
DEC AX ; AL = 0xFE, our marker (AH = 0xFF)

REPNE SCASB ; skip the INC CH above
REPNE SCASB ; find the DEC CH located at 0x10E

; we will later need 0xF, the char count minus the 'A'
PUSH DI ; DI = 0x10F

REPNE SCASB ; find the patch position
PUSH DI

REPNE SCASB ; find the next 0xfe; our data section
PUSH DI
POP SI ; load data from here

POP DI ; store data to the patch position
DEC DI

; patch in XOR
; XOR is 0x34, start with 0xCB
; second byte of DEC BL is 0xCB
LODSB
NOT AL
STOSB

POP CX ; get 0x0f in CX for our strlen
DEC CH

; patch in our XOR arg
; it is 0xF1 (take 0x0E and NOT it)
LODSB ; 0x0E (PUSH CS)
NOT AL
STOSB

; ADD is 0x00 (take 0xAA, apply weird AAA behaviour)
; this also zeroes AH
LODSB ; 0xAA (STOSB)
AAA
STOSB

INC DI ; skip next instruction byte

; LOOP is 0xE2
LODSB ; 0x1E PUSH DS
NEG AL
STOSB


; get b800 in ES (address of screen buffer)
; first get 0x47 in AL (INC DI)
LODSB  ; get 0x47 (INC DI)
NOT AL ; NOT 0x47 = 0xb8
; AX = 0x00b8 (bytes backwards)

PUSH AX
PUSH AX
; stack contains 0xb8 0x00 0xb8 0x00
; stack off-by-1 trick
INC SP
; now POP gives you 0xb800
POP ES
INC SP ;and clean up after ourselves

; store 0 in DI ***** PUSHED AT START OF PROGRAM ***
POP DI


LODSB ; get our magic 0xC0 (0x40 INC AX)
NOT AL
PUSH AX
POP BX

NEG AL ; NOT and +1 to get 0x41 ("A")


; charloop:
STOSB
INC DI
LODSB
DEC AL ; XOR
NEG AL ; modify this into an ADD AL, BL
DIV BH ; modify this to LOOP back to charloop

; doesn't print the last character
; but the last character turns into the address where 'B'
; is supposed to go

PUSH AX
POP DI
LODSB ; "B"
STOSB

; graceful exit this time ;)
RET


; *** DATA SECTION ***

         ; PURPOSE

DEC BL   ; 0xFE marks data section, 0xCB for XOR
PUSH CS  ; for XOR arg
STOSB    ; for ADD
PUSH DS  ; for LOOP
INC DI   ; 0x47 -> for 0xb800

INC AX   ; for magic number but also "A"


POP     SI ;n
PUSH    SP ;d
NOP        ;
INC     BP ;s
POP     AX ;h 
PUSH    DI ;e
NOP        ;
INC     BP ;s
PUSH    BX ;a
POP     BX ;i
PUSH    SP ;d
PUSHF      ;,
NOP        ;
CWD        ;'
PUSH    DX ;B
INC     DI ;u
INC     SP ;t
NOP        ;
INC     SP ;t
POP     AX ;h
PUSH    BX ;a
INC     SP ;t
CWD        ;'
INC     BP ;s
NOP        ;
POP     AX ;h
POP     BX ;i
INC     BP ;s
SAHF       ;.
CWD        ;'

SCASB     ; treated as char but turns into screen address!
INC DX    ; "B"

흠. 오프셋 0x3e에서 시작하여 두 어셈블리 소스에서 다른 .COM 파일을 얻습니다. Edit-Nvm은 다음과 같은 차이점을 발견했습니다. 주석 처리 된 버전의 117 행 INC AX은 주석 처리되지 않은 상태입니다 INC AL.
gastropner

1
대신 완전히 알파벳 이진을보고 싶습니다. :-)
피터 페리

1
선택한 어셈블러로 NASM을 잠그는 것이 편한 경우 label1 db자체 라인에서 레이블을 작성할 수 있습니다 . 경고가 표시되지만 오류는 없습니다.
gastropner

1
@gastropner는 너무 쉽게 만들 것입니다. : P 그것에 대해 몰랐습니다, 감사합니다! 언어를 "DEBUG.COM에 제공 할 수있는 것"으로 바꾸어야 할 수도 있습니다. 우연히 나는 이것을 디버깅하는 데 사용했습니다. xD
Artelius

1
@PeterCordes는 이제 스스로 수정합니다!
Artelius

23

펄 6 , 1299 1272 1220 1215 바이트

-27 바이트의 Grimy에게 감사합니다.

우리는 처음에는 토끼 귀가 필요하지 않기 때문에 -52 바이트.

-5 바이트의 Jo King에게 감사합니다.

print chr flip chars i x chars i xx pi
and print lc chr chars NaN x chars cis pi
and print lc chr chars e x e x e
and print chr chars i x e x e x e
and print lc chr flip chars exp i
and print lc chr chars NaN x tau x e x e
and print chr chars chop NaN x e lcm chars e
and print chr chars i x e x e x e
and print lc chr flip chars exp i
and print lc chr flip chars i x chars i xx pi
and print chr chars False x pi x ceiling tau
and print lc chr chars e x e x e
and print chr chars i xx chars NaN x pi
and print chr chars i x e x e x e
and print chr chars chop False x e x e x e
and print chr chars chop NaN xx chars e
and print lc chr chars e x chars False
and print lc chr chars chop e x chars False
and print chr chars i x e x e x e
and print lc chr chars chop e x chars False
and print lc chr chars NaN x tau x e x e
and print lc chr flip chars i x chars i xx pi
and print lc chr chars chop e x chars False
and print chr chars chop False x e x e x e
and print lc chr flip chars exp i
and print chr chars i x e x e x e
and print lc chr chars NaN x tau x e x e
and print chr chars False x pi x ceiling tau
and print lc chr flip chars exp i
and print chr chars NaN xx tau x e
and say chr chars chop False x e x e x e

온라인으로 사용해보십시오!

후행 줄 바꿈으로 문자열을 출력합니다. 원하지 않으면 마지막 say을 a 로 바꾸십시오 print. 소스의 개행을 공백으로 바꿀 수도 있습니다.

설명

이 코드는 문자열을 문자별로 인쇄합니다. 각 문자는 적절한 문자 코드를 chr함수 에 공급하고 필요한 경우 코드를 낮추어 구성 lc합니다.

현재 모든 값은 올바른 수의 문자가 포함 된 문자열을 생성하여 생성됩니다. 경우에 따라 문자 수는 대상 문자 코드의 반대입니다. 이 같은 수학 함수를 사용하는 것이 이론적으로 가능해야 log하고 exp직접,하지만 난 아주 쉽게 사람들을 사용 찾지 못했습니다.

숫자로 사용하기 위해, 우리는이 e, pi그리고 tau; x또는 의 오른쪽 xx에는 암시 적으로 바닥이 있습니다. 문자열 표현에는 모두 17자가 있으므로 e최소 문자 수를 사용 합니다. 우리는 또한이 i(4 자), False(5 자) 및 NaN(3 자). 우리는 문자열 길이를 x; xx문자열 길이에 1을 더하고 오른쪽에 곱하고 1을 더합니다. chop대상에서 멀어 질 경우 문자열에서 한 문자를 제거합니다.

인쇄 문은 and우선 순위가 매우 낮은을 사용하여 함께 연결됩니다 . 그것은 거의 존재하는 기적입니다. 그렇지 않으면 불법 세미콜론을 사용해야합니다.

손으로 캐릭터의 표현을 찾았습니다. 더 짧은 표현을 찾기 위해 프로그래밍 방식으로 검색하는 것이 좋습니다.



그건 그렇고, @JoKing, 당신은 손으로 더 짧은 표현을 검색 했습니까? 아니면 도움이되는 프로그램을 사용 했습니까?
bb94

1
손으로 나는 두렵다. 알고리즘 방식은 그리 어렵지 않을 것입니다
Jo King


@Grimy Clever, 그러나 불행하게도 사용하는 Zero Width Space가 공백 문자가 아니기 때문에 가능합니다.
Jo King

17

너비 , 66 64 바이트

QaaGmwmiimaGcwWiimawAGawmfciiiGaFmAmFiimFGcwAmFiGmaiiGcGamafFiGQ

온라인으로 사용해보십시오!

디버그하기 위해 인쇄합니다. stdout으로 인쇄하려면 ww코드의 끝에 추가하십시오. 그러면 코드의 상단이 튀어 나와 출력됩니다.

설명

이 표 에 따르면 너비에서 각 문자는 "폭"정도에 따라 숫자와 관련 있습니다. 이렇게하면 각 문자에 0에서 9까지의 숫자가 할당됩니다. 그런 다음 해당 숫자는 실제로 코드를 실행하는 데 사용됩니다.

특히 일치하는 문자보다 7문자열 리터럴이 시작됩니다. 원래 문자를 다시 읽을 때까지 한 번에 두 문자 세트를 읽습니다. 두 글자의 각 세트는 너비 숫자로 변환되어 0에서 99 사이의 10 진수로 읽히고 같은 문자는 다음 문자열에서 색인이됩니다.

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\n\t

예를 들어의 인덱스 !는 1이므로 01올바른 너비 숫자가됩니다. 따라서, if, iI, jt, 등 모든 문자열 리터럴에 상관 관계가됩니다 !.

이 경우 필요한 출력의 31자를 Q따옴표로 사용하여 적절한 문자 로 변환했습니다. 스택의 상단은 프로그램이 완료되면 디버그하기 위해 인쇄됩니다.


이것은 가장 짧은 것입니다. 당신이 이길 수 있다고 생각합니다!
Blue-Maned Hawk

14

x86 머신 코드 (32 비트), 256 바이트

코드 페이지 437 콘솔에서 코드를 인쇄하면 다음이 표시됩니다.

j XI a I a I a jbZ      Q fiQ Gf a f    Q I a I a I a I a h hisZ        Q I a I a I a I a hBP  Z        Q iQ
y       Q  a I a I a I a h thaZ Q I a I a I a Ih ButZ   Q  a I a I a I a fhu fZf        Q iQ g  S       Q  a I a I a I a hsaidZ Q I a I a I a I a hshe Z        Q I a I a I a I a hAnd Z        Q TZBX b 

여기에는 공백 문자가 포함되어 있으므로 모든 탭 문자 와 공백이 아닌 공백 문자 (코드 255 포함)를 *다음 과 같이 바꾸면 동일한 코드 가 있습니다 .

j XI a I a I a jbZ→Q fiQ Gf a f→Q I a I a I a I a h hisZ→Q I a I a I a I a hBP  Z→Q iQ →→y →Q  a I a I a I a h thaZ→Q I a I a I a Ih ButZ→Q  a I a I a I a fhu fZf→Q iQ g→S →Q  a I a I a I a hsaidZ→Q I a I a I a I a hshe Z→Q I a I a I a I a hAnd Z→Q TZBX*b*

16 진 덤프 :

6a 20 58 49 20 61 20 49 20 61 20 49 20 61 20 6a
62 5a 09 51 20 66 69 51 20 47 66 20 61 20 66 09
51 20 49 20 61 20 49 20 61 20 49 20 61 20 49 20
61 20 68 20 68 69 73 5a 09 51 20 49 20 61 20 49
20 61 20 49 20 61 20 49 20 61 20 68 42 50 20 20
5a 09 51 20 69 51 20 09 09 79 20 09 51 20 20 61
20 49 20 61 20 49 20 61 20 49 20 61 20 68 20 74
68 61 5a 09 51 20 49 20 61 20 49 20 61 20 49 20
61 20 49 68 20 42 75 74 5a 09 51 20 20 61 20 49
20 61 20 49 20 61 20 49 20 61 20 66 68 75 20 66
5a 66 09 51 20 69 51 20 67 09 53 20 09 51 20 20
61 20 49 20 61 20 49 20 61 20 49 20 61 20 68 73
61 69 64 5a 09 51 20 49 20 61 20 49 20 61 20 49
20 61 20 49 20 61 20 68 73 68 65 20 5a 09 51 20
49 20 61 20 49 20 61 20 49 20 61 20 49 20 61 20
68 41 6e 64 20 5a 09 51 20 54 5a 42 58 ff 62 ff

작동 방식에 대한 설명 :

유용한 지침은 다음과 같습니다.

  • push imm8, push imm16push imm32, pop상수 를 생성합니다. ah바이트 ( imm8)를 누를 때 0을 생성 할 수도 있습니다 .
  • and [ecx+32], ah-ah = 0이라고 가정하면 바이트를 0으로 설정합니다. 출력 문자열의 길이가 32이므로 코드는 버퍼를 끝에서 끝까지 채 웁니다.
  • or [ecx+32], edx-출력 바이트가 0으로 설정되어 있다고 가정하면 edx(4 바이트) 출력됩니다. 출력 버퍼 너머로 쓰면 안되기 때문에 버퍼의 끝 부분 dx대신에 변형을 사용합니다 edx. 코드 제한으로 인해 이런 방식으로 단일 바이트를 작성할 수 없습니다!
  • imul edx, [ecx+32], whatever이것은 주요 스크램블링 아이디어입니다. 충분한 엔트로피로 [ecx+32]하고 어떤 번호가 출력을 생성 할 수 있습니다. 필요한 값을 2 또는 3 바이트 생성하는 데 사용합니다. 일부 복잡한 점은 출력에 쓸 때 OR이미 존재하는 모든 것을 논리적 으로 수행해야한다는 것입니다. 이로 인해 때때로 메모리를 다시 한 번 제로화해야했습니다.
  • jmp명령어 의 변형이 반환에 사용됩니다. 0xff코드 페이지 437의 비 공백 공간에 해당하는 인코딩이 있기 때문에 선택했습니다 . 규칙에 약간의 스트레치가 있지만 그렇지 않으면 작업이 불가능하다고 생각합니다.

어셈블리 소스 코드와이를 실행하는 C 프로그램 (Visual Studio 구문 사용) :

#include <stdio.h>

__declspec(naked) void __fastcall doit(char* buf)
{
    __asm {
        push ' '
        pop eax

        dec ecx
        and [ecx+32], ah    // terminating 0 byte

        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah

        push 98
        pop edx
        or [ecx+32], edx
        imul dx, [ecx+32], 26183
        and [ecx+32], ah
        or [ecx+32], dx    // two bytes: [.']

        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        push 'sih '
        pop edx
        or [ecx+32], edx    // 4 bytes: [ his]

        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        push 538988610
        pop edx
        or [ecx+32], edx
        imul edx, [ecx+32], 544803081
        or [ecx+32], edx // 1 junk byte and 3 good bytes: (t's)

        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        push 'aht '
        pop edx
        or [ecx+32], edx    // 4 bytes: [ tha]

        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        dec ecx
        push 'tuB '
        pop edx
        or [ecx+32], edx    // 1 junk byte and 3 good bytes: [But]

        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        push word ptr 8309
        pop dx
        or [ecx+32], dx
        imul edx, [ecx+32], 542312807
        or [ecx+32], edx    // 1 junk byte and 3 good bytes: [, ']

        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        push 'dias'
        pop edx
        or [ecx+32], edx    // 4 bytes: [said]

        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        push ' ehs'
        pop edx
        or [ecx+32], edx    // 4 bytes: [she ]

        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        dec ecx
        and [ecx+32], ah
        push ' dnA'
        pop edx
        or [ecx+32], edx    // 4 bytes: [And ]

        push esp
        pop edx
        inc edx

        pop eax
        jmp dword ptr[edx-1]
    }
}

int main()
{
    char buf[100];
    doit(buf);
    puts(buf);
}

이것은 나에게 완전히 골프처럼 보이지 않습니다. 분명히 일련의 동일한 명령어를 반복하는 대신 루프를 사용하여 여러 바이트를 절약 할 수 있습니다. 그 dec ecx+ and [ecx+32], ah것들을 모두 제거 할 수 있습니다.
코디 그레이

당신은 시도를 환영합니다. 이것이 내가 할 수있는 최선이다; 다른 접근법을 보게되어 기쁩니다. 루프에 네거티브 점프 오프셋이 필요하다는 것을 알았을 때 루프 아이디어를 포기하기로 결정했습니다. 어쩌면이 제한은 창조적 인 방법으로 해결 될 수 있습니다. 어떻게 모르겠습니다.
아나 톨릭

1
@anatolyg 자체 수정 코드에 대한 테스트 환경의 입장에 따라 달라질 수 있습니다. 또는 스택에서 작성한 코드 실행에 대한 의견.
gastropner

0xff문자가 "문장 또는 알파벳 이외의 문자 없음"을 위반 하지 않습니까?
val


13

포스트 스크립트, 889 874 837 835 바이트

currentflat string dup rrand
count dup count count mul mul xor count count mul count dup mul exch count
count copy count copy count copy count copy count copy
add and sub put print
and sub add put print
sub sub add put print
mul or xor put print
idiv xor add put print
or xor add put print
mod idiv add put print
mul or xor put print
idiv xor add put print
sub and add put print
or and add put print
sub sub add put print
pop add sub put print
mul or xor dup copy put print
mod mul sub put print
add or xor put print
idiv add add put print
add or add put print
put print
add or add put print
or xor add put print
sub and add put print
add or add put print
mod mul sub put print
idiv xor add put print
mul or xor put print
or xor add put print
or and add put print
idiv xor add put print
xor add sub put print
mod mul sub put print
quit

온라인으로 사용해보십시오!

이것은 32 개의 정수 사본을 사용합니다 89 25 20 6. 대상 문자열의 모든 문자 코드는 해당 정수에 대한 연산으로 스택 순서로 얻을 수 있습니다. 예를 들어 'A'(ASCII 65)는 89-(25 & (20 + 6))입니다. 많은 4 튜플 정수가이 속성을 가지고 있습니다. 이것은 특히 생성하기 쉽기 때문에 선택되었습니다.

currentflat string dup rrand

Flat의 기본값은 1이므로 길이가 1 인 문자열이 생성됩니다 (초기화 됨 \0). dup깊은 사본이 아닙니다. 동일한 문자열에 대한 두 번째 참조를 작성합니다. rrand는 랜덤 시드를 푸시합니다. 기본값은 0입니다. Stack is now ["\0", "\0", 0].

count dup count count mul mul xor

count 스택의 항목 수를 푸시하므로 3 ^ (3 * (5 * 6)) = 89를 계산합니다.

count count mul count dup mul exch count

4 * 5 = 20, 5 * 5 = 25, 6 = 6 스택은 이제 ["\0", "\0", 0, 89, 25, 20, 6]입니다.

count copy count copy count copy count copy count copy

전체 스택을 5 번 복제하십시오. 따라서 우리는 초기 7 요소 스택의 32 복사본으로 끝납니다. 대상 문자열의 길이가 31 자이므로 추가 사본이 아프지 않기 때문에 31 개의 사본 만 있으면됩니다.

add and sub put print

상위 4 개의 정수에서 문자 코드를 계산하여 문자열의 인덱스 0에 쓴 다음 문자열을 인쇄하십시오.

quit

기본 프롬프트를 표시하지 않습니다.


11

루비 , 420 (354) 338 바이트

def P a
print String a
end
def Q a
p String a
end
class String
def inspect
putc sum size
q
end
end
def w
Q def hacked
end
rescue
end
P def And
end
w
P def she
end
w
P def said
end
Q def gadget
end rescue
w
def a
Q def afraid
end
rescue
end
a
P def But
end
w
P def that
end
a
putc String def s
end
w
P def his
end
Q def fierce
end rescue
a

온라인으로 사용해보십시오!

jankiness의 오름차순으로 :

대문자로 시작하는 단어는 해당 이름 display의 클래스를 정의하고 클래스 정의 본문 내에서 호출하여 인쇄 할 수 있습니다 .

다른 이름은 해당 이름으로 메소드를 정의하여 표시 할 수 있습니다.이 메소드는 Symbol을 리턴 한 다음이를 문자열로 캐스팅하여 선행 콜론을 제거합니다.

putcASCII 코드를 호출 하여 다른 문자를 표시 할 수 있습니다 . 우리는 String def트릭을 재사용하여 문자열을 얻은 다음 크기에 의해 결정된 계수를 사용하여 바이트의 합을 취 함으로써 적절한 숫자를 생성 할 수 있습니다 . 불행히도, 우리는 그 객체의 클래스 정의가 아닌 다른 객체에서 메소드를 호출하는 방법이 없으므로 인수를 전달하기가 어렵습니다. 따라서 마지막 해킹은 redefine으로 String#inspect, p메소드에 String을 전달할 때 암시 적으로 호출 되므로 오류를 발생시키기 전에 적절한 문자를 계산하여 출력하여 p실제로 실행을 완료하고 인쇄 할 수 없습니다 개행. 그런 다음 메인 코드에서 오류를 구조해야합니다.

편집 : Jordan 은 영리한 제어 흐름 골프로 바이트 수를 크게 줄 raise였습니다 .NameError가 발생하는 1 문자의 존재하지 않는 메소드 호출 로 대체하여 몇 바이트를 더 줄 였습니다.

편집 2 : print String메서드에 추출하면 메서드에 제목을 지정할 수 있으므로 클래스 정의 트릭을 사용하는 것보다 메서드 정의와 함께 사용하는 것이 더 저렴합니다.


아름다운 .... 나는 sum size합계 모듈로의 크기를 얻는 방법을 이해하지 못하지만 다른 모든 것들이 체크 아웃됩니다!
가치 잉크

나는 조금 게으르다. 실제로 문자열의 크기를 sum 메소드 의 선택적 인수전달 하고있다.
histocrat

11

> <> , 233122 바이트

cdacaabbglccgpcbfbbcaacdebbafbebbcebdbealbcpcdbcccdlcdpacbbalccpaalacpbcfafbaab









       g  sandBe
       o  Aviuth

온라인으로 사용해보십시오!

이것은 mbomb의 답변 으로 시작되었지만 엄청난 양의 바이트를 절약하는 근본적인 변화를 발견하여 내 답변으로 게시하고 있습니다.

알파벳이 아닌 문자를 출력으로 생성하는 것은 값을 반복해서 스택 l으로 푸시 한 다음을 사용 하여 스택 길이를 푸시 하여 수행 됩니다. 그러나 이것을 즉시 출력 할 필요는 없습니다.를 사용 p하면이 문자를 좌표가 10에서 15 사이의 셀에 배치하여 나중에 검색 할 수 있습니다 g. 마찬가지로 알파벳 문자를 초기 소스 코드에 배치하고 다음과 같이 읽을 수 있습니다. 입력에서 알파벳이 아닌 문자 코드가 46 ( .)이기 때문에 스택을 저장하는 데 필요한 62보다 스택을 더 많이 푸시 할 필요가 없습니다. 출력의 모든 31 자

또한, v7 열의 코드에 a 가 배치됩니다. 명령 포인터가 줄 바꿈되어 해당 위치 v를 누르면 시퀀스 go가 반복적으로 실행되어 푸시 된 좌표를 읽고 해당 문자를 출력합니다. 결국 스택은 비워지고 g오류와 함께 프로그램을 종료합니다.

코드의 처음 7 바이트는 처음 7 좌표와 마지막 7 좌표가 모두 푸시 될 때 재사용됩니다. v9 열에 배치하면 이론적으로 2 바이트가 더 절약되었지만 Ainsv코드에서 문자 를 2x2 정사각형으로 강제 설정할 수는 없었습니다. 이전 버전에서는 열 15를 사용했지만 소스 코드에 추가 행이 필요하고 6 바이트가 더 길었습니다.


추가로 생각한 후, r원하는 위치로 정렬을 이동하기 위해 바이트를 소비하여 9 열을 작동시킬 수 있다고 생각 합니다. 그러나이 프로그램을 골프로 쓰면 뇌가 약간 아프다.
Nitrodon

8

CJam 262 바이트

  KAbScibCmhc  CZbsic          GmQYbsic
S CmfYmeibc    ImqmeKmhcel     AZbAbc
S CmfYmeibc    KAbScibCmhcel   ImqmeKmhAmhcel  GmQYbsic    KAZbYbbBbc
S CGmQbDbc     EYbTYtZbc       FYbGmQbcel      EYbGmQbcel
S EYbGmQbcel   ImqmeKmhcel     KAbScibCmhcel   EYbGmQbcel  CGmQbDbc    CmfYmeibc
S ImqmeKmhcel  ImqmeKmhAmhcel  CmfYmeibc       PYmhmeKmhc  CGmQbDbc

온라인으로 사용해보십시오! 개행은 명확성을 위해 여기에 표시됩니다. 각 줄은 문자를 나타냅니다.

휴, 이것은 재미 있었다. 자신을 알파벳 명령으로 제한하면 몇 가지 흥미로운 과제가 있습니다.

  • {}이 없으면 실제로 제어 흐름에 f대한 기회가 없습니다 (제외 에 사용할 기회를 찾지 못했습니다).
  • 없이 \, _, ;, 또는 $, 우리는 스택 조작하는 수단이 없습니다.

즉, 주요 목표는 스택에서 관련 코드 포인트를 가져 와서를 사용하여 문자로 변환하는 것입니다 c.

문제는 정수 리터럴뿐만 아니라 대부분의 기본 산술 명령도 없다는 것입니다. m네임 스페이스에 수많은 고급 수학 연산이 포함되어 있고 유용한 숫자로 사전 정의 된 많은 변수가 있기 때문에 이것은 좋습니다.

나는 곱셈을 에뮬레이션하는 데 사용될 수있는 제곱근 ( mQmq), 지수 함수 me및 기본 변환 ( b)을 많이 사용했습니다 ( [X 0] YbX * Y 계산). 또한 대문자 코드 포인트를 구성하는 것이 더 쉬운 경우가 있습니다.이 경우 el결과 문자에 소문자로 변환 할 수 있습니다 .

나는 아직도 더 긴 것들 중 일부에 만족하지 않습니다. 오 잘

설명

출력에 대한 문자 별 설명입니다. 시작하기 전에 숫자를 만드는 몇 가지 간단한 방법이 있습니다.

  • 0, 1, 2, 3에 포함 된 변수 T, X, Y, Z각각.
  • 10에서 20까지의 숫자는를 통해 변수에 포함 A됩니다 K.
  • 32를 사용하여 만들 수 있습니다 Sci( S공백이 포함 된 문자열을 푸시 c하고이 문자열의 첫 번째 문자를 가져 와서 i해당 문자를 해당 코드 포인트로 변환). S공백에도 사용됩니다.
  • 4는 GmQ(16의 정수 제곱근 )으로 주어진다 .
  • 5는 AZbYb(10을 밑수 3으로 [1 0 1]변환 하고을 산출 하고 결과 배열을 밑수 2로 변환하여 5를 산출 함)에 의해 주어진다 .
  • 7은 Ymei(exp (exp)를 계산하고 정수로 변환)에 의해 주어진다 .

A

K           - push 20                        | 20
 Ab         - convert to base 10             | [2 0]
   Scib     - convert from base 32           | 64
       Cmh  - hypot(TOS, 12)                 | 65.115
          c - round down and convert to char | 'A

n

C      - push 12            | 12
 Zb    - convert to base 3  | [1 1 0]
   s   - convert to string  | "110"
    i  - convert to integer | 110
     c - convert to char    | 'n

d

GmQ      - push 4             | 4
   Yb    - convert to base 2  | [1 0 0]
     s   - convert to string  | "100"
      i  - convert to integer | 100
       c - convert to char    | 'd

s

C         - push 12         | 12
 mf       - factors         | [2 2 3]
   Ymeib  - base 7          | 115
        c - convert to char | 's

h

I           - push 18                        | 18
 mq         - sqrt                           | 4.242
   me       - exp                            | 69.591
     Kmh    - hypot(TOS, 20)                 | 72.408
        c   - round down and convert to char | 'H
         el - lowercase                      | 'h

e

A      - push 10              | 10
 Zb    - convert to base 3    | [1 0 1]
   Ab  - convert from base 10 | 101
     c - convert to char      | 'c

a

KAbScibCmhc   - push 'A (see above) | 'A
           el - lowercase           | 'a

i

I              - push 18         | 18
 mq            - square root     | 4.242
   me          - exp             | 69.591
     Kmh       - hypot(TOS, 20)  | 72.408
        Amh    - hypot(TOS, 10)  | 73.095
           c   - convert to char | 'I
            el - lowercase       | 'i

,

K          - push 20              | 20
 AZbYbb    - convert to base 5    | [4 0]
       Bb  - convert from base 11 | 44
         c - convert to char      | ',

'

C        - push 12              | 12
 GmQb    - convert to base 4    | [3 0]
     Db  - convert from base 13 | 39
       c - convert to char      | ''

B

E         - push 14               | 14
 Yb       - convert to base 2     | [1 1 1 0]
   TYt    - replace elem 0 with 2 | [2 1 1 0]
      Zb  - convert from base 3   | 66
        c - convert to char       | 'B

u

F          - push 15             | 15
 Yb        - convert to base 2   | [1 1 1 1]
   GmQb    - convert from base 4 | 85
       c   - convert to char     | 'U
        el - lowercase           | 'u

t

E          - push 14             | 14
 Yb        - convert to base 2   | [1 1 1 0]
   GmQb    - convert from base 4 | 85
       c   - convert to char     | 'T
        el - lowercase           | 't

.

P          - push pi                        | 3.141
 Ymh       - hypot(TOS, 2)                  | 3.724
    me     - exp                            | 41.437
      Kmh  - hypot(TOS, 20)                 | 46.011
         c - round down and convert to char | '.

1
HYbYCtYbc, HYbXAtYbc및 과 같이 기본에 대한 일반적인 범위를 벗어난 숫자로 기본 변환을 수행 할 수 있습니다 HYbXBtYbc.
Nitrodon

7

Deadfish ~ , 943 바이트

iiisdsiciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicddddddddddcddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcdddddddddddddddddddddsddddddcdddddddddddcdddcdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcdddddddddddddddddddddsddddddcddddddddddddddddddciiiiiiiicdddddcddddddddddddddddddddddddddddddddddddddddddddddddddddddddcddddddddddddciiiiiiiciiiiiiiiiiiiiiiiiiiiiiiiiiiciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicdcddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcdddddddddddddddddddddsdddddcddddddddddddcdddddddciiiiiiiiiiiiiiiiiiicdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcddddddddddddddddddddddddddddsddddddcdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcddddddddddddddddddddddsiiiiciciiiiiiiiiicdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcdddddddc

온라인으로 사용해보십시오!

루프가 허용되지 않습니다 :(




6

MATL , 187 158 바이트

IEWQKEtqhpEqqKQHhthpKWEyQKWEqqYqQQXJwtQQQwKWEJKQthpYqKQHhthptQQQQQwIIhKQhpqKWEIWKQhpqIEWQQJQQtqKWEyIIhIhpYqQXJyKQthpYqwIWKQhpqyqKWEyJtQwhhPIIhKQhpQIWKQhpqvlec

온라인으로 사용해보십시오!

더 읽기 쉬운 버전 : 온라인으로 사용해보십시오! 줄을 만들려는 수동 시도. 사용 편리 chuncks로 문자열을 절단하여 골프의 여지 거기에 아마 Ph플립과 캐릭터를 구축하기는. 누군가가 나를 능가하는 도전에 도전하기를 바랍니다. 주요 과제는 사용할 수 없다는 것입니다 +또는 -기본 산술 종종 불가능하므로,.

하이라이트:

  • KQthpYq: 25 번째 KQthp소수 Yq는 97이며 글자에 해당합니다 a. 문자 s(115)는 30 번째 소수 인 113에서 유사하게 생성됩니다. 그런 다음 클립 보드에서 광범위하게 재사용됩니다 J.
  • hishfrom을 클립 보드 에 저장하면 단축됩니다 J. 이전에 저장된 것이기 때문에 s, 우리 his는 역순으로 빌드 하여 최근 s사용을 검색하고 사용 y후 뒤집을 수 P있습니다.
  • Luis Mendo 덕분에 많은 바이트가 절약되었습니다 (대부분을로 변경 h하여 vle)

허-정말 사용하는 v것이 h이전의 것과 엉망이 될 것이라고 생각했습니다 . 그냥 가정하는 대신 내가해야한다고 생각합니다. 또한 헤즈 업 덕분에 지나치게 열성적인 삭제가 발생했습니다. 당신이 이것보다 더 잘할 수 있는지 궁금합니다.
Sanchises

시도하고 싶지만 기다려야합니다. 이 답변에 많은 시간이 걸리는 것 같습니다!
Luis Mendo

1
@LuisMendo Yup. 이것을 만들기 위해 한 시간 정도 걸렸습니다. 이것은 매우 지역 최적화 만 포함합니다. 전 세계를 조금 더 잘 살펴보면 더 잘할 수있을 것입니다.
Sanchises

나의 시도 . 나는 당신을 보지 않았으므로 접근 방식은 희망이 다릅니다.
Luis Mendo

@LuisMendo 나는 완전히 잊었다 U수단 ^2, 즉 꽤 몇 바이트 나 저장 한 수 ...
Sanchises

6

MATL , 118 바이트

KEUQtVQsQKBFZAXHKUqyyhsXJyyhdQtQQQwOJIUEyhdtKEhsHKQYqEEKQyywhdXJKEUQQHKUhstQwOytHKhsKYqyhdbJyqOHKhstQHKUqhsKUqYqqJvlec

온라인으로 사용해보십시오!

더 읽기 쉬운 버전 (각 줄은 스택 재 배열 작업을 제외하고 한 문자에 해당).

설명

프로그램은 필요한 문자의 코드 포인트를 독립 숫자로 생성합니다. 결국 모든 숫자는 열 벡터로 연결되고 행 벡터로 모양이 변경되고 문자로 변환됩니다. 결과는 암시 적으로 표시됩니다.

사용 된 몇 가지 트릭 :

  • 32 미만의 대부분의 코드 포인트는 공백으로 표시됩니다. 그래서 0그것은 단지 바이트 비용 때문에, 대부분의 공간에 사용된다 ( O).
  • 제 공간 그러나 15(같이 생성 사용 KUq이 다음에 추가하여 재사용 할 수 있기 때문에) 100(문자 d)로 정제하여 115( s). 다른 계기 5(생성 공간으로 사용된다 KQ) 때문에 나중에로부터 감산 될 수있다 44( ,줄) 39( ').
  • 클립 보드는 J첫째 : 반복됩니다 문자를 저장하는 데 사용되는 s, 다음을 '. 마찬가지로 클립 보드 H저장 100d다른 문자를 생성하고 생성하는 데 유용 합니다.
  • 클립 보드 ( ) 및 ( ) 의 사전 정의 된 리터럴과 함께 함수 Q(add 1), q(subtract 1), E( 2) 및 U(square)을 곱하여 사용합니다 .I3K4
  • 임의의 덧셈과 뺄셈은 벡터 ( h) 에 연결하고 그 합 ( s) 또는 연속적인 차이 ( d)를 계산하여 수행됩니다 .
  • 100( d)는 410 진수로 해석되는 이진수 로 생성됩니다 .
  • 110( n)은 문자열 ( : 코드 포인트 )으로 변환 하고 코드 포인트 ( )에 더한 다음에 합산하여 더함으로써 65( A) 에서 얻 습니다 .'65'[54 53]1[55 54]1
  • 숫자가 생성되는 순서는 때때로 편의상 변경됩니다. 그런 다음 스택 재정렬 기능으로 교체됩니다 (스왑 ( w), 버블 업 b).

1
아주 좋아요! 공백 O대신 영리한 터치를 사용 KWE하십시오. 그리고 다른 클립 보드를 희생하는 것이 더 낫다는 내 의심을 확인했습니다 H.
Sanchises

5

DC , 240 (222) 209 바이트

OOOOOziOOOOOOOOOOOOOOOOOOOOOOOOOOOzddddddzkdddzasBdzasAdzscdzdasCzsdOOlAxlAxPOBlBxdIlAxoPAdlBxddsrIlAxssPPOPlsIZlCxddspPOZlCxPPOPlrdZlCxPlsPlrPlcPPKPdZlBxdZlAxPOAZlAxdPIZlCxdPrPdPlpPlrdZlCxPPKPOPPlpPlsPOPldPKP

온라인으로 사용해보십시오!

내 첫 생각은 @seshoumara와 같았습니다. 모든 문자의 ASCII 값을 생성하기에 충분한 물건을 스택에 밀어 넣으십시오. 그런 다음 그 이후 나에게 발생 +, -*단일 문자 운영자입니다, 난 그냥 다시 작성하고 연산을 사용할 수있는 능력을 가질 수 있습니다! 분명히 그것은 더 작을 것입니다! 그리고 더 이상 바이트를 사용할 수 없다면 놀라지 않을 것입니다. 그러나 지금은 ...이 복잡한 접근법은 순진한 것을 묶어 놓았습니다.

OOOOOziOOOOOOOOOOOOOOOOOOOOOOOOOOOzddddddzkdddzasBdzasAdzscdzdasCzsd@seshoumara와 비슷한 접근 방식의 일부이지만 46까지 올라갑니다 .. 우리는 45까지 올라갈 필요가 있기 때문에이 작업을 수행 -해야하며 문자열에 마침표가 필요하므로 기간 동안 한 단계 더 나아가는 것이 가장 저렴합니다. 그 과정에서 일부 값을 저장합니다. 5, 32, 39는 모두 나중에 편리합니다. 실용적 인 경우 5, ASCII 값의 경우 32 및 39. 원래 나는 1-5를했지만 비용이 많이 들었고, 단순히 4를 사용하는 것을 피할 수있었습니다. Z해당 값에 대해 3 자리, 2 자리 또는 1 자리 숫자를 사용 (값 팝, 자릿수 누름)하십시오. 42, 43, 45, 우리는 문자열 (이 변환 *, +-각각) 및 (매크로로 저장 B, AC각기). 즉, 문자를 사용하지 않으면 *+-해당 연산자를 사용할 수 있습니다.

여기에서 우리는 기본적으로 깎아 지른 축적 대신 수학의 힘을 사용하여 ASCII 값을 생성하기 시작하고 그 과정에서 일부 반복을 저장합니다. 100, 105 및 115는 그것들을 (레지스터 또는 다른 방식으로) 저장하기에 충분히 올랐습니다. 원래, 나는 10으로 채워진 스택을 남겨두고 이것을 사용하여 100을 만들었습니다. 스택을 32로 채우고 나중에 공백으로 사용하기 위해 바이트를 절약했습니다. ASCII 섹션의 약간 더 읽기 쉬운 버전 : OOlAxlAxP OBlBxdIlAxoP AdlBxddsrIlAxssP P OP lsIZlCxddspP OZlCxP P OP lrdZlCxP lsP lrP lcP P KP dZlBxdZlAxP OAZlAxdP IZlCxdP rPdP lpP lrdZlCxP P KP OP P lpP lsP OP ldP KP.

레지스터 대신에 숫자 5를 입력 기수로 저장하는 단계; 레지스터 대신 정밀도로서 숫자 32; 레지스터 대신 출력 기수 인 숫자 115; 다음 변경했습니다 KZIZ1 초를 생성하는과 OZKZ2 초를 생성합니다.

스택에 32를 플러딩하여 13 바이트를 더 줄였습니다. 정밀도를 39로 설정; 저장을 피하기 위해 스택 조작을 사용하는 것 (116); 실수로 남은 두 번의 작업을 차단했습니다.


+1 a연산자를 다시 작성하고로 호출하는 데 사용 하는 것이 좋습니다 x. 이것은 dc의 데이터 코드 동작을 보여줍니다. 시간이 있으면 레지스터 대신 매개 변수에 데이터를 저장하는 최신 트릭을 적용합니다. 16 진수 만 사용하여 필요한 숫자를 입력하는 것이 운이 좋은 경우 P가 한 번에 더 많은 문자를 인쇄하는 방식을 남용하여 더 짧은 dc 솔루션을 얻을 수 있다고 생각하십니까?
seshoumara

@seshoumara 가능하지만 다른 도전 과제로 시도했을 때 그 값이 빠르게 커지기 때문에 불가능할 수도 있습니다. 처음 두 글자 'An'을 P얻으 려면 16750 또는 0x416E 가 필요합니다 . 방금 운이 좋았고 하위 문자열 중 하나가 값 AF로만 구성된 경우 바로 가기가 될 수 있습니다. 그래도 운이 좋을 것입니다! 그렇지 않으면 우리는 어떻게 든 큰 숫자를 입력하거나 어떻게 든 올라가거나 256을 더하고 곱하기를 할 것 P입니다.
brhfl

5

apt , 87 바이트

Bs g caA
HzG
Ts caV
iWisiiihiSisiUitiaihitiSitiuibu iUiSiWcaV idiiiaisiSieihisiSidiniau

시도 해봐

설명

첫 번째 줄은를 생성하여 'variable에 할당합니다 U.

Bs g caA
B                            :11
 s                           :To string
   g                         :First character
     c                       :Character code
      a                      :  Absolute difference with
       A                     :  10

두 번째 줄 2은 variable에 할당 합니다 V.

HzG
H                            :32
 z                           :Floor divided by
  G                          :16

세 번째 줄은를 생성하여 .variable에 할당합니다 W.

Ts caV
Ts                           :Convert 0 to a string
   caV                       :Absolute difference of its charcode with V (2)

마지막 줄은 한 번에 한 문자 씩 반대로 문자열을 만듭니다.

iW...ibu ...iWcaV ...iau
iW                           :Start by prepending W (.) to U (')
  ...                        :Each i prepends the literal character that follows it to the string, with S being space and U being "'"
     ibu                     :As B is the constant for 11 and it can't be quoted, here i prepends "b" to the string and u uppercases it
         ...                 :As above, each i is prepending the character/constant that follows it to the string
            iWcaV            :Gets the absolute difference of the charcode of W (.) and V (2) to get the "," and prepends that
                  ...        :Some more literals
                     iau     :And, finally, the same trick is used for the "A" as was for the "B", as A is the constant for 10

좋은 해결책. 당신과 함께 첫 선을 교체하여 바이트를 저장할 수 있습니다Qc dGaB
예 무지의

4

빨강 , 272 바이트

prin quote And prin sp prin quote she prin sp prin quote said prin comma prin sp prin subtract to sp mold quote G sp prin quote But prin sp prin quote that prin subtract to sp mold quote G sp prin quote s prin sp prin quote his prin dot prin subtract to sp mold quote G sp

큰 따옴표가 필요한 경우 :

빨강 , 344 바이트

prin subtract to sp mold quote B sp prin quote And prin sp prin quote she prin sp prin quote said prin comma prin sp prin subtract to sp mold quote G sp prin quote But prin sp prin quote that prin subtract to sp mold quote G sp prin quote s prin sp prin quote his prin dot prin subtract to sp mold quote G sp prin subtract to sp mold quote B sp

TIO에서는 작동하지 않지만 Red 인터프리터에서는 작동합니다.

빨간 콘솔

설명:

단어는 사소하다-나는 그것들을 리터럴로 (개행없이 인쇄) prin한다 quote. Red 에는 space 및 sp에는 물론 내장 단어가 있습니다. 그리고 더 흥미 : 나는에서 공간을 빼서을 프린터 용 소비 와 각각 문자에서 시작 과 함께 문자열로 먼저 변환, 다음 문자 wtih (그들에 빼기를 사용하기 위해) ( 레드는 프로토 타입으로 변환이 - 변환 문자열을의 유형으로 , 문자).commadot"'BGBGmoldto spsp


1
질문이 명확 해졌다. 그들은 그것에서 흥미로운 부분을 제거했습니다.
아나 톨릭

@anatolyg 감사합니다. 필요 '하므로 272 바이트 솔루션은 동일합니다.
Galen Ivanov

4

351 번 (포)

CHAR A DUP EMIT
CHAR n EMIT
CHAR d EMIT
SPACE
CHAR s DUP EMIT
CHAR h EMIT
CHAR e EMIT
SPACE
EMIT
CHAR a EMIT
CHAR i EMIT
CHAR d EMIT
DUP CHAR m XOR EMIT
SPACE
CHAR f XOR DUP EMIT
CHAR B EMIT
CHAR u EMIT
CHAR t DUP EMIT
SPACE
DUP EMIT
CHAR h EMIT
CHAR a EMIT
EMIT
DUP EMIT
CHAR s EMIT
SPACE
CHAR h EMIT
CHAR i DUP EMIT
CHAR s EMIT
CHAR G XOR EMIT
EMIT

너무 나쁜 나는 CHAR를 재정의하거나 그 중 하나를 사용하여 필요로하기 때문에, 한 글자 단어로 방출하지 수 :;(예를 들어 : C CHAR ;) 또는 '(예를 ' CHAR ALIAS C)

실제로 단어를 정의 할 수 있으면 인쇄하고 인쇄 : P CHAR EMIT ;P x수 있습니다 x. 오 잘

버퍼를 만들 수 없으며 해당 문자 시퀀스를 거기에 쓴 다음 입력으로 사용합니다. 메모리에 쓰려면 !또는C!



3

페페 , 266 바이트

r 스택을 비워두고 R 스택에 's'가 있습니다.

reeEeeeeeE reeEEeEEEe reeEEeeEee reEe REeEEEeeEE Reee reeEEeEeee reeEEeeEeE reEe Reee reeEEeeeeE reeEEeEeeE reeEEeeEee reeeEeEEee reEe reeeEeeeEe reeEeeeeEe reeEEEeEeE reeEEEeEee reEe reeEEEeEee reeEEeEeee reeEEeeeeE reeEEEeEee reeeEeeEEE Reee reEe reeEEeEeee reeEEeEeeE Reee reeeEeEEEe reeeEeeeEe

이것은 TIO가 아니지만 여기서 시도해 볼 수 있습니다


3

dc , 240 바이트

주요 아이디어는 각 고유 ASCII 코드와 일치 할 때 스택 크기 ( )를 사용자 지정 레지스터에 K저장 ( sX) 하여 스택을 1 ( ) 씩 지속적으로 늘리는 것 z입니다. 인쇄 ( P)는 전체적으로 수행됩니다.

KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKzsSKKzsQKKKKKzsqKKKKKzsCKKzsDKKKKKKKKKKKKKKKKKKKzPKzsBKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKzsaKKKzsdKzseKKKzshKzsiKKKKKzPldPlSPKKKKKzsszPlhPlePlSPlsPlaPliPldPlCPlSPlqPlBPKzdstzPdPlSPdPlhPlaPPlqPlsdPlSPlhPliPPlDPlqP

온라인으로 사용해보십시오!

d재 호출 ( lX)이 2 바이트 이므로 바이트를 저장하기 위해 스택에 문자 (예 : t)를 복제 ( )하는 것처럼 문자를 저장하지 않는 등의 최적화를 수행했습니다 .


+,-및 *에 대한 매크로를 만들어 산술을 사용하는 DC 솔루션을 생각해 냈습니다. 262 바이트입니다. 경쟁력을 높이기 위해 계속해서 최적화하려고 노력할 것이지만, (상대적으로) 순진한 솔루션보다 훨씬 더 나쁘다고 실망해야합니다.
brhfl

@brhfl 그래, dc는 매우 빠르다. 그럼에도 불구하고 귀하의 솔루션을보고 싶습니다. 포스트하십시오! 한편, 나는 현재 방법을 더 많이 사용하거나, 프로그램을 사용하거나, dc에 대한 다른 아이디어를 생각해내는 것을 생각하고 있습니다.
seshoumara

나는 240을 묶었 다! 1 ~ 2 바이트 더 골프를 칠 수 있다면 놀라지 않을 것입니다. 어쨌든, 나는 그것을 어딘가에 게시했습니다 ...
brhfl

가장 일반적인 레지스터 중 일부를 입력 / 출력 기수 및 정밀도로 대체하여 222로 줄었습니다. 상점에 1 바이트를 저장하고 모든로드에 1 바이트를 저장합니다 ... 숫자는 중요하지 않기 때문에 아무 영향을주지 않습니다.이 기능을 유리하게 사용할 수도 있습니다!
brhfl

3

80186+ 기계 코드, MS-DOS .COM 형식, 822 787 바이트

문자 외에 탭과 공백 만 사용됩니다. 허용되는 범위의 대부분의 opcode가 특정 증분, 감소, 푸시, 팝 및 레지스터 간접 AND 및 OR이라는 점을 감안할 때 IMUL 외에도 스택 레지스터가 끝에 도달하면 랩 레지스터가 래핑된다는 사실을 사용합니다. 코드를 반대로 수정하기 위해 세그먼트의! 즉각적인 가치를 추진하기 때문에 80186+ 조립이 필요합니다.

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXjhX   GXkOXYIQSX GXjdX    GXkOXwIIIIIIIIIQhhihs kOXeQh ihutSXH    GXHHHHHH GXSX GYkOXDAAAQSX GXjGX    GXkOXtQhidhsahe hshhd hAnSX GXjTX   GXkOXdIIIQkOXgAQSX GXHHHHHHHHHHHHHHHHHHHHH  GXSX GYkOXbAAAAAAAAAAAAAAQhhlh  Xhh qM

주석이 달린 소스 (TASM 형식) :

IDEAL
P186

MODEL   TINY
CODESEG
ORG 100H

MAIN:   
REPT 582
    POP AX  ; Set up stack to end of string
ENDM

    PUSH 68H
    POP AX
    OR [BX+58H],AX
    IMUL CX,[BX+58H],59H ; 68H*59H=2428H
    DEC CX ; -1=2427H
    PUSH CX

    PUSH BX
    POP AX
    AND [BX+58H],AL
    PUSH 64H
    POP AX
    OR [BX+58H],AX
    IMUL CX,[BX+58H],77H ; 64H*77H=2E7CH
REPT 9
    DEC CX ; -9=2E73H
ENDM
    PUSH CX

    PUSH 6968H
    PUSH 2073H

    IMUL CX,[BX+58H],65H ; 64H*65H=2774H
    PUSH CX

    PUSH 6920H
    PUSH 7475H

    PUSH BX
    POP AX
    DEC AX
    OR [BX+58H],AX ; FFFFH
REPT 6
    DEC AX
ENDM
    AND [BX+58H],AL ; FFF9H
    PUSH BX
    POP AX
    AND [BX+59H],AL ; 00F9H
    IMUL CX,[BX+58H],44H ; 0F9H*44H=4224H
REPT 3
    INC CX ; +3=4227H
ENDM
    PUSH CX

    PUSH BX
    POP AX
    AND [BX+58H],AL
    PUSH 47H
    POP AX
    OR [BX+58H],AX
    IMUL CX,[BX+58H],74H ; 47H*74H=202CH
    PUSH CX

    PUSH 6469H
    PUSH 6173H
    PUSH 2065H
    PUSH 6873H
    PUSH 2064H
    PUSH 6E41H

;; CODE STARTS:
;; PUSH 0909H
;; POP AX
;; PUSH 046CH
;; POP DX
;; INT 21H
;; INT 20H

    PUSH BX
    POP AX
    AND [BX+58H],AL
    PUSH 54H
    POP AX
    OR [BX+58H],AX
    IMUL CX,[BX+58H],64H ; 54H*64H=20D0H
REPT 3
    DEC CX ; -3=20CDH
ENDM
    PUSH CX

    IMUL CX,[BX+58H],67H ; 54H*67H=21CCH
    INC CX ; 21CDH
    PUSH CX

    PUSH BX
    POP AX
    AND [BX+58H],AL
REPT 21
    DEC AX
ENDM
    OR [BX+58H],AX ; 0FFEBH
    PUSH BX
    POP AX
    AND [BX+59H],AL ; 0EBH
    IMUL CX,[BX+58H],62H ; 0EBH*62H=59F6H
REPT 14
    INC CX ; +14=5A04H
ENDM
    PUSH CX

    PUSH 6C68H
    PUSH 5809H
    PUSH 0968H

    JNO $+4FH

END MAIN
ENDS

이것은 어셈블리가 아니며 머신 코드입니다 ...
Artelius

@Artelius Fair로 충분합니다. 설명을 업데이트했습니다.
ErikF

3

비 펀지-98 (FBBI) , 125 (124) 121 바이트

wab









And she said   But that s his












wakekekaayyeapwayyaayybyapayybyapcyabcyaayycayyba
a



b
wayapapoq

온라인으로 사용해보십시오! 이름이 지정된 파일\n (단일 개행)로 출력합니다 . 대본을 쓴 Jo King 에게 감사합니다 .

출력에는 10 개의 후행 줄 바꿈이 포함됩니다.

하나의 후행 줄 바꿈에 대해서만 다음 줄을 변경하여 +1 바이트 :

wakekekaayyeapwayydayybyapayybyapycyabcyaayycayyba

온라인으로 사용해보십시오!


설명:

명령 포인터는 다음과 같이 움직입니다.IP 경로

프로그램은 알파벳이 아닌 문자를 해당 행을 파일로 출력하기 전에 위치에 놓습니다.

Befunge-98에는 해당 16 진수 값을 스택으로 푸시하는 명령 a...이 포함되어 f있습니다. 다른 숫자를 생성하려면 해당 값을 y인수로 ( "Get SysInfo")에 인수로 전달하여 다음을 얻습니다.

10  y-position
11  x-position
12  y-velocity (= 0)
13  x-velocity (= 1)

23* stack size

대부분의 코드를 y = 23에 배치하면 ayy스택 크기에 반복적으로 액세스하는 데 사용될 수 있으며, 그런 다음 문자 코드를 생성하는 데 사용됩니다.


하나의 후행 줄 바꿈 만 허용되지 않습니까?
Delioth

게시물에 "공백이 완전히 허용됩니다"라고 표시되어 있습니다. 후행 줄 바꿈을 정당화하기 위해이 문구를 남용하는 것이 멋지다고 생각합니다!
anatolyg

2

Pyth , 210 바이트

pChyCdpCyhyhlGpCyytlGpdpChFhTyylGpCyylGpChyytlGpdpChFhTyylGpCtytytlGpChyylGpCyytlGpCyyhTpdpCtyyTpCyhCdpCtFyyCdhTpCyhFlGCdpdpCyhFlGCdpCyylGpCtytytlGpCyhFlGCdpCtyyTpChFhTyylGpdpCyylGpChyylGpChFhTyylGpCyhyhTpCtyyT

온라인으로 사용해보십시오!

문자 (예 : T= 10, Z= 0, lG= length (alphabet) = 26, Cd= charcode (space) = 32) 만 사용하여 표현할 수있는 몇 가지 숫자 와 문자 만 사용하여 수행 할 수있는 몇 가지 함수 (예 : t= 감소, h= 증가 , = 증가의 hF반복 적용 = 덧셈) 그리고 난폭 한 힘 검색을 실행하여 필요한 각 문자를 생성하는 함수와 숫자의 가장 짧은 조합을 찾습니다.


2

16 비트 x86 어셈블리 코드, 665 바이트

(이진은 소스가 아닌 알파벳순입니다)

어떻게 든 공백을 허용하는 규칙을 잊었습니다. 결과적으로 코드를 골프화 할 수 있습니다.

바이트 코드 :

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXsBFVKZPFFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXkLAFQQZJJJRkDCGPLXDPDJRkDBEPZJJRLZDRDZAAAQPLYDQDYXXDQhishZhDRDhZsDQDhaththRDhuthZBDQDRhidhsaRDhhehZsDRDhndhZADTZPiDEFY

출처:

    db    63 dup (58h) ;pop ax
    jnb   label1
    dw    5646h      ;magic #1
    dw    5a4bh      ;magic #2
    dw    4650h      ;magic #3
    dw    (42h-6)/2 dup ("PF")

label1:
    db    416 dup (58h) ;more pop ax
    imul  cx,[si+41h],46h ;cl=24h (string sentinel)
    push  cx         ;push string sentinel
    push  cx
    pop   dx         ;dl=24h
    dec   dx
    dec   dx
    dec   dx         ;dl=21h
    push  dx         ;save for later
    imul  ax,[si+43h],47h ;al=0CDh
    push  ax         ;push xxCDh
    dec   sp         ;insert xx
    pop   ax         ;ah=0CDh
    inc   sp         ;discard xx
    push  ax         ;push 0CDxx
    inc   sp         ;discard xx
    dec   dx         ;cl=20h (space)
    push  dx
    imul  ax,[si+42h],45h ;al=2Eh (dot)
    push  ax
    pop   dx         ;dl=2Eh
    dec   dx
    dec   dx         ;dl=2Ch (comma)
    push  dx         ;push xx2Ch
    dec   sp         ;insert xx
    pop   dx         ;dl=2Ch
    inc   sp         ;discard xx
    push  dx         ;push 2Cxxh
    inc   sp         ;discard xx
    pop   dx         ;dx=202Ch
    inc   cx
    inc   cx
    inc   cx         ;cl=27h (quote)
    push  cx         ;push xx27h
    push  ax         ;push xx2Eh
    dec   sp         ;insert xx
    pop   cx         ;ch=2Eh
    inc   sp         ;discard xx
    push  cx         ;push 2Exxh
    inc   sp         ;discard xx
    pop   cx         ;cx=272Eh
    pop   ax         ;discard xxxx
    pop   ax         ;ax=0CD21h
    inc   sp         ;discard xx
    push  cx         ;push ".'"
    push  7369h      ;push "is"
    push  685ah      ;push "h"+xx
    inc   sp         ;discard xx
    push  dx         ;" "+xx
    inc   sp         ;discard xx
    push  735ah      ;push "s"+xx
    inc   sp         ;discard xx
    push  cx         ;push "'"+xx
    inc   sp         ;discard xx
    push  7461h      ;push "at"
    push  6874h      ;push "th"
    push  dx         ;push " "+xx
    inc   sp         ;discard xx
    push  7475h      ;push "ut"
    push  425ah      ;push "B"+xx
    inc   sp         ;discard xx
    push  cx         ;push "'"+xx
    inc   sp         ;discard xx
    push  dx         ;push ", "+xx
    push  6469h      ;push "id"
    push  6173h      ;push "sa"
    push  dx         ;push " "+xx
    inc   sp         ;discard xx
    push  6568h      ;push "he"
    push  735ah      ;push "s"+xx
    inc   sp         ;discard xx
    push  dx         ;push " "+xx
    inc   sp         ;discard xx
    push  646eh      ;push "nd"
    push  415ah      ;push "A"+xx
    inc   sp         ;discard xx
    push  sp
    pop   dx         ;dx=sp
    push  ax
    imul  ax,[si+45h],5946h ;ah=09h

이 방법으로 작동합니다 :

  • POP AX를 통해 스택 포인터를 코드 끝으로 이동합니다 (알파벳이 아니기 때문에 POP SP를 사용할 수 없음).

  • 알파벳순이 아니기 때문에 DOS 호출을 디스패치하는 명령을 구성합니다.

  • 알파벳이 아닌 문자를 구성합니다.

  • 문자열을 스택에 배치합니다.

  • 코드의 정확한 끝에서 디스패치 명령을 스택에 배치하여 실행이 해당 명령으로 직접 전달되도록합니다.

  • 문자열을 인쇄하도록 명령을 구성합니다.

  • 문자열을 표시하면 즉시 충돌합니다. :-/ (우수한 종료에는 더 많은 코드가 필요합니다)




0

80186 머신 코드 + DOS, 91 바이트

텍스트 버전 :

hm  j   j   PPjzjzjgaAAA    JSJJ    RU  Sq  ReAA    JdJJJ   RfiJElK JEiS GtI And she said   But that s his   

탭 (코드 9)으로 대체되고 9공백 (코드 32)으로 대체 된 텍스트 버전 *:

hm9j9j9PPjzjzjgaAAA9JSJJ9RU9Sq9ReAA9JdJJJ9RfiJElK9JEiS*GtI*And*she*said***But*that*s*his***

16 진 덤프 :

68 6D 09 6A 09 6A 09 50 50 6A 7A 6A 7A 6A 67 61
41 41 41 09 4A 53 4A 4A 09 52 55 09 53 71 09 52
65 41 41 09 4A 64 4A 4A 4A 09 52 66 69 4A 45 6C
4B 09 4A 45 69 53 20 47 74 49 20 41 6E 64 20 73
68 65 20 73 61 69 64 20 20 20 42 75 74 20 74 68
61 74 20 73 20 68 69 73 20 20 20

머신 코드는 확장자를 가진 파일에 나타납니다 .com. 실행할 때 필요한 메시지를 인쇄 한 다음 중단 (임의 데이터 실행).

그것이하는 일에 대한 높은 수준의 설명 :

  1. 상수 값으로 레지스터를 초기화합니다
  2. 메시지의 공백을 필수 특수 기호 ( ,'.$)로 바꿉니다.
  3. int 21메시지를 인쇄하는 명령 을 생성하기 위해 코드를 패치
  4. DOS 호출

어셈블리 코드 (로 컴파일 가능 tasm) :

my_bp equ 7ah
my_si equ 7ah
my_di equ 67h
my_msg equ 13bh
    .model tiny
    .code
    .startup
    .186
    org 100h
    push 96dh   ; ax (ah = 0; al = don't care, but see below)
    push 9      ; cx
    push 9      ; dx
    push ax     ; bx = don't care
    push ax     ; don't care
    push my_bp
    push my_si
    push my_di
    popa
    inc cx
    inc cx
    inc cx
    or [bp+si+my_msg-my_bp-my_si+12], cx ; ,
    dec dx
    dec dx
    or [bp+si+my_msg-my_bp-my_si+14], dx ; '
    or [bp+di+my_msg-my_bp-my_di+23], dx ; '
    or [bp+si+my_msg-my_bp-my_si+30], dx ; '
    inc cx
    inc cx
    or [bp+si+my_msg-my_bp-my_si+29], cx ; .
    dec dx
    dec dx
    dec dx
    or [bp+si+my_msg-my_bp-my_si+31], dx ; $

    ; 0x2049 * 0x4b6c = 0x98301cc
    ; So this sets cx to 1cc (a temporary constant used to patch code)
    imul cx, [bp+si+my_msg-my_bp-my_si-2], 4b6ch
    ; 0x1cc | 0x2049 = 0x21cd (the instruction which calls DOS int 21)
    ; Here ah = 9 ("print" mode)
    or [bp+si+my_msg-my_bp-my_si-2], cx

    ; At address 101, there is the constant 96d, which was loaded into ax
    ; 0x96d * 0x7447 = 0x448013b
    ; So the following sets dx to 13b (adddress of the message)
    imul dx, [bp+di+101h-my_bp-my_di], 7447h

int21:
    dw 2049h

    db 'And she said   But that s his   '
    end

poparegular pop는 필요한 모든 레지스터를 채울 수 없기 때문에 명령어를 사용하여 모든 레지스터를 팝합니다 (예 : pop di금지 된 opcode).

패치 할 바이트의 주소는 0x100 ... 0x160 범위에 있습니다. 운 좋게도 허용되는 값을 가진 3 바이트의 합계로 표시 될 수 있습니다.

  • 에 0x7a bp
  • 0x7a 또는 0x67 si또는di
  • 즉각적인 가치

메시지의 바이트 패치는 OR0x20 (공백 문자)과 작은 상수 (4, 7, 12 또는 14) 에서 논리 를 수행하여 작동합니다 . 작은 상수는 초기화 cx하고 dx9 (탭 문자) 및 수행 INC또는 DEC필요에 따라 얻습니다 .

코드 패치에는 IMUL명령 이 사용됩니다. 무차별 검색을 사용하여 필요한 16 비트 상수를 찾았습니다.

마지막으로, 메시지의 주소 (0x13b)는 곱셈에 의해 얻어진다. 공간을 절약하기 위해 즉각적인 값을 포함하는 명령어 중 하나에서 상수 중 하나를 사용했습니다 0x96d. 여기서 9부품은 DOS 인쇄 기능을 선택하고 6d부품은 자유 매개 변수입니다. 6d곱셈 후에 0x13b를 줄 수있는 유일한 가능성 이라는 것이 밝혀졌습니다 .

코드 부분의 분해 :

06BA:0100 686D09            PUSH    096D
06BA:0103 6A09              PUSH    +09
06BA:0105 6A09              PUSH    +09
06BA:0107 50                PUSH    AX
06BA:0108 50                PUSH    AX
06BA:0109 6A7A              PUSH    +7A
06BA:010B 6A7A              PUSH    +7A
06BA:010D 6A67              PUSH    +67
06BA:010F 61                POPA
06BA:0110 41                INC     CX
06BA:0111 41                INC     CX
06BA:0112 41                INC     CX
06BA:0113 094A53            OR      [BP+SI+53],CX
06BA:0116 4A                DEC     DX
06BA:0117 4A                DEC     DX
06BA:0118 095255            OR      [BP+SI+55],DX
06BA:011B 095371            OR      [BP+DI+71],DX
06BA:011E 095265            OR      [BP+SI+65],DX
06BA:0121 41                INC     CX
06BA:0122 41                INC     CX
06BA:0123 094A64            OR      [BP+SI+64],CX
06BA:0126 4A                DEC     DX
06BA:0127 4A                DEC     DX
06BA:0128 4A                DEC     DX
06BA:0129 095266            OR      [BP+SI+66],DX
06BA:012C 694A456C4B        IMUL    CX,[BP+SI+45],4B6C
06BA:0131 094A45            OR      [BP+SI+45],CX
06BA:0134 6953204774        IMUL    DX,[BP+DI+20],7447
06BA:0139 CD21              INT     21 (after the code patches itself)

재미있는 사실 : 일반적으로 offset message하드 코딩 대신을 사용 13bh하지만이 경우 주소를 구문 분석 할 때 알 수 없으므로 tasm은 16 비트 즉시 오프셋을 생성하여 1 코드 바이트를 낭비합니다.

06BA:0131 098A4600          OR      [BP+SI+0046],CX
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.