PocketFuck+

From Esolang
Jump to navigation Jump to search

PocketFuck+ is an improved version of PocketFuck 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, 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 32 by 32 (If the number of bits is not divisible, add zeros until it is), every 24 bits stands for the RGBA value (e.g.: 10011010110011100000000011111111 becomes (154, 206, 0, 255)) 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 that support RGBA, like PNG.

Example Programs

Cat Program

The cat program in this esolang is 1 pixel large and colorless.

Enlarged view

Pocketfuck cat program

Actual size

Pocketfuck cat program

Hello World

Enlarged view

Pocketfuck hello world

Actual size

Pocketfuck hello world

1px less than PocketFuck.

Nope. interpreter

Enlarged view

Pocketfuck Nope. interpreter

Actual size

Pocketfuck Nope. interpreter

2px less than PocketFuck.

XKCD Random Number

Enlarged view

Pocketfuck XKCD Random Number

Actual size

Pocketfuck XKCD Random Number

Interpreter

Python

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))%32)
    pixels=[]
    for i in range(len(s)//32):
        pixels.append([int(s[i*32:i*32+8],2),int(s[i*32+8:i*32+16],2),int(s[i*32+16:i*32+24],2),int(s[i*32+24:i*32+32],2)])
    return Image.fromarray(np.array([pixels],dtype=np.uint8))
def pf2bf(pf):
    prog=''
    tmp=''
    if pf.mode!='RGBA':
        print('PocketFuck+ only supports RGBA 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])))

See also