The function Iter exhibits tail recursion which can be removed.

There is no need to compute all required Iter() calls before checking the required conditions.

The calls Iter(6,1,z), Iter(6,2,z) and Iter(6,3,z) can be vectorized. Same for the other 3 conditions.

So I did this:

mIteru <- function(n,y) {

z <- rep(y,3)

s <- c(1,2,3)

for(k in 1:n) {

z <- trunc(z/10) + (z%%10)*s

}

return(z)

}

mIterv <- function(n,y) {

z <- rep(y,3)

s <- c(1,2,3)

for(k in 1:n) {

z <- trunc(z/10) – (z%%10)*s

}

return(z)

}

tb <- proc.time()

# for recording all numbers that satisfy the first 3 conditions of the puzzle

zsuc <- numeric(10000000)

p <- 0

for(z in 1000000:9999999) {

if( all(mIteru(6,z) == c(12,19,29)) ) {p <- p+1; zsuc[p] <- z}

}

print(p)

zsuc[1:p]

# the second set of conditions only needs to be checked for numbers that passes the first test

zfin <- numeric(p)

q <- 0

for(k in 1:p) {

if( all(mIterv(6,zsuc[k]) == c(0,0,0)) ) {q <- q+1; zfin[q] <- zsuc[k]}

}

print(q)

zfin[1:q]

proc.time()-tb

On my MacBookPro 13" 2010 (C2D 2.4Ghz) using R 2.12.1 (64-bit) on Mac OS X 10.6.5 this took 242.6 seconds.

The answer is 3945711.

I wouldn't be surprised if this can be speeded up more.

Berend

]]>