1
\$\begingroup\$

Task: Take every 2nd char from the string, then the other chars, that are not every 2nd char, and concat them as new String. Do this n times!

Examples:

"This is a test!", 1 -> "hsi  etTi sats!"
"This is a test!", 2 -> "hsi  etTi sats!" -> "s eT ashi tist!"

Code:

const split = (text) => {
  const firstPart = text.split('').filter((element, index) => index % 2 != 0).join('')
  const secondPart = text.split('').filter((element, index) => index % 2 == 0).join('')

  return firstPart + secondPart
}

const encrypt = (text, n) => {
  if (text == null) {
    return null
  }

  let result = text

  for (let i = 0; i < n; i++) {
    result = split(result)
  }

  return result
}

const decrypt = (text, n) => {
  if (text == null) {
    return null
  }

  for (let i = 0; i < n; i++) {
    let firstPartLength = text.length % 2 == 0 ? text.length / 2 : (text.length - 1) / 2 + 1
    let secondPartLenght = text.length % 2 == 0 ? text.length / 2 : (text.length - 1) / 2
    let firstPart = text.substring(0, firstPartLength)
    let secondPart = text.substring(secondPartLenght, text.length)

    secondPart = secondPart.split('').map(element => element + ' ').join('')
    let position = -1
    secondPart = secondPart.split('').map((element, index) => index % 2 != 0 ? firstPart[++position] : element).join('').substring(0, text.length)

    text = secondPart
  }

  return text
}

console.log(decrypt(encrypt('This is a test!', 3), 3))

console.log(encrypt('Some text!', 4))

\$\endgroup\$
1
\$\begingroup\$

Here's a declarative take on it:

const is2ndChar = (c, i) => i % 2;
const isNot2ndChar = (c, i) => !(i % 2)

const scramble = s => 
  s.split('').filter(is2ndChar)
  .concat(s.split('').filter(isNot2ndChar))
  .join('');

const test1 = scramble('This is a test!');
const test2 = scramble(scramble('This is a test!'));

console.log(test1, test1 === 'hsi  etTi sats!');
console.log(test2, test2 === 's eT ashi tist!');

The filter-functions are only used once each, so they could just go directly into filter, but it's a little more legible this way.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ -1, declaring functions with fat arrow syntax is stack trace hell, fat arrow are only okay for inline declarations. We should not show this as an alternative. \$\endgroup\$ – konijn Aug 22 '17 at 18:05
1
\$\begingroup\$
const split = (text) => (text.replace(/.(.)?/g, '$1') + ("d"+text).replace(/.(.)?/g, '$1')

The regex matches every other char. Do it twice, add any arbitrary char to the start of the string the second time to offset it.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This could additionally take advantage of arrow functions' syntax for implied return -- just remove the curly brackets and return. \$\endgroup\$ – shabs Aug 21 '17 at 20:38
  • \$\begingroup\$ @shabs - idk, i feel like the other way was more readable, but as you wish.. \$\endgroup\$ – I wrestled a bear once. Aug 21 '17 at 20:53
  • \$\begingroup\$ :P i don't have wishes, just options \$\endgroup\$ – shabs Aug 21 '17 at 20:54
1
\$\begingroup\$
  1. Modification on the split function should be a little more efficient since you only go through the variable once.
  2. Added join function using similar logic as split. Again, should be more efficient.
  3. Removed let result = text in the encrypt function and used text. No need to create an extra variable here.

const split = (text) => {
  let n = Math.floor(text.length / 2)
  return text.split('').reduce((a, v, i) => {
    a[i % 2 ? (i - 1) / 2 : n + (i / 2)] = v
    return a
  }, []).join('')
}

const join = (text) => {
  let n = Math.floor(text.length / 2)
  return text.split('').reduce((a, v, i) => {
    a[i < n ? (i + 1) * 2 - 1 : (i - n) * 2] = v
    return a
  }, []).join('')
}

const encrypt = (text, n) => {
  if (text == null) {
    return null
  }

  for (let i = 0; i < n; i++) {
    text = split(text)
  }

  return text
}

const decrypt = (text, n) => {
  if (text == null) {
    return null
  }

  for (let i = 0; i < n; i++) {
    text = join(text)
  }

  return text
}

console.log(decrypt(encrypt('This is a test!', 3), 3))

console.log(encrypt('Some text!', 4))

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.