Search

vendredi 3 mars 2017

Quine: optimization (5)

Context

Our quine is now fully functional, however it is really verbose. We can definitely improve this.
The global idea is that:
  • Code should be as short as possible (because it impacts size of course, but actually the main reason is because of the data generated from code, that is really verbose (average of  62 chars per instruction in code), so we should avoid too complex algorithms
  • Our data is generated from the source code's characters. Actually, even spaces, comments, line breaks, ... are kept. All these garbage characters are known as introns, and are sometimes very useful (especially writing multi-quines). But here, to shorten our code, we should definitely define another syntax for the data part and get rid of introns.
This will be the key point here. As all our code will be composed only by characters + - , . > < [ ], the one with smallest ASCII code being + (43), then we can definitely remove 42 to each code in the data (not 43, to ensure non-null items). Then, one instruction will use an average of 20 chars when encoded into data. A huge save, if we are able to adapt our code without too many changes

Initial state

  • Memory : empty
  • Cursor : first cell
  • Input : any

Process

  • Go 4 cells to the left, load (modified) data, then generate PLUS and GT, and print GT 4 times
  • Display data generation part : for each data cell
    • Print PLUS as many times as needed and copy value (same as before)
    • Print GT once (same as before)
    • Move GT (same as before)
    • Move PLUS and add it to the data cell at the same time.
  • Then, all the data generation part has been generated, and data itself have been modified, each cell value being equal to 43 plus its original value
  • Finally, go back to array start, and for each cell
    • subtract 1
    • print code
And to conclude, let's transform all the code after data loading into data definition, using the following rules
  • Char is not BF instruction : ignore
  • Char is BF instruction : return ASCII code minus 42

Code - quine skeleton

>>>>
(data that ends with >)
go to array start
<[<]
build PLUS and GT
<<<+++++++[->+++<]>[->++>+++<<]>+>-
print GT 4 times
....
go to first cell
>
[
  print PLUS as many times as needed and save current data value
  [-<<.<+>>>]
  print GT
  <.
  move symbol GT
  [->+<]
  move symbol PLUS and update data
  <[-<+>>+<]
  >>>
]
print code
<<<<[<]>[-.>]

Code - data generator (in BF as well) - try it

generate PLUS and GT
++++++[->++++++++++>+++++++<<]>++>+
read cell
>,[
  remove 42
  >++++++[-<------->]<
  print PLUS as many times as needed
  [-<.>]
  print GT
  <<.
  loop
  >>,
]

Code - final optimized quine - minified - try it

 >>>>++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++>++++++++++++++++++>++++++++++++++++++>+>+>+>+>+>+>+>+++++++++++++++++++++++++++++++++++++++++++++++++>+++>++++++++++++++++++++>+>+>+>++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++>+++>++++++++++++++++++++>+>+>++++++++++++++++++++>+>+>+>++++++++++++++++++>++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++>+>++++++++++++++++++++>+++>++++>++++>++++>++++>++++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++>+++>++++++++++++++++++>++++++++++++++++++>++++>++++++++++++++++++>+>++++++++++++++++++++>++++++++++++++++++++>++++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++>++++>+++++++++++++++++++++++++++++++++++++++++++++++++>+++>++++++++++++++++++++>+>++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++>+++>++++++++++++++++++>+>++++++++++++++++++++>++++++++++++++++++++>+>++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++>++++++++++++++++++++>++++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++>++++++++++++++++++>++++++++++++++++++>++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++>+++>++++>++++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++++><[<]<<<+++++++[->+++<]>[->++>+++<<]>+>-....>[[-<<.<+>>>]<.[->+<]<[-<+>>+<]>>>]<<<<[<]>[-.>]

Final state

  • Memory : all our quine code characters
  • Cursor : after the code characters
  • Input : unchanged
  • Output : initial source code

Note: this time, only 1892 bytes are used to write code, more than 65% less than the rough version !

Aucun commentaire:

Enregistrer un commentaire