TPK algorithm: Difference between revisions

Content deleted Content added
Implementations: remove all but the ALGOL example, which I assume is not OR
Line 21:
The algorithm reads eleven numbers from an input device, stores them in an array, and then processes them in reverse order, applying a user-defined function to each value and reporting either the value of the function or a message to the effect that the value has exceeded some threshold.
 
==[[ALGOL 60]] implementation==
==Implementations==
{{example farm|date=November 2011}}
 
===[[ALGOL 60]]===
<!-- Note that ALGOL is not correctly colored by <source>. -->
<code lang="algol60">
Line 40 ⟶ 37:
 
The problem with the usually specified function is that the term <code>5*t^3</code> gives overflows in almost all languages for very large negative values.
 
===[[Bash (Unix shell)|Bash]]===
 
The following works with and outputs (rounded-off) integers only:
 
<source lang="bash">
f() {
echo "sqrt(${1#-}) + 5 * $1 ^ 3" | bc
}
 
array=()
for i in {0..10}; do
read array[i]
done
 
for ((i=${#array[@]}-1; i>=0; --i)); do
let x=$(f ${array[$i]})
(( x > 400 )) && echo 'TOO LARGE' || echo $x
done
</source>
 
Although external programs can be used for unavailable (complex) functions, Bash is inherently incapable of floating-point arithmetic comparison.
 
===[[C (programming language) | C]]===
<source lang="c">
#include <stdio.h>
#include <math.h>
 
#define N 11
 
double vals[N];
 
double f(double x) {
return sqrt(fabs(x)) + 5*x*x*x;
}
 
int main(void) {
int i;
 
for(i = 0; i < N; ++i)
scanf("%lf", &vals[i]);
 
for(i = N-1; i >= 0; --i) {
double x = f(vals[i]);
if(x > 400)
printf("TOO LARGE\n");
else
printf("%.3f\n", x);
}
 
return 0;
}
</source>
 
===[[C++]]===
<source lang="cpp">
#include <iostream>
#include <cmath>
using namespace std;
double f(double x) {
return sqrt(abs(x)) + 5*x*x*x;
}
int main() {
double vs[11];
for (auto& v : vs) cin >> v;
for (int i = 10; i >= 0; --i) {
auto x = f(vs[i]);
(x > 400 ? cout << "TOO LARGE" : cout << x) << endl;
}
}
</source>
 
===[[Groovy (programming language)|Groovy]]===
<source lang="Groovy">
 
def grooVals = []
def scanner = new Scanner(System.in)
11.times {
grooVals << scanner.nextDouble()
}
grooVals = grooVals.reverse()
for (val in grooVals) {
def calcVal = f(val)
if (calcVal.isInfinite())
println 'TOO LARGE'
else
println calcVal
}
</source>
 
===[[Haskell (programming language)|Haskell]]===
<source lang="haskell">
f :: Floating a => a -> a
f x = sqrt (abs x) + 5 * x ^ 3
 
message :: (Num a, Show a) => a -> String
message x
| x > 400 = "TOO LARGE"
| otherwise = show x
 
main :: IO ()
main = do
values <- replicateM 11 readLn
mapM_ (putStrLn . message . f) values</source>
 
===[[Java_(programming_language)|Java 5]]===
<source lang="java">
import static java.util.Collections.reverse;
 
import java.util.LinkedList;
import java.util.Scanner;
 
public class TrabbPardoKnuth {
private static double f(double x) {
return Math.sqrt(Math.abs(x)) + 5 * Math.pow(x, 3);
}
 
public static void main(String[] args) {
LinkedList<Double> numbers = new LinkedList<Double>();
Scanner scanner = new Scanner(System.in);
try {
for (int i = 0; i < 11; ++i) {
numbers.add(scanner.nextDouble());
}
} finally {
scanner.close();
}
assert (numbers.size() == 11) : "input should be eleven numbers";
reverse(numbers);
for (double number : numbers) {
Double fx = f(number);
if (fx.isInfinite()) {
System.out.println("TOO LARGE");
} else {
System.out.println(fx);
}
}
}
}
</source>
 
===[[Lua (programming language)|Lua]]===
A [[Lua (programming language)|Lua]] variant might look like this. [[Lua (programming language)|Lua]] is compiled with [[Double precision]] numbers by default, but any other format is possible.
 
<!-- Coloring for Lua seems to be only minimal. -->
<source lang="lua">
function f(x)
return math.abs(x)^.5 + 5*x^3
end
 
t = {}
 
for i=1,11 do
table.insert(t, io.read"*n")
end
 
for i=#t,1,-1 do
local r = f(t[i])
print (r > 400 and "TOO LARGE" or r)
end
</source>
 
===[[OCaml]]===
The [[OCaml]] version using imperative features such as for loops:
 
<source lang="ocaml">
let () =
let f x = sqrt x +. 5.0 *. (x ** 3.0) in
let pr v = print_endline (if v > 400.0 then "overflow" else string_of_float v) in
let a = Array.init 11 (fun _ -> read_float ()) in
for i = 10 downto 0 do
pr (f a.(i))
done
</source>
 
A [[functional programming|functional]] version can also be written in OCaml:
 
<source lang="ocaml">
let tpk l =
let f x = sqrt x +. 5.0 *. (x ** 3.0) in
let p x = x < 400.0 in
List.filter p (List.rev_map f l)
</source>
 
===[[Pascal (programming language)|Pascal]]===
<source lang="pascal">
program TrabbPardoKnuth(input, output);
 
const
N = 11;
 
var
Vals: array[1..N] of real;
I, X: integer;
 
function F(X: real): real;
begin
F := Sqrt(Abs(X)) + 5 * X * X * X
end;
 
begin
for I := 1 to N do
ReadLn(Vals[I]);
 
for I := N downto 1 do
begin
X := F(Vals[I]);
if X > 400 then
WriteLn('Too large!')
else
WriteLn(X)
end
end.
</source>
 
===[[Perl]]===
A [[Perl]] version using exceptions might look like this:
 
<source lang="perl">
use feature 'say';
 
sub f {
sqrt(abs($_[0])) + 5*$_[0]**3
}
 
for (1..11) {
push @inputs, scalar <>
}
 
for (reverse @inputs) {
eval { say f($_) } or say "Problem with entry $_: $@"
}
</source>
 
===[[Python (programming language)|Python]]===
<source lang="python">
import math
 
def f(x):
return math.sqrt(abs(x)) + 5 * x**3
 
vals = [float(raw_input()) for i in range(11)]
for i, x in enumerate(reversed(vals)):
y = f(x)
print('{0}: {1}'.format(i, y if y <= 400 else 'TOO LARGE'))
</source>
 
Floating point in Python on most platforms is [[IEEE-754]], which can return "nan" and "inf" values, or raise an appropriate Python exception.
 
===[[K_(programming_language)|q/KDB]]===
<source lang="q">
/input : 1 2 3 4 5 6 7 8 9 10 11
tpk:{[x] $[400>res:sqrt[abs x] + 5* x xexp 3; res; `$"TOO LARGE"]};
tpk each reverse input
</source>
q does not provide any function/operator for standard input.
 
===[[R (programming language)|R]]/[[S-PLUS]]===
In R/S-Plus the user is alerted of an overflow by NaN value. Three of many possible implementations are
<source lang="javascript">
# without an assignment
(function(t) sqrt(abs(t))+5*t^3)(rev(scan(nmax=11)))
 
# with an assignment
sqrt(abs(S <- rev(scan(nmax=11))))+5*S^3
 
# as a routine
tpk <- function(S = scan(nmax=11), t=rev(S)) sqrt(abs(t))+5*t^3
</source>
The last implementation makes use of the [[lazy evaluation]] mechanism of R for default values of parameters: <code>t</code> is evaluated only the first time it is used in a computation, after which <code>t</code> is well defined.
 
===[[Ruby (programming language)|Ruby]]===
The [[Ruby (programming language)|Ruby]] version takes advantage of some of its distinctive features:
 
<!-- Note that Ruby is not correctly colored by <source>. -->
<source lang="ruby">
def f(x)
Math.sqrt(x.abs) + 5*x ** 3
end
 
11.times.collect{ gets.to_i }.reverse.each do |x|
y = f(x)
puts "#{x} #{y.infinite? ? 'TOO LARGE' : y}"
end
</source>
 
===[[Scala (programming language)|Scala]]===
 
<source lang="scala">
object TrabbPardoKnuth extends App {
def f(x: Double) = math.sqrt(math.abs(x)) + 5 * x * x * x
(0 to 10).map(_ => readDouble()).reverse.map(f).foreach { x =>
println(if (x > 400) "TOO LARGE" else x)
}
}
</source>
 
===[[Scheme (programming language)|Scheme]]===
 
The following is tested with [[Chicken Scheme]].
 
<source lang="scheme">
(define (read-values n)
(if (zero? n)
'()
(cons (string->number (read-line))
(read-values (- n 1)))))
 
(define (f x)
(+ (sqrt (abs x)) (* 5 x x x)))
 
(for-each
(lambda (val)
(let ((result (f val)))
(print
(if (> result 400)
"TOO LARGE"
result))))
(reverse (read-values 11)))
</source>
 
==References==