Note that, processing a brainfuck program from start to end, each new bit group must be appended to the least significant position of the accumulating bit sequence.
Then, stick 001 at the beginning (this is not counted as a command), or most significant position, and convert to decimal. Then, write that number of exclamation points.
Cat program (one time input)
The BF program
,. would have 108 exclamation points.
Cat program (looped)
The BF program
,[.,] would have 56,623 exclamation points.
The BF program
,.[.] would have 55,719 exclamation points.
To print "Hello, world!" with the brainfuck program
-[------->+<]>-.-[->+++++<]>++.+++++++..+++.[->+++++<]>+.------------.--[->++++<]>-.--------.+++.------.--------.-[--->+<]>. you would need 11,745,396,970,761,548,557,844,427,413,766,327,995,589,772,739,314,086,919,355,093,720,961,223,541,738,614,442,550,691,210,954,782,889,076,179,929,044 exclamation points.
The following Common Lisp functions implement the conversion from brainfuck to Ecstatic and vice versa, additionally elucidating some principles utilized in the encoding and decoding processes:
(defun convert-brainfuck-to-binary (brainfuck-code) "Encodes the BRAINFUCK-CODE as a binary sequence according to the rules of Ecstatic and returns the same as an unsigned integer value." (declare (type string brainfuck-code)) (let ((binary 0) (binary-position 0)) (declare (type unsigned-byte binary binary-position)) (flet ((append-bits (bits) (declare (type (unsigned-byte 3) bits)) (setf binary (ash binary 3)) (setf (ldb (byte 3 0) binary) bits) (incf binary-position 3)) (prepend-bits (bits) (declare (type (unsigned-byte 3) bits)) (setf (ldb (byte 3 binary-position) binary) bits) (incf binary-position 3))) (loop for character of-type character across brainfuck-code do (case character (#\+ (append-bits #b000)) (#\- (append-bits #b001)) (#\> (append-bits #b010)) (#\< (append-bits #b011)) (#\. (append-bits #b100)) (#\, (append-bits #b101)) (#\[ (append-bits #b110)) (#\] (append-bits #b111)) (T NIL)) finally (prepend-bits #b001))) (the unsigned-byte binary))) (defun convert-brainfuck-to-ecstatic (brainfuck-code &optional (destination T)) "Converts the BRAINFUCK-CODE into Ecstatic code and writes the latter to the DESTINATION." (declare (type string brainfuck-code) (type (or null (eql T) stream string) destination)) (if destination (let ((number-of-exclamations (convert-brainfuck-to-binary brainfuck-code))) (declare (type (integer 0 *) number-of-exclamations)) (loop repeat number-of-exclamations do (write-char #\! destination))) (with-output-to-string (output) (declare (type string-stream output)) (convert-brainfuck-to-ecstatic brainfuck-code output)))) (defun convert-binary-to-brainfuck (binary &optional (destination T)) "Decodes an Ecstatic-compatible binary sequence and writes the resulting brainfuck code to the DESTINATION." (declare (type unsigned-byte binary) (type (or null (eql T) stream string) destination)) (if destination (let ((binary-length (integer-length binary))) (declare (type (integer 0 *) binary-length)) (when (or (zerop binary) (not (zerop (mod (1- binary-length) 3)))) (error "Invalid binary sequence: '~v,'0b'." binary-length binary)) (loop for bit-position of-type integer from (- binary-length 4) downto 0 by 3 for bit-group of-type (unsigned-byte 3) = (ldb (byte 3 bit-position) binary) do (case bit-group (#b000 (write-char #\+ destination)) (#b001 (write-char #\- destination)) (#b010 (write-char #\> destination)) (#b011 (write-char #\< destination)) (#b100 (write-char #\. destination)) (#b101 (write-char #\, destination)) (#b110 (write-char #\[ destination)) (#b111 (write-char #\] destination)) (T (error "Invalid bit group: '~3,'0b'." bit-group))))) (with-output-to-string (output) (declare (type string-stream output)) (convert-binary-to-brainfuck binary output)))) (defun convert-ecstatic-to-brainfuck (ecstatic-code &optional (destination T)) "Converts the ECSTATIC-CODE to brainfuck code, which is then written to the DESTINATION." (declare (type string ecstatic-code) (type (or null (eql T) stream string) destination)) (let ((number-of-exclamations (count #\! ecstatic-code :test #'char=))) (declare (type unsigned-byte number-of-exclamations)) (convert-binary-to-brainfuck number-of-exclamations destination)))
- Common Lisp implementation of the Ecstatic programming language, including an interpreter as well as conversion routines betwixt the language and brainfuck.