user1618672
user1618672

Reputation: 5

R: putting a function and for loop together to create a function

I'm trying to reverse and invert to see if the digits to see if they are the same when the numbers are upside down

I got up to this far and im confused...

revdigits = 
function(n) {
    sapply(lapply(strsplit(as.character(n),""),rev),paste,collapse="")  
}
    for(i in 1:length(n)){
        n[i]=
        if(n[i]==0) 0
        else if(n[i] == 1) 1
        else if(n[i] == 6) 9
        else if(n[i] == 8) 8
        else if(n[i] == 9) 6
        else -1 
    }

invertible=
function(n)

n[1] == revdigits(n[1])

is there anyway to put them together (or relate them) to produce

invertible(c(99, 123, 1691))

[1] FALSE FALSE TRUE

this outcome??

Upvotes: 0

Views: 1155

Answers (2)

themel
themel

Reputation: 8895

You're already using apply in your code, so I may be misunderstanding the question, but I suppose the answer is

> invertible = function(n) sapply(n, function(x) x == revdigits(x))
> invertible(c(99, 123, 1691))
[1]  TRUE FALSE FALSE

This alerts us to the fact that revdigits isn't quite working right. It's a bit hard to say what you intended to do since your code as is doesn't include the for loop in the function and has syntax errors:

> revdigits = 
+ function(n) {
+     sapply(lapply(strsplit(as.character(n),""),rev),paste,collapse="")
+ }
> 
> 
>     for(i in 1:length(n)){
+         n[i]=
+         if(n[i]==0) 0
+         else if(n[i] == 1) 1
+         else if(n[i] == 6) 9
+         else if(n[i] == 8) 8
+         else if(n[i] == 9) 6
+         else -1 
+         }
Error: object 'n' not found
> }
Error: unexpected '}' in "}"

revdigits as is simply reverses the order of digits and converts numbers to strings:

> revdigits(c(123,69))
[1] "321" "96" 

To find out how it does that, let's have a look at the sapply that looks like you didn't write it yourself, analyzing from the inside out with a simple example:

> n <- 69
> as.character(n)
[1] "69"
> strsplit(as.character(n),"")
[[1]]
[1] "6" "9"    
> lapply(strsplit(as.character(n),""),rev)
[[1]]
[1] "9" "6"
> sapply(lapply(strsplit(as.character(n),""),rev),paste,collapse="")
[1] "96"

So your loop looks like it should be applied to the digit vector before the final step. Packaging your loop into a function:

rotate = function(n) { 
    for(i in 1:length(n)){
      n[i]=
        if(n[i]==0) 0
      else if(n[i] == 1) 1
      else if(n[i] == 6) 9
      else if(n[i] == 8) 8
      else if(n[i] == 9) 6
      else -1 
    }
  n
}

Testing:

> rotate(0:9)
 [1]  0  1 -1 -1 -1 -1  9 -1  8  6

and applying in revdigits

revdigits = function(n) {
    sapply(lapply(lapply(strsplit(as.character(n),""),rev),rotate),paste,collapse="") 
}

we get something that seems to work:

> revdigits(69)
[1] "69"
> revdigits(99)
[1] "66"

Even better, it already works with vectors!

> n <- c(99, 123, 1691)
> revdigits(n)
[1] "66"    "-1-11" "1691" 
> invertible <- function(n) n == revdigits(n)
> invertible(n)
[1] FALSE FALSE  TRUE

No need to use indexes at all.

Upvotes: 3

tim riffe
tim riffe

Reputation: 5691

my try:

    invertible <- function(n){
      nd <- unlist(strsplit(as.character(n),split=""))
        if (all(nd %in% c("0","1","6","9","8"))){
          n == as.integer(paste(rev(sapply(nd, function(x){
                                            ifelse(!x %in% c("9","6"),x,
                                                    ifelse(x == "9","6","9"))
                                        })), collapse=""))
        } else {
          FALSE
      }
   }

sum(sapply(1:1e6, invertible))
# 198

Edit: you can put the sapply() inside still:

invertible <- function(N){
  sapply(N, function(n){
            nd <- unlist(strsplit(as.character(n),split=""))
            if (all(nd %in% c("0","1","6","9","8"))){
                n == as.integer(paste(rev(sapply(nd, function(x){
                                                    ifelse(!x %in% c("9","6"),x,
                                                            ifelse(x == "9","6","9"))
                                                })), collapse=""))
            } else {
                FALSE
            }                
        })

}

Upvotes: 1

Related Questions