Coder88
Coder88

Reputation: 1055

How to translate all characters in a string

I'm building a function in R, where the function will take a string (like "ABCDEFG") and a matrix as inputs, and convert each character in the string into another string according the matrix.

The code I tried is this:

plugboard <- function() {
    matrix(sample(letters, 26, 
                  replace = FALSE, prob = NULL), 
           nrow = 2, ncol = 13)
}

This is to generate a matrix of two rows, where in each column there are two letters that are paired together.

And this function to decode the characters in the string according to the matrix generated in the first function:

decoder <- function(message, matrix) {
   message = tolower(message)
   for (i in 1:13){
      message = gsub(matrix[1,i], matrix[2,i], message)
   }
   return(message)
}

The result I get is something like this (x is the matrix, m is the string):

> x
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
[1,] "w"  "f"  "u"  "p"  "g"  "i"  "j"  "o"  "b"  "q"   "z"   "d"   "c"  
[2,] "k"  "s"  "a"  "l"  "m"  "e"  "n"  "r"  "y"  "t"   "x"   "v"   "h"  
> m = "wfupksal"
> decoder(m,x)
[1] "wfupwfup"
> 

it should turn "wfupksal" into "ksalwfup".

I mean the code should convert all characters in row 1 into characters in row two AND vica versa in the string. But I can only do one way (change all characters in row 2 into characters in row 1).

Example: If we take matrix "x" above as example, the string "hey how are you", should be converted into "cib crk uoi bra". In this case all characters in the string which are in row one is changed into the ones in row two and vice versa.

Is there a function in R to invert characters in a string?

Upvotes: 4

Views: 219

Answers (4)

Luke C
Luke C

Reputation: 10291

Late to the game, but a function that accommodates spaces in your message:

set.seed(42)

x <- plugboard()

message <- "example text"

codedecode <- function(message_, matrix) {
  output <- ""
  newmat <- matrix[nrow(matrix):1, ]
  splitmessage <- unlist(strsplit(message_, ""))
  for (i in splitmessage) {
    nl = newmat[which(matrix == i)]
    output <-
      paste(output, ifelse(length(nl != 0), nl, " "), sep = "")
  }
  return(output)
}

> scrambled <- codedecode(message, x); print(scrambled)
[1] "izqpmri gizg"
> unscrambled <- codedecode(scrambled, x); print(unscrambled)
[1] "example text"

Upvotes: 0

Douglas Mesquita
Douglas Mesquita

Reputation: 1021

First I will create a mat and define a message:

set.seed(1)
mat <- plugboard()
message <- "isbba"

Now you can solve the problem for each letter using a function:

decode_letter <- function(mat, letter){
  pos <- which(letter == mat, arr.ind = T)
  letter <- mat[ifelse(pos[1] == 1, 2, 1), pos[2]]

  return(letter)
}

After that you can split your message and apply the function for all letters:

message_split <- unlist(strsplit(x = message, split = ""))

letter_dec <- sapply(message_split, FUN = decode_letter, mat = mat, simplify = T)
message_dec <- paste(letter_dec, collapse = "")

message_dec
[1] "hello"

I hope it works!

Upvotes: 1

JasonAizkalns
JasonAizkalns

Reputation: 20463

@akrun's solution is much more elegant and introduces a new function to me chartr, but here's a more long-winded approach with a walkthrough:

mat <- matrix(letters[1:6], nrow = 2, byrow = TRUE)
mat
#     [,1] [,2] [,3]
# [1,] "a"  "b"  "c" 
# [2,] "d"  "e"  "f" 

inputs <- mat[1, ]
outputs <- mat[2, ]

# See how this gives you 1 3
match(c("a", "c"), inputs)
# Then...
outputs[match(c("a", "c"), inputs)]

# So...
paste(outputs[match(unlist(strsplit("ac", "")), inputs)], collapse = "")

# In a function:
decode <- function(matix, string) {
  inputs <- mat[1, ]
  outputs <- mat[2, ]

  paste(outputs[match(unlist(strsplit(string, "")), inputs)], collapse = "")

}

decode(matix, "ac")
# [1] "df"

Upvotes: 3

akrun
akrun

Reputation: 886998

Not clear about the conditions, perhaps

v1 <- apply(x, 1, paste, collapse="")
chartr(paste(v1, collapse=""), paste(rev(v1), collapse=""), m)
#[1] "ksalwfup"

Upvotes: 6

Related Questions