Skip to main content
fix typos
Source Link
angel_p_57
  • 251
  • 3
  • 4
  • Exchange the position in code of the Lj code block and the Lc code block.
  • Replace relative backward jump instructions -ib, -iA in Lc code block to forward jumps +ib, `+iA+iA.
  • Omit the instruction +ii, which works to stoppingstop the code, from Lj code block.
    * The code stops in error when the instruction pointer points the dvars area just after the Lj code block.
  • Exchange the position in code of the Lj code block and the Lc code block.
  • Replace relative backward jump instructions -ib, -iA in Lc code block to forward jumps +ib, `+iA.
  • Omit the instruction +ii, which works to stopping the code, from Lj code block.
    * The code stops in error when the instruction pointer points the dvars area just after the Lj code block.
  • Exchange the position in code of the Lj code block and the Lc code block.
  • Replace relative backward jump instructions -ib, -iA in Lc code block to forward jumps +ib, +iA.
  • Omit the instruction +ii, which works to stop the code, from Lj code block.
    * The code stops in error when the instruction pointer points the dvars area just after the Lj code block.
Source Link
angel_p_57
  • 251
  • 3
  • 4

Aubergine, 225 bytes ( 222 bytes with error )

:Ba=aA-A1=ba-b1:BA-Ai+Ai+a1=bi=oA+a1:bA+a1+iA=a1-ii?		\0B*Fizz\0\0FBuzz\0[-aa=aA-aA+ai-ai=bi-bi+iA=ab-a1=oA=oB=bi-bi+B1+b1=oB+b1-aa:aB+ii=a1=aA+A1+A1-aa=aA-a1-a1=bA-a1-bA=Ab-ib-a1-AA-a1-AA-aa-a1-A1-a1=bA-a1-Ab-a1+A1-a1-iAo01


* four \0 mean NUL(ASCII 0) character

Try it online!

The equivalent pseudo code in C is like below;


#include <stdio.h>
#include <stdint.h>

#define I(x) ((intptr_t)&&x)
#define P(x) *(void*)(x)

static void nop(void) {}

int main(void) {
  intptr_t
    *cp,*cpt,t,p,
    pvars0[] =
      { I(Tj3)-I(Tj1), I(Tj2)-I(Tj1), I(Tj2)-I(Tj1), 0, I(Tc1)-I(Tj3),
        I(Lb), 3, 'F', 'i', 'z', 'z', 0, I(Lb)-I(Tx2), },
    pvars1[] =
      { I(Lj), 5, 'B', 'u', 'z', 'z', 0, I(Lc)-I(Tx2), },
    dvars[] = { I(Tc2)-I(Tj3), '0', '1', '\n', 10, },
    *pbase[] = { &pvars0[6], &pvars1[1] },
    *dbase3=&dvars[2], *dbase1=&dvars[4];
  int i=0;

Lx: // Fizz/Buzz print ( i=0 for Fizz, i=1 for Buzz )
  // decrement counter
  cp = pbase[i];
  *cp-=1;
  if ( *cp!=0 ) goto P(*(cp-1));  // skip printing and jump to Lb/Jj
  *cp+=3; // restore the counter to 3 ( add more 2 for Buzz in Lc )
  cp+=1;
  p=I(Tx1);
Tx1: // putchar loop
  putchar(*cp);
  cp+=1;
  if ( *cp!=0 ) goto P(p); // jump to Tx1
  goto P(I(Tx2)+*(cp+1)); // jump to Lb/Lc
Tx2:

Lb: // Buzz print
  i=1;
  goto Lx;

Lj: // number print and post process
  cp=pbase[0];
  // select &pvars[0] thru &pvars[2] as jump offset
  cp-=*cp;
  cp-=3;
  cpt=dbase3;
  goto P( I(Tj1)+*cp ); // jump to Tj3(when Fizz) or Tj1/Tj2
Tj1: // print the upper digit
  cp=cpt-1;
  putchar(*cp);
Tj2: // print the lower digit
  putchar(*cpt);
Tj3: // print a new line and increment the lower digit
  cp=dbase3;
  *cp+=1;
  cp+=1;
  putchar(*cp);
  cp+=1;
  i=0;
  if ( *cp!=0 ) goto Lx; // next iteration
  return 0; // exit

Lc: // after Buzz
  // add more 2 to the Buzz counter
  cp=pbase[1];
  *cp+=2;
  // switch pvars0[3] ( jump offset ) between 0 and pvars0[4]
  cp=pbase[0]-2;
  t=*cp;
  cp-=1;
  t-=*cp;
  *cp=t;
  goto P( I(Tc1)-t ); // jump to Tc1/Tj3
Tc1: // carry up
  // reset jump offsets in pvars[1],pvars[2]
  // so that the 1st "goto" in Lj jump to Tj1 instead of Tj2
  cp-=1;
  *cp=0;
  cp-=1;
  *cp=0;
  // decrement global loop counter
  cp=dbase1;
  *cp-=1;
  // decrease the lower digit by 10
  cp-=1;
  t=*cp;
  cp-=1;
  *cp-=t;
  // increment the upper digit
  cp-=1;
  *cp+=1;
  cp-=1;
  goto P(I(Tc2)-*cp); // jump to Tj3
Tc2:
  nop(); // not reached
}

Each code block handles;

  • Label Lx
    Print Fizz ( when i=0 ) or Buzz ( when i=1 ) if n is the multiple of 3 or 5.
  • Label Lb
    Just jump to Lx after setting i=1.
  • Label Lj
    Print n itself ( when Fizz or Buzz are not printed ) and do post-process.
  • Label Lc
    Carry-up operation.

In Aubergine code, each address range corresponds to;

  • 0 thru 2
    The 1st instruction :Ba has no effect, but stores pbase[].
    pbase[0] is ord(':')=58, pbase[1] is ord('B')=66.
  • 3 thru 50
    The code block with label Lx.
    Lx: =aA-A1=ba-b1:BA-Ai+Ai+a1=bi=oA+a1:bA+a1+iA, Tx1: =a1-ii
    * set i=0 ( -ii ) to implement goto Lx
  • 51
    A blank area.
  • 52 thru 72
    Stores pvars0[] and pvars1[]
  • 73 thru 135
    The code block with Label Lj.
    Lj: -aa=aA-aA+ai-ai=bi-bi+iA, Tj1: =ab-a1=oA, Tj2: =oB, TJ3: =bi-bi+B1+b1=oB+b1-aa:aB+ii
    The last instruction +ii jumps to an address out of range to stop the program.
  • 136 thru 219
    The code block with Label Lc.
    Lc: =a1=aA+A1+A1-aa=aA-a1-a1=bA-a1-bA=Ab-ib, Tc1: -a1-AA-a1-AA-aa-a1-A1-a1=bA-a1-Ab-a1+A1-a1-iA
  • 220 thru 224
    Stores dvars[]
    This area is accessed via minus addresses such as dbase1=-1 or dbase3=-3.

The 222 bytes version, which is shown below, outputs some error.

:Ba=aA-A1=ba-b1:BA-Ai+Ai+a1=bi=oA+a1:bA+a1+iA=a1-ii?		\0Q*Fizz\0\0\x9aBuzz\0=a1=aA+A1+A1-aa=aA-a1-a1=bA-a1-bA=Ab+ib-a1-AA-a1-AA-aa-a1-A1-a1=bA-a1-Ab-a1+A1-a1+iA-aa=aA-aA+ai-ai=bi-bi+iA=ab-a1=oA=oB=bi-bi+B1+b1=oB+b1-aa:aB$01


* \0 is NUL, and \x9a is a byte 232

This code cannot be run on TIO because TIO requires codes to be UTF-8 clean. ( a single \x9a is not valid as UTF-8 byte sequence )

The differences between 225B version and this 222B version are;

  • Exchange the position in code of the Lj code block and the Lc code block.
  • Replace relative backward jump instructions -ib, -iA in Lc code block to forward jumps +ib, `+iA.
  • Omit the instruction +ii, which works to stopping the code, from Lj code block.
    * The code stops in error when the instruction pointer points the dvars area just after the Lj code block.