Создавая приложение за приложением в течение последних нескольких месяцев, я лично забыл многие приемы и приемы, которым научился, когда начинал программировать. Например, методы, которые раньше так укоренились в моей голове, я больше не использовал в повседневной жизни. Но с таким количеством онлайн-ресурсов, документации и моих собственных заметок я могу освежить свои знания.

Но просто читать документацию и заметки недостаточно, но, к счастью, есть много веб-сайтов, на которых можно зарегистрироваться и попрактиковаться с множеством задач по кодированию и / или руководств. Ниже приведен список лишь некоторых из этих типов ресурсов:
- https://www.hackerrank.com
- https://leetcode.com/
- https://www.codewars.com
- https://www.codecademy.com

Ниже я потренируюсь с некоторыми проблемами и покажу некоторые решения, которые я придумал, и объясню свой мыслительный процесс.

Практика №1

Функция #accum принимает строку и выводит следующее:

accum("abcd")    # "A-Bb-Ccc-Dddd" 
accum("RqaEzty") # "R-Qq-Aaa-Eeee-Zzzzz-Tttttt-Yyyyyyy" accum("cwAt")    # "C-Ww-Aaa-Tttt"

Решение №1 с Ruby

def accum(s)     
  new_string = ""  
    
  s.each_char.with_index do |char, idx|       
    segment = (char * (idx + 1)).capitalize  
     
    if idx == s.length - 1         
        new_string << "#{segment}"       
    else         
        new_string << "#{segment}-"       
    end   
  end    
  
  new_string 
end

Пошаговая инструкция:
 – объявите new_string, чтобы сохранить ответ и вывести его позже. Он будет иметь тип String
- #each_char разбивает строку на отдельные символы. #with_index — это метод цепочки, который предоставляет нам индекс каждого элемента. Используя оба метода, я могу передать char (каждый символ) и idx (индекс символа).
- я объявляю переменную segment и установите его равным строке, созданной путем умножения символа (idx + 1) раз. Метод #capitalize сделает только первую букву прописной, а все остальные — строчными.
 — Условие используется, чтобы решить, добавлять ли тире ("-") к конкретному segment или нет, И чтобы поместить его в переменную new_string. Если индекс является последним элементом введенной строки, это означает, что мне не нужно добавлять тире. В противном случае мне придется добавить тире к сегменту.
 — Вернуть новую_строку

Решение № 2 с Ruby

def accum(s)
 answer = []
  s.split("").each_with_index do |letter, index|
    segment = letter.upcase
    index.times { segment << letter.downcase }
    answer << segment
  end
  answer.join("-")
end

Пошаговая инструкция:
 – объявите ответ, чтобы сохранить результаты и вывести их позже. Он будет сохранен в виде массива.
 – Использование #split разделит строку на массив отдельных символов. Поскольку s теперь представляет собой массив, я могу использовать метод #each_with_index для перебора каждого символа и индекса, я могу передать letter и index, соответственно.
- На каждой итерации я устанавливаю переменную segment, которая будет инициализироваться буквой, переданной в #верхнем регистре. Segment будет строкой.
- Затем, используя индекс, я могу использовать итератор #times, чтобы поместить букву #в нижний регистр-d в строку сегмент. В Ruby я могу объединять строки с помощью метода #push (‹‹).
- После завершения сегмента я могу вставить сегмент в ответ. Это продолжается до тех пор, пока я не достигну конца исходной строки.
— наконец, я возвращаю переменную answer, соединенную дефисом.

Решение №3 с использованием JavaScript

function accum(s) {
  var answer = []
  s.split("").forEach( (letter, idx) => {
    var segment = ""
    segment += letter.toUpperCase()
    while (idx > 0 ){
      segment += letter.toLowerCase()
      idx -= 1
    }
    answer.push(segment)
  })
 return answer.join("-")
}

Пошаговая инструкция (аналогично решению №2):
- Объявите переменную answer для сохранения результатов и вывода позже. Он будет храниться в виде массива.
. Как и в Ruby, в JavaScript есть функция #split, которая работает со строками для разделения символов. Затем я хочу перебрать каждый символ с помощью функции #forEach. Я могу передать букву и индекс, letter и idx соответственно.
- В каждом цикле я объявляю переменную segment для хранения строка
— первый символ, который нужно объединить в сегмент, — это заглавная буква с использованием toUpperCase(). В отличие от Ruby, я не могу вставлять подстроки в строки, поэтому мне нужно конкатенировать с помощью +=.
- Затем у меня есть итератор, если idx больше нуля, я буду конкатенировать букву в segment idx-times.
— После завершения цикла, если он вообще выполняется, я использую push(), чтобы сегментировать в массив answer.
- В JavaScript мне нужно явно использовать ключевое слово return, чтобы дать ответ, соединенный тире.

Практика №2

The goal of this exercise is to convert a string to a new string where each character in the new string is ‘(‘ if that character appears only once in the original string, or ‘)’ if that character appears more than once in the original string. Ignore capitalization when determining if a character is a duplicate.
"din" # "((("
"recede" #  "()()()"
"Success" # ")())())"
"(( @" # "))(("

Решение №1 с Ruby

def duplicate_encode(word)
  answer = ""
  count = Hash.new(0)
  word.each_char { |letter| count[letter.downcase] += 1}
  word.each_char { |letter| count[letter.downcase] == 1 ? answer <<   
      "(" : answer << ")" }
  answer
end

Пошаговая инструкция:
 – объявите ответ, чтобы сохранить результаты и вывести их позже.
 – объявить хэш count и d присвоить значениям значение по умолчанию с нулевым значением. Здесь будет храниться количество раз, когда символ появляется в слове.
 – Первая итерация будет проходить через каждую букву слова, #в нижнем регистре ее, установить ее в качестве ключа в хэше count и добавьте единицу к количеству раз, которое оно появилось.
 — Вторая итерация снова пройдёт слово. На этот раз он #прописывает букву и проверяет по хешу count, сколько раз она появлялась. Если он появился один раз, я вставлю «(» в строку ответа, иначе вставлю «)». Я использую однострочный оператор if-else, так как требуется только одно действие.
— В конце я неявно возвращаю строку answer.

Решение № 2 с Ruby

def duplicate_encode(word)
   word.each_char.map { |letter|   
      word.downcase.count(letter.downcase) == 1 ? "(" : 
      ")" 
   }.join
end

Пошагово:
- Все это записывается одной строкой
- Чтобы исключить необходимость хранения ответа, я могу использовать метод #map для возврата нового массива . Я разбиваю слово по символам и сопоставляю его, передавая букву.
 — С каждой буквой я буду использовать #count, чтобы узнать, сколько раз оно встречается в слове. Так как это должно быть нечувствительным к регистру, мне нужно #уменьшить регистр всего слова перед использованием #count.
- Затем мне нужно также #перевести в нижний регистр переданную букву. Если она появится один раз, я создам "(" в новом массиве из # сопоставить, иначе я создам ")" в новом массиве.
- В конце я #объединю вновь сопоставленный массив

Решение №3 с JavaScript

function duplicateEncode(word){
  var count = new Object
  for (i = 0; i < word.length; i++ ){
    var letter = word[i].toLowerCase()
    if (count[letter]){
      count[letter]++
    } else {
      count[letter] = 1
    }
  }
  return word.split("").map( (char) => {
    if (count[char.toLowerCase()] === 1){
      return "("
    } else {
      return ")"
    }
  }).join("")
}

Пошагово (аналогично решению №1):
- Объявите переменную count, которая является объектом.
- Пройдите через все слово один раз, используя цикл for.
- Для каждого символа в i-й индексируем его toLowerCase() и устанавливаем как переменную буква.
- Если объект count имеет букву в качестве ключа, я увеличу его на единицу, иначе установлю букву в >count и установите значение равным единице.
- Javascript содержит функцию map(), и мне придется явно возвращать результаты.
- Для каждого char, если count[char] равен единице, я верну в этот вновь сопоставленный массив «(», иначе «)».
- В конце мне нужно join() отображать массив с помощью “”.