Tpk Algorithm

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

EditText of this page (last edited March 22, 2009) or FindPage with title or text search