Menu
Coddy logo textTech

Racha más larga

Parte de la sección Lógica y Flujo del Journey de Swift de Coddy — lección 35 de 56.

Una racha es una serie de días consecutivos en los que un hábito se marcó como completado. Para los días [1, 2, 3, 5, 6], la racha más larga es 3 (días 1-3).

Calcularlo una vez que tienes una lista de días ordenada es un simple escaneo lineal: compara cada día con el anterior, extendiendo la racha actual cuando son consecutivos; de lo contrario, reinicia.

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
}

El patrón, "rastrear la ejecución actual + lo mejor hasta ahora", se repite en muchos problemas. Reconócelo una vez y será tuyo para siempre.

challenge icon

Desafío

Intermedio

Lee una sola línea de entrada: una lista separada por comas de entradas habit:day. Construye el mismo diccionario que hiciste en la lección anterior, luego, para cada hábito, calcula la racha más larga de días consecutivos a lo largo de la semana.

Imprime los hábitos en orden alfabético, uno por línea, en el formato:

<habit>: streak=<n>

Para la entrada read:1,read:2,read:3,read:5,workout:2,workout:4, la salida es:

read: streak=3
workout: streak=1

Hoja de referencia

Racha más larga – escaneo lineal rastreando la racha actual y la mejor hasta ahora:

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
}

Los días son consecutivos cuando cada uno es igual al anterior más uno. Reinicia run a 1 cuando haya un salto; actualiza best en cada iteración.

Pruébalo tú mismo

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: racha más larga por hábito, imprimir ordenado por nombre como 'nombre: racha=n'
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Lógica y Flujo