Skip to main content
golfing
Source Link
anatolyg
  • 13.9k
  • 2
  • 39
  • 110

x86 machine code, 2929 27 bytes

Hexdump:

33 c0 40 41 80 79 ff 61 74 f8 48 41 80 79 fe 62
74 f8 0a 41 fe 91f7 33d8 1b c0 40 e3 01 48 c3

Assembly code:

    xor eax, eax;
loop1:
    inc eax;
    inc ecx;
    cmp byte ptr [ecx-1], 'a';
    je loop1;

loop2:
    dec eax;
    inc ecx;
    cmp byte ptr [ecx-2], 'b';
    je loop2;

    or al, [ecx-2];
    xchg ecx,neg eax;
    xorsbb eax, eax;
    inc eax;
    jecxz done;
    dec eax;
done:
    ret;

Iterates over the a bytes in the beginning, then over the following 'b' bytes. The first loop increases a counter, and the second loop decreases it. Afterwards, does a bitwise OR between the following conditions:

  1. If the counter is not 0 at the end, the string doesn't match
  2. If the byte that follows the sequence of bs is not 0, the string also doesn't match

Then, it has to "invert" the truth value in eax - set it to 0 if it was not 0, and vice versa. It turns out that the shortest code to do that is the following 75-byte code, which I stole from the output of my C++ compiler for result = (result == 0):

    xchg ecx,neg eax; // move eax to ecx; use "xchg" because it's 1-byte
    xor// eax,negate eax;  // set eaxC toflag 0
to 1 if it incwas eax;nonzero
    sbb eax, eax; // increasesubtract eax and set it to 1
    jecxz done;    // ifthe ecxC isflag 0,from doneeax
    decinc eax;       // otherwise, decreaseincrease eax and set it back to 0
done:

x86 machine code, 29 bytes

Hexdump:

33 c0 40 41 80 79 ff 61 74 f8 48 41 80 79 fe 62
74 f8 0a 41 fe 91 33 c0 40 e3 01 48 c3

Assembly code:

    xor eax, eax;
loop1:
    inc eax;
    inc ecx;
    cmp byte ptr [ecx-1], 'a';
    je loop1;

loop2:
    dec eax;
    inc ecx;
    cmp byte ptr [ecx-2], 'b';
    je loop2;

    or al, [ecx-2];
    xchg ecx, eax;
    xor eax, eax;
    inc eax;
    jecxz done;
    dec eax;
done:
    ret;

Iterates over the a bytes in the beginning, then over the following 'b' bytes. The first loop increases a counter, and the second loop decreases it. Afterwards, does a bitwise OR between the following conditions:

  1. If the counter is not 0 at the end, the string doesn't match
  2. If the byte that follows the sequence of bs is not 0, the string also doesn't match

Then, it has to "invert" the truth value in eax - set it to 0 if it was not 0, and vice versa. It turns out that the shortest code to do that is the following 7-byte

    xchg ecx, eax; // move eax to ecx; use "xchg" because it's 1-byte
    xor eax, eax;  // set eax to 0
    inc eax;       // increase eax and set it to 1
    jecxz done;    // if ecx is 0, done
    dec eax;       // otherwise, decrease eax and set it back to 0
done:

x86 machine code, 29 27 bytes

Hexdump:

33 c0 40 41 80 79 ff 61 74 f8 48 41 80 79 fe 62
74 f8 0a 41 fe f7 d8 1b c0 40 c3

Assembly code:

    xor eax, eax;
loop1:
    inc eax;
    inc ecx;
    cmp byte ptr [ecx-1], 'a';
    je loop1;

loop2:
    dec eax;
    inc ecx;
    cmp byte ptr [ecx-2], 'b';
    je loop2;

    or al, [ecx-2];
    neg eax;
    sbb eax, eax;
    inc eax;
done:
    ret;

Iterates over the a bytes in the beginning, then over the following 'b' bytes. The first loop increases a counter, and the second loop decreases it. Afterwards, does a bitwise OR between the following conditions:

  1. If the counter is not 0 at the end, the string doesn't match
  2. If the byte that follows the sequence of bs is not 0, the string also doesn't match

Then, it has to "invert" the truth value in eax - set it to 0 if it was not 0, and vice versa. It turns out that the shortest code to do that is the following 5-byte code, which I stole from the output of my C++ compiler for result = (result == 0):

    neg eax;      // negate eax; set C flag to 1 if it was nonzero
    sbb eax, eax; // subtract eax and the C flag from eax
    inc eax;      // increase eax
Source Link
anatolyg
  • 13.9k
  • 2
  • 39
  • 110

x86 machine code, 29 bytes

Hexdump:

33 c0 40 41 80 79 ff 61 74 f8 48 41 80 79 fe 62
74 f8 0a 41 fe 91 33 c0 40 e3 01 48 c3

Assembly code:

    xor eax, eax;
loop1:
    inc eax;
    inc ecx;
    cmp byte ptr [ecx-1], 'a';
    je loop1;

loop2:
    dec eax;
    inc ecx;
    cmp byte ptr [ecx-2], 'b';
    je loop2;

    or al, [ecx-2];
    xchg ecx, eax;
    xor eax, eax;
    inc eax;
    jecxz done;
    dec eax;
done:
    ret;

Iterates over the a bytes in the beginning, then over the following 'b' bytes. The first loop increases a counter, and the second loop decreases it. Afterwards, does a bitwise OR between the following conditions:

  1. If the counter is not 0 at the end, the string doesn't match
  2. If the byte that follows the sequence of bs is not 0, the string also doesn't match

Then, it has to "invert" the truth value in eax - set it to 0 if it was not 0, and vice versa. It turns out that the shortest code to do that is the following 7-byte

    xchg ecx, eax; // move eax to ecx; use "xchg" because it's 1-byte
    xor eax, eax;  // set eax to 0
    inc eax;       // increase eax and set it to 1
    jecxz done;    // if ecx is 0, done
    dec eax;       // otherwise, decrease eax and set it back to 0
done: