Здесь собраны интересные и разнообразные задачи по алгоритмам — от простых до сложных, подходящие для любого уровня подготовки. Упражнения из этого сборника помогут отработать умение решать алгоритмические задачи, поддерживать навыки программирования в тонусе и сделать процесс обучения увлекательным.
Что было раньше:
В предыдущей части мы решили:
- Welcome! (Добро пожаловать!)
- Eliminate the intruders! Bit manipulation (Уничтожьте злоумышленников! Битовые манипуляции)
- Two Sum (Две суммы)
- The Deaf Rats of Hamelin (Глухие крысы Гамельна)
- Factorial decomposition (Факториальное разложение)
Решение новых задач:
Задача 1
Платформа: CodeWars
Название задачи: Will there be enough space? (Будет ли достаточно места?)
Ссылка на задачу: https://www.codewars.com/kata/5875b200d520904a04000003
Сложность: 8 kyu
Уже решили (На момент написания статьи): 80 708 из 188 569
Тэги: Основы
Оригинальное описание задачи:
The Story:
Bob is working as a bus driver. However, he has become extremely popular amongst the city's residents. With so many passengers wanting to get aboard his bus, he sometimes has to face the problem of not enough space left on the bus! He wants you to write a simple program telling him if he will be able to fit all the passengers.
Task Overview:
You have to write a function that accepts three parameters:
`cap` is the amount of people the bus can hold excluding the driver.
`on` is the number of people on the bus excluding the driver.
`wait` is the number of people waiting to get on to the bus excluding the driver.
If there is enough space, return 0, and if there isn't, return the number of passengers he can't take.
Usage Examples:
cap = 10, on = 5, wait = 5 --> 0 He can fit all 5 passengers
cap = 100, on = 60, wait = 50 --> 10 He can't fit 10 of the 50 waiting
Пояснение задачи:
Задача формулируется следующим образом:
Описание задачи:
Боб работает водителем автобуса, который стал очень популярным среди горожан. Из-за большого количества желающих проехать на его автобусе иногда возникает проблема нехватки места. Нужно написать программу, определяющую, сможет ли Боб принять всех пассажиров, стоящих в очереди.
Формулировка задачи:
Функция принимает три параметра:
- `cap` — вместимость автобуса (количество мест, исключая водителя);
- `on` — количество пассажиров уже находящихся в автобусе (исключая водителя);
- `wait` — количество ожидающих пассажиров.
Необходимо определить, сколько человек не смогут сесть в автобус, либо вернуть 0, если есть возможность разместить всех ожидающих.
Примеры использования:
cap = 10, on = 5, wait = 5 → 0 // автобус вмещает всех ожидающих
cap = 100, on = 60, wait = 50 → 10 // автобус не вместит 10 ожидающих
Дополнительные комментарии:
- Возвращаемое значение — это количество людей, которых нельзя посадить в автобус.
- Если автобус способен вместить всех ожидающих, функция возвращает 0.
- Важно учесть, что проверка должна проводиться только относительно количества свободных мест, оставшихся после посадки уже находящихся пассажиров.
Задача 2
Платформа: CodeWars
Название задачи: Leap Years (Високосные годы)
Ссылка на задачу: https://www.codewars.com/kata/526c7363236867513f0005ca
Сложность: 7 kyu
Уже решили (На момент написания статьи): 45 016 из 132 080
Тэги: Дата Время, Алгоритмы
Оригинальное описание задачи:
In this kata you should simply determine, whether a given year is a leap year or not. In case you don't know the rules, here they are:
Years divisible by 4 are leap years, but years divisible by 100 are not leap years, but years divisible by 400 are leap years.
Tested years are in range `1600 ≤ year ≤ 4000`.
Пояснение задачи:
Задача заключается в проверке, является ли заданный год високосным согласно следующим правилам:
- Год считается високосным, если он делится на 4.
- Однако годы, делящиеся на 100, не являются високосными, за исключением тех, которые делятся на 400.
Проверяются года в диапазоне от 1600 до 4000.
Пример запроса(SQL-подход)
Для SQL-запроса требуется создать таблицу с двумя колонками: `id` (идентификатор строки) и `year` (год).
Необходимо вернуть результат проверки для каждого года, добавив колонку `is_leap`, где значение `1` означает, что год високосный, а `0` — невисокосный.
Результат должен быть отсортирован по возрастанию значений года.
Пример корректного SQL-запроса:
sql SELECT year,
CASE
WHEN year 400 = 0 THEN 1
WHEN year 100 = 0 THEN 0
WHEN year 4 = 0 THEN 1 ELSE 0 END AS is_leap FROM years ORDER BY year ASC;
Пример вывода:
| year | is_leap |
|-------|---------|
| 1600 | 1 |
| 1601 | 0 |
| 1604 | 1 |
| 1608 | 1 |
| 1616 | 1 |
Таким образом, задача сводится к написанию условия, проверяющего соответствие годов указанным критериям високосности.
Задача 3
Платформа: CodeWars
Название задачи: Valid Parentheses (Допустимые круглые скобки)
Ссылка на задачу: https://www.codewars.com/kata/6411b91a5e71b915d237332d
Сложность: 7 kyu
Уже решили (На момент написания статьи): 11 360 из 30 669
Тэги: Строки, синтаксический анализ, алгоритмы
Оригинальное описание задачи:
Write a function that takes a string of parentheses, and determines if the order of the parentheses is valid. The function should return `true` if the string is valid, and `false` if it's invalid.
Examples
"()" => true
")(()))" => false
"(" => false
"(())((()())())" => true
Constraints
`0 <= length of input <= 100`
- All inputs will be strings, consisting only of characters `(` and `)`.
- Empty strings are considered balanced (and therefore valid), and will be tested.
- For languages with mutable strings, the inputs should not be mutated.
Protip: If you are trying to figure out why a string of parentheses is invalid, paste the parentheses into the code editor, and let the code highlighting show you!
Пояснение задачи:
Необходимо написать функцию, проверяющую корректность последовательности скобок в строке.
Пояснение:
1. Входные данные: строка, состоящая исключительно из символов открывающихся (`(`) и закрывающихся (`)`) скобок.
2. Цель функции — определить, является ли последовательность скобок корректной (балансированной):
- Каждый открывающийся символ должен иметь соответствующий закрывающий.
- Последовательность должна начинаться с открывающих скобок и завершаться закрывающими.
- Нельзя встретить закрывающую скобку раньше соответствующей открывающей.
3. Решение через стек:
- Используем структуру данных «стек», который позволяет эффективно отслеживать соответствие открывающих и закрывающих скобок.
- При встрече открывающейся скобки добавляем её в стек.
- При встрече закрывающейся скобки извлекаем элемент из стека и проверяем, соответствует ли она открывающему символу.
- Если стек становится пустым до завершения проверки или не удается найти соответствующую открывающую скобку, возвращаем `false`.
4. Граничные случаи:
- Пустая строка считается корректной.
- Строка, содержащая только открывающиеся или только закрывающиеся скобки, некорректна.
- Для строки вида `(())`, `(())()` и аналогичных корректны.
Пример:
python def is_valid_parentheses(s: str) -> bool:
Создаем пустой стек для хранения открывающихся скобок
stack = []
Проходим по каждому символу строки
for char in s: if char == '(': Открывающаяся скобка stack.append(char) elif char == ')':
Закрывающаяся скобка if not stack or stack[-1]
'(': Проверяем наличие подходящей открывающей скобки return False stack.pop()
После прохода по всей строке проверяем, остались ли незакрытые скобки return len(stack) == 0
Объяснение примера:
- Строка "()" — корректная, потому что каждый открывающийся символ имеет пару закрывающего.
- Строка ")(()))" — некорректная, потому что сначала встречаем закрывающую скобку, не имеющую пары.
- Строка "(" — некорректная, поскольку не хватает закрывающей скобки.
- Строка "()()()" — корректная, каждая открыв
Задача 4
Платформа: CodeWars
Название задачи: Word a10n (abbreviation) (Слово а10н (аббревиатура))
Ссылка на задачу: https://www.codewars.com/kata/5375f921003bf62192000746
Сложность: 6 kyu
Уже решили (На момент написания статьи): 13 734 из 155 209
Тэги: Струны, основы
Оригинальное описание задачи:
The word `i18n` is a common abbreviation of `internationalization` in the developer community, used instead of typing the whole word and trying to spell it correctly. Similarly, `a11y` is an abbreviation of `accessibility`.
Write a function that takes a string and turns any and all "words" (see below) within that string of **length 4 or greater** into an abbreviation, following these rules:
A "word" is a sequence of alphabetical characters. By this definition, any other character like a space or hyphen (eg. "elephant-ride") will split up a series of letters into two words (eg. "elephant" and "ride").
The abbreviated version of the word should have the first letter, then the number of removed characters, then the last letter (eg. "elephant ride" => "e6t r2e").
Example input:
"elephant-rides are really fun!"
^^^^^^^^*^^^^^*^^^*^^^^^^*^^^*
words (^): "elephant" "rides" "are" "really" "fun"
123456 123 1 1234 1
ignore short words: X X
abbreviate: "e6t" "r3s" "are" "r4y" "fun"
all non-word characters (*) remain in place
"-" " " " " " " "!"
output: "e6t-r3s are r4y fun!"
Пояснение задачи:
Задача состоит в написании функции, которая преобразует слова внутри строки определённой длины в сокращённую форму по следующему правилу: -
Любое слово длиной четыре символа и больше заменяется аббревиатурой, состоящей из первой буквы, количества пропущенных букв и последней буквы.
- Слова короче четырёх символов остаются неизменёнными.
- Все остальные символы (пробелы, знаки препинания, дефисы и т.п.) сохраняются без изменений.
Пояснение к решению:
1. Определение слова: Слово считается последовательностью алфавитных символов, разделённых пробелами, знаками препинания или специальными символами.
2. Форматирование слова: Если слово имеет длину 4 или больше символов, оно заменяется на аббревиатуру следующего вида:
- Первая буква слова.
- Количество пропущенных букв между первой и последней (вычитается из общей длины слова).
- Последняя буква слова.
3. Сохранение структуры строки:
Все другие символы, включая пробелы, дефисы, запятые и точки, остаются без изменений.
Пример работы функции:
| Исходная строка | Преобразованная строка |
|-----------------|-------------------------------|
| elephant-rides | e6t-r3s|
| hello world | h5o w4|
| abcdefghij | a10j|
| test | t3t |
| 12345 | 12345 |
Дополнительные пояснения:
- Функция должна корректно обрабатывать длинные слова, содержащие заглавные буквы, цифры и специальные символы. - Пробелы и знаки пунктуации должны оставаться на своих местах, не влияя на процесс преобразования слов.
- Короткие слова (менее 4 символов) пропускаются и выводятся без изменений.
Пример кода
(общий принцип):
import re def abbreviate_words(input_string):
Регулярное выражение для поиска слов длиной 4 и более символов
pattern = r'\b[a-zA-Z]{4,}\b'
Замена каждого подходящего слова на аббревиатуру
def replace_word(match): word = match.group() return f"{word[0]}{len(word)-2}{word[-1]}"
Применяем замену к каждому слову result = re.sub(pattern, replace_word, input_string)
Задача 5
Платформа: CodeWars
Название задачи: Molecule to atoms (Молекула к атомам)
Ссылка на задачу: https://www.codewars.com/kata/52f831fa9d332c6591000511
Сложность: 5 kyu
Уже решили (На момент написания статьи): 6 281 из 84 705
Тэги: Синтаксический анализ, алгоритмы, строки
Оригинальное описание задачи:
For a given chemical formula represented by a string, count the number of atoms of each element contained in the molecule and return an object (associative array in PHP, `Dictionary` in C#, Map in Java).
For example:
water = 'H2O';
parseMolecule(water); # return {H: 2, O: 1}
magnesiumHydroxide = 'Mg(OH)2';
parseMolecule(magnesiumHydroxide); # return {Mg: 1, O: 2, H: 2}
fremySalt = 'K4[ON(SO3)2]2';
parseMolecule(fremySalt); # return {K: 4, O: 14, N: 2, S: 4}
As you can see, some formulas have brackets in them. The index outside the brackets tells you that you have to multiply count of each atom inside the bracket on this index. For example, in Fe(NO3)2 you have one iron atom, two nitrogen atoms and six oxygen atoms.
Note that brackets may be round, square or curly and can also be nested. Index after the braces is optional.
Пояснение задачи:
Требуется разработать функцию, принимающую химическую формулу в виде строки и возвращающую ассоциативный массив (словарь, карту), содержащий количество атомов каждого химического элемента, присутствующего в молекуле.
Пример входных данных и ожидаемого результата
- Формула: `"H2O"`
Результат: `{H: 2, O: 1}`
Объяснение:
молекула воды содержит два атома водорода и один атом кислорода.
- Формула: "Mg(OH)2"
Результат: `{Mg: 1, O: 2, H: 2}`
Объяснение: магнийгидроксид состоит из одного атома магния, двух атомов кислорода и двух атомов водорода.
-Формула: "K4[ON(SO3)2]2"
Результат: `{K: 4, O: 14, N: 2, S: 4}`
Объяснение: формула фремиевого соединения калия включает четыре атома калия, четырнадцать атомов кислорода, два атома азота и четыре атома серы.
Особенности обработки формул
- Химические формулы могут содержать круглые, квадратные и фигурные скобки, внутри которых указывается состав и количество молекул.
- Число после закрывающей скобки обозначает количество повторений содержимого скобок.
- Если число после скобки отсутствует, считается, что оно равно единице.
- Например, формула "Fe(NO3)2" означает, что внутри содержится одна молекула железа, две молекулы нитрата, каждая из которых состоит из одного атома азота, трёх атомов кислорода и одного атома кислорода, итого получаем одну молекулу железа, два атома азота и шесть атомов кислорода.
Примеры сложных формул:
- "Na2[AlF6]": {Na: 2, Al: 1, F: 6} (две молекулы натрия, одна молекула алюминия и шесть молекул фтора)
- "Ca3(PO4)2": {Ca: 3, P: 2, O: 8} (три атома кальция, два атома фосфора и восемь атомов кислорода)
Алгоритм решения:
Для корректной обработки химической формулы используется следующий алгоритм:
1. Разделяем строку на отдельные элементы (атомы и индексы).
2. Для каждого элемента определяем количество атомов, учитывая наличие индекса
Заключение:
Платформа: CodeWars
Название задачи: Will there be enough space? (Будет ли достаточно места?)
Ссылка на задачу: https://www.codewars.com/kata/5875b200d520904a04000003
Сложность: 8 kyu
Уже решили (На момент написания статьи): 80 708 из 188 569
Тэги: Основы
Оригинальное описание задачи:
The Story:
Bob is working as a bus driver. However, he has become extremely popular amongst the city's residents. With so many passengers wanting to get aboard his bus, he sometimes has to face the problem of not enough space left on the bus! He wants you to write a simple program telling him if he will be able to fit all the passengers.
Task Overview:
You have to write a function that accepts three parameters:
`cap` is the amount of people the bus can hold excluding the driver.
`on` is the number of people on the bus excluding the driver.
`wait` is the number of people waiting to get on to the bus excluding the driver.
If there is enough space, return 0, and if there isn't, return the number of passengers he can't take.
Usage Examples:
cap = 10, on = 5, wait = 5 --> 0 He can fit all 5 passengers
cap = 100, on = 60, wait = 50 --> 10 He can't fit 10 of the 50 waiting
Пояснение задачи:
Задача формулируется следующим образом:
Описание задачи:
Боб работает водителем автобуса, который стал очень популярным среди горожан. Из-за большого количества желающих проехать на его автобусе иногда возникает проблема нехватки места. Нужно написать программу, определяющую, сможет ли Боб принять всех пассажиров, стоящих в очереди.
Формулировка задачи:
Функция принимает три параметра:
- `cap` — вместимость автобуса (количество мест, исключая водителя);
- `on` — количество пассажиров уже находящихся в автобусе (исключая водителя);
- `wait` — количество ожидающих пассажиров.
Необходимо определить, сколько человек не смогут сесть в автобус, либо вернуть 0, если есть возможность разместить всех ожидающих.
Примеры использования:
cap = 10, on = 5, wait = 5 → 0 // автобус вмещает всех ожидающих
cap = 100, on = 60, wait = 50 → 10 // автобус не вместит 10 ожидающих
Дополнительные комментарии:
- Возвращаемое значение — это количество людей, которых нельзя посадить в автобус.
- Если автобус способен вместить всех ожидающих, функция возвращает 0.
- Важно учесть, что проверка должна проводиться только относительно количества свободных мест, оставшихся после посадки уже находящихся пассажиров.
Платформа: CodeWars
Название задачи: Leap Years (Високосные годы)
Ссылка на задачу: https://www.codewars.com/kata/526c7363236867513f0005ca
Сложность: 7 kyu
Уже решили (На момент написания статьи): 45 016 из 132 080
Тэги: Дата Время, Алгоритмы
Оригинальное описание задачи:
In this kata you should simply determine, whether a given year is a leap year or not. In case you don't know the rules, here they are:
Years divisible by 4 are leap years, but years divisible by 100 are not leap years, but years divisible by 400 are leap years.
Tested years are in range `1600 ≤ year ≤ 4000`.
Пояснение задачи:
Задача заключается в проверке, является ли заданный год високосным согласно следующим правилам:
- Год считается високосным, если он делится на 4.
- Однако годы, делящиеся на 100, не являются високосными, за исключением тех, которые делятся на 400.
Проверяются года в диапазоне от 1600 до 4000.
Пример запроса(SQL-подход)
Для SQL-запроса требуется создать таблицу с двумя колонками: `id` (идентификатор строки) и `year` (год).
Необходимо вернуть результат проверки для каждого года, добавив колонку `is_leap`, где значение `1` означает, что год високосный, а `0` — невисокосный.
Результат должен быть отсортирован по возрастанию значений года.
Пример корректного SQL-запроса:
sql SELECT year,
CASE
WHEN year 400 = 0 THEN 1
WHEN year 100 = 0 THEN 0
WHEN year 4 = 0 THEN 1 ELSE 0 END AS is_leap FROM years ORDER BY year ASC;
Пример вывода:
| year | is_leap |
|-------|---------|
| 1600 | 1 |
| 1601 | 0 |
| 1604 | 1 |
| 1608 | 1 |
| 1616 | 1 |
Таким образом, задача сводится к написанию условия, проверяющего соответствие годов указанным критериям високосности.
Платформа: CodeWars
Название задачи: Valid Parentheses (Допустимые круглые скобки)
Ссылка на задачу: https://www.codewars.com/kata/6411b91a5e71b915d237332d
Сложность: 7 kyu
Уже решили (На момент написания статьи): 11 360 из 30 669
Тэги: Строки, синтаксический анализ, алгоритмы
Оригинальное описание задачи:
Write a function that takes a string of parentheses, and determines if the order of the parentheses is valid. The function should return `true` if the string is valid, and `false` if it's invalid.
Examples
"()" => true
")(()))" => false
"(" => false
"(())((()())())" => true
Constraints
`0 <= length of input <= 100`
- All inputs will be strings, consisting only of characters `(` and `)`.
- Empty strings are considered balanced (and therefore valid), and will be tested.
- For languages with mutable strings, the inputs should not be mutated.
Protip: If you are trying to figure out why a string of parentheses is invalid, paste the parentheses into the code editor, and let the code highlighting show you!
Пояснение задачи:
Необходимо написать функцию, проверяющую корректность последовательности скобок в строке.
Пояснение:
1. Входные данные: строка, состоящая исключительно из символов открывающихся (`(`) и закрывающихся (`)`) скобок.
2. Цель функции — определить, является ли последовательность скобок корректной (балансированной):
- Каждый открывающийся символ должен иметь соответствующий закрывающий.
- Последовательность должна начинаться с открывающих скобок и завершаться закрывающими.
- Нельзя встретить закрывающую скобку раньше соответствующей открывающей.
3. Решение через стек:
- Используем структуру данных «стек», который позволяет эффективно отслеживать соответствие открывающих и закрывающих скобок.
- При встрече открывающейся скобки добавляем её в стек.
- При встрече закрывающейся скобки извлекаем элемент из стека и проверяем, соответствует ли она открывающему символу.
- Если стек становится пустым до завершения проверки или не удается найти соответствующую открывающую скобку, возвращаем `false`.
4. Граничные случаи:
- Пустая строка считается корректной.
- Строка, содержащая только открывающиеся или только закрывающиеся скобки, некорректна.
- Для строки вида `(())`, `(())()` и аналогичных корректны.
Пример:
python def is_valid_parentheses(s: str) -> bool:
Создаем пустой стек для хранения открывающихся скобок
stack = []
Проходим по каждому символу строки
for char in s: if char == '(': Открывающаяся скобка stack.append(char) elif char == ')':
Закрывающаяся скобка if not stack or stack[-1]
'(': Проверяем наличие подходящей открывающей скобки return False stack.pop()
После прохода по всей строке проверяем, остались ли незакрытые скобки return len(stack) == 0
Объяснение примера:
- Строка "()" — корректная, потому что каждый открывающийся символ имеет пару закрывающего.
- Строка ")(()))" — некорректная, потому что сначала встречаем закрывающую скобку, не имеющую пары.
- Строка "(" — некорректная, поскольку не хватает закрывающей скобки.
- Строка "()()()" — корректная, каждая открыв
Платформа: CodeWars
Название задачи: Word a10n (abbreviation) (Слово а10н (аббревиатура))
Ссылка на задачу: https://www.codewars.com/kata/5375f921003bf62192000746
Сложность: 6 kyu
Уже решили (На момент написания статьи): 13 734 из 155 209
Тэги: Струны, основы
Оригинальное описание задачи:
The word `i18n` is a common abbreviation of `internationalization` in the developer community, used instead of typing the whole word and trying to spell it correctly. Similarly, `a11y` is an abbreviation of `accessibility`.
Write a function that takes a string and turns any and all "words" (see below) within that string of **length 4 or greater** into an abbreviation, following these rules:
A "word" is a sequence of alphabetical characters. By this definition, any other character like a space or hyphen (eg. "elephant-ride") will split up a series of letters into two words (eg. "elephant" and "ride").
The abbreviated version of the word should have the first letter, then the number of removed characters, then the last letter (eg. "elephant ride" => "e6t r2e").
Example input:
"elephant-rides are really fun!"
^^^^^^^^*^^^^^*^^^*^^^^^^*^^^*
words (^): "elephant" "rides" "are" "really" "fun"
123456 123 1 1234 1
ignore short words: X X
abbreviate: "e6t" "r3s" "are" "r4y" "fun"
all non-word characters (*) remain in place
"-" " " " " " " "!"
output: "e6t-r3s are r4y fun!"
Пояснение задачи:
Задача состоит в написании функции, которая преобразует слова внутри строки определённой длины в сокращённую форму по следующему правилу: -
Любое слово длиной четыре символа и больше заменяется аббревиатурой, состоящей из первой буквы, количества пропущенных букв и последней буквы.
- Слова короче четырёх символов остаются неизменёнными.
- Все остальные символы (пробелы, знаки препинания, дефисы и т.п.) сохраняются без изменений.
Пояснение к решению:
1. Определение слова: Слово считается последовательностью алфавитных символов, разделённых пробелами, знаками препинания или специальными символами.
2. Форматирование слова: Если слово имеет длину 4 или больше символов, оно заменяется на аббревиатуру следующего вида:
- Первая буква слова.
- Количество пропущенных букв между первой и последней (вычитается из общей длины слова).
- Последняя буква слова.
3. Сохранение структуры строки:
Все другие символы, включая пробелы, дефисы, запятые и точки, остаются без изменений.
Пример работы функции:
| Исходная строка | Преобразованная строка |
|-----------------|-------------------------------|
| elephant-rides | e6t-r3s|
| hello world | h5o w4|
| abcdefghij | a10j|
| test | t3t |
| 12345 | 12345 |
Дополнительные пояснения:
- Функция должна корректно обрабатывать длинные слова, содержащие заглавные буквы, цифры и специальные символы. - Пробелы и знаки пунктуации должны оставаться на своих местах, не влияя на процесс преобразования слов.
- Короткие слова (менее 4 символов) пропускаются и выводятся без изменений.
Пример кода
(общий принцип):
import re def abbreviate_words(input_string):
Регулярное выражение для поиска слов длиной 4 и более символов
pattern = r'\b[a-zA-Z]{4,}\b'
Замена каждого подходящего слова на аббревиатуру
def replace_word(match): word = match.group() return f"{word[0]}{len(word)-2}{word[-1]}"
Применяем замену к каждому слову result = re.sub(pattern, replace_word, input_string)
Платформа: CodeWars
Название задачи: Molecule to atoms (Молекула к атомам)
Ссылка на задачу: https://www.codewars.com/kata/52f831fa9d332c6591000511
Сложность: 5 kyu
Уже решили (На момент написания статьи): 6 281 из 84 705
Тэги: Синтаксический анализ, алгоритмы, строки
Оригинальное описание задачи:
For a given chemical formula represented by a string, count the number of atoms of each element contained in the molecule and return an object (associative array in PHP, `Dictionary` in C#, Map in Java).
For example:
water = 'H2O';
parseMolecule(water); # return {H: 2, O: 1}
magnesiumHydroxide = 'Mg(OH)2';
parseMolecule(magnesiumHydroxide); # return {Mg: 1, O: 2, H: 2}
fremySalt = 'K4[ON(SO3)2]2';
parseMolecule(fremySalt); # return {K: 4, O: 14, N: 2, S: 4}
As you can see, some formulas have brackets in them. The index outside the brackets tells you that you have to multiply count of each atom inside the bracket on this index. For example, in Fe(NO3)2 you have one iron atom, two nitrogen atoms and six oxygen atoms.
Note that brackets may be round, square or curly and can also be nested. Index after the braces is optional.
Пояснение задачи:
Требуется разработать функцию, принимающую химическую формулу в виде строки и возвращающую ассоциативный массив (словарь, карту), содержащий количество атомов каждого химического элемента, присутствующего в молекуле.
Пример входных данных и ожидаемого результата
- Формула: `"H2O"`
Результат: `{H: 2, O: 1}`
Объяснение:
молекула воды содержит два атома водорода и один атом кислорода.
- Формула: "Mg(OH)2"
Результат: `{Mg: 1, O: 2, H: 2}`
Объяснение: магнийгидроксид состоит из одного атома магния, двух атомов кислорода и двух атомов водорода.
-Формула: "K4[ON(SO3)2]2"
Результат: `{K: 4, O: 14, N: 2, S: 4}`
Объяснение: формула фремиевого соединения калия включает четыре атома калия, четырнадцать атомов кислорода, два атома азота и четыре атома серы.
Особенности обработки формул
- Химические формулы могут содержать круглые, квадратные и фигурные скобки, внутри которых указывается состав и количество молекул.
- Число после закрывающей скобки обозначает количество повторений содержимого скобок.
- Если число после скобки отсутствует, считается, что оно равно единице.
- Например, формула "Fe(NO3)2" означает, что внутри содержится одна молекула железа, две молекулы нитрата, каждая из которых состоит из одного атома азота, трёх атомов кислорода и одного атома кислорода, итого получаем одну молекулу железа, два атома азота и шесть атомов кислорода.
Примеры сложных формул:
- "Na2[AlF6]": {Na: 2, Al: 1, F: 6} (две молекулы натрия, одна молекула алюминия и шесть молекул фтора)
- "Ca3(PO4)2": {Ca: 3, P: 2, O: 8} (три атома кальция, два атома фосфора и восемь атомов кислорода)
Алгоритм решения:
Для корректной обработки химической формулы используется следующий алгоритм:
1. Разделяем строку на отдельные элементы (атомы и индексы).
2. Для каждого элемента определяем количество атомов, учитывая наличие индекса
На этом пока всё. Надеюсь, статья была для вас интересной. Спасибо за внимание! Присоединяйтесь к решению алгоритмических задач, делитесь мыслями и решениями в комментариях — сохраняйте позитивный настрой. До встречи в новых статьях!
Вступайте в нашу телеграмм-группу Инфостарт