Reverse Digits in R

How to reverse a number in R

I feel like reverse an integer should stay in the integer world instead of getting into the string manipulation world. It seems there isn't a built in function for such task in R, so we can create one, using the Rcpp package for instance. Here's an example

library(Rcpp)
cppFunction('int Reverse_CPP(int x) {
int reverse = 0;
while(x != 0) {
int remainder = x%10;
reverse = reverse*10 + remainder;
x/= 10;
}
return reverse ;
}')

Reverse_CPP(1234)
# [1] 4321

And here's a vectorized version

cppFunction('IntegerVector Reverse_CPP2(IntegerVector x) {
int n = x.size();
IntegerVector out(n);
IntegerVector xx = clone(x); // Will need this if you don"t want to modify x in place

for (int i = 0; i < n; ++i){
int reverse = 0;
while(xx[i] != 0) {
int remainder = xx[i]%10;
reverse = reverse*10 + remainder;
xx[i]/= 10;
}
out[i] = reverse;
}

return out;

}')

Reverse_CPP2(c(12345, 21331, 4324234, 4243))
# [1] 54321 13312 4324234 3424

Note that I had to add IntegerVector xx = clone(x); and hence slow the function drastically (see @alexis_laz comment) as Rcpp will modify the original x by reference otherwise. You don't need that if you are passing a bare vector or if you don't care if the original vector is being modifyied


Some benchmarks against other vectorized string manipulation functions

Stringi <- function(x) as.integer(stringi::stri_reverse(x))

Base <- function(x) {
as.integer(vapply(lapply(strsplit(as.character(x), "", fixed = TRUE), rev),
paste, collapse = "", FUN.VALUE = character(1L)))
}

library(microbenchmark)
set.seed(123)
x <- sample(1e3L:1e7L, 1e5, replace = TRUE)

microbenchmark(
Base(x),
Stringi(x),
Reverse_CPP2(x)
)

# Unit: milliseconds
# expr min lq mean median uq max neval cld
# Base(x) 855.985729 913.602215 994.60640 976.836206 1025.482170 1867.448511 100 c
# Stringi(x) 86.244426 94.882566 105.58049 102.962924 110.334702 179.918461 100 b
# Reverse_CPP2(x) 1.842699 1.865594 2.06674 1.947703 2.076983 6.546552 100 a

Reverse a number in R

Fix to your code (digit here is not an integer, so when you divide it by 10, it goes 51.2, then 5.12 and so on, which is why you got INF as output):

digit<-512 
rev_num<-0
while(digit>0){
rev_num=rev_num*10 + digit %% 10
digit=as.integer(digit / 10)
}
print(paste(rev_num))

Another approach to reversing a number:

z <- 4321
as.numeric(paste(rev(strsplit(as.character(z),"")[[1]]),collapse=""))

Reverse digits in R

It is actually the decimial representation of the number that you are testing to be a palindrome, not the number itself (255 is a palendrome in hex and binary, but not decimal).

You can do this fairly simply using pattern matching:

> tmp <- c(100001, 123321, 123456)
> grepl( '^([0-9])([0-9])([0-9])\\3\\2\\1$', tmp )
[1] TRUE TRUE FALSE
>

you could convert the numbers to character, split into individual characters (strsplit), reverse each number (sapply and rev), then paste the values back together (paste) and covert back to numbers (as.numeric). But I think the above is better if you are just interested in 6 digit palendromes.

Reverse the order of digits in a large number

Make the following changes:

n <- 12345 # An example
rev <- 0
while (n>0){ #Include Open and closed Curly braces
r <- n %% 10
rev <- rev*10 + r
n <- n %/% 10 # Integer division is %/% and not %
}
sprintf("Reverse number is: %d", rev) # Use sprintf

[1] "Reverse number is: 54321"

Reverse digits of a list of numbers in python

Nice try, but what about a function that reverses the numbers? You should be happy to know that reversed already exists in Python, and you can use it this way:

>>> list(reversed(str(0.1223142131)))
['1', '3', '1', '2', '4', '1', '3', '2', '2', '1', '.', '0']
>>> float(''.join(reversed(str(0.1223142131))))
1312413221.0

so you can implement your own function:

def myReverser(n: float) -> float:
return float(''.join(reversed(str(n))))

and then use it over the whole list:

reversedList = [myReverser(i) for i in [1234, 124, 654]]

If you don't want the .0 at the end of all the numbers, this means that you don't want floating point numbers, but integers, so you can just do this:

reversedList = [int(i) for i in reversedList]

How to reverse a string in R

As @mplourde points out, you want the collapse argument:

paste(test_rev, collapse='')

Most commands in R are vectorized, but how exactly the command handles vectors depends on the command. paste will operate over multiple vectors, combining the ith element of each:

> paste(letters[1:5],letters[1:5])
[1] "a a" "b b" "c c" "d d" "e e"

collapse tells it to operate within a vector instead.

R:: reverse a string from x,y to y,x in r

will this do? using dplyr and tidyr functions

library(tidyverse)

aa %>% mutate(id = row_number()) %>%
pivot_longer(cols = -id) %>%
separate(value, into = c("Lat", "Long"), sep = ", ") %>%
mutate(new = paste(Long, Lat, sep = ", ")) %>%
select(-Lat, -Long) %>%
pivot_wider(id_cols = id, names_from = name, values_from = new)

# A tibble: 4 x 5
id a b c d
<int> <chr> <chr> <chr> <chr>
1 1 9.9365072, 78.1445111 9.9365044, 78.1444646 9.9365072, 78.1445111 9.9365044, 78.1444646
2 2 9.9365166, 78.1444197 9.9365422, 78.1443816 9.9365748, 78.142359 9.9366057, 78.1421918
3 3 9.9366057, 78.1421918 9.9367106, 78.1419488 9.9365166, 78.1444197 9.9365422, 78.1443816
4 4 9.9365748, 78.142359 9.9366057, 78.1421918 9.9366057, 78.1421918 9.9367106, 78.1419488

aa used

aa <- tribble(
~"a",~"b",~"c",~"d",
"78.1445111, 9.9365072", "78.1444646, 9.9365044", "78.1445111, 9.9365072", "78.1444646, 9.9365044",
"78.1444197, 9.9365166", "78.1443816, 9.9365422",
"78.142359, 9.9365748", "78.1421918, 9.9366057",
"78.1421918, 9.9366057", "78.1419488, 9.9367106",
"78.1444197, 9.9365166", "78.1443816, 9.9365422",
"78.142359, 9.9365748", "78.1421918, 9.9366057",
"78.1421918, 9.9366057", "78.1419488, 9.9367106",
)

Reverse a given number

Keep track of the number of digits in your number, and then print the number with a formatted length:

int numDigits = 0;
while (n != 0) {
...
numDigits++;
}

and then:

printf("Reversed number = %.*d", numDigits, rev);


Related Topics



Leave a reply



Submit