Hailstone sequence: Difference between revisions

Content added Content deleted
m (→‎{{header|R}}: Syntax highlighting.)
(→‎Vectorization solution: Improved syntax.)
Line 8,255: Line 8,255:
The previous solution is entirely satisfactory and may be more efficient than the following solution. However, problems like these are a great chance to show off the strength of R's vectorization. Also, this lets us show off how the <- syntax can do multiple variable assignments in one line. Observe how short the following code is:
The previous solution is entirely satisfactory and may be more efficient than the following solution. However, problems like these are a great chance to show off the strength of R's vectorization. Also, this lets us show off how the <- syntax can do multiple variable assignments in one line. Observe how short the following code is:
<lang rsplus>###Task 1:
<lang rsplus>###Task 1:
collatz<-function(n)
collatz <- function(n)
{
{
lastIndex<-1
lastIndex <- 1
output<-lastEntry<-n
output <- lastEntry <- n
while(lastEntry!=1)
while(lastEntry != 1)
{
{
#Each branch updates lastEntry, lastIndex, and appends a new element to the end of output.
#Each branch updates lastEntry, lastIndex, and appends a new element to the end of output.
#Note that the return value of lastIndex<-lastIndex+1 is lastIndex+1.
#Note that the return value of lastIndex <- lastIndex + 1 is lastIndex + 1.
#You may be surprised that output can be appended to despite starting as just a single number.
#You may be surprised that output can be appended to despite starting as just a single number.
#If so, recall that R's numerics are vectors, meaning that output<-n created a vector of length 1.
#If so, recall that R's numerics are vectors, meaning that output<-n created a vector of length 1.
#It's ugly, but efficient.
#It's ugly, but efficient.
if(lastEntry%%2==0){lastEntry<-output[lastIndex<-lastIndex+1]<-lastEntry%/%2}
if(lastEntry %% 2) lastEntry <- output[lastIndex <- lastIndex + 1] <- 3 * lastEntry + 1
else{lastEntry<-output[lastIndex<-lastIndex+1]<-3*lastEntry+1}
else lastEntry <- output[lastIndex <- lastIndex + 1] <- lastEntry %/% 2
}
}
output
output
Line 8,274: Line 8,274:
###Task 2:
###Task 2:
#Notice how easy it is to access the required elements:
#Notice how easy it is to access the required elements:
twentySeven<-collatz(27)
twentySeven <- collatz(27)
cat("The first four elements are:", twentySeven[1:4],"and the last four are:", twentySeven[length(twentySeven)-3:0])
cat("The first four elements are:", twentySeven[1:4], "and the last four are:", twentySeven[length(twentySeven) - 3:0], "\n")


###Task 3:
###Task 3:
#Notice how a several line long loop can be avoided with R's sapply or Vectorize:
#Notice how a several line long loop can be avoided with R's sapply or Vectorize:
seqLenghts<-sapply(1:99999,function(x) length(collatz(x)))
seqLenghts <- sapply(seq_len(99999), function(x) length(collatz(x)))
longest<-which.max(seqLenghts)
longest <- which.max(seqLenghts)
print(paste0("The longest sequence before the 100000th is found at n=",longest,". It has length ",seqLenghts[longest],"."))
cat("The longest sequence before the 100000th is found at n =", longest, "and it has length", seqLenghts[longest], "\n")
#Equivalently, line 1 could have been: seqLenghts<-sapply(Vectorize(collatz)(1:99999),length).
#Equivalently, line 1 could have been: seqLenghts <- sapply(Vectorize(collatz)(1:99999), length).
#Another good option would be seqLenghts<-lengths(Vectorize(collatz)(1:99999)).</lang>
#Another good option would be seqLenghts <- lengths(Vectorize(collatz)(1:99999)).</lang>
{{out}}
{{out}}
<pre>The first four elements are: 27 82 41 124 and the last four are: 8 4 2 1
<pre>
The longest sequence before the 100000th is found at n = 77031 and it has length 351</pre>
> twentySeven<-collatz(27)
> cat("The first four elements are:", twentySeven[1:4],"and the last four are:", twentySeven[length(twentySeven)-3:0])
The first four elements are: 27 82 41 124 and the last four are: 8 4 2 1

> seqLenghts<-sapply(1:99999,function(x) length(collatz(x)))
> longest<-which.max(seqLenghts)
> print(paste0("The longest sequence before the 100000th is found at n=",longest,". It has length ",seqLenghts[longest],"."))
[1] "The longest sequence before the 100000th is found at n=77031. It has length 351."
</pre>


=={{header|Racket}}==
=={{header|Racket}}==