Menu
Coddy logo textTech

Plus longue série

Fait partie de la section Logique et Flux du Journey Swift de Coddy — leçon 35 sur 56.

Une série est une suite de jours consécutifs où une habitude a été marquée comme accomplie. Pour les jours [1, 2, 3, 5, 6], la plus longue série est de 3 (jours 1-3).

Le calculer une fois que vous avez une liste de jours triée est un simple balayage linéaire : comparez chaque jour au précédent, en prolongeant la série actuelle lorsqu'ils sont consécutifs, sinon réinitialisez.

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
}

Le schéma, « suivre la série actuelle + le meilleur résultat jusqu'à présent », réapparaît dans de nombreux problèmes. Reconnaissez-le une fois et il est à vous pour toujours.

challenge icon

Défi

Moyen

Lisez une seule ligne d'entrée : une liste d'entrées habit:day séparées par des virgules. Construisez le même dictionnaire que celui que vous avez créé dans la leçon précédente, puis, pour chaque habitude, calculez la plus longue série de jours consécutifs sur la semaine.

Affichez les habitudes par ordre alphabétique, une par ligne, au format :

<habit>: streak=<n>

Pour l'entrée read:1,read:2,read:3,read:5,workout:2,workout:4, la sortie est :

read: streak=3
workout: streak=1

Aide-mémoire

Série la plus longue – balayage linéaire suivant la série actuelle et la meilleure jusqu'à présent :

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
}

Les jours sont consécutifs lorsque chacun est égal au précédent plus un. Réinitialisez run à 1 lors d'un écart ; mettez à jour best à chaque itération.

Essayez vous-même

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: plus longue série par habitude, afficher trié par nom sous la forme 'name: streak=n'
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Logique et Flux