256

dc Programmes

dc (desk calculator) is a Unix command that performs arbitrary-precision calculations. It uses RPN (reverse polish notation), so the sum of 1 and 2 is expressed as 1 2 +. dc has just barely enough features to be Turing-complete, and is considered an esolang.

For whatever reason, I have tried to write some actual programmes in it over the years. Here they are.

Golden ratio

I tried to calculate the golden ratio with a binary search (which, it seems, is my go-to approach for calculating any mathematical constant). i used the mathematical function x/((1/x)+1), which approaches 1 as x approaches the golden ratio.

#!/bin/dc
# gold.dc
# 2023
#
# Binary search for the golden ratio.
67k
60si # Iterator variable; num of iterations to do.
1sb # Test value to use.
0.5sd # Difference to move by; halved each iteration.
[lb1lb/1+/]st # Function that tests value in b. Return is >1 if b>phi.
[lbpld+sbltx1<?ld2/sdli1-dsi0!=l]sl # Main loop.
[lbld-sb]s? # Conditional that un-does the incrementation by d.

llxq

I then tried to implement a different method, using linear interpolation. My idea was to take 2 points on either side of the proper value, draw a straight line between them, and then go to the middle of that line. This idea didn't work very well, in fact it seems to be even worse:

#!/bin/dc
# gold2.dc
# 2023
#
# More advanced search for the golden ratio.

67k
80si # Iterator variable; num of iterations to do.
1sa2sb # Upper and lower bounds.
[l-1l-/1+/]st # Function that tests value in -. Return is >1 if value > phi.

[
las-ltxsAlbs-ltxsB # now A = t(a) and B = t(b)
1lA/la*p # approximate n for which t(n) = 1
s-ltx # get t(n)
d1>r1<R # Assume they are never equal, as that only happens at infinity.

las-ltxsAlbs-ltxsB # now A = t(a) and B = t(b)
1lB/lb*p # approximate n for which t(n) = 1
s-ltx # get t(n)
d1>r1<R # Assume they are never equal, as that only happens at infinity.

li1-dsi0!=l]sl # Main loop.

[l-sa]sr
[l-sb]sR

llxq

Conway's Game of Life

#!/usr/bin/dc
0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0
1 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
8 # width
8 # height

sxsy
lxly*ss # s=size
0[ds_:wl_1+dls>F]dsFxs0 # load cell values into array 'w'

# transition table
#B0 1 2 3 4 5 6 7 8 (births)
  0 0 0 1 0 0 0 0 0
#S0 1 2 3 4 5 6 7 8
  0 0 1 1 0 0 0 0 0
2 # amount of rows in trans. table
9*[1-ds_:tl_d0<F]dsFxs0
# PRINT ------------------------------------------------------------------------
[1-dds_lx%d0=R0!=Sd0<Q]sQ # print world main loop
[l_;wps0]sR # print rightmost cell of row
[l_;wn]sS # print other ones
[lslQxs0]sP # print world
# SIMULATE ---------------------------------------------------------------------
[r[r]sFd0!>Fs0]sA # wrap around on -1 (top of stack=bound, below that=coord)
[ly1-lAxly%lx*rlx1-lAxlx%+;w]sC # get cell (torus; top of stack=y, below that=x)
[1-sv
lxlVxs0
lvd0<U]sU # for y
[1-sh # store x,y in h,v (horz., vert.) and get neighbours
lh1-lv1-lCx
lh  lv1-lCx+
lh1+lv1-lCx+
lh1-lv  lCx+
lh1+lv  lCx+
lh1-lv1+lCx+
lh  lv1+lCx+
lh1+lv1+lCx+
lhlvlCx # get center cell
9*+;t # look up new cell value in trans. table
lvlx*lh+:n
lhd0<V]sV # for x (h=x, v=y)
[[1-dd;nr:wd0<F]sFlslFxs0]sW # flush new generation (n) into old (w)
[lylUxs0lWx]sT # simulate tick
# ------------------------------------------------------------------------------
[Press RET to simulate a generation. Type and enter 'q' to quit. ]P
[?lTxlPxdx]dxq

Triangle fill

As Terry A. Davis said, "it's fucking algebra, nigger!"

Both this and life.dc were made in September 2020. The 6 numbers at the end specify the points of the triangle.

#!/usr/bin/dc
# REGISTERS ARE THE CRUTCH OF THE STACK-IMPAIRED MIND . . .
16 16 # width, height
# b=buffer
sxdsylx*dss # s=size
[1-d0r:bd0<F]dsFxs0 # init b
# RENDER -----------------------------------------------------------------------
[       3k# returns (m=(ax-bx)/(ay-by)|c=(ax-m*ay))
        dS_r-S- # -=ax-bx
        dS_r-L-r/
        dL_*L_r-
0k]sS # calculate slope and offset of line defined by 2 points (ax|bx|ay|by)
[r]sR
[2Q]sQ
[S_[dl_<Qd1r:b1+lFx]dsFxL_s0s0]sL # draw horizontal line (right|left)
[[      lilx*d # index to beg. of row
        # c,m = offset,slope of left line; C,M = right line
        lilm*lc+ .5+d1%- +r # calculate coord of left edge
        lilM*lC+ .5+d1%- + # right edge
        lLx # draw row
        li1+dsil.>J
]sJsiS.lJxL.s0
]sG # Draw section of triangle from top to bot with lines cm,CM (top|bot)
[       0k
        s1s2 s3s4 s5s6 # 12=a, 34=b, 56=c (all are xy)
        # cycle points until a is at the top
        [l6l5l4l3l2l1s5s6s1s2s3s4 l2l4<F l2l6<F]dsFx
        #TODO: make by this point invariant: ay<=by && ay<=cy
        l2d1%-s^ # top y value
        l4d1%-s- # mid y value
        l6d1%-s_ # bot. y value
        [l_l-s_s-]sFl_l->F # swap mid and bot if they're ordered wrong
        [       l4l2l3l1lSxscsm # draw triangle from top to mid (if ay<mid)
                l6l2l5l1lSxsCsM
                l-l^lGx
        ]sH l-l2<H
        [       l6l4l5l3lSxscsm # draw triangle from mid to bot (if by<cy)
                l2l6l1l5lSxsCsM
                l_l-lGx
        ]sH l6l4<H
        [       l4l2l3l1lSxscsm # draw triangle from mid to bot (if cy<by)
                l4l6l3l5lSxsCsM
                l_l-lGx
        ]sH l4l6<H
]sT # draw triangle (ax|ay|bx|by|cx|cy)
# SHOW -------------------------------------------------------------------------
[       [[]pn]sG # print newline
        0k # modulo works weird when precision is above 0
        0[d;bn1+dlx%0=Gdls>F]dsFx
]sP # print buffer as plaintext
#........
#...b....
#........
#........
#.c......
#.......a
#........
#........
4 1 1 3 6 7
#5 7 4 1 1 3
#6 12 14 1 1 3
lTx
lPxq

About | Contact Me | Index
Page last modified on 2026-04-03.