Desafio Rust

Busca em matriz com labels

Enunciado

Dada uma matriz 3x3 de inteiros, encontre a posição (linha, coluna) do primeiro número negativo. Use loops aninhados com labels para interromper ambos os loops assim que encontrar. Se não houver negativo, imprima uma mensagem adequada.

Requisitos

  • Use for aninhado com label no loop externo.
  • Use break 'label para sair de ambos os loops ao encontrar.
  • Imprima Encontrado negativo em (linha, coluna): (i, j) ou Nenhum negativo encontrado.

Código inicial

fn main() {
    let matriz = [
        [1, 2, 3],
        [4, -5, 6],
        [7, 8, -9],
    ];
    // use labels para encontrar o primeiro negativo
}

Saída esperada

Encontrado negativo em (linha, coluna): (1, 1)
Ver dica

O label deve ser declarado antes do for externo: 'externo: for .... Use break 'externo; quando encontrar.

Mostrar solução
fn main() {
    let matriz = [
        [1, 2, 3],
        [4, -5, 6],
        [7, 8, -9],
    ];

    let mut encontrado = false;

    // label no loop externo
    'externo: for (i, linha) in matriz.iter().enumerate() {
        for (j, &valor) in linha.iter().enumerate() {
            if valor < 0 {
                println!("Encontrado negativo em (linha, coluna): ({}, {})", i, j);
                encontrado = true;
                break 'externo; // sai dos dois loops
            }
        }
    }

    if !encontrado {
        println!("Nenhum negativo encontrado");
    }
}

Passo a passo

  1. Definimos uma matriz 3x3 de inteiros.
  2. Declaramos encontrado como false para controlar se achamos ou não.
  3. Iniciamos o loop externo com label 'externo, iterando sobre as linhas com enumerate() para obter o índice i.
  4. No loop interno, iteramos sobre os elementos da linha com enumerate() para obter o índice j.
  5. Se encontramos um valor negativo, imprimimos a posição, marcamos encontrado = true e usamos break 'externo; para sair de ambos os loops.
  6. Após os loops, se encontrado for falso, imprimimos a mensagem de que nenhum negativo foi achado.

Por que funciona

Labels permitem nomear loops e direcionar break ou continue para um loop específico. Sem labels, teríamos que usar uma flag booleana e verificar após cada iteração interna, o que é mais verboso. O break 'externo interrompe imediatamente o loop externo, economizando iterações desnecessárias.

Erros comuns

  • Esquecer o apóstrofo no label: externo: for está errado; o correto é 'externo: for.
  • Usar break 'externo dentro do loop interno sem ter declarado o label no loop externo: erro de compilação.
  • Não usar &valor na desestruturação: for (j, valor) in linha.iter().enumerate() daria &i32, e a comparação valor < 0 funcionaria, mas é mais idiomático desestruturar com &valor para obter i32.

Outra forma de resolver

Poderia usar iter().flatten() e position(), mas perderíamos a informação da linha e coluna. Labels são a forma mais clara aqui.

Saída esperada

Encontrado negativo em (linha, coluna): (1, 1)