x86-Computercode (IA-32), 126 Byte
Hexdump:
60 8b f9 57 33 c0 f2 ae 5e 2b fe 4f 87 fa 8d 1c
12 8b c3 48 f6 e3 c6 04 07 00 48 c6 04 07 20 75
f9 8b ea 4d 53 8d 04 2a 50 53 8b c5 f6 e3 8d 44
68 01 50 53 2b c2 8b c8 50 4b 53 55 53 03 c5 50
f7 d3 53 50 53 95 f6 e2 6b c0 04 50 43 53 51 6a
01 4a 52 6a 01 50 6a ff 51 b0 0a 6a 0b 8b dc 59
8b 6c cb fc 88 04 2f 03 2c cb 89 6c cb fc 83 f9
0a 75 01 ac e2 ea 4a 79 e0 83 c4 58 61 c3
Das ist ein bisschen lang. Um es zu erklären, gebe ich zuerst C-Code:
void doit(const char* s, char out[])
{
int n = strlen(s);
int w = 2 * n;
int h = w - 1;
int m = n - 1;
memset(out, ' ', h * w);
out[h * w] = 0;
int offset1 = n + m;
int offset2 = w * m + 2 * m + 1; // 2 * n * n - 1
int offset3 = offset2 - n; // 2 * n * n - n - 1
int offset4 = 4 * n * m; // 4 * n * n - 4 * n
int offsets[] = {
offset3, -1,
offset4, 1,
m, 1,
offset3, 1 - w,
offset4, -w,
offset2 - 1, -w,
offset2 - 1, w - 1,
m, w - 1,
offset3, w,
offset2, w,
offset1, w,
};
do
{
char c = *s++;
for (int i = 0; i < 11; ++i)
{
if (i == 9)
c = '\n';
int offset = offsets[i * 2];
assert(offset > 0 && offset < w * h);
out[offset] = c;
offsets[i * 2] += offsets[i * 2 + 1];
}
} while (--n);
}
Hier n
ist die Länge der Eingabezeichenfolge.
Die Abmessungen des Ausgabebereichs sind 2n
(Breite) mal 2n-1
(Höhe). Zunächst wird alles mit Leerzeichen gefüllt (und ein abschließendes Null-Byte hinzugefügt). Anschließend bewegt es sich im Ausgabebereich entlang elf gerader Linien und füllt sie mit Text:
- 2 Zeilen werden mit Zeilenende-Bytes gefüllt (= 10)
- 9 Zeilen werden mit den aufeinanderfolgenden Bytes der Eingabezeichenfolge gefüllt
Jede Zeile wird durch zwei Zahlen dargestellt, einen Startoffset und einen Schritt. Ich habe beide in das Array gesteckt offsets
, um den Zugriff "einfach" zu gestalten.
Der interessante Teil füllt das Array. Die Reihenfolge der Einträge im Array ist von geringer Bedeutung. Ich habe versucht, sie neu anzuordnen, um die Anzahl der Registerkonflikte zu minimieren. Außerdem haben quadratische Formeln eine gewisse Freiheit bei der Wahl der Berechnungsweise. Ich habe versucht, die Anzahl der Subtraktionen zu minimieren (da durch die flexible LEA
Anweisung Additionen implementiert werden können ).
Versammlungsquelle:
pushad;
; // Calculate the length of the input string
mov edi, ecx;
push edi;
xor eax, eax;
repne scasb;
pop esi; // esi = input string
sub edi, esi;
dec edi;
; // Calculate the size of the output area
xchg edi, edx; // edx = n
// edi = output string
lea ebx, [edx + edx]; // ebx = w
mov eax, ebx;
dec eax; // eax = h
mul bl; // eax = w * h
; // Fill the output string with spaces and zero terminate it
mov byte ptr [edi + eax], 0;
myfill:
dec eax;
mov byte ptr [edi + eax], ' ';
jnz myfill;
mov ebp, edx;
dec ebp; // ebp = m
; // Fill the array of offsets
push ebx; // w
lea eax, [edx + ebp];
push eax; // offset1
push ebx; // w
mov eax, ebp;
mul bl;
lea eax, [eax + 2 * ebp + 1];
push eax; // offset2
push ebx; // w
sub eax, edx;
mov ecx, eax; // ecx = offset3
push eax; // offset3
dec ebx;
push ebx; // w - 1
push ebp; // m
push ebx; // w - 1
add eax, ebp;
push eax; // offset2 - 1
not ebx;
push ebx; // -w
push eax; // offset2 - 1
push ebx; // -w
xchg eax, ebp; // eax = m
mul dl;
imul eax, eax, 4;
push eax; // offset4
inc ebx;
push ebx; // 1 - w
push ecx; // offset3
push 1;
dec edx; // edx = n - 1
push edx;
push 1;
push eax;
push -1;
push ecx;
; // Use the array of offsets to write stuff to output
myout:
mov al, '\n';
push 11;
mov ebx, esp;
pop ecx;
myloop:
mov ebp, [ebx + ecx * 8 - 4];
mov [edi + ebp], al;
add ebp, [ebx + ecx * 8];
mov [ebx + ecx * 8 - 4], ebp;
cmp ecx, 10;
jne skip_read;
lodsb;
skip_read:
loop myloop;
dec edx;
jns myout;
add esp, 11 * 8;
popad;
ret;
Ich habe hier Byte-Multiplikationen verwendet, um die Länge der Eingabezeichenfolge auf 127 zu begrenzen. Dadurch wird ein Überladen des Registers vermieden edx
- ax
stattdessen wird das Produkt berechnet .
Ein kleiner Fehler: Beim Ausfüllen des Arrays wird die Länge des Strings um 1 verringert. Deshalb habe ich die Loop-Exit-Bedingung angepasst:
jns myout
Es zählt bis -1 herunter.