x86 32-bit machine code, 39(削除) 39 (削除ここまで) 36 bytes
B9 02 08 12 20 99 42 A9 FE 42 3C 02 76 181A F68D C24A 0102 75D1 03E9 C10F E9AF 08C9 D1 E1 28 C8 77 EFED 4A 42 2C F1 7F 04 42 7B F8 4A 04 03 C3
This takes a 32-bit integer in EAX, following the regparm(1) convention. It returns two 32-bit integers in EAX and EDX; this document seems to say that this would be the standard way of returning a structure of two 32-bit integers, but it apparently doesn't actually work that way (or am I misreading that document?), which is why the linked TIO program is coded differently.
-3 by calculating line lengths instead of hardcoding them.
f: mov ecx, (2 | 8<<8 | 18<<16 | 32<<24)
cdq
inc edx
.byte 0xA9, 0xFE
a: inc edx
cmp al, 2
jbe e
testlea dlecx, [edx + 2]
shr ecx, 1
jnzimul secx, ecx
shrshl ecx, 81
s: sub al, cl
ja a
dec edx
b: inc edx
sub al, -15
jg t
inc edx
jpo b
dec edx
t: add al, 3
e: ret
- If AL ≤ 2 (in the first two columns), jump straight to the end.
- If EDX is odd, shift ECX right to advance to the next line length value.
- SubtractCalculate the length of the current line as (which is in CL)\$ \lfloor\frac{\textrm{line number} + 2}{2}\rfloor^2\cdot 2\$ and subtract it from AL.
- If the result is positive, jump back to repeat, moving to the next line.
- Otherwise, add a net +18 to AL and return.
x86 32-bit machine code, 39 bytes
B9 02 08 12 20 99 42 A9 FE 42 3C 02 76 18 F6 C2 01 75 03 C1 E9 08 28 C8 77 EF 4A 42 2C F1 7F 04 42 7B F8 4A 04 03 C3
This takes a 32-bit integer in EAX, following the regparm(1) convention. It returns two 32-bit integers in EAX and EDX; this document seems to say that this would be the standard way of returning a structure of two 32-bit integers, but it apparently doesn't actually work that way (or am I misreading that document?), which is why the linked TIO program is coded differently.
f: mov ecx, (2 | 8<<8 | 18<<16 | 32<<24)
cdq
inc edx
.byte 0xA9, 0xFE
a: inc edx
cmp al, 2
jbe e
test dl, 1
jnz s
shr ecx, 8
s: sub al, cl
ja a
dec edx
b: inc edx
sub al, -15
jg t
inc edx
jpo b
dec edx
t: add al, 3
e: ret
- If AL ≤ 2 (in the first two columns), jump straight to the end.
- If EDX is odd, shift ECX right to advance to the next line length value.
- Subtract the length of the current line (which is in CL) from AL.
- If the result is positive, jump back to repeat, moving to the next line.
- Otherwise, add a net +18 to AL and return.
x86 32-bit machine code, (削除) 39 (削除ここまで) 36 bytes
99 42 A9 FE 42 3C 02 76 1A 8D 4A 02 D1 E9 0F AF C9 D1 E1 28 C8 77 ED 4A 42 2C F1 7F 04 42 7B F8 4A 04 03 C3
This takes a 32-bit integer in EAX, following the regparm(1) convention. It returns two 32-bit integers in EAX and EDX; this document seems to say that this would be the standard way of returning a structure of two 32-bit integers, but it apparently doesn't actually work that way (or am I misreading that document?), which is why the linked TIO program is coded differently.
-3 by calculating line lengths instead of hardcoding them.
f: cdq
inc edx
.byte 0xA9, 0xFE
a: inc edx
cmp al, 2
jbe e
lea ecx, [edx + 2]
shr ecx, 1
imul ecx, ecx
shl ecx, 1
s: sub al, cl
ja a
dec edx
b: inc edx
sub al, -15
jg t
inc edx
jpo b
dec edx
t: add al, 3
e: ret
- If AL ≤ 2 (in the first two columns), jump straight to the end.
- Calculate the length of the current line as \$ \lfloor\frac{\textrm{line number} + 2}{2}\rfloor^2\cdot 2\$ and subtract it from AL.
- If the result is positive, jump back to repeat, moving to the next line.
- Otherwise, add a net +18 to AL and return.
x86 32-bit machine code, 39 bytes
B9 02 08 12 20 99 42 A9 FE 42 3C 02 76 18 F6 C2 01 75 03 C1 E9 08 28 C8 77 EF 4A 42 2C F1 7F 04 42 7B F8 4A 04 03 C3
This takes a 32-bit integer in EAX, following the regparm(1) convention. It returns two 32-bit integers in EAX and EDX; this document seems to say that this would be the standard way of returning a structure of two 32-bit integers, but it apparently doesn't actually work that way (or am I misreading that document?), which is why the linked TIO program is coded differently.
In assembly:
f: mov ecx, (2 | 8<<8 | 18<<16 | 32<<24)
cdq
inc edx
.byte 0xA9, 0xFE
a: inc edx
cmp al, 2
jbe e
test dl, 1
jnz s
shr ecx, 8
s: sub al, cl
ja a
dec edx
b: inc edx
sub al, -15
jg t
inc edx
jpo b
dec edx
t: add al, 3
e: ret
The main part of the code works as follows:
- If AL ≤ 2 (in the first two columns), jump straight to the end.
- If EDX is odd, shift ECX right to advance to the next line length value.
- Subtract the length of the current line (which is in CL) from AL.
- If the result is positive, jump back to repeat, moving to the next line.
- Otherwise, add a net +18 to AL and return.
Special cases are handled as follows:
sub al, -15is used to check for being in the extracted block and reused to adjust the horizontal position for elements in that block.- That check gives a false positive for elements 21 and 39 (the only ones in column 3). That is corrected for by looking at the parity flag after
inc edx; the incremented value is 5 (1012) or 6 (1102), with even parity, for elements 21 and 39, whereas it is 7 (1112) or 8 (10002), with odd parity, for elements that do belong in the extracted block. - Helium (2) is dealt with by
.byte 0xA9, 0xFE, which subsumes the following two instructions into atest eax, 0x023C42FE. The followingbecondition is (CF or ZF); CF is always 0 after atest, and in this case, ZF is 1 only for element 1.