Codewars "For building the encrypted string"

For building the encrypted string:
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!"

Write two methods:

function encrypt(text, n)
function decrypt(encryptedText, n)

For both methods:
If the input-string is null or empty return exactly this value!
If n is <= 0 then return the input text.

Я вот на чем застрял:

'use strict';

function encrypt(text) {
  let result = '';
  console.log(text.length);
  for (let i = 0; i < text.lenght; i++) {
    if (i % 2 === 0) {
      result += text.charAt(i);
    }
  }
  console.log({ result });
}

encrypt('This is a test!');

выводит text.length как 15, но цикл проходит 1 раз и не прибавляет к result ничего. Можете объяснить мне в чем проблема?

text.lenght-> text.length

1 лайк

Подход отладки для таких случаев

  1. Ты знаешь по какому условию цикл прерывается.
  2. Ты ожидаешь что он прервется после 15 итераций.
  3. 15 итераций не происходит.
  4. Смотришь во что вычисляется значение которое используется в условии прерывания.
1 лайк

ее можно через рекурсию сделать?

Да. Большинство (если не все, не знаю точно) вещей которые выражаются через цикл можно выразить через рекурсию. И наоборот: рекурсию можно выразить через цикл. При выборе метода выражения вопрос только в удобстве понимания конечного решения. Ну или выпендрится.

1 лайк

Да, здесь через рекурсию проще.

'use strict';

function encrypt(text, n) {
  if (text === null || text === '' || n < 0) return text;

  let first = '',
    second = '';

  for (let i = 0; i < text.length; i++) {
    if (i % 2 !== 0) first += text[i];
    else second += text[i];
  }
  if (n > 1) return encrypt(first + second, n - 1);
  else return first + second;
}

console.log(encrypt('This is a test!', 1));
console.log(encrypt('This is a test!', 2));

Это спорное утверждение. Я бы сказал что без рекурсии как раз проще. Сравни количество нюансов примере с рекурсией и в примере влоб:

function encode(text) {
	var letters = text.split('')
	var rest = []
	var even = []
	for (var i = 0; i < letters.length; i += 1) {
		if (i % 2) {
			rest.push(letters[i])
		} else {
			even.push(letters[i])
		}
	}
	return even.join('') + rest.join('')
}

Я не учел количество итераций. Сейчас пересмотрю пример.

Тесты codewars

describe("Solution", function(){
  it("EncryptExampleTests", function(){    
    Test.assertEquals(encrypt("This is a test!", 0), "This is a test!");
    Test.assertEquals(encrypt("This is a test!", 1), "hsi  etTi sats!");
    Test.assertEquals(encrypt("This is a test!", 2), "s eT ashi tist!");
    Test.assertEquals(encrypt("This is a test!", 3), " Tah itse sits!");
    Test.assertEquals(encrypt("This is a test!", 4), "This is a test!");
    Test.assertEquals(encrypt("This is a test!", -1), "This is a test!");
    Test.assertEquals(encrypt("This kata is very interesting!", 1), "hskt svr neetn!Ti aai eyitrsig");
  });
});

describe("Solution", function(){
  it("DecryptExampleTests", function(){    
    Test.assertEquals(decrypt("This is a test!", 0), "This is a test!");
    Test.assertEquals(decrypt("hsi  etTi sats!", 1), "This is a test!");
    Test.assertEquals(decrypt("s eT ashi tist!", 2), "This is a test!");
    Test.assertEquals(decrypt(" Tah itse sits!", 3), "This is a test!");
    Test.assertEquals(decrypt("This is a test!", 4), "This is a test!");
    Test.assertEquals(decrypt("This is a test!", -1), "This is a test!");
    Test.assertEquals(decrypt("hskt svr neetn!Ti aai eyitrsig", 1), "This kata is very interesting!");
  });
});

describe("Solution", function(){
  it("Null or Empty", function(){    
    Test.assertEquals(encrypt("", 0), "");
    Test.assertEquals(decrypt("", 0), "");
    Test.assertEquals(encrypt(null, 0), null);
    Test.assertEquals(decrypt(null, 0), null);
  });
});

Думаю даже с учетом функционала повторения, линейный пример проще для понимания чем рекурсия.

Рекурсия обычно более компактная, но ее сложнее понять потому что нужно выстраивать ментальную модель работы функции из большего количества условий/факторов.

function encode(text, n) {
	for (j = 0; j < n; j += 1) {
		var letters = text.split('')
		var rest = []
		var even = []
		for (var i = 0; i < letters.length; i += 1) {
			if (i % 2) {
				rest.push(letters[i])
			} else {
				even.push(letters[i])
			}
		}
		text = even.join('') + rest.join('')
	}
	return text
}
1 лайк