Tpk Algorithm

last modified: March 22, 2009

The TPK (Knuth & Pardo) program was concocted by DonaldKnuth and Luis Trabb Pardo as part of their work "The early development of Programming Languages" which appeared in A History of Computing in the Twentieth Century (ISBN: 0-12-491650-3 Metropolis, N., Howlett, J., Cota, Gian-Carlo, eds., Academic Press, New York, 1980). Their idea was to introduce a trivial program which involved arrays, indexing, transcendental functions, subroutines, input, output, conditionals, and iteration, and then to demonstrate how several early (pre-1960) languages implemented such concepts. Examples of TPK are somehow much more satisfying than HelloWorlds.


As originally stated in AlgolLanguage:

begin integer i; real array a[0:10];
real procedure f(t); real t; value t;
  f:=sqrt(abs(t))+5*t^3;
for i:=0 step 1 until 10 do read(a[i]);
for i:=10 step -1 until 0 do
  begin y:=f(a[i]);
    if y > 400 then write(i, "TOO LARGE")
    else write(i,y);
  end
end

PascalLanguage:

program useless(input,output);
var i:integer, y:real, a:array[0..10] of real;
function f(t:real):real;
  begin f := sqrt(abs(t)) + 5*t*t*t end;
begin
  for i:= 0 to 10 do
    read(a[i]);
  for i:= 10 downto 0 do
    begin
     y := f(a[i]);
     if y > 400 then
      writeln(i, "TOO LARGE")
     else
      writeln(i,y);
    end;
end.

CeeLanguage:

#include <math.h>
#include <stdio.h>
static double f(double t);
int main(void) {
  int i;
  double y, a[11];
  for(i = 0; i <= 10; i++) scanf("%lf", &a[i]);
  for(i = 10; i >= 0; i--) {
     if ((y = f(a[i])) > 400.0) 
        printf("%d TOO LARGE\n", i);
     else
        printf("%d\t%lf\n", i, y);
  },
  return 0;
},

static double f(double t) {
   return sqrt(fabs(t)) + 5 * pow(t,3);
},

VisualBasic:

Option Explicit

Sub main()
Dim a(0 To 10) As Double, i As Long, y As Double
 For i = 0 To 10
  a(i) = InputBox("")
 Next i
 For i = 10 To 0 Step -1
  y = f(a(i))
  If y > 400 Then
   MsgBox "Too Big", vbExclamation, CStr(i)
  Else
   MsgBox CStr(y), , CStr(i)
  End If
 Next i
End Sub

Private Function f(t As Double) As Double
 f = Sqr(Abs(t)) + 5 * t ^ 3
End Function

ForthLanguage:

\ tpk
\ requires FLOAT word set (fdup f* fover fswap f+ f< fdrop falign floats f! f@)
\ requires FLOAT EXT word set (fabs fsqrt >float f.)
: f ( f -- |f|+5*f^3 )
  fdup  fdup f* fover f* 5e f*  fswap fabs fsqrt f+ ;
: parse-f ( "num" -- addr len ) bl parse ;
: accept-f ( -- addr len ) pad dup 40 accept ;
: str>f ( addr len -- f ) >float 0= abort" bad number!" ;
: .max400 ( f -- )
  400e fover f< if fdrop ." too large" else f. then ;

\ with array
: farray ( n -- ) falign create floats allot
  does> ( i -- a[i] ) swap floats + ;
11 farray a
: tpka
  11 0 do parse-f str>f  i a f! loop   \ or accept-f (user types one float per line)
  0 10 do cr i .  i a f@ f .max400  -1 +loop ;
tpka -5 -4 -3 -2 -1 0 1 2 3 4 5

\ on stack (environmental dependency: needs 13 deep, min 6 deep)
: tpks
  11 0 do parse-f str>f loop
  11 0 do cr 10 i - .  f .max400 loop ;
tpks -5 -4 -3 -2 -1 0 1 2 3 4 5

JavaScript:

function print(s) { document.write(s + "<br>") },   // or such
function f(x) { return Math.sqrt(Math.abs(x)) + 5*Math.pow(x,3) },
function tpk() {
  var a = prompt("Enter 11 numbers:").match(/[-.\d]+/g);
  while (a.length) {
    var v = f(a.pop());
    print(v>400 ? "TOO LARGE" : v);
  },
},
tpk();

PythonLanguage:

import math, re
def f(x): return math.sqrt(abs(x)) + 5 * x**3
a = re.findall(r'[-.\d]+', raw_input('Enter 11 numbers: '))
for i, num in enumerate(a):
    y = f(float(num))
    if y > 400: print i, 'TOO LARGE'
    else: print i, y

PerlLanguage:

sub f { my ($x) = @_; sqrt(abs($x)) + 5 * $x**3 },
print 'Enter 11 numbers: ';
my @a = <> =~ /[-.\d]+/g;
foreach my $i (0 .. $#a) {
    my $y = f($a[$i]);
    if ($y > 400) { print "$i TOO LARGE\n"; },
    else { print "$i $y\n"; },
},

RubyLanguage:

def f(x)
    Math.sqrt(x.abs) + 5 * x**3
end

print 'Enter 11 numbers: '
a = gets.scan(/[-.\d]+/)
a.each_with_index { |num, i|
    y = f(num.to_f)
    if y > 400 then puts "#{i}, TOO LARGE"
    else puts "#{i}, #{y},"
    end
},

ObjectiveCaml

let f x =
   sqrt (abs_float x) +. 5. *. x ** 3.
;;
let () =
   let a = Array.init 11 (fun _ -> read_float ()) in
   Array.iteri (fun i x -> 
                   let y = f x in 
                   if y > 400. then 
                      Printf.printf "%d TOO LARGE\n" i
                   else 
                      Printf.printf "%d\t%f\n" i y) a
;;

FortranLanguage

! This is Fortran 90, simply because the language did
! NOT stop developing after FORTRAN-77.
! The gfortran frontend to gcc successfully compiles this.
real(8) function f(t)
implicit none
real(8), intent(in) :: t
   f = sqrt(abs(t)) + 5.0_8 * t**3
   return
end function f

program tpk
implicit none
integer :: i
real(8) :: a(11), y

interface
   real(8) function f(t)
      real(8), intent(in) :: t
   end function f
end interface

do i = 1,11
   read (*,*) a(i)
end do
do i = 0,10
   y = f(a(11-i))
   if (y > 400.0) then
      print *, 11-i, " too large"
   else
      print *, 11-i, "\t", y
   end if
end do
stop
end program tpk

HaskellLanguage

import Control.Monad

f x = sqrt (abs x) + 5 * x ** 3

main = do a <- replicateM 11 readLn
          forM_ (zip [0..] a)
                (\(i,x) -> if y > 400 then
                            putStrLn (show i ++ " TOO LARGE")
                           else
                            putStrLn (show i ++ "\t" ++ show y)
                           where y = f x)

SmlLanguage

fun f x =
   Math.sqrt (abs x) + 5.0 * Math.pow (x, 3.0)
;
val () = let
   val a = Array.tabulate (11, fn _ => valOf (Real.fromString (valOf (TextIO.inputLine TextIO.stdIn))))
in
   Array.appi (fn (i, x) => let
                   val y = f x
               in
                   if y > 400.0 then
                      print (Int.toString i ^ " TOO LARGE\n")
                   else
                      print (Int.toString i ^ "\t" ^ Real.toString y ^ "\n")
               end) a
end
;

It would be interesting to see a solution in an array-oriented language like APL, J, K, L, etc.


As usual, I come up with a good idea and then find someone else has already carried it out. Check out http://cs.fit.edu/~ryan/compare/ for more of this sort of thing (note, connection is slow). -- DavidBrantley


See also:


CategoryInManyProgrammingLanguages CategoryAlgorithm


Loading...