Ecstatic

From Esolang
Jump to navigation Jump to search

Ecstatic is a Turing tarpit created by User:JWinslow23 in 2013. It is highly based off of MGIFOS and Unary, with one difference being that the instructions are different.

Syntax

To make programs in Ecstatic, first make a program in BF. Then, convert it to binary according to this table (the same table that CompressedFuck uses in fact).

BF Binary
+ 000
- 001
> 010
< 011
. 100
, 101
[ 110
] 111

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.

Examples

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.

Truth machine

The BF program ,.[.] would have 55,719 exclamation points.

Hello, World!

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.



































...Minor setback.

Implementations

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)))

See also