Écrivez la phrase «Et elle a dit: 'Mais c'est le sien.'» En n'utilisant que l'alphabet


51

Imprimez la phrase en And she said, 'But that's his.'utilisant uniquement les caractères suivants: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ Pas de ponctuation ni de caractères non alphabétiques. Vous pouvez utiliser le langage de programmation de votre choix. Les espaces sont complètement autorisés. Le programme le plus court gagne.


Qu'en est-il des espaces en sortie? (premier /
deuxième

2
Bon, mon esolang ne peut pas terminer parce qu'il n'y a aucune possibilité de produire une sortie avec seulement a-zA-Z. En théorie, je pourrais utiliser write et Eval pour créer les instructions nécessaires, mais aucune d'entre elles +-*,%'"ne peut être construite sans utiliser (au moins) l'une d'entre elles +-*,%'"0-9.
Draco18s

11
(programmer-of (language 'lisp))n'aime pas cela.
MatthewRock

4
Je dois avouer que je ne pensais pas que cela était particulièrement intéressant au début, mais la combinaison de caractères uniques et répétés en faisait vraiment quelque chose d'amusant à optimiser (en particulier sur une langue de pile!). Très agréable.
brhfl

1
Pouvez-vous préciser si des espaces supplémentaires sont autorisés dans la sortie ? Vous aimez les nouvelles lignes de fuite? Ou seulement des espaces dans la source , plus des caractères alphabétiques. Il existe une réponse Befunge qui imprime avec un retour à la ligne supplémentaire.
Peter Cordes

Réponses:


75

Espace blanc , 417 414 349 265 octets

265 octets grâce à Kevin Cruijssen

  							
  				   
   		 	
   		
   	 
  		   		 
 	  		
 	  		 
   			 
  		 	
   	 
 	  	 
 	  		 
 	  	
   				
  		  	  
  							
 	  	  
  				 	 
  		 
   		
  		 	
   		 	
 	  	 	
  		
   	 
 	  		
 	  		
  		 
   	   
  		  	 	

  
   		  		 
	   	
  
 


Essayez-le en ligne!

A expliqué:

[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.Je vois que vous avez pris cela à la lettre.
Benjamin Urquhart

3
Vous m'avez battu. Plusieurs choses peuvent être jouées au golf, cependant. :) Vous pouvez supprimer le dernier NNNpour quitter, car il s'arrête déjà avec une erreur lorsque vous faites l'ajout avant le print_char, il ne viendra donc même pas après le Jump_to_Label. Aussi, pourquoi stocker le 63au début et le récupérer dans la boucle? Vous pouvez simplement le pousser avant d'ajouter à la place. Et pourquoi le Label-nr TTSSSSTN? Une étiquette peut même être vide. Il suffit donc NSSNde créer l'étiquette et NSNNde passer directement à l'étiquette lorsque vous n'utilisez qu'une seule étiquette.
Kevin Cruijssen le

1
318 octets avec les modifications que j'ai proposées ci-dessus. Voici le même programme avec la surbrillance ajoutée. Et comment avez-vous déduit la valeur constante 63? Je ne suis pas sûr à 100% que ce soit la constante la plus courte possible ici. Si c'est le cas, quelque chose ne va pas avec mon programme de génération constante que j'ai écrit pour un défi précédent. :)
Kevin Cruijssen le

1
Oui, j'avais raison. La constante 102est la plus efficace: 281 octets (ou ici avec surlignage ). (REMARQUE: j'ai également utilisé une copie pour économiser 4 octets pour l'espace entre ehs dnA(copie de l'espace entre dias ehs).
Kevin Cruijssen

3
Ok, maintenant j'ai fini. :) 265 octets (ou ici avec surlignage ). Ajout de quelques copies supplémentaires. ( Voici le conseil pertinent sur les
espaces blancs

63

Perl 5 , 133 102 95 octets

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

Essayez-le en ligne!

Explication:

Les expressions régulières, print et chop s'appliquent toutes à la variable $_par défaut.

s qqAnd she saidZ ZBut thatZs hisZZGjGGfq

Remplace la chaîne vide par And she saidZ ZBut thatZs hisZZGjGGf.

s qZqchr oct oct oct ord chopqge

Remplace chacun Zpar le résultat de l'évaluation chr oct oct oct ord chop. Cela supprime le dernier caractère de $_, prend son code clé, l’interprète comme une valeur octale trois fois et le reconvertit en un caractère. Par exemple, j→ 106 → 70 → 56 → 46 → ..

En raison de la manière dont le remplacement fonctionne, les modifications apportées $_lors de l'évaluation du remplacement sont perdues, il en $_est de même maintenant And she said, 'But that's his.'GjGGf.

y qGjfqqd

Supprime tout G, jet fdans $_.


27
Ne connaissant pas Perl, il semblerait que vous ayez juste essayé de taper la phrase, mais que vous ayez eu plusieurs combats à
mener

2
C'est peut-être le plus bel élément de code que j'ai jamais vu écrit sur ce site, et je le dis en tant que personne connaissant Perl.
Silvio Mayolo le

1
En relation, mais vous pouvez remplacer printpar say-2 caractères. Le méta-consensus actuel indique que les indicateurs de ligne de commande, tels -M5.010que ne comptent pas dans le nombre d'octets.
Silvio Mayolo le

34

> <> , 916 915 903 octets

Au début, j’imaginais qu’une solution dans> <> était impossible, puis j’ai réalisé… qui a besoin de conditions ou d’un contrôle logique? :RÉ

fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffloffffffffffffffffffffffffffffffffffffffffffffflopppgloppppppppppppppppppppppggloffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffflopppggloploppppppppppppppppppppppploffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffflopppppplofffffffflopggloppppppppppppppppppgglopppplofffffffloffffffffffffffffffffffffffflofffffffffffffffffffffffffffffffffffffffffffffffffffloglopppppppppppppppppppppppppppplofffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffflopppploppgloffffffffffffffffffflopppppppppppppppppppppppppgglofffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffflopppppppppppppppppppppppppppgglofffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffflofloffffffffffloppppppppppppppppppppppploppgloio

Essayez-le en ligne

J'insère à plusieurs reprises des nombres (le nombre 15) sur la pile, puis pousse la longueur de la pile et imprime le caractère avec cette valeur ASCII. Si j'ai besoin de réduire la longueur de la pile, je réduis la pile trois valeurs à la fois en utilisant p, ou une à la fois en utilisant gsi je suis à moins de trois de la cible. Le programme se termine par un appel i(entrée), qui appuie sur une touche -1car il n'y a pas d'entrée, puis l'imprime pour provoquer une erreur.

C’est le programme Python 3 que j’ai utilisé pour créer la solution une fois que j’avais réfléchi à la façon de le faire:

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

Essayez-le en ligne


5
C’est le bon contrepoint à la solution d’espace! Avoir un +1 de moi, j'apprécie aussi le programme de génération ...
Francesco

La dernière section peut être entièrement éliminé avec une utilisation prudente de p: créer un 59 sur la pile tout en déplaçant vers le haut de l'espace à l' sen said, puis placez - le dans le code sur le chemin vers le bas de dla ,. (Notez que (15,15) en a 15 à ce point.)
Nitrodon le

En fait, vous pouvez abuser let pmettre plusieurs caractères utiles dans le rectangle (10,10) - (15,15), puis les récupérer avec l' gendroit le plus pratique.
Nitrodon le

C'est une très bonne idée. C'est tellement difficile de penser à <> de cette façon. C'est comme coder avec BF
mbomb007

J'ai posté ma propre réponse: codegolf.stackexchange.com/a/186916/69059
Nitrodon

28

8086 Assembly sur IBM PC, 1463 845 664 bytes

Précision: la source réelle du langage d'assemblage est l'entrée et non le code machine généré.

La difficulté est que la plupart des instructions x86 (telles que ADD, SUB, JMP, sauts conditionnels, accès mémoire) ont deux arguments et ont donc besoin d’une virgule ou d’une adresse mémoire. Donc, nous ne pouvons pas utiliser d'addition, de soustraction, de ifs ou de boucles!

Lors de ma première tentative, j'ai été capable de "construire" des nombres en combinant incrément, décrément, multiplication, division, tours d'octets et les instructions obscures de BCD (comme AAA, DAS). Après cela, j'ai réalisé que cette idée pouvait être utilisée pour créer du code auto-vérifiant et auto-modificateur.

  • Tentative 1. (1463 octets)

    Utilisé les instructions disponibles pour construire des codes ASCII et l'adresse 0xb800 du tampon d'écran. Le calcul de chaque personnage de la séquence a été joué au golf à la main.

  • Tentative 2. (non complet)

    Nous nous sommes rendus compte qu’il existe un opcode pour chaque entier compris dans la plage 0x40-0x5f. Cette gamme comprend AZ. Ainsi, par exemple, INC CX correspond à 0x41 = 'A'. (Cette table d'opcode est très pratique.)

    J'ai essayé de construire 3 chaînes de "données" et de les superposer les unes sur les autres. Le premier tel quel (majuscule), le second "décalé" dans la zone 0x60-0x7f (minuscule) et le dernier "décalé" dans la zone 0x20-0x3f (ponctuation).

    Un code auto-modifiable produirait une boucle ou trois pour parcourir les données.

  • Tentative 3. (845 octets)

    Comme pour l'approche précédente, mais pour réduire les données, la chaîne ne serait encodée qu'une seule fois, avec des "caractères de contrôle" mélangés pour changer de jeu de caractères.

  • Tentative 4. (664 octets)

    Comment se débarrasser des caractères de contrôle qui nécessitent de nombreuses instructions corrigées pour gérer les branches? Etant donné que seules deux lettres majuscules sont utilisées, je me suis demandé si je pouvais "retourner" la table d'opcode pour coder des lettres minuscules en utilisant la plage 0x40-0x4f et la ponctuation en utilisant la plage 0x90-0x9f (en soustrayant de 0xc0). Le "A" et le "B" pourraient être ajoutés séparément.

    Cependant, seuls la moitié des opcodes de la gamme 0x90-0x9f sont utilisables et ils ne s'alignent pas avec ceux qui sont nécessaires. Ensuite, j'ai pensé que je pourrais peut-être les utiliser à l'aide d'un XOR et j'ai trouvé celui qui fonctionnait. Et le voici.

Golfé:

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

Assembler avec

nasm golf.asm -o golf.com

et exécutez-le dans DOSBOX (exécutez d'abord CLS). Ressemble à ça:

Échantillon de sortie

Commenté:

; 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. Je reçois des fichiers .COM différents à partir des deux sources d'assemblage, en commençant à offset 0x3e. Modifier - Nvm a trouvé la différence: la ligne 117 dans la version commentée est INC AXalors que la non commentée est INC AL.
gastropner

1
Je veux voir un binaire entièrement alphabétique à la place. :-)
peter ferrie le

1
Si vous êtes à l'aise de choisir NASM en tant qu'assembleur de choix, vous pouvez créer des étiquettes en créant label1 dbune ligne distincte. Cela produira un avertissement, mais pas d'erreur.
gastropner

1
@gastropner, cela rendrait les choses trop faciles. : P Ne savait pas à ce sujet, merci! Je devrais peut-être renommer ma langue en "quelque chose que vous pouvez nourrir dans DEBUG.COM". Ce qui incidemment j'avais l'habitude de déboguer ceci. xD
Artelius

1
@PeterCordes maintenant celui-ci est auto-modifiable!
Artelius

23

Perl 6 , 1299 1272 1220 1215 octets

Merci à Grimy pour -27 octets.

-52 octets parce que nous n'avions pas besoin des oreilles de lapin.

Merci à Jo King pour -5 octets.

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

Essayez-le en ligne!

Affiche la chaîne avec un retour à la ligne final. Si vous ne le souhaitez pas, remplacez le dernier saypar un print. Vous pouvez également remplacer les nouvelles lignes de la source par des espaces.

Explication

Ce code imprime la chaîne caractère par caractère. Chaque caractère est formé en introduisant le code de caractère approprié dans la chrfonction et en le mettant en minuscule lcsi nécessaire.

Actuellement, toutes les valeurs sont générées en générant une chaîne contenant le nombre correct de caractères. dans certains cas, le nombre de caractères est l'inverse du code de caractère cible. Il devrait être théoriquement possible d'utiliser des fonctions mathématiques telles que loget expdirectement, mais je n'ai pas trouvé très facile de les utiliser.

Pour une utilisation en tant que chiffres, nous avons e, piet tau; dans le côté droit de xou xx, ils sont implicitement pavés. Ils ont tous 17 caractères dans leurs représentations en chaîne, nous utilisons donc epour un nombre minimal de caractères. Nous avons également i(4 caractères), False(5 caractères) et NaN(3 caractères). Nous pouvons multiplier les longueurs de chaîne avec x; xxmultiplie un plus la longueur de la corde par le côté droit et en ajoute un. chopsupprime un caractère de la chaîne au cas où nous en aurions un de la cible.

Les instructions d'impression sont enchaînées en utilisant and, ce qui a une priorité assez faible. C'est presque un miracle qu'il existe; sinon, nous devrions utiliser des points-virgules illégaux.

J'ai trouvé les expressions pour les personnages à la main. Il pourrait être intéressant de les rechercher par programme pour trouver des expressions plus courtes.



À propos, @JoKing, avez-vous recherché manuellement les expressions les plus courtes ou avez-vous utilisé un programme pour vous aider?
bb94

1
À la main j'ai peur. Une méthode algorithmique ne serait probablement pas trop difficile
Jo King


@ Grimy Clever, mais malheureusement seulement possible parce que le Zero Width Space que vous utilisez n'est pas un caractère d'espacement
Jo King

17

Largeur , 66 64 octets

QaaGmwmiimaGcwWiimawAGawmfciiiGaFmAmFiimFGcwAmFiGmaiiGcGamafFiGQ

Essayez-le en ligne!

Imprime à déboguer. Pour imprimer sur stdout, ajoutez wwà la fin du code ce qui apparaît et sort le haut de la pile.

Explication

Dans Width, chaque lettre est corrélée à un nombre, en fonction de sa largeur, selon ce tableau . Cela attribue à chaque lettre un nombre compris entre 0 et 9. Ces chiffres sont ensuite utilisés pour exécuter le code.

En particulier, une lettre correspondant à une correspondance 7démarrera un littéral de chaîne. Il lira des séries de deux lettres à la fois, jusqu'à ce qu'il lise à nouveau la lettre originale. Chaque ensemble de deux lettres sera converti en son nombre en largeur, lu comme un nombre décimal compris entre 0 et 99, et le caractère auquel elles correspondent sera son index dans la chaîne suivante:

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

Par exemple, l'index !est égal à 1, ainsi 01seront les bons nombres de largeur. Ainsi, if, iI, jt, etc seront tous corrélat à un littéral de chaîne de !.

Dans ce cas, j'ai traduit les 31 caractères de la sortie requise en lettres appropriées, en utilisant Qles guillemets. Le haut de la pile est imprimé pour déboguer à la fin du programme.


C'est le plus court à ce jour. Je pense que vous pourriez gagner!
Blue-Maned Hawk

14

Code machine x86 (32 bits), 256 octets

Lorsque j'imprime mon code sur la console de la page de codes 437, les indications suivantes apparaissent:

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 

Cela contient des caractères d'espacement, donc voici le même code lorsque je remplace tous les caractères de tabulation par et tous les espaces insécables (avec le code 255) de *:

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

Quelques explications sur son fonctionnement:

Les instructions utiles sont:

  • push imm8, push imm16et push imm32, suivi de popgénérer des constantes. Cela peut également générer un zéro (in ah) lorsque vous appuyez sur un octet ( imm8).
  • and [ecx+32], ah- en supposant que ah = 0, ceci met l'octet à zéro. Il se trouve que la longueur de la chaîne de sortie est égale à 32, de sorte que le code remplit la mémoire tampon de bout en bout.
  • or [ecx+32], edx- en supposant que l'octet de sortie soit mis à zéro, cela copie edx(4 octets) dans la sortie. J'utilise une variante avec dxau lieu de se edxrapprocher de la fin du tampon, car il ne devrait pas écrire au-delà du tampon de sortie. La restriction de code rend impossible l'écriture d'octets simples de cette façon!
  • imul edx, [ecx+32], whatever- C’est l’idée principale de brouillage. Avec assez d'entropie [ecx+32]et peu importe le nombre, il peut générer n'importe quelle sortie. Je l'utilise pour générer 2 ou 3 octets de valeurs nécessaires. Une certaine complication est, lorsqu’il écrit dans la sortie, il doit faire logique ORavec tout ce qui est déjà là. Cela rendait parfois nécessaire de remettre à zéro la mémoire.
  • Une variante d'une jmpinstruction est utilisée pour retourner. Je l'ai choisi parce que son codage 0xffcorrespond à un espace insécable dans la page de codes 437. Un peu exagéré, mais je pense que la tâche est impossible ...

Le code source de l'assembly, ainsi qu'un programme C qui l'exécute (utilise la syntaxe 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);
}

Cela ne semble pas être complètement joué pour moi. Vous économiserez sûrement plusieurs octets en utilisant des boucles plutôt que de répéter une série d'instructions identiques. Tout cela dec ecx+ and [ecx+32], ahchoses peuvent être refactorisée.
Cody Grey

Vous êtes invités à essayer. C'est le mieux que j'ai pu faire; Je serais heureux de voir une approche différente. J'ai décidé d'abandonner l'idée de boucles quand j'ai vu qu'elles nécessitaient un décalage de saut négatif. Peut-être que cette restriction peut être résolue de manière créative - je ne sais pas comment.
Anatolyg

1
@anatolyg Cela peut résulter de la position de votre environnement de test sur le code à modification automatique. Ou ses opinions sur l'exécution du code que vous avez construit sur la pile.
gastropner

Le caractère ne 0xffviole- t-il pas "pas de ponctuation ni de caractères non alphabétiques"?
Val


13

PostScript, 889 874 837 835 octets

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

Essayez-le en ligne!

Ceci utilise 32 copies des nombres entiers 89 25 20 6. Tous les codes de caractères de la chaîne cible peuvent être obtenus avec des opérations sur ces entiers, dans l'ordre de la pile: par exemple, 'A' (ASCII 65) est égal à 89 - (25 & (20 + 6)). Beaucoup de 4-tuples d'entiers ont cette propriété; celui-ci a été choisi car ils sont particulièrement faciles à générer.

currentflat string dup rrand

Flat correspond par défaut à 1, ce qui crée une chaîne de longueur 1 (initialisée à \0). dupn’est pas une copie profonde: il crée une deuxième référence à la même chaîne. rrand pousse la graine aléatoire, dont la valeur par défaut est 0. Stack is now ["\0", "\0", 0].

count dup count count mul mul xor

count pousse le nombre d'éléments dans la pile, ceci calcule donc 3 ^ (3 * (5 * 6)) = 89.

count count mul count dup mul exch count

4 * 5 = 20, 5 * 5 = 25, 6 = 6. La pile est maintenant ["\0", "\0", 0, 89, 25, 20, 6].

count copy count copy count copy count copy count copy

Dupliquer la pile entière cinq fois. Nous nous retrouvons donc avec 32 copies de notre pile initiale de 7 éléments. Nous n'avons besoin que de 31 copies, car la chaîne cible compte 31 caractères, mais la copie supplémentaire ne fait pas mal.

add and sub put print

Calculez un charcode parmi les quatre premiers entiers, écrivez-le à l'index 0 de la chaîne, puis imprimez la chaîne.

quit

Supprime l'invite par défaut.


11

Ruby , 420 354 338 octets

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

Essayez-le en ligne!

Par ordre croissant de jankiness:

Les mots commençant par une lettre majuscule peuvent être imprimés en définissant une classe portant ce nom et en l'appelant displaydans le corps de la définition de classe.

D'autres mots peuvent être affichés en définissant des méthodes portant ce nom, qui retourne un symbole, puis en les transposant en chaîne pour supprimer les deux points.

D'autres caractères peuvent être affichés en appelant putcleur code ASCII. Nous pouvons générer les nombres appropriés en réutilisant l' String defastuce pour obtenir une chaîne, puis en prenant la somme de ses octets en utilisant un module déterminé par sa taille. Malheureusement, nous n'avons aucun moyen d'appeler des méthodes sur un objet autre que dans la définition de classe de cet objet, ce qui rend difficile la transmission d'arguments. Le hack final consiste donc à redéfinir String#inspect, ce qui est appelé implicitement lorsqu’on passe une chaîne à la pméthode, de sorte qu’elle calcule et génère le caractère approprié en tant qu’effet secondaire, avant de générer une erreur afin que l’opération pne puisse pas se terminer et imprimer. nouvelle ligne. Ensuite, nous devons récupérer l'erreur dans le code principal.

Edit: Jordan a fait beaucoup moins compter les octets, ahem, haut avec quelques astuces de golf intelligentes, et j’ai coupé quelques octets supplémentaires en les remplaçant raisepar un appel de méthode inexistant d’une lettre, ce qui déclenche un NameError.

Edit 2: Remarqué qu'avec print Stringextrait dans une méthode, il est moins coûteux de simplement l'utiliser avec une définition de méthode que d'utiliser l'astuce de définition de classe, car les méthodes sont autorisées à être classées dans le titre.


Beau .... Je ne comprends pas comment sum sizeobtient la somme modulo de sa taille, mais tout le reste vérifie!
Valeur d'encre

Je pose cela un peu paresseusement, il passe en fait la taille de la chaîne comme argument optionnel de la méthode sum.
histocrate

11

> <> , 233 122 octets

cdacaabbglccgpcbfbbcaacdebbafbebbcebdbealbcpcdbcccdlcdpacbbalccpaalacpbcfafbaab









       g  sandBe
       o  Aviuth

Essayez-le en ligne!

Cela a commencé comme une réponse de mbomb , mais j’ai découvert un changement fondamental qui économise un nombre considérable d’octets. Je le publie donc comme ma propre réponse.

La génération de caractères non alphabétiques à la sortie est effectuée en insérant de manière répétée des valeurs dans la pile, puis en utilisant lla longueur de la pile. Cependant, cela n'a pas besoin d'être affiché immédiatement: en utilisant p, ce caractère peut être placé dans n'importe quelle cellule dont les coordonnées sont comprises entre 10 et 15 inclus, pour être récupérées ultérieurement avec g. De même, les caractères alphabétiques peuvent être placés dans le code source initial et lus de la manière suivante: puisque le code de caractère non alphabétique le plus élevé dans l’entrée est 46 ( .), cela signifie que la pile n’a pas besoin d’être poussée plus haut que le nombre 62 nécessaire pour le stockage. tous les 31 caractères de la sortie.

De plus, a vest placé dans le code de la colonne 7. Lorsque le pointeur d'instruction tourne autour de cela et le frappe v, la séquence goest exécutée de manière répétée pour lire les coordonnées insérées et générer les caractères correspondants. Finalement, la pile devient vide et gtermine le programme avec une erreur.

Les 7 premiers octets de code sont réutilisés en tant que coordonnées initiales 7 et 7 dernières. Placer le vin de la colonne 9 aurait théoriquement enregistré deux octets supplémentaires, mais aurait forcé les caractères Ainsvdans un carré 2x2 du code, ce qui est impossible. Une version antérieure utilisait la colonne 15, mais cela nécessitait une ligne supplémentaire dans le code source et aboutissait à six octets de plus.


Après mûre réflexion, je pense que je peux faire fonctionner la colonne 9 en passant un octet rà déplacer l’alignement où je veux. Cependant, jouer au golf avec ce programme me fait un peu mal au cerveau.
Nitrodon le

8

CJam , 262 octets

  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

Essayez-le en ligne! Les nouvelles lignes ne sont montrées ici que par souci de clarté; chaque ligne représente un personnage.

Ouf, c'était amusant. Se limiter aux commandes alphabétiques pose des défis intéressants:

  • Sans {et }, il n'y a pratiquement aucune possibilité de contrôle du flux (à l'exception de fce que je n'ai pas trouvé l'occasion d'utiliser).
  • Sans \, _, ;ou $, nous avons aucun moyen pour la manipulation de la pile.

Cela signifie que l'objectif principal consiste à obtenir les points de code appropriés sur la pile, puis à les convertir en caractères avec c.

Le problème est que nous manquons également de la plupart des commandes arithmétiques de base, ainsi que des littéraux entiers. Cela convient cependant, car l' mespace de noms contient de nombreuses opérations mathématiques avancées et de nombreuses variables prédéfinies en nombres utiles.

J'ai fini par faire un usage intensif des racines carrées ( mQet mq), de la fonction exponentielle meet de la conversion de base ( b), qui peuvent également être utilisées pour émuler la multiplication ( [X 0] Ybcalcule X * Y). De plus, il est parfois plus facile de construire le point de code en majuscule, auquel cas nous pouvons utiliser el(convertir en minuscule) le caractère résultant.

Je ne suis toujours pas satisfait des plus longs. Tant pis.

Explication

Ceci est une explication caractère par caractère de la sortie. Avant de commencer, voici quelques méthodes simples pour faire des nombres:

  • 0, 1, 2, 3 sont contenus dans des variables T, X, Y, Zrespectivement.
  • Les nombres 10 à 20 sont contenus dans les variables Ajusqu'au K.
  • 32 peut être créé avec Sci( Spousse une chaîne contenant un espace, cobtient le premier caractère de cette chaîne et iconvertit ce caractère en son point de code). Sest également utilisé pour les espaces.
  • 4 est donné par GmQ(racine carrée entière de 16).
  • 5 est donné par AZbYb(convertir 10 en base 3, donnant [1 0 1], et convertir le tableau résultant de nombres en base 2, donnant 5).
  • 7 est donné par Ymei(compute exp (2) et converti en entier).

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
Vous pouvez effectuer des conversions de base avec des chiffres hors de la plage habituelle pour la base, tels que HYbYCtYbc, HYbXAtYbcet HYbXBtYbc.
Nitrodon le

7

Poisson-mort ~ , 943 octets

iiisdsiciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicddddddddddcddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcdddddddddddddddddddddsddddddcdddddddddddcdddcdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcdddddddddddddddddddddsddddddcddddddddddddddddddciiiiiiiicdddddcddddddddddddddddddddddddddddddddddddddddddddddddddddddddcddddddddddddciiiiiiiciiiiiiiiiiiiiiiiiiiiiiiiiiiciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicdcddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcdddddddddddddddddddddsdddddcddddddddddddcdddddddciiiiiiiiiiiiiiiiiiicdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcddddddddddddddddddddddddddddsddddddcdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcddddddddddddddddddddddsiiiiciciiiiiiiiiicdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcdddddddc

Essayez-le en ligne!

Aucune boucle autorisée :(


7

mal , 198 octets

aeeeannkhhwzuuuuuueaeuekwuuuuuuuuuunkhwzaeeeeehknwgueeywguuuuuuhhknnwuuuwhgwpwnngheeuwguuuuuwngwzaeeeaaaeeeeeewhhgwnguuuueewnngawpaawuwnngwpawhgwhhgeeuwpawhguuuueewpwhgwhgwawpwnngaaaaaaeeeewguuuueew

Essayez-le en ligne!

C'était très amusant.



6

MATL , 187 158 octets

IEWQKEtqhpEqqKQHhthpKWEyQKWEqqYqQQXJwtQQQwKWEJKQthpYqKQHhthptQQQQQwIIhKQhpqKWEIWKQhpqIEWQQJQQtqKWEyIIhIhpYqQXJyKQthpYqwIWKQhpqyqKWEyJtQwhhPIIhKQhpQIWKQhpqvlec

Essayez-le en ligne!

Version plus lisible: Essayez-le en ligne! Tentative manuelle de construction de la chaîne. Il y a probablement beaucoup de place pour jouer au golf en coupant la corde en tronçons pratiques, en utilisant Pet hpour retourner et construire une corde. J'espère que quelqu'un relèvera le défi de me battre. Le principal défi est que vous ne pouvez pas utiliser +ou -, de sorte que l'arithmétique de base est souvent impossible.

Points forts:

  • KQthpYq: le 25e ( KQthp) nombre premier Yqest 97, ce qui correspond à la lettre a. La lettre s(115) est générée de manière similaire à partir de 113, le 30e nombre premier. Il est ensuite largement réutilisé dans le presse-papier J.
  • hisest raccourci en stockant l' havant de dans le presse-papiers J. Depuis celle précédemment stockée s, nous construisons hisà l’inverse afin de pouvoir récupérer la dernière sutilisation y, et la retourner après utilisation P.
  • Un grand nombre d'octets sauvés grâce à Luis Mendo (principalement en changeant un tas de hen vle)

Huh - Je pensais vraiment que l'utilisation vserait gâcher avec ce hque j'avais auparavant. Je suppose que j'aurais dû ça au lieu de simplement assumer. Merci également pour le heads-up, une suppression trop zélée. Je suis curieux de voir si vous pouvez faire mieux que cela ...
Sanchises

J'aimerais essayer, mais il faudra attendre. Répondre à cette question semble prendre beaucoup de temps!
Luis Mendo

1
@ LuisMendo Yup. Cela m'a pris environ une heure, ce qui ne comprend que des optimisations très locales. Je suis sûr que l’on peut faire mieux avec un peu plus de vision globale des choses.
Sanchises

Ma tentative . Je n’ai pas regardé la vôtre, donc les approches sont, espérons-le, différentes
Luis Mendo

@ LuisMendo j'ai complètement oublié que cela Usignifie ^2, cela aurait pu me sauver pas mal d'octets ...
Sanchises

6

MATL , 118 octets

KEUQtVQsQKBFZAXHKUqyyhsXJyyhdQtQQQwOJIUEyhdtKEhsHKQYqEEKQyywhdXJKEUQQHKUhstQwOytHKhsKYqyhdbJyqOHKhstQHKUqhsKUqYqqJvlec

Essayez-le en ligne!

Version plus lisible (chaque ligne correspond à un caractère, sauf les opérations de réorganisation de pile).

Explication

Le programme produit les points de code des caractères requis, sous forme de nombres indépendants. À la fin, tous ces nombres sont concaténés dans un vecteur de colonne, redéfinis en tant que vecteur de ligne et convertis en caractères. Le résultat est implicitement affiché.

Quelques astuces utilisées:

  • La plupart des points de code inférieurs à 32 sont affichés sous forme d'espace. Donc, 0est utilisé pour la plupart des espaces, car cela ne coûte qu'un octet ( O).
  • Pour le premier espace, cependant, 15est utilisé (généré en tant que KUq), car il peut ensuite être réutilisé en l'ajoutant à 100(char d) pour donner 115( s). À une autre occasion, l’ 5espace (généré en tant que KQ) est utilisé ; il peut donc être soustrait ultérieurement de 44( ,) pour donner 39( ').
  • Le Presse J- papiers est utilisé pour stocker des caractères qui seront répétés: d'abord s, ensuite '. De même, les Hmagasins presse-papiers 100, ce qui est utile pour det pour générer d'autres caractères.
  • Les fonctions Q(add 1), q(soustraire 1), E(multiplier par 2) et U(carré), ainsi que les littéraux prédéfinis dans les presse-papiers I( 3) et K( 4) sont largement utilisés .
  • L'addition et la soustraction arbitraires sont effectuées en concaténant un vecteur ( h) et en calculant sa somme ( s) ou ses différences consécutives ( d).
  • 100( d) est généré comme 4en binaire interprété comme un nombre décimal.
  • 110( n) est obtenu à partir de 65( A) en convertissant en chaîne ( '65': points de code [54 53]), en ajoutant 1aux points de code ( [55 54]), en les additionnant et en les additionnant 1.
  • L'ordre dans lequel les numéros sont générés est parfois modifié pour des raisons de commodité. et elles sont ensuite réorganisées par des fonctions de réorganisation de pile: swap ( w), bulle vers le haut b).

1
Très agréable! Touche intelligente en utilisant Oau lieu de KWEpour les espaces. Et vous avez confirmé mes soupçons selon lesquels il vaut probablement mieux sacrifier un autre bloc-notes H.
Sanchises

5

dc , 240 222 209 octets

OOOOOziOOOOOOOOOOOOOOOOOOOOOOOOOOOzddddddzkdddzasBdzasAdzscdzdasCzsdOOlAxlAxPOBlBxdIlAxoPAdlBxddsrIlAxssPPOPlsIZlCxddspPOZlCxPPOPlrdZlCxPlsPlrPlcPPKPdZlBxdZlAxPOAZlAxdPIZlCxdPrPdPlpPlrdZlCxPPKPOPPlpPlsPOPldPKP

Essayez-le en ligne!

Ma première pensée était identique à celle de @seshoumara: il suffit d'insérer suffisamment d'éléments dans la pile pour générer toutes les valeurs ASCII des caractères. Puis, je me suis rendu compte que depuis +, -et que *je suis un opérateur à caractère unique, je ne peux que les recréer et pouvoir utiliser l’arithmétique! Ce serait sûrement plus petit! Et, je ne serais pas surpris si je suis capable de jouer plus d’octets, mais pour l’instant ... cette approche compliquée a réussi à lier le naïf (ish).

OOOOOziOOOOOOOOOOOOOOOOOOOOOOOOOOOzddddddzkdddzasBdzasAdzscdzdasCzsdest la partie de l’approche qui ressemble à celle de @ seshoumara, mais nous montons seulement à 46, ce qui est .. Nous faisons cela parce que nous devons monter à 45, -et nous avons également besoin d'une période dans notre chaîne, donc simplement aller plus loin pour la période est (je pense) moins cher. En cours de route, nous stockons certaines valeurs: 5, 32, 39 seront utiles plus tard. 5 pour les choses utilitaires, 32 et 39 pour leurs valeurs ASCII. À l’origine, j’en avais 1-5, mais c’était cher, et j’ai simplement pu éviter d’en utiliser 4; utilisez Z(entrez une valeur, appuyez sur le nombre de chiffres dont elle dispose) sur un nombre à trois, deux ou un chiffre pour ces valeurs. 42, 43 et 45, nous convertir en chaînes ( *, +et -respectivement) et de les stocker sous forme de macros ( B, AetCrespectivement). Cela signifie que sans utiliser les caractères *+-, nous pouvons maintenant utiliser ces opérateurs.

À partir de là, nous commençons généralement à générer les valeurs ASCII en utilisant la puissance des mathématiques au lieu d’une simple accumulation, en stockant certaines répétitions en cours de route. 100, 105 et 115 arrivent suffisamment pour que leur stockage (dans des registres ou autrement) ait un sens. À l'origine, j'ai laissé la pile remplie de 10 et les ai utilisées pour en faire des 100; il a fini par économiser des octets pour remplir la pile avec 32 secondes et les utiliser ensuite comme espaces. Une version légèrement plus lisible de la section 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.

Supprimez 18 octets en: stockant le nombre 5 en tant que base d'entrée au lieu d'un registre; le nombre 32 comme précision au lieu d'un registre; le nombre 115 comme radix de sortie au lieu d'un registre; puis a dû changer KZde IZgénérer 1 et OZà KZgénérer 2 s.

Rasé 13 autres octets en inondant la pile avec 32 s; réglage de précision à 39; en utilisant la manipulation de pile pour éviter de stocker 116; couper un double travail que j'ai accidentellement laissé.


+1 Belle idée à utiliser apour recréer ces opérateurs, puis les appeler avec x. Cela montre le comportement data-is-code de dc. Quand j’ai le temps, je vais appliquer votre dernière astuce, celle de stocker des données dans des paramètres plutôt que dans des registres. Pensez-vous que nous pourrions obtenir une solution de courant continu encore plus courte en abusant de la façon dont P travaille pour imprimer plus de lettres à la fois si nous avons la chance de saisir le nombre énorme nécessaire en utilisant uniquement l'hexagone?
seshoumara le

@seshoumara C'est possible, bien que mes tentatives pour le faire avec d'autres défis suggèrent qu'il est peu probable que ce soit simplement parce que ces valeurs deviennent grandes rapidement. Juste pour obtenir les deux premières lettres, 'An', nous devons P16750 ou 0x416E. Si nous avions juste de la chance et que l’une des chaînes était composée exclusivement de valeurs AF, cela pourrait nous donner un raccourci. Ce serait un peu de chance, cependant! Sinon, nous pourrions soit entrer un nombre important, soit les calculer, soit faire beaucoup d’additions et de multiplications par 256. Ce qui semble ... plus volumineux que de nombreux Part.
brhfl

5

Japt , 87 octets

Bs g caA
HzG
Ts caV
iWisiiihiSisiUitiaihitiSitiuibu iUiSiWcaV idiiiaisiSieihisiSidiniau

L'essayer

Explication

La première ligne génère le 'et l'assigne à la variable U.

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

La deuxième ligne affecte 2une variable V.

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

La troisième ligne génère le .et l'assigne à la variable W.

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

La dernière ligne, ensuite, construit la chaîne un caractère à la fois en sens inverse.

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

Belle solution. Vous pouvez sauvegarder un octet en remplaçant la première ligne parQc dGaB
Embodiment of Ignorance

4

Rouge , 272 octets

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

Si les guillemets sont nécessaires:

Rouge , 344 octets

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

Ne fonctionne pas dans TIO mais fonctionne dans l'interprète rouge.

Console rouge

Explication:

Les mots sont triviaux - je les prie (imprimer sans nouvelle ligne) comme des littéraux quote. Rouge a un mot intégré pour l'espace - sp, ainsi que commaet dot. "et 'plus intéressant: je les Prin en soustrayant un espace de Bet Grespectivement, à partir d'un littéral Bet G, en les convertissant d' abord en chaîne avec moldpuis à caractère (pour soustraction d'utilisation sur les) wtih to sp( rouge a conversion par prototype - convertir le chaîne au type de sp, qui est un caractère).


1
La question a été clarifiée. ils en ont retiré la partie intéressante.
Anatolyg

@anatolyg Merci, j'en ai toujours besoin ', donc la solution de 272 octets est la même.
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

Dommage que je ne puisse pas redéfinir CHAR ou EMIT en mots d'une lettre, car il faudrait utiliser soit :et ;(exemple : C CHAR ;) ou '(exemple ' CHAR ALIAS C)

En fait, si je pouvais définir les mots, je pourrais faire : P CHAR EMIT ;et ensuite P ximprimer x. Tant pis.

Je ne peux même pas créer de tampon, écrire cette séquence de caractères là-bas, puis l'utiliser comme entrée, car écrire en mémoire nécessite d'utiliser !ouC!


3

AlphaBeta , 180 177 175 163 octets

cccaaggtFgDILrFigggDLjDLCLigggggDLjhDLhhhDLCLiggggDLjjggDLihhDLhhhhhDLcaaCLdbbCLcbbbCLHgDLiiiiigDLhDLdaaaCLDLjhhDLjgggDLiihDLcbbbCLhDLdaaaCLjhDLgDLiDLcaaaaCLdaaaCL

Essayez-le en ligne!

WIP


3

Pepe , 266 octets

Je garde la pile r vide et ai 's sur la pile r

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

Ce n'est pas sur TIO, mais vous pouvez l'essayer ici


3

dc , 240 octets

L'idée principale est de faire croître la pile de 1 ( K) en continu , en enregistrant ( sX) la taille de la pile ( z) dans des registres personnalisés lorsqu'elle correspond à chaque code ASCII unique. L'impression ( P) est terminée.

KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKzsSKKzsQKKKKKzsqKKKKKzsCKKzsDKKKKKKKKKKKKKKKKKKKzPKzsBKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKzsaKKKzsdKzseKKKzshKzsiKKKKKzPldPlSPKKKKKzsszPlhPlePlSPlsPlaPliPldPlCPlSPlqPlBPKzdstzPdPlSPdPlhPlaPPlqPlsdPlSPlhPliPPlDPlqP

Essayez-le en ligne!

J'ai fait quelques optimisations, comme ne pas enregistrer une lettre si elle n'est pas utilisée par la suite, comme dupliquer ( d) une lettre, par exemple t, sur la pile pour enregistrer un octet, puisque rappel ( lX) est de 2 octets.


Je suis venu avec une solution en courant continu qui utilise l'arithmétique en créant des macros pour +, - et *. C'est 262 octets. Je vais continuer à essayer de l'optimiser pour être compétitif, mais je dois dire que je suis déçu que ce soit beaucoup plus gros que la solution (relativement) naïve.
brhfl

@brhfl Ouais, la parole est très rapide. Malgré tout, j'aimerais beaucoup voir votre solution, alors postez-la! En attendant, je pense aussi à jouer davantage à la méthode actuelle, à utiliser un programme, ou à proposer une autre idée pour la dc.
Seshoumara le

J'ai réussi à nouer 240! Et je ne serais pas surpris si je pouvais jouer au golf avec un ou deux octets de plus, mais… c'est une approche beaucoup plus obtuse pour un gain minime ou nul. En tout cas, je l'ai posté quelque part là-bas ...
brhfl

Je suis descendu à 222 en remplaçant certains de mes registres les plus courants avec une base et une précision d'entrée / sortie; enregistre un octet sur le magasin et un octet sur chaque chargement ... Puisque les chiffres sont immatériels, cela n’affecte en rien ... Vous pourrez peut-être aussi utiliser ceci à votre avantage!
brhfl

3

Code machine 80186+, format MS-DOS .COM, 822 787 octets

Seuls les onglets et les espaces sont utilisés en plus des lettres. Etant donné que la plupart des opcodes dans la plage autorisée sont certains incréments, décréments, poussées, sauts et ET / OU à registre indirects, en plus de IMUL, je profite du fait que le registre de pile tourne quand il atteint la fin du segment pour modifier le code en sens inverse! L'assemblage 80186+ est requis car j'inscris des valeurs immédiates.

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

Source annotée (format 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

Ce n'est pas du montage, c'est du code machine ...
Artelius

@Artelius assez juste. J'ai mis à jour la description.
ErikF

3

Befunge-98 (FBBI) , 125 124 121 octets

wab









And she said   But that s his












wakekekaayyeapwayyaayybyapayybyapcyabcyaayycayyba
a



b
wayapapoq

Essayez-le en ligne! Sortie dans un fichier nommé \n(une nouvelle ligne). Merci à Jo King pour son scénario.

La sortie comprend 10 nouvelles lignes de fuite.

Pour un seul retour à la ligne, +1 octet en modifiant la ligne suivante:

wakekekaayyeapwayydayybyapayybyapycyabcyaayycayyba

Essayez-le en ligne!


Explication:

Le pointeur d'instruction se déplace comme suit:Chemin IP

Le programme met les caractères non alphabétiques en position avant de sortir cette ligne dans un fichier.

Befunge-98 inclut des instructions a... f, qui poussent la valeur hexadécimale correspondante dans la pile. Pour générer d'autres nombres, il transmet ces valeurs à y("Get SysInfo") en tant qu'arguments pour obtenir:

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

23* stack size

En plaçant la majeure partie du code à y = 23, vous ayypouvez utiliser l'accès répété à la taille de la pile, qui est ensuite utilisée pour générer des codes de caractères.


Un seul nouveau trait est-il autorisé?
Delioth

Le message indique "L'espace est totalement autorisé". Je pense que c'est cool d'abuser de cette formulation pour justifier le retour à la ligne!
Anatolyg

2

Pyth , 210 octets

pChyCdpCyhyhlGpCyytlGpdpChFhTyylGpCyylGpChyytlGpdpChFhTyylGpCtytytlGpChyylGpCyytlGpCyyhTpdpCtyyTpCyhCdpCtFyyCdhTpCyhFlGCdpdpCyhFlGCdpCyylGpCtytytlGpCyhFlGCdpCtyyTpChFhTyylGpdpCyylGpChyylGpChFhTyylGpCyhyhTpCtyyT

Essayez-le en ligne!

J'ai trouvé quelques chiffres qui pourraient être exprimés en utilisant uniquement des lettres (comme T= 10, Z= 0, lG= longueur (alphabet) = 26, Cd= charcode (espace) = 32), et quelques fonctions pouvant être exécutées en utilisant uniquement des lettres (comme t= décrément, h= incrément, hF= application répétée d’incrément = addition), puis il suffit de lancer une recherche de force brute pour trouver les combinaisons les plus courtes de ces fonctions et de ces nombres, donnant ainsi chacune des lettres dont j'avais besoin.


2

Code d'assemblage x86 16 bits, 665 octets

(le binaire est alphabétique, pas la source)

J'ai en quelque sorte oublié la règle qui autorise les espaces. En conséquence, le code peut être joué au golf.

Bytecode:

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXsBFVKZPFFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXkLAFQQZJJJRkDCGPLXDPDJRkDBEPZJJRLZDRDZAAAQPLYDQDYXXDQhishZhDRDhZsDQDhaththRDhuthZBDQDRhidhsaRDhhehZsDRDhndhZADTZPiDEFY

La source:

    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

Cela fonctionne de cette façon:

  • déplace le pointeur de pile à la fin du code, via POP AX (impossible avec SP SP car ce n'est pas alphabétique);

  • construit l'instruction pour envoyer un appel DOS (par algorithme car ce n'est pas alphabétique);

  • construit les caractères non alphabétiques;

  • place la chaîne sur la pile;

  • place l'instruction d'envoi sur la pile à la fin exacte du code, de sorte que l'exécution passe directement à cette instruction;

  • construit l'instruction pour imprimer une chaîne;

  • affiche la chaîne et les écrase rapidement. : - / (Une sortie gracieuse nécessiterait plus de code)




0

80186 code machine + DOS, 91 octets

Version texte:

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

Version textuelle, avec tabulations (code 9) remplacées par 9et espaces (code 32) remplacées par *:

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

Le code machine apparaît dans un fichier avec une extension .com. Lorsque je l'exécute, il imprime le message requis, puis se bloque (en exécutant des données aléatoires).

Explication de haut niveau sur ce qu'il fait:

  1. Initialise les registres avec des valeurs constantes
  2. Remplace les espaces dans le message par les symboles spéciaux requis ( ,'.$)
  3. Corrige le code pour générer l' int 21instruction, qui imprime le message
  4. Appelle le DOS

Code d'assemblage (peut être compilé avec 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

Il utilise l' popainstruction pour faire apparaître tous les registres, parce que regular popne peut pas remplir tous les registres nécessaires (par exemple, pop diest un opcode interdit).

Les adresses d'octets à corriger sont dans la plage 0x100 ... 0x160. Par chance, ils peuvent être représentés par une somme de 3 octets avec les valeurs autorisées:

  • 0x7a dans bp
  • 0x7a ou 0x67 dans sioudi
  • Valeur immédiate

La correction des octets dans le message fonctionne de manière logique ORsur 0x20 (caractère espace) et une petite constante (4, 7, 12 ou 14). La petite constante est obtenue en initialisant cxet dxà 9 (caractère de tabulation) et en faisant INCou DECau besoin.

La correction du code utilise l' IMULinstruction. J'ai trouvé les constantes 16 bits nécessaires pour se multiplier à l'aide de la recherche par force brute.

Enfin, l'adresse du message (0x13b) est obtenue par multiplication. Pour économiser de l'espace, j'ai pris l'une des constantes de l'une des instructions, qui contient une valeur immédiate 0x96d. Ici, la 9pièce choisit une fonction d’impression DOS et la 6dpièce est un paramètre libre. Il s’avère que 6dc’est la seule possibilité qui puisse donner 0x13b après la multiplication.

Démontage de la partie code:

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)

Anecdote: Normalement, j'utiliserais offset messagele code codé en dur 13bh, mais dans ce cas, car au moment de l'analyse de son adresse est inconnue, tasm génère un décalage immédiat de 16 bits, gaspillant un octet de code:

06BA:0131 098A4600          OR      [BP+SI+0046],CX
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.