We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.

Trigbf

From Esolang
Jump to navigation Jump to search
Trigbf
Paradigm(s) procedural, imperative
Designed by User:None1
Appeared in 2025
Memory system Cell-based
Dimensions one-dimensional
Computational class Turing complete/FSA
Major implementations Python
Dialects Trigbf0 - Trigbf7
Influenced by brainfuck
File extension(s) .tbf

Trigbf is an esolang invented by User:None1, inspired by brainfuck.

Trigbf is also known as Trigbf7, you'll know why in the Dialects section.

Memory

Trigbf uses an unbounded (in both directions) tape which contains signed unbounded infinite-precision real numbers. Initially, every cell is zero.

Commands

Trigbf has these commands:

  • ,.><[]: The same as bf, except ., which rounds before printing as ASCII. Brackets use exact comparison.
  • s: Let current cell value be x. x becomes sin(x rad) after the command.
  • c: Let current cell value be x. x becomes cos(x rad) after the command.
  • t: Let current cell value be x. x becomes tan(x rad) after the command. It is undefined behavior to run this command when current cell is an invalid value for tangent (e.g.: pi/2).

Dialects

Trigbf has 8 dialects: Trigbf0 to Trigbf7. After converting the dialect number (0~7) to a big-endian binary number, the 1st, 2nd and 3rd digits decide whether the s, c and t commands are available: 0 if unavailable, 1 if available. The original Trigbf has all three commands, so it's also known as Trigbf7.

Examples (In Trigbf7)

Most text-printing examples are generated by the following code generator in Python:

"""
Trigbf code generator improved:
- It uses bruteforce (IDDFS), so it always generates the shortest code for every character.
- It caches both internally and externally, so you won't have to generate the same character multiple times.
"""
from mpmath import *
from json import *
mp.dps=100
dic={}
try:
    with open('tbfgen_cache.json','r') as f:
        dic={int(i):j for i,j in load(f).items()}
except:
    pass
def recur(n,s,c,v):
    if len(s)==n:
        if abs(v-c)<=mpf(0.5):
            return s
        else:
            return
    w=recur(n,s+'s',c,sin(v))
    if w:
        return w
    w=recur(n,s+'c',c,cos(v))
    if w:
        return w
    w=recur(n,s+'t',c,tan(v))
    if w:
        return w
def cgen(c):
    if c in dic:
        return dic[c]
    l=0
    while 1:
        print(f'Brute-forcing strings of length: {l+1}')
        w=recur(l,'',c,1)
        if w:
            dic[c]='c'+w
            with open('tbfgen_cache.json','w') as f:
                dump(dic,f)
            return 'c'+w
        l+=1
def sgen(s):
    ans=''
    for i in s:
        print(f'Generating character: {i}')
        ans+=cgen(ord(i))
        ans+='.>'
    return ans[:-1]
string=input('Enter string: ')
print(sgen(string))
with open('tbfgen_cache.json','w') as f:
    dump(dic,f)

Cat

c[,.]

or:

,[.,]

Hello, world!

A program by User:Blashyrkh that works even without multi-precision math libraries:

cststtctcctt.>cststtcsccttt.>csttttcsccttt..>>ccsstcstttsttt.>cccscstttt.>ccsscsttstt.>ccctstsccccttt.<<<.<csccttt.<.<<<cccccsssscccttt.<csstctcttstt.<ccsscsttt.

Nope.

cscctsctttt.>ccsstcstttsttt.>ctssccttt.>cststtcsccttt.>cssctttsctt.

XKCD Random Number

cssscttstt.

HI!

csscttsttctt.>ctstt.>csstctcttstt.

Computational class

Dialects without the c command are FSAs because they can't do anything to the tape, making the tape useless.

Dialects with the c command are Turing-complete because brainfuck is Turing-complete even if only changing 0s into 1s is allowed.

Interpreter (Trigbf7 dialect)

In Python, requires the mpmath library and is used by Interpret Esolangs Online:

import sys
from mpmath import *
mp.dps=100 # 100 digits should be enough
def tbf(code):
    s=[]
    matches={}
    tape=[mpf(0)]*2000000
    for i,j in enumerate(code):
        if j=='[':
            s.append(i)
        if j==']':
            m=s.pop()
            matches[m]=i
            matches[i]=m
    cp=0
    p=1000000
    while cp<len(code):
        if code[cp]=='s':
            tape[p]=sin(tape[p])
        if code[cp]=='c':
            tape[p]=cos(tape[p])
        if code[cp]=='t':
            tape[p]=tan(tape[p])
        if code[cp]==',':
            c=sys.stdin.read(1)
            tape[p]=(ord(c) if c else 0)%256
        if code[cp]=='.':
            print(chr(int(round(tape[p],0))),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
tbf(sys.stdin.read())

There's also an alternate implementation by User:I am islptng, which requires SymPy and should be absolutely correct in theory.

See also