Move to the printable ASCII front Background

The move-to-front transform (MTF) is a data encoding algorithm designed to improve the performance of entropy encoding techniques.

In the bzip2 compression algorithm, it is applied after the Burrows–Wheeler transform (as seen in Burrows, Wheeler and Back), with the objective of turning groups of repeated characters into small, easily compressible non-negative integers.

Definition

For the purpose of this challenge, we'll define the printable ASCII version of the MTF as follows:

Given an input string s, take an empty array r, the string d of all printable ASCII characters (0x20 to 0x7E) and repeat the following for each character c of s:


Append the index of c in d to r.
Move c to the front of d, i.e., remove c from d and prepend it to the remainder.


Finally, we take the elements of r as indexes in the original d and fetch the corresponding characters.

Step-by-step example

INPUT: "CODEGOLF"

0. s = "CODEGOLF"
   d = " !\"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = []
1. s = "ODEGOLF"
   d = "C !\"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35]
2. s = "DEGOLF"
   d = "OC !\"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABDEFGHIJKLMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47]
3. s = "EGOLF"
   d = "DOC !\"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABEFGHIJKLMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47 37]
4. s = "GOLF"
   d = "EDOC !\"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABFGHIJKLMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47 37 38]
5. s = "OLF"
   d = "GEDOC !\"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABFHIJKLMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47 37 38 40]
6. s = "LF"
   d = "OGEDC !\"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABFHIJKLMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47 37 38 40 3]
7. s = "F"
   d = "LOGEDC !\"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABFHIJKMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47 37 38 40 3 45]
8. s = ""
   d = "FLOGEDC !\"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABHIJKMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47 37 38 40 3 45 41]

OUTPUT: "COEFH#MI"


Task

Write a program or function that implements the printable ASCII MTF (as defined above).

Test cases

Input:  Programming Puzzles &amp; Code Golf
Output: Prpi"do lp%((uz rnu&amp;3!P/o&amp;$U$(p

Input:  NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN BATMAN!
Output: Na! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !!"DDUP"%'

Input:  Two more questions and I have bzip2 in less than 100 bytes!
Output: Twp#o"si$sv#uvq(u$(l#o#W!r%w+$pz,xF%#,"x(. #0--'$GG ".z(**:


Additional rules


You cannot use any built-in operator that computes the MTF of a string.
Your code may print a trailing newline if you choose STDOUT for output.
Your code has to work for any input of 1000 or less printable ASCII characters (0x20 to 0x7E).
Standard code golf rules apply. The shortest submission in bytes wins.
Ostrich, 46 45 chars

Don't have a version number in the header because this is actually just the latest commit. I added the O (ascii code to string) operator after releasing the latest version (but still before this challenge was posted).

{a95,{32+O}%:d3@{:x\.3@?3@\+\x-x\+}/;{d=}%s*}


Explanation:

a             this is the "r" array (a is short for [], empty array)
95,{32+O}%:d  this is the "d" array
3@{...}/      for each character in the input (as an "argument")...
  :x            store in variable x (stack is now [r d c])
  \.3@?         find index in d     (stack is now [r d idx])
  3@\+          append index to r   (stack is now [d modified_r])
  \x-           remove char from d, and then...
  x\+           prepend char to d   (stack is now [modified_r modified_d])
;             throw away modified_d
{d=}%         map r to indices of (original) d
s*            join (s is short for ``, empty string)