Stampa la frase "E lei disse: 'Ma è suo.'" Usando solo l'alfabeto


51

Stampa la frase And she said, 'But that's his.'usando solo i seguenti caratteri: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ Nessun segno di punteggiatura o caratteri non alfabetici. Puoi usare qualunque linguaggio di programmazione desideri. Lo spazio bianco è completamente consentito. Vince il programma più breve.


Che dire dello spazio bianco in uscita? (protagonista / finale?)
attinat

2
Accidenti, il mio esolang non può essere completato perché non è possibile produrre solo output a-zA-Z. In teoria potrei usare write e Eval per creare le istruzioni necessarie, ma nessuna di +-*,%'"esse può essere costruita senza usare (almeno) una delle +-*,%'"0-9.
Draco18s

11
(programmer-of (language 'lisp))Non mi piace questo.
MatthewRock,

4
Devo ammetterlo, all'inizio non pensavo che fosse particolarmente interessante, ma la combinazione di personaggi ripetuti e unici lo rendeva davvero divertente da ottimizzare (specialmente su un linguaggio stack!). Molto bella.
brhfl

1
Potete chiarire se è consentito uno spazio extra nell'output ? Ti piacciono le nuove righe finali? O solo spazi bianchi nella fonte , oltre a caratteri alfabetici. C'è una risposta Befunge che stampa con una nuova riga finale.
Peter Cordes,

Risposte:


75

Spazio bianco , 417 414 349 265 byte

265 byte grazie a Kevin Cruijssen

  							
  				   
   		 	
   		
   	 
  		   		 
 	  		
 	  		 
   			 
  		 	
   	 
 	  	 
 	  		 
 	  	
   				
  		  	  
  							
 	  	  
  				 	 
  		 
   		
  		 	
   		 	
 	  	 	
  		
   	 
 	  		
 	  		
  		 
   	   
  		  	 	

  
   		  		 
	   	
  
 


Provalo online!

Ha spiegato:

[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]

101
Whitespace is completely allowed.Vedo che l'hai preso alla lettera.
Benjamin Urquhart,

3
Mi hai battuto fino in fondo. Tuttavia, è possibile giocare a golf con alcune cose. :) È possibile rimuovere il finale NNNper uscire, poiché si interrompe già con un errore quando si esegue l'aggiunta prima di print_char, quindi non verrà nemmeno dopo Jump_to_Label. Inoltre, perché archiviare 63all'inizio e recuperarlo nel ciclo? Puoi semplicemente spingerlo prima di aggiungere invece. E, perché Label-nr TTSSSSTN? Un'etichetta può anche essere vuota, quindi solo NSSNper creare l'etichetta e NSNNpassare all'etichetta è sufficiente quando si utilizza solo un'etichetta.
Kevin Cruijssen il

1
318 byte con le modifiche che ho proposto sopra. Ecco lo stesso programma con l'evidenziazione aggiunta. E come hai dedotto il valore costante 63? Non sono sicuro al 100% che qui sia la costante più breve possibile. Se lo è, c'è qualcosa che non va nel mio programma a generazione costante che ho scritto per una sfida precedente. :)
Kevin Cruijssen il

1
Sì, avevo ragione. Costante 102è il più efficiente: 281 byte (o qui con l'evidenziazione ). (NOTA: ho anche usato una copia per salvare 4 byte per lo spazio tra ehs dnA(copiato dallo spazio tra dias ehs).
Kevin Cruijssen

3
Ok, ora ho finito. :) 265 byte (o qui con l'evidenziazione ). Aggiunte alcune copie aggiuntive. ( Qui il suggerimento relativo agli
spazi bianchi

63

Perl 5 , 133 102 95 byte

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

Provalo online!

Spiegazione:

Regexes, print e chop si applicano tutti alla variabile $_per impostazione predefinita.

s qqAnd she saidZ ZBut thatZs hisZZGjGGfq

Sostituisce la stringa vuota con And she saidZ ZBut thatZs hisZZGjGGf.

s qZqchr oct oct oct ord chopqge

Sostituisce ciascuno Zcon il risultato della valutazione chr oct oct oct ord chop. Questo rimuove l'ultimo carattere di $_, prende il suo codice chiave, lo interpreta come ottale tre volte e lo converte in un carattere. Ad esempio, j→ 106 → 70 → 56 → 46 → ..

A causa del modo in cui funziona la sostituzione, le modifiche apportate $_durante la valutazione della sostituzione vengono perse, così come $_è ora And she said, 'But that's his.'GjGGf.

y qGjfqqd

Elimina tutto G, je fin $_.


27
Non conoscendo Perl, sembra che tu abbia appena provato a digitare la frase, ma hai avuto più combattimenti con il tuo gatto nel processo
popctrl

2
Questo potrebbe essere il codice più bello che abbia mai visto scritto su questo sito Web, e lo dico come qualcuno che conosce Perl.
Silvio Mayolo,

1
Correlato, ma è possibile sostituirlo printcon sayper -2 caratteri. L'attuale meta consenso afferma che i flag della riga di comando -M5.010non contano ai fini del conteggio dei byte.
Silvio Mayolo,

34

> <> , 916 915 903 byte

All'inizio ho pensato che una soluzione in> <> fosse impossibile, ma poi ho capito ... chi ha bisogno di condizionali o controllo logico? : D

fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffloffffffffffffffffffffffffffffffffffffffffffffflopppgloppppppppppppppppppppppggloffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffflopppggloploppppppppppppppppppppppploffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffflopppppplofffffffflopggloppppppppppppppppppgglopppplofffffffloffffffffffffffffffffffffffflofffffffffffffffffffffffffffffffffffffffffffffffffffloglopppppppppppppppppppppppppppplofffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffflopppploppgloffffffffffffffffffflopppppppppppppppppppppppppgglofffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffflopppppppppppppppppppppppppppgglofffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffflofloffffffffffloppppppppppppppppppppppploppgloio

Provalo online

Spingo ripetutamente numeri (il numero 15) nello stack, quindi spingo la lunghezza dello stack e stampo il carattere con quel valore ASCII. Se ho bisogno di ridurre la lunghezza della pila, restringo la pila di tre valori alla volta usando p, o uno alla volta usando gse sono entro tre dalla destinazione. Il programma termina chiamando i(input), che spinge a -1poiché non c'è input, quindi lo stampa per causare un errore.

Questo è il programma Python 3 che ho usato per creare la soluzione una volta che avevo pensato a come farlo:

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')

Provalo online


5
Questo è il giusto contrappunto alla soluzione degli spazi bianchi! Ho un +1 da parte mia, apprezzo anche il programma di generazione ...
Francesco,

L'ultima sezione può essere completamente rimosso con facilità uso di p: creare un 59 in pila mentre salendo dallo spazio al sdi said, poi posto nel codice durante la discesa da da ,. (Nota che (15,15) ha 15 a questo punto.)
Nitrodon il

In realtà, puoi abusare le pmettere diversi caratteri utili nel rettangolo (10,10) - (15,15), quindi recuperarli gdove è più conveniente.
Nitrodon,

Questa è davvero una buona idea. È così difficile pensare> <> in questo modo. È come programmare con BF
mbomb007 il

Ho pubblicato la mia risposta: codegolf.stackexchange.com/a/186916/69059
Nitrodon

28

8086 Assembly su IBM PC, 1463 845 664 byte

Chiarimento: l'origine del linguaggio assembly effettivo è la voce, non il codice macchina generato.

La difficoltà è che la maggior parte delle istruzioni x86 (come ADD, SUB, JMP, salti condizionali, accesso alla memoria) hanno due argomenti e quindi hanno bisogno di una virgola o di un indirizzo di memoria. Quindi, non possiamo usare addizioni, sottrazioni, if o loop!

Durante il mio primo tentativo sono stato in grado di "costruire" numeri usando una combinazione di incremento, decremento, moltiplicazione, divisione, trucchi byte e le oscure istruzioni BCD (come AAA, DAS). Successivamente, mi sono reso conto che questa idea poteva essere utilizzata per creare codice auto-ispezionante e auto-modificante.

  • Tentativo 1. (1463 byte)

    Utilizzate le istruzioni disponibili per costruire codici ASCII e l'indirizzo 0xb800 del buffer dello schermo. Il calcolo di ciascun personaggio nella sequenza è stato giocato a mano.

  • Tentativo 2. (non completo)

    Realizzato che esiste un codice operativo per ogni numero intero nell'intervallo 0x40-0x5f. Questa gamma include AZ. Quindi, ad esempio, INC CX corrisponde a 0x41 = 'A'. (Questa tabella dei codici operativi è molto utile.)

    Ho tentato di costruire 3 stringhe di "dati", sovrapponendole. Il primo com'è (maiuscolo), il secondo "spostato" nella zona 0x60-0x7f (minuscolo) e l'ultimo "spostato" nella zona 0x20-0x3f (punteggiatura).

    Il codice automodificante produrrebbe un ciclo o tre per scorrere i dati.

  • Tentativo 3. (845 byte)

    Come l'approccio precedente, ma per ridurre i dati, la stringa verrebbe codificata una sola volta, con "caratteri di controllo" mescolati per cambiare set di caratteri.

  • Tentativo 4. (664 byte)

    Come sbarazzarsi dei personaggi di controllo che richiedono molte istruzioni rattoppate per gestire le ramificazioni? Dato che vengono utilizzate solo due lettere maiuscole, mi chiedevo se potevo "capovolgere" la tabella degli opcode per codificare le lettere minuscole utilizzando l'intervallo 0x40-0x4f e la punteggiatura utilizzando l'intervallo 0x90-0x9f (sottraendo da 0xc0). "A" e "B" potrebbero essere inseriti separatamente.

    Tuttavia, solo metà degli opcode nell'intervallo 0x90-0x9f sono utilizzabili e non si allineano con quelli necessari. Poi ho pensato che forse avrei potuto mescolarli in giro usando un XOR, e ho trovato uno che ha funzionato. Ed eccolo qui.

golfed:

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

Assemblare con

nasm golf.asm -o golf.com

ed esegui in DOSBOX (esegui prima CLS). Somiglia a questo:

Uscita campione

ha commentato:

; 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"

Hm. Ricevo file .COM diversi dalle due origini assembly, a partire dall'offset 0x3e. Modifica - Nvm ha trovato la differenza: la riga 117 nella versione commentata è INC AXmentre il non commentato è INC AL.
Gastropner

1
Voglio invece vedere un binario completamente alfabetico. :-)
peter ferrie

1
Se ti senti a tuo agio nel bloccare NASM come assemblatore preferito, puoi creare etichette facendo label1 dbuna linea a sé stante. Produrrà un avviso, ma nessun errore.
Gastropner

1
@gastropner bene, sarebbe semplicemente troppo facile. : P Non lo sapevo, grazie! Forse dovrei rinominare la mia lingua come "qualcosa che puoi alimentare in DEBUG.COM". Che per inciso ho usato per il debug di questo. xD
Artelius il

1
@PeterCordes ora questo si sta modificando da solo!
Artelius il

23

Perl 6 , 1299 1272 1220 1215 byte

Grazie a Grimy per -27 byte.

-52 byte perché non avevamo bisogno delle orecchie di coniglio in primo luogo.

Grazie a Jo King per -5 byte.

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

Provalo online!

Emette la stringa con una nuova riga finale. Se non lo desideri, sostituisci l'ultimo saycon a print. Puoi anche sostituire le newline nella sorgente con spazi.

Spiegazione

Questo codice stampa la stringa carattere per carattere. Ogni carattere viene formato inserendo nella chrfunzione il codice carattere appropriato e inserendolo in lettere minuscole lcse necessario.

Attualmente, tutti i valori vengono generati generando una stringa con il numero corretto di caratteri al suo interno; in alcuni casi, il numero di caratteri è il contrario del codice del carattere target. Dovrebbe essere teoricamente possibile usare funzioni matematiche come loge expdirettamente, ma non ho trovato molto facile usarle.

Per l'uso come numeri, abbiamo e, pie tau; nella parte destra di xo xx, sono implicitamente pavimentati. Hanno tutti 17 caratteri nelle loro rappresentazioni di stringa, quindi usiamo eper un conteggio minimo dei caratteri. Abbiamo anche i(4 caratteri), False(5 caratteri) e NaN(3 caratteri). Possiamo moltiplicare le lunghezze delle stringhe con x; xxmoltiplica uno più la lunghezza della stringa per il lato destro e ne aggiunge uno. choprimuove un carattere dalla stringa nel caso in cui siamo lontani dal bersaglio.

Le dichiarazioni di stampa sono concatenate usando and, che ha una precedenza piuttosto bassa. È quasi un miracolo che esista; altrimenti, dovremmo usare un punto e virgola illegale.

Ho trovato le espressioni per i personaggi a mano. Potrebbe valere la pena cercarli a livello di codice per trovare espressioni più brevi.



A proposito, @JoKing, hai cercato le espressioni più brevi a mano o hai usato un programma per aiutarti?
bb94,

1
A mano ho paura. Un modo algoritmico probabilmente non sarebbe troppo difficile
Jo King il


@Grimy Clever, ma sfortunatamente è possibile solo perché lo spazio a larghezza zero che stai utilizzando non è un personaggio di spazi bianchi
Jo King il

17

Larghezza , 66 64 byte

QaaGmwmiimaGcwWiimawAGawmfciiiGaFmAmFiimFGcwAmFiGmaiiGcGamafFiGQ

Provalo online!

Stampa per il debug. Per stampare su stdout, aggiungi wwalla fine del codice, che si apre e genera la parte superiore dello stack.

Spiegazione

In Larghezza, ogni lettera è correlata a un numero, in base alla sua "larghezza", secondo questa tabella . Questo assegna a ogni lettera un numero compreso tra 0 e 9. Quindi, quei numeri vengono utilizzati per eseguire effettivamente il codice.

In particolare, una lettera rispetto alle partite 7inizierà una stringa letterale. Leggerà gruppi di due lettere contemporaneamente, fino a quando non rileggerà nuovamente la lettera originale. Ogni set di due lettere verrà convertito nei loro numeri di larghezza, letto come un numero decimale tra 0 e 99 e il carattere che uguaglia sarà il loro indice nella seguente stringa:

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

Ad esempio, l'indice di !è 1, quindi 01saranno i numeri di larghezza giusta. Così, if, iI, jt, ecc saranno tutti correlato ad un letterale serie di !.

In questo caso, ho tradotto i 31 caratteri dell'output richiesto in lettere appropriate, usando Qcome virgolette. La parte superiore dello stack viene stampata per eseguire il debug al termine del programma.


Questo è il più corto di sempre. Penso che potresti vincere!
Blue-Maned Hawk,

14

codice macchina x86 (32 bit), 256 byte

Quando stampo il mio codice sulla mia console 437 codepage, vedo quanto segue:

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 

Questo contiene alcuni caratteri di spazi bianchi, quindi ecco lo stesso codice quando sostituisco tutti i caratteri di tabulazione e tutti i caratteri di spazio non infrangente (con il codice 255) di *:

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*

hexdump:

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

Alcune spiegazioni su come funziona:

Le istruzioni utili sono:

  • push imm8, push imm16E push imm32, seguito da popgenerare costanti. Questo può anche generare zero (in ah) quando si preme un byte ( imm8).
  • and [ecx+32], ah- supponendo ah = 0, questo imposta il byte a zero. Accade solo che la lunghezza della stringa di output sia 32, quindi il codice riempie il buffer dall'inizio alla fine.
  • or [ecx+32], edx- supponendo che il byte di output sia impostato su zero, questo copia edx(4 byte) sull'output. Uso una variante con dxanziché edxvicino alla fine del buffer, perché non dovrebbe scrivere oltre il buffer di output. La restrizione sul codice rende impossibile scrivere singoli byte in questo modo!
  • imul edx, [ecx+32], whatever- questa è la principale idea di confusione. Con abbastanza entropia [ecx+32]e qualunque numero, può generare qualsiasi output. Lo uso per generare 2 o 3 byte di valori necessari. Qualche complicazione è che, quando lo scrive sull'output, deve fare la logica ORcon tutto ciò che è già lì. Questo a volte rendeva necessario azzerare di nuovo la memoria.
  • Una variante di jmpun'istruzione viene utilizzata per restituire. L'ho scelto perché la sua codifica è 0xff, che corrisponde a uno spazio non interrotto nella tabella codici 437. Un po 'un tratto delle regole, ma per il resto penso che il compito sia impossibile ...

Codice sorgente assembly, insieme a un programma C che lo esegue (utilizza la sintassi di 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);
}

Questo non sembra essere completamente golfato per me. Sicuramente risparmieresti diversi byte usando i loop, piuttosto che ripetere una serie di istruzioni identiche. Tutte queste dec ecx+ and [ecx+32], ahcose possono essere prese in considerazione.
Cody Gray,

Sei il benvenuto per provare. Questo è il meglio che potrei fare; Sarei felice di vedere un approccio diverso. Ho deciso di abbandonare l'idea dei loop quando ho visto che richiedono un offset di salto negativo. Forse questa restrizione può essere risolta in modo creativo - non so come.
Anatolyg

1
@anatolyg Potrebbe dipendere dalla posizione del tuo ambiente di test sul codice auto-modificante. O le sue opinioni sull'esecuzione del codice che hai creato nello stack.
Gastropner

Il carattere non 0xffviola "Nessuna punteggiatura o caratteri non alfabetici"?
val


13

PostScript, 889 874 837 835 byte

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

Provalo online!

Questo utilizza 32 copie dei numeri interi 89 25 20 6. Tutti i codici a caratteri della stringa di destinazione possono essere ottenuti con operazioni su tali numeri interi, in ordine di stack: ad esempio, 'A' (ASCII 65) è 89 - (25 & (20 + 6)). Molte 4 tuple di numeri interi hanno questa proprietà; questo è stato scelto perché sono particolarmente facili da generare.

currentflat string dup rrand

Il valore predefinito è 1, quindi viene creata una stringa di lunghezza 1 (inizializzata su \0). dupnon è una copia profonda: crea un secondo riferimento alla stessa stringa. rrand spinge il seme casuale, il cui valore predefinito è 0. Lo stack è ora ["\0", "\0", 0].

count dup count count mul mul xor

count spinge il numero di oggetti nella pila, quindi questo calcola 3 ^ (3 * (5 * 6)) = 89.

count count mul count dup mul exch count

4 * 5 = 20, 5 * 5 = 25, 6 = 6. Lo stack è ora ["\0", "\0", 0, 89, 25, 20, 6].

count copy count copy count copy count copy count copy

Duplica l'intero stack, cinque volte. Quindi finiamo con 32 copie del nostro stack iniziale di 7 elementi. Abbiamo solo bisogno di 31 copie, poiché la stringa di destinazione è lunga 31 caratteri, ma la copia aggiuntiva non fa male.

add and sub put print

Calcola un charcode dai primi quattro numeri interi, scrivilo all'indice 0 della stringa, quindi stampa la stringa.

quit

Elimina il prompt predefinito.


11

Rubino , 420 354 338 byte

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

Provalo online!

In ordine crescente di jankiness:

Le parole che iniziano con una lettera maiuscola possono essere stampate definendo una classe con quel nome e chiamando displayall'interno del corpo della definizione della classe.

Altre parole possono essere visualizzate definendo i metodi con quel nome, che restituisce un simbolo, quindi lo converte in una stringa per rimuovere i due punti iniziali.

Altri caratteri possono essere visualizzati chiamando putcil loro codice ASCII. Possiamo generare i numeri appropriati riutilizzando il String deftrucco per ottenere una stringa, quindi prendendo la somma dei suoi byte usando un modulo determinato dalla sua dimensione. Sfortunatamente, non abbiamo modo di chiamare metodi su un oggetto se non all'interno della definizione di classe di tale oggetto, il che rende difficile passare argomenti. Quindi l'hacking finale è ridefinire String#inspect, che viene chiamato implicitamente quando si passa una stringa al pmetodo, in modo che calcoli e produca il carattere appropriato come effetto collaterale, prima di generare un errore in modo che pnon possa effettivamente finire l'esecuzione e stampare un nuova linea. Quindi abbiamo bisogno di salvare l'errore nel codice principale.

Modifica: Jordan ha ridotto il conteggio dei byte molto meno, ahem, in alto con un po 'di golf di flusso di controllo intelligente, e ho tagliato alcuni byte in più sostituendo raisecon una chiamata di metodo inesistente di una lettera, che genera un NameError.

Modifica 2: ho notato che con l' print Stringestrazione in un metodo, è più economico usarlo solo con una definizione del metodo piuttosto che usare il trucco di definizione della classe, poiché i metodi possono essere inseriti in maiuscolo / minuscolo.


Bello .... Non capisco come sum sizeottiene la somma modulo le sue dimensioni, ma tutto il resto controlla!
Value Ink

L'ho messo un po 'pigramente, in realtà sta passando la dimensione della stringa come argomento facoltativo al metodo sum.
histocrat

11

> <> , 233 122 byte

cdacaabbglccgpcbfbbcaacdebbafbebbcebdbealbcpcdbcccdlcdpacbbalccpaalacpbcfafbaab









       g  sandBe
       o  Aviuth

Provalo online!

Questo è iniziato come un golf della risposta di mbomb , ma ho scoperto un cambiamento fondamentale che consente di risparmiare un numero enorme di byte, quindi lo sto pubblicando come la mia risposta.

La generazione di caratteri non alfabetici per l'output viene eseguita spingendo ripetutamente i valori nella pila, quindi usando lper spingere la lunghezza della pila. Tuttavia, questo non deve essere emesso immediatamente: utilizzando p, questo personaggio può essere inserito in qualsiasi cella le cui coordinate sono comprese tra 10 e 15 inclusi, da recuperare in seguito g. Allo stesso modo, i caratteri alfabetici possono essere inseriti nel codice sorgente iniziale e letti in questo modo: poiché il codice del carattere non alfabetico più alto nell'input è 46 ( .), ciò significa che lo stack non deve essere spinto più in alto del 62 necessario per memorizzare tutti i 31 caratteri dell'output.

Inoltre, a vviene inserito nel codice nella colonna 7. Quando il puntatore dell'istruzione si avvolge e colpisce quello v, la sequenza goviene eseguita ripetutamente per leggere dalle coordinate inviate e generare i caratteri corrispondenti. Alla fine, lo stack diventa vuoto e gtermina il programma con un errore.

I primi 7 byte di codice vengono riutilizzati quando vengono spinte sia le prime 7 che le ultime 7 coordinate. Posizionare la vcolonna 9 avrebbe teoricamente salvato altri due byte, ma avrebbe forzato i caratteri Ainsvin un quadrato 2x2 nel codice, il che è impossibile. Una versione precedente utilizzava la colonna 15, ma ciò richiedeva una riga aggiuntiva nel codice sorgente e finiva per sei byte in più.


Dopo ulteriori riflessioni, penso di poter far funzionare la colonna 9 spendendo un byte rper spostare l'allineamento dove voglio. Tuttavia, giocare a golf con questo programma mi fa un po 'male al cervello.
Nitrodon,

8

CJam , 262 byte

  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

Provalo online! Le nuove righe vengono mostrate qui solo per chiarezza; ogni riga rappresenta un carattere.

Accidenti, è stato divertente. Limitare noi stessi ai comandi alfabetici pone alcune sfide interessanti:

  • Senza {e }, non c'è praticamente alcuna opportunità per il flusso di controllo (tranne f, che non ho trovato l'opportunità di utilizzare).
  • Senza \, _, ;, o $, non abbiamo mezzi per la manipolazione pila.

Ciò significa che l'obiettivo principale è quello di ottenere i punti di codice rilevanti nello stack e quindi convertirli in caratteri con c.

Il problema è che mancano anche la maggior parte dei comandi aritmetici di base, così come i letterali interi. Questo va bene però, poiché lo mspazio dei nomi contiene numerose operazioni matematiche avanzate e ci sono molte variabili predefinite in numeri utili.

Ho finito per usare pesantemente le radici quadrate ( mQe mq), la funzione esponenziale mee la conversione base ( b), che può anche essere usata per emulare la moltiplicazione ( [X 0] Ybcalcola X * Y). Inoltre, a volte è più semplice costruire il punto di codice in maiuscolo, nel qual caso possiamo usare el(converti in minuscolo) sul carattere risultante.

Non sono ancora soddisfatto di alcuni dei più lunghi. Oh bene.

Spiegazione

Questa è una spiegazione carattere per carattere dell'output. Prima di iniziare, ecco alcuni brevi modi per creare numeri:

  • 0, 1, 2, 3 sono contenuti in variabili T, X, Y, Zrispettivamente.
  • I numeri da 10 a 20 sono contenuti in variabili Aattraverso K.
  • 32 può essere creato usando Sci( Sspinge una stringa contenente uno spazio, cottiene il primo carattere di questa stringa e iconverte quel carattere nel suo punto di codice). Sviene utilizzato anche per gli spazi.
  • 4 è dato da GmQ(radice quadrata intera di 16).
  • 5 è dato da AZbYb(converti 10 in base 3, cedendo [1 0 1], e converti l'array di numeri risultante in base 2, cedendo 5).
  • 7 è dato da Ymei(calcola exp (2) e converti in numero intero).

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
Puoi eseguire conversioni di base con cifre al di fuori del normale intervallo per la base, ad esempio HYbYCtYbc, HYbXAtYbce HYbXBtYbc.
Nitrodon,

7

Pesce morto ~ , 943 byte

iiisdsiciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicddddddddddcddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcdddddddddddddddddddddsddddddcdddddddddddcdddcdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcdddddddddddddddddddddsddddddcddddddddddddddddddciiiiiiiicdddddcddddddddddddddddddddddddddddddddddddddddddddddddddddddddcddddddddddddciiiiiiiciiiiiiiiiiiiiiiiiiiiiiiiiiiciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicdcddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcdddddddddddddddddddddsdddddcddddddddddddcdddddddciiiiiiiiiiiiiiiiiiicdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcddddddddddddddddddddddddddddsddddddcdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcddddddddddddddddddddddsiiiiciciiiiiiiiiicdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcdddddddc

Provalo online!

Nessun loop consentito :(


7

male , 198 byte

aeeeannkhhwzuuuuuueaeuekwuuuuuuuuuunkhwzaeeeeehknwgueeywguuuuuuhhknnwuuuwhgwpwnngheeuwguuuuuwngwzaeeeaaaeeeeeewhhgwnguuuueewnngawpaawuwnngwpawhgwhhgeeuwpawhguuuueewpwhgwhgwawpwnngaaaaaaeeeewguuuueew

Provalo online!

Questo è stato abbastanza divertente.



6

MATL , 187 158 byte

IEWQKEtqhpEqqKQHhthpKWEyQKWEqqYqQQXJwtQQQwKWEJKQthpYqKQHhthptQQQQQwIIhKQhpqKWEIWKQhpqIEWQQJQQtqKWEyIIhIhpYqQXJyKQthpYqwIWKQhpqyqKWEyJtQwhhPIIhKQhpQIWKQhpqvlec

Provalo online!

Versione più leggibile: provala online! Tentativo manuale di costruzione della stringa. Probabilmente c'è molto spazio per giocare a golf tagliando la corda in comodi pezzi, usando Pe hper capovolgere e costruire una corda. Spero che qualcuno raccolga la sfida per superarmi. La sfida principale è che non puoi usare +o -, quindi l'aritmetica di base spesso non è possibile.

Mette in risalto:

  • KQthpYq: il 25 ° ( KQthp) primo Yqè 97, corrispondente alla lettera a. La lettera s(115) è generata in modo simile da 113, il 30 ° numero primo. Viene quindi ampiamente riutilizzato negli Appunti J.
  • hisviene abbreviato memorizzando hnegli appunti il ​​file precedente J. Dato che precedentemente memorizzato s, costruiamo hisal contrario in modo da poter ancora recuperare l' sutilizzo recente ye capovolgerlo dopo l'uso P.
  • Un gran numero di byte salvato grazie a Luis Mendo (principalmente cambiando un gruppo di ha vle)

Huh - Pensavo davvero che usare vavrebbe fatto casino con quello hche avevo prima. Immagino che avrei dovuto farlo invece di supporre. Inoltre, grazie per l'heads-up, è avvenuta l'eliminazione eccessiva. Sono curioso di vedere se riesci a fare meglio di così ...
Sanchises,

Mi piacerebbe provare, ma dovrà aspettare. Rispondere a questo sembra richiedere molto tempo!
Luis Mendo,

1
@LuisMendo Yup. Mi ci sono voluti circa un'ora per farlo, e questo include solo un'ottimizzazione molto locale. Sono sicuro che si può fare di meglio con uno sguardo un po 'più globale alle cose.
Sanchises,

Il mio tentativo . Non ho guardato il tuo, quindi gli approcci sono, si spera, diversi
Luis Mendo il

@LuisMendo Ho completamente dimenticato che Usignifica ^2che avrebbe potuto salvarmi un bel po 'di byte ...
Sanchises

6

MATL , 118 byte

KEUQtVQsQKBFZAXHKUqyyhsXJyyhdQtQQQwOJIUEyhdtKEhsHKQYqEEKQyywhdXJKEUQQHKUhstQwOytHKhsKYqyhdbJyqOHKhstQHKUqhsKUqYqqJvlec

Provalo online!

Versione più leggibile (ogni riga corrisponde a un carattere, ad eccezione delle operazioni di riordino dello stack).

Spiegazione

Il programma produce i punti di codice dei caratteri richiesti, come numeri indipendenti. Alla fine tutti quei numeri vengono concatenati in un vettore di colonna, rimodellati come un vettore di riga e convertiti in caratteri. Il risultato viene visualizzato implicitamente.

Alcuni dei trucchi utilizzati:

  • La maggior parte dei punti di codice inferiori a 32 vengono visualizzati come spazio. Quindi 0viene utilizzato per la maggior parte degli spazi, perché costa solo un byte ( O).
  • Per il primo spazio, tuttavia, 15viene utilizzato (generato come KUq), perché può quindi essere riutilizzato aggiungendolo a 100(char d) per dare 115( s). In un'altra occasione 5viene utilizzato per lo spazio (generato come KQ), quindi può essere successivamente sottratto da 44( ,) a give 39( ').
  • Gli appunti Jvengono utilizzati per memorizzare i caratteri che verranno ripetuti: prima s, poi '. Allo stesso modo, i Hnegozi di appunti 100, che è utile per de per generare altri personaggi.
  • Viene fatto ampio uso delle funzioni Q(aggiungi 1), q(sottrai 1), E(moltiplica per 2) e U(quadrato), insieme ai valori letterali predefiniti negli appunti I( 3) e K( 4).
  • L'aggiunta e la sottrazione arbitrarie vengono eseguite concatenando in un vettore ( h) e calcolando la sua somma ( s) o differenze consecutive ( d).
  • 100( d) viene generato come 4in binario interpretato come un numero decimale.
  • 110( n) si ottiene da 65( A) convertendolo in stringa ( '65': punti di codice [54 53]), aggiungendo 1ai punti di codice ( [55 54]), sommandoli e aggiungendoli 1.
  • L'ordine in cui vengono generati i numeri viene talvolta modificato per comodità; e poi vengono riordinati dalle funzioni di riordinamento dello stack: swap ( w), bubble up b).

1
Molto bella! Tocco intelligente usando Oanziché KWEper gli spazi. E hai confermato il mio sospetto che probabilmente è meglio sacrificare un altro appunti H.
Sanchises,

5

dc , 240 222 209 byte

OOOOOziOOOOOOOOOOOOOOOOOOOOOOOOOOOzddddddzkdddzasBdzasAdzscdzdasCzsdOOlAxlAxPOBlBxdIlAxoPAdlBxddsrIlAxssPPOPlsIZlCxddspPOZlCxPPOPlrdZlCxPlsPlrPlcPPKPdZlBxdZlAxPOAZlAxdPIZlCxdPrPdPlpPlrdZlCxPPKPOPPlpPlsPOPldPKP

Provalo online!

Il mio primo pensiero è stato lo stesso di @seshoumara, ho semplicemente messo abbastanza roba nello stack per generare tutti i valori ASCII dei personaggi. Poi mi è venuto in mente che da allora +, -e *sono operatori a carattere singolo, posso semplicemente ricrearli e avere la possibilità di usare l'aritmetica! Sicuramente sarebbe più piccolo! E non sarei sorpreso se riuscissi a giocare a golf più byte, ma per ora ... questo approccio contorto è riuscito a legare quello ingenuo (ish).

OOOOOziOOOOOOOOOOOOOOOOOOOOOOOOOOOzddddddzkdddzasBdzasAdzscdzdasCzsdè la parte dell'approccio simile a quella di @seshoumara, ma saliamo solo a 46, che è .. Lo facciamo perché dobbiamo andare fino a 45, -e abbiamo anche bisogno di un punto nella nostra stringa, quindi andare oltre per il periodo è (penso) il più economico. Lungo la strada, memorizziamo alcuni valori: 5, 32, 39 torneranno utili in seguito. 5 per cose utilitarie, 32 e 39 per i loro valori ASCII. Inizialmente ho fatto 1-5, ma era costoso, e sono stato in grado di evitare semplicemente di usare 4; usare Z(pop un valore, premere il numero di cifre che ha) su un numero di tre, due o una cifra per quei valori. A 42 anni, 43, e 45, convertiamo queste stringhe ( *, +, e -rispettivamente) e memorizzarli come macro ( B, A, eCrispettivamente). Ciò significa che senza usare i caratteri *+-, ora possiamo usare quegli operatori.

Da qui in pratica iniziamo a generare i valori ASCII usando il potere della matematica anziché la pura accumulazione, memorizzando alcune delle ripetizioni lungo il percorso. 100, 105 e 115 escono abbastanza da averne la memorizzazione (in registri o altro). Inizialmente, ho lasciato la pila piena di 10 e li ho usati per fare 100; ha finito per salvare byte per riempire lo stack di 32 secondi e usarli come spazi in seguito. Una versione leggermente più leggibile della sezione 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.

Eliminato 18 byte: memorizzando il numero 5 come radice di input anziché come registro; il numero 32 come precisione anziché un registro; il numero 115 come output radix anziché un registro; poi ha dovuto cambiare KZper IZgenerare 1s e OZper KZgenerare 2s.

Eliminato altri 13 byte inondando lo stack di 32 secondi; impostare la precisione su 39; usare la manipolazione dello stack per evitare di immagazzinare 116; tagliando qualche doppio lavoro che ho lasciato accidentalmente dentro.


+1 Bella idea da usare aper ricreare quegli operatori, quindi chiamarli x. Questo mostra il comportamento data-is-code di dc. Quando avrò tempo, applicherò il tuo ultimo trucco per memorizzare i dati nei parametri, anziché nei registri. Pensi che potremmo ottenere una soluzione cc ancora più breve abusando del modo in cui P lavora per stampare più lettere alla volta se siamo fortunati a inserire il numero enorme necessario usando solo esadecimali?
seshoumara,

@seshoumara È possibile, anche se i miei tentativi di farlo con altre sfide suggeriscono che è improbabile semplicemente perché quei valori diventano grandi rapidamente. Solo per ottenere le prime due lettere, "An", abbiamo bisogno di P16750 o 0x416E. Se ci fosse capitato di essere fortunati e una delle sottostringhe fosse composta esclusivamente da valori AF, allora questo potrebbe darci una scorciatoia. Sarebbe un po 'di fortuna, però! Altrimenti inseriremmo un numero elevato in qualche modo, arriveremmo in qualche modo con loro, o faremmo molto aggiungendo e moltiplicando per 256. Il che sembra ... più grosso di un gruppo di Ps.
brhfl

5

Japt , 87 byte

Bs g caA
HzG
Ts caV
iWisiiihiSisiUitiaihitiSitiuibu iUiSiWcaV idiiiaisiSieihisiSidiniau

Provalo

Spiegazione

La prima riga genera il 'e lo assegna alla variabile U.

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

La seconda riga assegna 2alla variabile V.

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

La terza riga genera il .e lo assegna alla variabile W.

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

L'ultima riga, quindi, costruisce la stringa di un carattere alla volta al contrario.

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

Bella soluzione. Puoi salvare un byte sostituendo la prima riga conQc dGaB
Incarnazione dell'ignoranza il

4

Rosso , 272 byte

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

Se sono necessarie le doppie virgolette:

Rosso , 344 byte

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

Non funziona in TIO ma funziona nell'interprete rosso.

Console rossa

Spiegazione:

Le parole sono insignificanti: le pronuncio (stampate senza una nuova riga) come letterali quote. Red ha una parola incorporata per spazio - sp, così come commae dot. "e 'più interessante: li premo sottraendo uno spazio da Be Grispettivamente, partendo da un letterale Be G, convertendoli prima in stringa con molde poi in carattere (per usare la sottrazione su di essi) con to sp( Red ha la conversione per prototipo - converti il stringa al tipo di sp, che è carattere).


1
La domanda è stata chiarita; ne hanno rimosso la parte interessante.
Anatolyg

@anatolyg Grazie, ne ho ancora bisogno ', quindi la soluzione da 272 byte è la stessa.
Galen Ivanov,

4

Forth (gforth), 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

Peccato che non riesco a ridefinire CHAR o EMIT in parole di una lettera, poiché ciò richiederebbe l'uso di :e ;(es. : C CHAR ;) O '(es. ' CHAR ALIAS C)

In effetti, se potessi definire le parole, potrei fare : P CHAR EMIT ;e poi P xstampare x. Oh bene.

Non riesco nemmeno a creare un buffer, scrivere quella sequenza di caratteri lì e quindi usarlo come input, poiché la scrittura in memoria richiede l'uso di !oC!


3

AlphaBeta , 180 177 175 163 byte

cccaaggtFgDILrFigggDLjDLCLigggggDLjhDLhhhDLCLiggggDLjjggDLihhDLhhhhhDLcaaCLdbbCLcbbbCLHgDLiiiiigDLhDLdaaaCLDLjhhDLjgggDLiihDLcbbbCLhDLdaaaCLjhDLgDLiDLcaaaaCLdaaaCL

Provalo online!

WIP


3

Pepe , 266 byte

Tengo vuoto lo stack e ho "s" nello stack

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

Questo non è su TIO, ma puoi provarlo qui


3

dc , 240 byte

L'idea principale è di aumentare continuamente lo stack di 1 ( K), salvando ( sX) la dimensione dello stack ( z) in registri personalizzati quando corrisponde a ciascun codice ASCII univoco. La stampa ( P) viene eseguita dappertutto.

KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKzsSKKzsQKKKKKzsqKKKKKzsCKKzsDKKKKKKKKKKKKKKKKKKKzPKzsBKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKzsaKKKzsdKzseKKKzshKzsiKKKKKzPldPlSPKKKKKzsszPlhPlePlSPlsPlaPliPldPlCPlSPlqPlBPKzdstzPdPlSPdPlhPlaPPlqPlsdPlSPlhPliPPlDPlqP

Provalo online!

Ho fatto un po 'di ottimizzazione, come non salvare una lettera se non viene usata dopo, come duplicare ( d) una lettera, ad esempio t, nello stack per salvare un byte, poiché il richiamo ( lX) è 2 byte.


Ho trovato una soluzione cc che usa l'aritmetica creando macro per +, - e *. Sono 262 byte. Continuerò a cercare di ottimizzarlo per cercare di diventare competitivo, ma devo dire che sono deluso, è molto più grasso della soluzione (relativamente) ingenua.
brhfl,

@brhfl Sì, dc diventa prolisso abbastanza velocemente. Anche così, mi piacerebbe molto vedere la tua soluzione, quindi pubblicala! Nel frattempo, sto anche pensando di giocare a golf con il metodo attuale di più, di usare un programma o di avere un'altra idea per DC.
seshoumara,

Sono riuscito a legare 240! E non sarei sorpreso se fossi in grado di golf uno o due byte in più, ma ... è un approccio molto più ottuso per guadagno scarso / nullo. Comunque, l'ho pubblicato laggiù da qualche parte ...
brhfl

Sono sceso a 222 sostituendo alcuni dei miei registri più comuni con radix input / output e precisione; salva un byte sull'archivio e un byte su ogni carico ... Poiché i numeri sono irrilevanti, non influisce su nulla ... Potresti essere in grado di utilizzarlo anche a tuo vantaggio!
brhfl

3

80186+ codice macchina, formato .COM MS-DOS, 822 787 byte

Vengono utilizzate solo schede e spazi oltre alle lettere. Dato che la maggior parte degli opcode nell'intervallo consentito sono determinati incrementi, decrementi, push, pop e AND e OR indiretti del registro, oltre a IMUL, faccio uso del fatto che il registro dello stack si avvolge quando raggiunge la fine del segmento per modificare il codice al contrario! È necessario un assemblaggio 80186+ perché sto spingendo i valori immediati.

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

Fonte annotata (formato 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

Questo non è un assemblaggio, questo è un codice macchina ...
Artelius

@Artelius Abbastanza giusto. Ho aggiornato la descrizione.
ErikF

3

Befunge-98 (FBBI) , 125 124 121 byte

wab









And she said   But that s his












wakekekaayyeapwayyaayybyapayybyapcyabcyaayycayyba
a



b
wayapapoq

Provalo online! Emette in un file chiamato \n(una nuova riga). Grazie a Jo King per la sua sceneggiatura.

L'output include 10 newline finali.

Solo per una nuova riga finale, +1 byte modificando la riga seguente:

wakekekaayyeapwayydayybyapayybyapycyabcyaayycayyba

Provalo online!


Spiegazione:

Il puntatore dell'istruzione si sposta come segue:Percorso IP

Il programma mette in posizione i caratteri non alfabetici, prima di inviare quella linea a un file.

Befunge-98 include istruzioni a... f, che spingono il loro corrispondente valore esadecimale nella pila. Per generare altri numeri, passa questi valori a y("Get SysInfo") come argomenti per ottenere:

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

23* stack size

Posizionando la maggior parte del codice su y = 23, ayypuò essere utilizzato per l'accesso ripetuto alla dimensione dello stack, che viene quindi utilizzato per generare codici di caratteri.


Non è consentita solo una nuova riga finale?
Delioth,

Il post afferma "Whitespace è completamente consentito". Penso che sia bello abusare di questa formulazione per giustificare il trascinamento di nuove righe!
Anatolyg

2

Pyth , 210 byte

pChyCdpCyhyhlGpCyytlGpdpChFhTyylGpCyylGpChyytlGpdpChFhTyylGpCtytytlGpChyylGpCyytlGpCyyhTpdpCtyyTpCyhCdpCtFyyCdhTpCyhFlGCdpdpCyhFlGCdpCyylGpCtytytlGpCyhFlGCdpCtyyTpChFhTyylGpdpCyylGpChyylGpChFhTyylGpCyhyhTpCtyyT

Provalo online!

Ho trovato alcuni numeri che potevano essere espressi usando solo lettere (come T= 10, Z= 0, lG= lunghezza (alfabeto) = 26, Cd= charcode (spazio) = 32) e alcune funzioni che potevano essere eseguite usando solo lettere (come t= decremento, h= incremento, hF= applicazione ripetuta di incremento = aggiunta), quindi ho appena eseguito una ricerca della forza bruta per trovare le combinazioni più brevi di quelle funzioni e numeri che hanno portato a ciascuna delle lettere di cui avevo bisogno.


2

Codice assembly x86 a 16 bit, 665 byte

(il binario è alfabetico, non l'origine)

In qualche modo mi sono dimenticato della regola che consente gli spazi bianchi. Sicuramente il codice può essere golfato di conseguenza.

bytecode:

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXsBFVKZPFFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXkLAFQQZJJJRkDCGPLXDPDJRkDBEPZJJRLZDRDZAAAQPLYDQDYXXDQhishZhDRDhZsDQDhaththRDhuthZBDQDRhidhsaRDhhehZsDRDhndhZADTZPiDEFY

Fonte:

    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

Funziona in questo modo:

  • sposta il puntatore dello stack alla fine del codice, tramite POP AX (non può POP SP perché non è alfabetico);

  • costruisce l'istruzione per inviare una chiamata DOS (algoritmicamente perché non è alfabetica);

  • costruisce i caratteri non alfabetici;

  • posiziona la stringa nello stack;

  • posiziona l'istruzione di invio nello stack alla fine esatta del codice, in modo che l'esecuzione fluisca direttamente a quell'istruzione;

  • costruisce l'istruzione per stampare una stringa;

  • visualizza la stringa e si blocca immediatamente. : - / (Un'uscita aggraziata richiederebbe più codice)



1

05AB1E , 145 121 109 byte

TnVYTOUXZxNJTZXTZZZXYTYxMNYTTMNNNYRYNNYNNNNYTXZMNNYxXRZZZXTYXRZZXZYxTRMRNXRMRMXNNYxYMRNTYxTRYNTZMYXRXXXTZJCXB

Provalo online!


0

80186 codice macchina + DOS, 91 byte

Versione testuale:

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

Versione testo, con schede (codice 9) sostituite da 9e spazi (codice 32) sostituite da *:

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

hexdump:

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

Il codice macchina appare in un file con estensione .com. Quando lo eseguo, stampa il messaggio richiesto e quindi si blocca (eseguendo dati casuali).

Spiegazione di alto livello su ciò che fa:

  1. Inizializza i registri con valori costanti
  2. Sostituisce gli spazi nel messaggio con i simboli speciali richiesti ( ,'.$)
  3. Patch il codice per generare l' int 21istruzione, che stampa il messaggio
  4. Chiama DOS

Codice assembly (può essere compilato con 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

Utilizza le popaistruzioni per far apparire tutti i registri, perché regolare popnon può riempire tutti i registri necessari (ad es. pop diÈ un codice operativo proibito).

Gli indirizzi dei byte da correggere sono compresi nell'intervallo 0x100 ... 0x160. Per fortuna, possono essere rappresentati come una somma di 3 byte con valori consentiti:

  • 0x7a in bp
  • 0x7a o 0x67 in siodi
  • Valore immediato

Il patching dei byte nel messaggio funziona in modo logico ORsu 0x20 (carattere spazio) e una piccola costante (4, 7, 12 o 14). La piccola costante si ottiene inizializzando cxe dxsu 9 (carattere di tabulazione) e facendo INCo DECsecondo necessità.

Patch del codice utilizza l' IMUListruzione. Ho trovato le costanti necessarie a 16 bit da moltiplicare usando la ricerca della forza bruta.

Infine, l'indirizzo del messaggio (0x13b) viene ottenuto per moltiplicazione. Per risparmiare spazio, ho preso una delle costanti da una delle istruzioni, che contiene un valore immediato 0x96d. Qui la 9parte sceglie una funzione di stampa DOS e la 6dparte è un parametro gratuito. Si scopre che 6dè l'unica possibilità che può dare 0x13b dopo la moltiplicazione.

Disassemblaggio della parte di codice:

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)

Curiosità: normalmente, offset messageinvece di 13bhhardcoded, userei, ma in questo caso, poiché al momento dell'analisi il suo indirizzo è sconosciuto, tasm genera un offset immediato a 16 bit, sprecando 1 byte di codice:

06BA:0131 098A4600          OR      [BP+SI+0046],CX
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.