Самая длинная серия
Часть раздела Логика и управление потоком путешествия по Swift на Coddy — урок 35 из 56.
Серия — это последовательность идущих подряд дней, в которые привычка была отмечена как выполненная. Для дней [1, 2, 3, 5, 6] самая длинная серия составляет 3 (дни 1-3).
Вычисление этого после получения отсортированного списка дней представляет собой простое линейное сканирование: сравните каждый день с предыдущим, увеличивая текущую последовательность, если они идут подряд, в противном случае выполните сброс.
func longestStreak(_ days: [Int]) -> Int {
let sorted = days.sorted()
var best = 0
var run = 0
var prev: Int? = nil
for d in sorted {
if let p = prev, d == p + 1 {
run += 1
} else {
run = 1
}
if run > best { best = run }
prev = d
}
return best
}Паттерн «отслеживание текущего прогона + лучший результат на данный момент» встречается во многих задачах. Распознайте его один раз, и он останется с вами навсегда.
Задание
СреднеПрочитайте одну строку ввода: список записей habit:day, разделенных запятыми. Создайте такой же словарь, как в предыдущем уроке, а затем для каждой привычки вычислите самую длинную серию последовательных дней в течение недели.
Выведите привычки в алфавитном порядке, по одной в строке, в формате:
<habit>: streak=<n>Для входных данных read:1,read:2,read:3,read:5,workout:2,workout:4 результатом будет:
read: streak=3
workout: streak=1Шпаргалка
Самая длинная серия – линейное сканирование, отслеживающее текущую серию и лучший результат на данный момент:
func longestStreak(_ days: [Int]) -> Int {
let sorted = days.sorted()
var best = 0, run = 0
var prev: Int? = nil
for d in sorted {
if let p = prev, d == p + 1 { run += 1 } else { run = 1 }
if run > best { best = run }
prev = d
}
return best
}Дни считаются последовательными, когда каждый следующий равен предыдущему плюс один. Сбрасывайте run до 1 при разрыве; обновляйте best на каждой итерации.
Попробуйте сами
var habits: [String: [Int]] = [:]
let ops = readLine()!.components(separatedBy: ",")
for op in ops {
let parts = op.components(separatedBy: ":")
let day = Int(parts[1])!
if !(habits[parts[0], default: []].contains(day)) {
habits[parts[0], default: []].append(day)
}
}
// TODO: самая длинная серия для каждой привычки, вывести отсортированным по имени в формате 'name: streak=n'
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Строки в деталях
Подсчет и индексыРегистр и удаление пробеловПоиск в строкахРазделение и объединениеЗамена подстрокИтоги — Проверка имени пользователя4Множества
Создание множествОбъединение и пересечениеРазность и симметрическая разностьПодмножество и надмножествоИтоги — Фильтр тегов7Проект — Трекер привычек
Обзор проектаОтметить выполнение10Проект — Движок викторины
Обзор проектаЗадаем вопросы2Диапазоны и шаги
Закрытые и полуоткрытыеШагМетоды диапазоновДиапазоны в SwitchИтоги: Сетка календаря