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 HelloWorld''''''s. * The example given, which is claimed to be the original, doesn't actually have any transcendental functions. ---- '''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 #include 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) = Input''''''Box("") 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 + "
") } // 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: * AlgorithmsRoadMap ---- CategoryInManyProgrammingLanguages CategoryAlgorithm