[The Original Shootout]   [NEWS]   [FAQ]   [Methodology]   [Platform Details]   [Acknowledgements]   [Scorecard]
All Source For rexx
Ackermann's Function
```
parse arg n
If n < 1 Then Do
n = 1
End

R = Ack(3,N)

say "Ack(3,"n"): "R
exit

Ack:
PROCEDURE
PARSE ARG M,N
IF M<1 THEN RETURN N+1
IF N<1 THEN RETURN Ack(M-1, 1)
R1 = Ack(M, N-1)
RETURN Ack(M-1, R1)

```
Array Access
```parse arg n
If n < 1 Then Do
n = 1
End

last = n - 1

Y.0 = 0
Do i = 0 To last
X.i = i + 1
Y.i = 0
End

Do k = 0 To 999
Do i = last To 0 By -1
Y.i = Y.i + X.i
End
End

say Y.0" "Y.last
```
Count Lines/Words/Chars
```nl = 0
nw = 0
nc = 0
DO UNTIL LINES() = 0
PARSE LINEIN L
nw = nw + WORDS(L)
nc = nc + LENGTH(L) + 1
nl = nl + 1
END
nc = nc - 1
nl = nl - 1
SAY nl nw nc
```
Fibonacci Numbers
```
parse arg n
If n < 1 Then Do
n = 1
End

R = fib(N)

say R
exit

fib:
PROCEDURE
PARSE ARG N
IF N<2 THEN RETURN 1
RETURN fib(N-2) + fib(N-1)
```
Hash (Associative Array) Access
```parse arg n
If n < 1 Then Do
n = 1
End

Do i = 1 To n
xx = d2x(i)
X.xx = i
End

c = 0

Do i = n To 1 By -1
if X.i <> "X."i Then Do
c = c + 1
End
End
Say c
```
Hashes, Part II
```parse arg n
If n < 1 Then Do
n = 1
End

keys.0 = 10000
Do i = 0 To 9999
k = "FOO_"i
hash1.k = i
ki = i + 1
keys.ki = k
End

hash2. = 0
Do i = 1 To n
Do j = 1 To keys.0
k = keys.j
hash2.k = hash2.k + hash1.k
End
End

Say hash1.FOO_1" "hash1.FOO_9999" "hash2.FOO_1" "hash2.FOO_9999
```
Heapsort
```NUMERIC DIGITS 10

vIM=139968
vIA=3877
vIC=29573

LAST=42

parse arg n
If n < 1 Then Do
n = 1
End

Do i = 1 TO N
ary.i = gen_random(1)
End

CALL heapsort N

SAY ary.N

EXIT

gen_random:
PROCEDURE EXPOSE LAST vIM vIA vIC
PARSE ARG n
LAST = (LAST * vIA + vIC) // vIM
return n * LAST / vIM

heapsort:
PARSE ARG n
rra = 0
i = 0
j = 0
l = (n % 2) + 1
ir = n

Do While 1
If l > 1 Then Do
l = l - 1
rra = ary.l
End
Else Do
rra = ary.ir
ary.ir = ary.1
ir = ir - 1
If ir = 1 Then Do
ary.1 = rra
return
End
End

i = l
j = l * 2

Do While  j <= ir
If j < ir Then Do
jj = j+1
If ary.j < ary.jj Then Do
j = j + 1
End
End

If rra < ary.j Then Do
ary.i = ary.j
i = j
j = j + i
End
Else Do
j = ir + 1
End
End
ary.i = rra
End

```
Hello World
```say "hello world"
```
List Operations
```SIZE = 10000

parse arg ITER
If ITER < 1 Then Do
ITER = 1
End

result = 0
Do While ITER > 0
result = test_lists()
ITER = ITER - 1
End
Say result
exit

test_lists

test_lists:

Do A = 0 To SIZE
Li1.A = A
End

/* [dada] this should work, but does not:
* Li2. = Li1.
*/
Do A = 0 To SIZE
Li2.A = Li1.A
End

Do A = 0 To SIZE
B = SIZE - A
Li3.A = Li2.B
End

Do A = 0 To SIZE
Li2.A = Li3.A
End

Do A = 0 To SIZE
B = SIZE-A
Li4.A = Li1.B
End
Do A = 0 To SIZE
Li1.A = Li4.A
End

If Li1.0 <> SIZE Then Do
return -1
End

Do i = 0 To SIZE

If Li1.i <> Li2.i Then Do
return 0
End
End
return SIZE
```
Matrix Multiplication
```size = 30

parse arg n
If n < 1 Then Do
n = 1
End

call mkmatrix size, size, "m1"
call mkmatrix size, size, "m2"
Do While n > 0
call mmult(size, size, "m1", "m2", "mm")
n = n - 1
End
say mm.0.0" "mm.2.3" "mm.3.2" "mm.4.4

exit

mkmatrix:
parse arg rows, cols, mx
rows = rows - 1
cols = cols - 1
count = 1
Do r = 0 To rows
Do c = 0 To cols
interpret mx || ".r.c = " count
count = count + 1
End
End
return mx

mmult:
parse arg rows, cols, m1, m2, m3
rows = rows - 1
cols = cols - 1
Do i = 0 To rows
Do j = 0 To cols
val = 0
Do k = 0 To cols
interpret "val = val + " || m1 || ".i.k * " || m2 || ".k.j"
End
interpret m3 || ".i.j = " val
End
End
```
Nested Loops
```parse arg n
If n < 1 Then Do
n = 1
End

x = 0

Do A = 1 To n
Do B = 1 To n
Do C = 1 To n
Do D = 1 To n
Do E = 1 To n
Do F = 1 To n
x = x + 1
End
End
End
End
End
End

say x
```
Random Number Generator
```NUMERIC DIGITS 10

vIM=139968
vIA=3877
vIC=29573

LAST=42

parse arg n
If n < 1 Then Do
n = 1
End

Do i = 1 TO N
result = gen_random(100)
End

SAY result

EXIT

gen_random:
PROCEDURE EXPOSE LAST vIM vIA vIC
PARSE ARG n
LAST = (LAST * vIA + vIC) // vIM
return n * LAST / vIM

```
Reverse a File
```A = 1
DO UNTIL LINES() = 0
PARSE LINEIN L
PUSH L
A = A + 1
END
PULL
DO B = A-2 TO 1 BY -1
PARSE PULL L
SAY L
END
```
Sieve of Erathostenes
```parse arg n
If n < 1 Then Do
n = 1
End

Do While n > 0
count = 0
Do j = 0 To 8192
flags.j = 1
End
Do i = 2 To 8192
If flags.i <> 0 Then Do
Do k = i+i To 8192 By i
flags.k = 0
End
count = count + 1
End
End
n = n - 1
End

say "Count: "count
```
Statistical Moments
```NUMERIC DIGITS 10

n = 1
nums. = 0
sum = 0
DO WHILE LINES() <> 0
PARSE LINEIN L
IF L <> "" THEN DO
INTERPRET "sum = sum + " L
INTERPRET "nums." || n || "=" || L
n = n + 1
END
END

n = n - 1
nums.0 = n
mean = sum/n
average_deviation = 0
standard_deviation = 0
variance = 0
skew = 0
kurtosis = 0
DO I = 1 TO nums.0
deviation = nums.I - mean
average_deviation = average_deviation + ABS(deviation)
variance = variance + deviation ** 2
skew = skew + deviation ** 3
kurtosis = kurtosis + deviation ** 4
END
average_deviation = average_deviation / n
variance = variance / (n-1)
standard_deviation = SQRT(variance)

IF variance <> 0 THEN DO
skew = skew / (n * variance * standard_deviation)
kurtosis = kurtosis / (n * variance * variance) - 3
END

call qqsort 1, n

mid = n%2+1
if n//2 <> 0 then do
median = nums.mid
end
else do
pmid = mid - 1
median = (nums.mid + nums.pmid) / 2
end

SAY sprintf("n:                  %d", n)
SAY sprintf("median:             %-.6f", median)
SAY sprintf("mean:               %-.6f", mean)
SAY sprintf("average_deviation:  %-.6f", average_deviation)
SAY sprintf("standard_deviation: %-.6f", standard_deviation)
SAY sprintf("variance:           %-.6f", variance)
SAY sprintf("skew:               %-.6f", skew)
SAY sprintf("kurtosis:           %-.6f", kurtosis)

EXIT

SQRT: PROCEDURE
ARG n

ans = n / 2
prevans = n
do until prevans = ans
prevans = ans
ans = ( prevans + ( n / prevans ) ) / 2
end
return ans

SQRTOLD:
PROCEDURE
PARSE ARG n
parse value format(n,,,,0) with mant "E" exp
if exp = "" then exp = 0
if exp//2 < > 0 then do
mant = mant * 10
exp = exp -1
end
root = 0
do 10
do digit = 9 by -1 to 0,
while,
(root + digit) ** 2 > mant
end
root = root + digit
if root**2 = mant then leave
root = root * 10
mant = mant * 100
exp = exp -2
end
return root * 10**(exp/2)

sprintf: procedure
argno = 1
string = ""
start = 1
len = length(arg(1))

do until(p >= len)
s = ""
argno = argno + 1
p = pos("%", arg(1), start)
if p = 0 then
do
p = len + 1
end
if substr(arg(1), p, 1) == "%" then
do
s = "%"
end
string = string || substr(arg(1), start, p - start)
start = p + 1
p = verify(arg(1), "%cdfsx", "M", start)
if p = 0 then
leave
spec = substr(arg(1), start, p - start + 1)
start = p + 1
r = right(spec, 1)
spec = delstr(spec, length(spec), 1)
if left(spec,1) == "-" then
do
left = 1
spec = substr(spec, 2)
end
else
do
left = 0
spec = substr(spec, 1)
end
if spec \== "" then
parse var spec width "." prec
else
do
width = 0
prec = 0
end
if \datatype(width, "W") then
width = 0
if \datatype(prec, "W") then
prec = 0
pad = " "

select

when r == "s" then
do
if width = 0 then
width = length(arg(argno))
if prec \= 0 then
s = left(arg(argno), prec)
else
s = arg(argno)
end

when r == "d" then
do
if width = 0 then
width = length(arg(argno))
s = format(arg(argno), length(arg(argno)), 0)
end

when r == "f" then
do
if arg(argno) > -1 & arg(argno) < 1 then
parse value arg(argno) with int "." frac
if width = 0 & prec = 0 then
do
d = 1
if arg(argno) < 0 then d = 2
width = digits() + d
prec = digits() - (length(int)) + d - 1
end
if width = 0 then
width = len - prec
s = format(arg(argno), width, prec, 0)
end

when r == "x" then
do
if width = 0 then
width = length(arg(argno))
s = d2x(arg(argno))
if prec \= 0 then
s = left(s, prec)
end

when r == "%" then
do
argno = argno - 1
end

otherwise
nop

end

if r \== "%" then
do
if left then
s = left(strip(s), width, pad)
else
s = right(strip(s), width, pad)
end
string = string || s
end
return string

Fast Quick sort

/*
This is a fast quick sort routine.

Author: Ruediger Wilke
*/

qqsort: procedure expose nums.

arg lf, re

if re -lf < 9 then
do lf = lf to re -1

m = lf

do j = lf +1 to re
if nums.j < nums.m then
m = j
end

t = nums.m; nums.m = nums.lf; nums.lf = t

end
else
do
i = lf
j = re
k = (lf + re)%2
t = nums.k

do until i > j

do while nums.i < t
i = i + 1
end

do while nums.j > t
j = j - 1
end

if i <= j then
do
xchg = nums.i
nums.i = nums.j
nums.j = xchg
i = i + 1
j = j - 1
end

end

call qqsort lf, j
call qqsort i, re
end

return

```
String Concatenation
```parse arg n
If n < 1 Then Do
n = 1
End

str = ""
Do I=1 to N
str = str || "hello" || D2C(13)
End
say length(str)
```
Sum a Column of Integers
```NUMERIC FORM SCIENTIFIC
TOT = 0
DO WHILE LINES() <> 0
PARSE LINEIN L
IF L <> "" THEN DO
INTERPRET "TOT = TOT + " L
END
END
SAY TOT
```
Word Frequency Count
```
count. = 0
ws = ''
transtab = XRANGE('A', 'Z') || XRANGE('a', 'z')
transin  = XRANGE('A', 'Z')
transout = XRANGE('a', 'z')
notword  = XRANGE('00'x, D2C(C2D('a')-1)) || XRANGE(D2C(C2D('z')+1), 'FF'x)
DO UNTIL LINES() = 0
PARSE LINEIN L

L = TRANSLATE(TRANSLATE(L, transout, transin), '', notword, ' ')

DO i = 1 TO WORDS(L)
w = STRIP(WORD(L, i))
count.w = count.w + 1
IF count.w = 1 THEN ws = ws w
END
END

STREAM('rexx_tmp', 'C', 'CREATE')

DO i = 1 to WORDS(ws)
w = WORD(ws, i)
IF count.w > 0 THEN DO
line = format(count.w, 7) || '09'x || w
CALL LINEOUT('rexx_tmp', line)
END
END

'c:\cygwin\bin\sort -nr rexx_tmp >rexx_sorted'

DO WHILE LINES('rexx_sorted') > 0
SAY LINEIN('rexx_sorted')
END

/*
STREAM('rexx_tmp', 'C', 'CLOSE')
STREAM('rexx_sorted', 'C', 'CLOSE')

'del rexx_tmp'
'del rexx_sorted'
*/
```