PocketFuck

From Esolang
Jump to navigation Jump to search

PocketFuck is an image version of brainfuck by User:None1. Programs in this esolang are small enough to be put in your pocket!

How to write Programs

To write a program in PocketFuck, first write a program in brainfuck, and pad it in the end with the + instruction until the number of instructions is divisible by 8, then convert every instruction into 3 binary bits using the table below.

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

Then group the binary bits 24 by 24, every 24 bits stands for the RGB value (e.g.: 100110101100111000000000 becomes (154, 206, 0)) of a pixel in the image. Finally, arrange the pixels into an image, starting from the top left corner, going right then restarting at the next line from the left.

Unlike other brainfuck-based image esolangs, PocketFuck uses every bit in every pixel to store instructions, allowing it to be very space-efficient.

Example Programs

Cat Program

The cat program in this esolang is 1 pixel long

Enlarged view

{{{2}}}

Actual size

{{{2}}}

Hello World

Enlarged view

{{{2}}}

Actual size

{{{2}}}

XKCD Random Number

Enlarged view

{{{2}}}

Actual size

{{{2}}}

Nope. interpreter

Enlarged view

{{{2}}}

Actual size

{{{2}}}

Truth Machine

Enlarged view

{{{2}}}

Actual size

{{{2}}}

Turing completeness

Since brainfuck is Turing complete, this esolang is also Turing complete.

Interpreters

The following is the official interpreter in Python, which also provides conversion from and to brainfuck.

from PIL import Image
import numpy as np
import sys
def bf(code):
    s1=[]
    s2=[]
    matches={}
    tape=[0]*1000000
    for i,j in enumerate(code):
        if j=='[':
            s1.append(i)
        if j==']':
            m=s1.pop()
            matches[m]=i
            matches[i]=m
    cp=0
    p=0
    while cp<len(code):
        if code[cp]=='+':
            tape[p]=(tape[p]+1)%256
        if code[cp]=='-':
            tape[p]=(tape[p]-1)%256
        if code[cp]==',':
            ch=sys.stdin.read(1)
            tape[p]=(ord(ch) if ch else 0)%256
        if code[cp]=='.':
            print(chr(tape[p]),end='')
        if code[cp]=='<':
            p-=1
        if code[cp]=='>':
            p+=1
        if code[cp]=='[':
            if not tape[p]:
                cp=matches[cp]
        if code[cp]==']':
            if tape[p]:
                cp=matches[cp]
        cp+=1
def bf2pf(bf):
    f='+-><,.[]'
    s=''
    for i in bf:
        s+='{:03b}'.format(f.index(i))
    s=s+'0'*((-len(s))%24)
    pixels=[]
    for i in range(len(s)//24):
        pixels.append([int(s[i*24:i*24+8],2),int(s[i*24+8:i*24+16],2),int(s[i*24+16:i*24+24],2)])
    return Image.fromarray(np.array([pixels],dtype=np.uint8))
def pf2bf(pf):
    prog=''
    tmp=''
    if pf.mode!='RGB':
        print('PocketFuck only supports RGB images')
        return ''
    dat=pf.tobytes()
    for i in dat:
        tmp+='{:08b}'.format(i)
    for i in range(len(tmp)//3):
        prog+='+-><,.[]'[int(tmp[i*3:i*3+3],2)]
    return prog
if __name__=='__main__':
    bf(pf2bf(Image.open(sys.argv[1])))

It requires the Python Imaging Library and NumPy.