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.

As every bit in the image counts, you must use lossless image formats, like PNG.

Example Programs

Cat Program

The cat program in this esolang is 1 pixel large

Enlarged view

Pocketfuck cat program

Actual size

Pocketfuck cat program

Hello World

Enlarged view

Pocketfuck hello world

Actual size

Pocketfuck hello world

XKCD Random Number

Enlarged view

Pocketfuck XKCD Random Number

Actual size

Pocketfuck XKCD Random Number

Nope. interpreter

Enlarged view

Pocketfuck Nope. interpreter

Actual size

Pocketfuck Nope. interpreter

Truth Machine

Enlarged view

Pocketfuck Truth Machine

Actual size

Pocketfuck Truth Machine

dbfi based brainfuck interpreter

Enlarged view

Pocketfuck Brainfuck interpreter

Actual size

Pocketfuck Brainfuck interpreter

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.

See also