User:Albedo: Difference between revisions
m (→Ackermann Function: missing word) |
|||
Line 495: | Line 495: | ||
A(0,2) = 3 ,A(m,n)= n+1 if m=0 |
A(0,2) = 3 ,A(m,n)= n+1 if m=0 |
||
The coefficients and the results can found |
The coefficients and the results can be found on the stack. See the places marked with square brackets [] and Labels in the program/stack flow above. |
||
At each turn, the upper two values on the stack are flipped, so they are in the proper order for computing inner functions. For highly nested A(...,(A(A(A(...))))) functions the stack can grow to enormous proportions very fast, then computing its way outwards again, from innermost functions outwards. The innermost coefficients are always on top of the stack. |
At each turn, the upper two values on the stack are flipped, so they are in the proper order for computing inner functions. For highly nested A(...,(A(A(A(...))))) functions the stack can grow to enormous proportions very fast, then computing its way outwards again, from innermost functions outwards. The innermost coefficients are always on top of the stack. |
||
Revision as of 01:20, 18 July 2015
My Favorite Languages | |
Language | Proficiency |
Piet | Intermediate |
Julia | Beginner |
Cardinal | Intermediate |
There aren’t any ways to upload images at the moment, so all examples are rendered as wikitables. See my PNG to wikitable conversion code written in Julia at the bottom of the page.
Explanation of shorthand code for Piet examples
To shrink down the size of larger problems, I invented a shorthand text version for explaining the general program flow in a more compact form:
NOP ADD DIV GRT DUP INC END . + / > = c ~ PSH SUB MOD PTR ROL OUN X - % # @ N POP MUL NOT SWI INN OUC ? * ! $ n C
Ackermann Function
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
Program flow (see explanation of the shorthand codes at the top of the page), with labels:
l1 l3 ↓ ↓ 1X2X-nn2X1X@=1X=->!#2X1X@=1X=- . l2→? > . 2 ! ................X1-X1?# . X l4↑2←l5 . 1 X . X 1 . @ X . = @ . 1 = . ~ X 3 . N = X . + - 1 . X 2 X . 1 X @ . l6→? 1 1 .+X1@X1X2#>@X X . l7↑ - ...............-X1@X1X3
Explanation with stack for the Ackermann Function(2,0):
(for the meaning of the square brackets, please read below)
[A] [B] 1 1 1 1 1 0 1 1 1 0 2 2 2 2 2 2 1 0 2 2 0 0 0 0 0 1 0 0 0 [2] 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0 1 [1] 2 2 2 2 2 [0] 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 1 [1] 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ——————————————————————————————————————————————————————————————————————————————————————— 1X2X - n n 2X 1X @ = 1X = - > ! # 2X 1X @ = 1X = - > ! # ? 1X - 1X ↑ ↑ ↑ l1 l3 l4 --------------------------------------------------------------------------------------- explanation: correct order m>0? yes n>0? no A(m-1,1) of m,n
[B] [C] 1 1 1 1 1 1 1 0 1 1 1 0 1 3 3 1 3 3 1 2 2 1 1 1 1 1 0 2 2 1 1 1 1 1 0 2 2 1 1 1 1 1 0 0 0 1 1 [0] 1 1 [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 [1] 1 1 [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 [0] -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 —————————————————————————————————————————————————————————————————————————————————————————————————————— 2X 1X @ = 1X = - > ! # 2X 1X @ = 1X = - > ! # 2X 1X @ = 3X 1X @ 1X - 3X 1X @ 1X - ↑ ↑ ↑ l1 l3 l5 ------------------------------------------------------------------------------------------------------- correct order m>0? yes n>0? yes A(m-1,A(m,n-1)) of m,n
[D] 1 1 1 1 1 1 0 1 1 1 0 1 1 0 2 2 1 1 1 1 1 0 2 2 0 0 0 0 0 1 2 2 0 0 0 0 0 1 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 [1] 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 [0] 0 0 1 1 1 1 1 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 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ————————————————————————————————————————————————————————————————————————————————————————————————————— 2X 1X @ = 1X = - > ! # 2X 1X @ = 1X = - > ! # ? 1X - 1X 2X 1X @ = 1X = - > ! # ↑ ↑ ↑ ↑ l1 l3 l4 l1 ----------------------------------------------------------------------------------------------------- correct order m>0? yes n>0? no A(m-1,1) correct order m>0? of m,n for inner inner for inner f. function function
1 1 2 2 1 1 1 1 0 0 0 0 1 1 1 1 0 2 2 0 0 0 0 0 0 0 0 2 2 1 2 2 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 2 2 2 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 2 2 2 2 2 2 2 2 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ——————————————————————————————————————————————————————————————————————————————————— ? 2X 1X @ = 1X = - 2X 1X @ > # 2X 1X @ 1X + 2X 1X @ = 1X = - > ! # ↑ ↑ ↑ l2 l7 l1
output 3 ————————————————————————————————————————————————————— 1 1 2 2 1 1 1 0 0 0 -1 2 2 -1 -1 -1 -1 -1 -1 0 1 2 2 2 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 -1 -1 -1 2 2 2 2 2 2 2 2 2 2 2 2 3 ————————————————————————————————————————————————————— ? 2X 1X @ = 1X = - 2X 1X @ > # ? 1X + N ~ ↑ ↑ l2 l6
Which leads to the result Ackermann(2,0) = 3
What the program actually does is working through the whole steps of calculating the A(m,n) functions, according to:
A(2,0) = A(1,1) ,A(m,n)= A(m-1,1) if m>0 and n=0 A(1,1) = A(0,A(1,0)) ,A(m,n)= A(m-1,A(m,n-1)) if m>0 and n>0 A(0,A(1,0)) = A(0,A(0,1)) ,A(m,n)= A(m,n-1) if m>1 and n=0, for the inner function A(0,A(0,1)) = A(0,2) ,A(m,n)= n+1 if m=0, for the inner function A(0,2) = 3 ,A(m,n)= n+1 if m=0
The coefficients and the results can be found on the stack. See the places marked with square brackets [] and Labels in the program/stack flow above. At each turn, the upper two values on the stack are flipped, so they are in the proper order for computing inner functions. For highly nested A(...,(A(A(A(...))))) functions the stack can grow to enormous proportions very fast, then computing its way outwards again, from innermost functions outwards. The innermost coefficients are always on top of the stack.
Checks for the appropriate substitute function and branching structures take the largest part of the program.
Binary Digits
png image download:
[Image:https://copy.com/Ixp3nc7QJQTCrcDb]
Rendered as wikitable
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww | ww |
Example output:
? 3 11 ? 13 1101
Program flow (explanation of codes at the top of the page):
2Xn=2X/=1X!>#?N=1X . . 2 . > . @ X . . . X1X2%X2@X1 . . ? . . C+=X5............# . . ....
Example, with stack and output, for base-10 number 3:
1 1 \n | Output ———————————————————————————————————————————————————————————+——————— 10 | Stack 10 1 1 2 0 000 | 2 1 111 2 2 2 2 2 1 100 0000 1 | 3 311 1111 1 13 31 1 111 111 11111 1 10 1 5 | 33 333 3333 3 31 11 1 111 111 1111111 111 2 21 55 10 | 222 222 2222 2 22 22 2 222 222 2222222 22222 222 22 2 2 | ———————————————————————————————————————————————————————————+ 2Xn=2X/=1X!>#2X1X@2X%2X1X@=2X/=1X!>#?N=1X>#N=1X>#5X= + C ? ... 2Xn=2X ... (return to beginning)
The program executes short division with remainder.
l0: 2X : acts as marker for the end of the binary output n : input base-10 number l1: = : duplicate number 2X/= : divide n by 2 and duplicate the result 1X!>#: is the result >0? (is n>=2?) It is, thus rotate the pointer by 1 (downwards, continue at l2) and go through the loop l2: 2X1X@: move the result down (needed for further processing), and move n to the top of the stack 2X% : n mod 2 (remainder, last binary digit) 2X1X@: move binary digit down, move result of division up loop is finished, back to the beginning (l1) l1: = : duplicate result of division 2X/= : divide n by 2 and duplicate the result 1X!>#: is the result >0? (is n>=2?) It is not, thus don’t rotate the pointer and move on (towards l3) ? : pop division result from the stack l3: N : output first bit: 1 (1*2^1) = : duplicate next bit 1X># : is top of stack >1? It isn’t (end marker check). Thus, back to beggining of loop (l3) N : output next bit: 1 (1*2^0) = : duplicate next bit (which, in this case, is the marker) 1X># : is top of stack >1? It is (end marker reached). Thus, move on to (l4) l4: 5X=+ : 5+5=10, 10 is the ASCII value for the newline character (\n) C? : output top of stack as character (newline) and pop the marker. End reached, leading back to (l0) l0: 2Xn=2X/=...........
Flow diagram, with labels l0 to l3:
l0 l1 l3 ↓ ↓ ↓ 2Xn=2X/=1X!>#?N=1X . . . . . . . l2→2 . > . @ X . . . X1X2%X2@X1 . . ? . . C+=X5............# ↑ . . l4 ....
Integer Sequence
PNG image download:
[Image:https://copy.com/TQuwy3dwBRl7nEOL]
Rendered as wikitable:
ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww |
ww | ww | ww | ww | ww | ww | ww |
(7x3 codels)
Opcodes:
1 PSH NOT DUP OUN 5 PSH ROL ADD DUP PSH 1 OUC ADD
Shorthand:
1 X ! = N 5 X @ . + = X 1 C +
0 \n 1 \n 2 \n 3 OUTPUT ————————————————————————————————————————————————————————————————————————————— 5 5 5 0 5 5 10 1 1 5 5 10 1 2 5 5 10 1 3 STACK 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 3 ... ————————————————————————————————————————————————————————————————————————————— 1X ! = N 5X = + C 1X + @ = N 5X = + C 1X + @ = N 5X = + C 1X + @ = N ... | \_____/ | | | | | | | +—————————— Repeating the Loop | | | | | | | +———————————— ROL acting as NOP (stack too small), needed to guide the codel chooser | | | | | +—————————————— Count up | | | +———————————————————————— 10 = ASCII for \n (newline) | +————————————————————————————————— !1=0 (Sequence begins at 0)
Create Wikitable from PNG files
This is the Julia code I use to generate wikitables from Piet program png files (codel size 1).
I just copy/paste the console output of the program.
Usage: convert("filename.png", blocksize)
using Images, ImageView function convert(name::String,blocksize::Int) img=Images.imread("$name") view(img) println("{| style=\"border-collapse: collapse; border-spacing: 0; font-family: courier-new,courier,monospace; font-size: $(blocksize)px; line-height: 1.2em; padding: 0px\"") for y=1:height(img) for x=1:width(img) r=hex(int(img[x,y].r*255)) g=hex(int(img[x,y].g*255)) b=hex(int(img[x,y].b*255)) r=="0" ? r="00" : nothing g=="0" ? g="00" : nothing b=="0" ? b="00" : nothing print("| style=\"background-color:#$r$g$b; color:#$r$g$b;\" | ww\n") x==width(img) ? print("|-\n\n"):nothing end end print("|}") end