Menu
Coddy logo textTech

Сравнение недель

Часть раздела Логика и управление потоком путешествия по 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 превращает в ноль.

challenge icon

Задание

Средне

Прочитайте две строки входных данных, каждая из которых представляет собой список записей habit:day, разделенных запятыми (по одной строке на неделю). Для каждой привычки, которая встречается в любой из недель, выведите одну строку в следующем формате:

<habit>: <a> -> <b> <arrow>

где a — количество уникальных дней в первой неделе, b — количество уникальных дней во второй неделе, а arrow принимает значения:

  • UP, когда b > a
  • DOWN, когда b < a
  • SAME, когда 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>'
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Логика и управление потоком