Сравнение недель
Часть раздела Логика и управление потоком путешествия по Swift на Coddy — урок 37 из 56.
Финальная функция: возьмите данные за две недели и выведите отчет об изменениях по каждой привычке.
Каждая неделя представляет собой отдельный список операций habit:day на отдельной строке. Создайте два словаря тем же способом, что и раньше, а затем сравните их.
Интересующий нас набор привычек — это объединение ключей за обе недели (привычка может появиться в одну неделю, но отсутствовать в другой). Переберите это объединение, отсортированное по алфавиту.
let allKeys = Set(weekA.keys).union(weekB.keys).sorted()
for name in allKeys {
let a = weekA[name]?.count ?? 0
let b = weekB[name]?.count ?? 0
print("\(name): \(a) -> \(b)")
}Выражение ?? 0 обрабатывает случай отсутствующего ключа. weekA[name]?.count — это способ чтения количества с использованием опциональной цепочки без предварительного извлечения значения; оно возвращает nil, если ключ отсутствует, что выражение ?? 0 превращает в ноль.
Задание
СреднеПрочитайте две строки входных данных, каждая из которых представляет собой список записей habit:day, разделенных запятыми (по одной строке на неделю). Для каждой привычки, которая встречается в любой из недель, выведите одну строку в следующем формате:
<habit>: <a> -> <b> <arrow>где a — количество уникальных дней в первой неделе, b — количество уникальных дней во второй неделе, а arrow принимает значения:
UP, когдаb > aDOWN, когдаb < aSAME, когдаb == a
Выводите привычки в алфавитном порядке. После строк для каждой привычки выведите одну итоговую строку:
Improved: <n>где n — количество привычек со значением UP.
Для входных данных read:1,read:3,workout:2 в первой строке и read:1,read:2,read:5,yoga:7 во второй строке, результат будет следующим:
read: 2 -> 3 UP
workout: 1 -> 0 DOWN
yoga: 0 -> 1 UP
Improved: 2Шпаргалка
Чтобы получить объединение ключей из двух словарей и перебрать их в алфавитном порядке:
let allKeys = Set(weekA.keys).union(weekB.keys).sorted()
for name in allKeys {
let a = weekA[name]?.count ?? 0
let b = weekB[name]?.count ?? 0
print("\(name): \(a) -> \(b)")
}weekA[name]?.count использует опциональную цепочку (optional chaining), чтобы получить количество без извлечения; возвращает nil, если ключ отсутствует. ?? 0 преобразует этот nil в ноль.
Попробуйте сами
func parse(_ line: String) -> [String: [Int]] {
var habits: [String: [Int]] = [:]
if line.isEmpty { return habits }
for op in line.components(separatedBy: ",") {
let parts = op.components(separatedBy: ":")
let day = Int(parts[1])!
if !(habits[parts[0], default: []].contains(day)) {
habits[parts[0], default: []].append(day)
}
}
return habits
}
let weekA = parse(readLine()!)
let weekB = parse(readLine()!)
// TODO: объединение ключей; для каждой привычки '<name>: a -> b ARROW'; затем 'Improved: <n>'
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Строки в деталях
Подсчет и индексыРегистр и удаление пробеловПоиск в строкахРазделение и объединениеЗамена подстрокИтоги — Проверка имени пользователя4Множества
Создание множествОбъединение и пересечениеРазность и симметрическая разностьПодмножество и надмножествоИтоги — Фильтр тегов7Проект — Трекер привычек
Обзор проектаОтметить выполнение10Проект — Движок викторины
Обзор проектаЗадаем вопросы2Диапазоны и шаги
Закрытые и полуоткрытыеШагМетоды диапазоновДиапазоны в SwitchИтоги: Сетка календаря