8088 어셈블리, IBM PC DOS, 164 159 156 155 바이트
이진 :
00000000: d1ee 8a0c 03f1 53fd ac3a d075 0343 e2f7 ......S..:.u.C..
00000010: 85db 741c 5f8a d043 f6c3 0174 0a57 bd64 ..t._..C...t.W.d
00000020: 0155 83eb 0374 0957 bd5d 0155 4b4b 75f7 .U...t.W.].UKKu.
00000030: 8ad0 2c2f 7213 518a f0b0 24b1 31bf 6a01 ..,/r.Q...$.1.j.
00000040: fcf2 aefe ce75 fa59 57e2 bc5a 85d2 740c .....u.YW..Z..t.
00000050: b409 cd21 b220 b402 cd21 ebef c364 6f75 ...!. ...!...dou
00000060: 626c 6524 7472 6970 6c65 246f 6824 6f6e ble$triple$oh$on
00000070: 6524 7477 6f24 7468 7265 6524 666f 7572 e$two$three$four
00000080: 2466 6976 6524 7369 7824 7365 7665 6e24 $five$six$seven$
00000090: 6569 6768 7424 6e69 6e65 24 eight$nine$
xxd -r
위에서 실행 파일을 빌드하고 테스트 하거나 PHONE.COM을 다운로드 하십시오 .
조립되지 않은 리스팅 :
D1 EE SHR SI, 1 ; point SI to DOS PSP (80H) for input string
8A 0C MOV CL, BYTE PTR[SI] ; load input string length into CX
03 F1 ADD SI, CX ; move SI to end of input
53 PUSH BX ; push a 0 to signal end of output stack
CHAR_LOOP:
FD STD ; set LODS direction to reverse
AC LODSB ; load next char from [SI] into AL, advance SI
3A D0 CMP DL, AL ; is it same as previous char?
75 03 JNZ NEW_CHAR ; if not, it's a different char
43 INC BX ; otherwise it's a run, so increment run length
E2 F7 LOOP CHAR_LOOP ; move on to next char
NEW_CHAR:
85 DB TEST BX, BX ; is there a run greater than 0?
74 1C JZ GET_WORD ; if not, look up digit name
5F POP DI ; get name for the current digit
8A D0 MOV DL, AL ; save current char in DL
43 INC BX ; adjust run count (BX=1 means run of 2, etc)
F6 C3 01 TEST BL, 1 ; is odd? if so, it's a triple
74 0A JZ IS_DBL ; is even, so is a double
57 PUSH DI ; push number string ("one", etc) to stack
BD 0164 MOV BP, OFFSET T ; load "triple" string
55 PUSH BP ; push to stack
83 EB 03 SUB BX, 3 ; decrement run count by 3
74 09 JZ GET_WORD ; if end of run, move to next input char
IS_DBL:
57 PUSH DI ; push number string to stack
BD 015D MOV BP, OFFSET D ; load "double" string
55 PUSH BP ; push to stack
4B DEC BX ; decrement by 2
4B DEC BX
75 F7 JNZ IS_DBL ; if not end of run, loop double again
GET_WORD:
8A D0 MOV DL, AL ; save current char into DL
2C 2F SUB AL, '0'-1 ; convert ASCII char to 1-based index
72 13 JB NOT_FOUND ; if not a valid char, move to next
51 PUSH CX ; save outer loop counter
8A F0 MOV DH, AL ; DH is the index to find, use as scan loop counter
B0 24 MOV AL, '$' ; word string is $ delimited
B1 31 MOV CL, 031H ; search through length of word data (49 bytes)
BF 016A MOV DI, OFFSET W ; reset word data pointer to beginning
FC CLD ; set DF to scan forward for SCAS
SCAN_LOOP:
F2/ AE REPNZ SCASB ; search until delimiter '$' is found in [DI]
FE CE DEC DH ; delimiter found, decrement counter
75 FA JNZ SCAN_LOOP ; if counter reached 0, index has been found
59 POP CX ; restore outer loop position
57 PUSH DI ; push string on stack
NOT_FOUND:
E2 BC LOOP CHAR_LOOP ; move to next char in input
OUTPUT_STACK:
5A POP DX ; get string from top of stack
85 D2 TEST DX, DX ; it is the last?
74 0C JZ EXIT ; if so, exit
B4 09 MOV AH, 09H ; DOS display string function
CD 21 INT 21H ; write string to console
B2 20 MOV DL, ' ' ; load space delimiter
B4 02 MOV AH, 02H ; DOS display char function
CD 21 INT 21H ; write char to console
EB EF JMP OUTPUT_STACK ; continue looping
EXIT:
C3 RET ; return to DOS
D DB "double$"
T DB "triple"
W DB "$oh$","one$","two$","three$","four$","five$","six$","seven$","eight$","nine$"
TL; DR :
트리플을 쉽게 찾을 수 있도록 입력 문자열을 오른쪽에서 왼쪽으로 읽습니다. 출력은 x86 스택 으로 푸시되어 표시 순서 반전을 단순화하고 숫자 이름 앞에 "double"및 "triple"단어를 쉽게 다시 정렬 할 수 있습니다.
다음 숫자가 마지막 숫자와 다른 경우 이름이 단어 목록에서 조회되어 스택으로 푸시됩니다. 기계 코드에는 "가변 길이 문자열의 색인 배열"에 대한 공식적인 개념이 없기 때문에, 단어 목록 i
(문자 색인)이 문자열 분리 문자 ( $
)에 해당하는 단어를 찾기 위해 스캔됩니다 (단어 색인) . 유용하게도 x86에는 C REPNZ SCASB
와 비슷한 간단한 명령어 쌍이있어서 memchr()
이를 단순화합니다 ( CISC 덕분에 ).
숫자가 이전 숫자와 동일하면 "실행"길이의 카운터가 증가하고 입력에서 왼쪽으로 계속 반복됩니다. 실행이 끝나면 각 그룹의 "더블"또는 "트리플"뒤에 배치해야하므로 숫자 이름이 스택에서 가져옵니다. 런의 길이가 홀수이고 런 길이가 > 1
이면 문자열 "triple"뒤에 오는 숫자 이름이 스택으로 푸시되고 런 길이는 3만큼 줄어 듭니다. 실행 길이가 0이 될 때까지 "double"에 대해 반복됩니다.
입력 문자열이 끝에 도달하면 스택에 저장된 각 문자열이 역순으로 화면에 기록됩니다.
I / O :
명령 행 출력에서 콘솔로 입력되는 독립형 PC DOS 실행 파일.
PHONE.COM을 다운로드하여 테스트 하십시오 .