Menu
Coddy logo textTech

Longest Streak

Part of the Logic & Flow section of Coddy's Swift journey — lesson 35 of 56.

A streak is a run of consecutive days a habit was marked done. For days [1, 2, 3, 5, 6], the longest streak is 3 (days 1-3).

Computing it once you have a sorted day list is a simple linear scan: compare each day to the previous one, extending the current run when they're consecutive, otherwise reset.

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
}

The pattern, "track current run + best so far", recurs in many problems. Recognise it once and it's yours forever.

challenge icon

Challenge

Medium

Read a single line of input: a comma-separated list of habit:day entries. Build the same dictionary you did in the previous lesson, then for each habit compute the longest consecutive-day streak across the week.

Print the habits in alphabetical order, one per line, in the format:

<habit>: streak=<n>

For input read:1,read:2,read:3,read:5,workout:2,workout:4, the output is:

read: streak=3
workout: streak=1

Cheat sheet

Longest streak – linear scan tracking current run and best so far:

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
}

Days are consecutive when each equals the previous plus one. Reset run to 1 on a gap; update best every iteration.

Try it yourself

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: longest streak per habit, print sorted by name as 'name: streak=n'
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Logic & Flow