Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Exercício resolvido... mas gostaria de saber se é possível resolver sem os booleans?

Segue a minha resolução (com os booleans):

<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Programa</title>
</head>
<body>
    <script>
        function pulaLinha() {
            document.write("<br><hr><br>");
        }

        function mostra(frase) {
            document.write(frase);
            pulaLinha();
        }

        var ingredientes = [];

        var quantidade = parseInt(prompt("Quantos ingredientes vão ser adicionados?"));

        var contador = 1;

        while (contador <= quantidade) {
            var ingrediente = prompt("Informe o ingrediente " + contador);
            var jaAdicionou = false;
            for (var i = 0; i < ingredientes.length; i++) {
                if (ingredientes[i] == ingrediente) {
                    alert("Você já adicionou esse ingrediente");
                    jaAdicionou = true;
                    break;
                }
            }

            if (jaAdicionou == false) {
                ingredientes.push(ingrediente);
                contador++;
            }
        }

        mostra("Os ingredientes desta receita são " + ingredientes);

    </script>
</body>
</html>

Porém, gostaria de saber se seria possível resolver esse exercício sem criar a variável que recebe um boolean?? Apenas com for, while, if e else...?

Tentei da seguinte forma (e de outras tb, mas essa foi a que fez mais sentido no raciocínio lógico para mim), porém, dessa forma, eu entro num loop infinito logo após aparecer a caixinha de inserir o ingrediente 1:

<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        var ingredientes = [];

        var quantidade = parseInt(prompt("Quantos ingredientes vão ser adicionados?"));

        var contador = 1;

        while (contador <= quantidade) {
            var ingrediente = prompt("Informe o ingrediente " + contador);
            for (var i = 0; i < ingredientes.length; i++) {
                if (ingredientes[i] == ingrediente) {
                    alert("Você já adicionou esse ingrediente");
                    break;
                } else {
                    ingredientes.push(ingrediente);
                    contador++;
                }
            }
        }
        console.log(ingredientes);
    </script>
</body>
</html>
3 respostas

Olá, Anne, tudo bem?

No seu código que não está usando booleans está acontecendo o seguinte problema: quando entramos no while pela primeira vez, o array ingredientes ainda está vazio, e o for que o percorre não é executado! Dessa forma, o comando contador++ dentro do else nunca é executado, então a variável contador sempre terá valor 1 e o laço do while nunca é quebrado, e sempre executará a pergunta "Informe o ingrediente 1".

Sobre resolver esse exercício sem utilizar booleans, admito que pensei bastante e não cheguei a uma solução sem utilizá-los. A questão é que o problema desse exercício envolve uma lógica mais complexa e, portanto, um algoritmo mais complexo.

Vamos revisar o que está sendo pedido: queremos adicionar itens no array ingredientes, mas não queremos que nenhum se repita. A estratégia é percorrer o array sempre que vamos adicionar um novo item, verificando se ele já existe.

Prosseguindo com a estratégia, guardaremos em uma variável (por exemplo, existe) o valor booleano que diz se pelo menos um dos ingredientes do array é igual ao novo ingrediente digitado.

É uma verificação um tanto complexa, que depende inclusive do tamanho do array para que possamos percorrê-lo utilizando o for. E queremos verificar se devemos adicionar o novo item apenas com a certeza de termos percorrido o array completamente.

Precisamos então de uma informação, uma variável, para nos dizer se devemos ou não adicionar esse novo ingrediente, depois de termos percorrido o array, e uma variável booleana é o ideal para isso.

Espero ter ajudado! Abraços e bons estudos :)

Oi Antônio!

Primeiramente, obrigada pela resposta, ajudou sim!

Porém, fiquei ainda com uma dúvida. Na tentativa sem boolean, o for dentro do while não é executado pelo fato do array estar vazio? Ele tentaria percorrer a lista, porém ela está vazia, por isso o for não é executado, é isso? E se eu colocasse um item dentro do array, então, funcionaria?

Obrigada!

solução!

Olá novamente, Anne!

Na tentativa sem boolean, o for dentro do while não é executado pelo fato do array estar vazio? Ele tentaria percorrer a lista, porém ela está vazia, por isso o for não é executado, é isso?

Isso mesmo! Quando o array ingredientes está vazio, ingredientes.length tem valor 0. Na primeira verificação i < ingredientes.length, a variável i também tem valor 0, e como 0 não é menor do que 0, a verificação é avaliada como false e o for não é executado.

E se eu colocasse um item dentro do array, então, funcionaria?

Sim, o for seria executado pelo menos uma vez. O problema é que o código ainda não funcionaria como esperado, vamos analisar o bloco for:

            for (var i = 0; i < ingredientes.length; i++) {
                if (ingredientes[i] == ingrediente) {
                    alert("Você já adicionou esse ingrediente");
                    break;
                } else {
                    ingredientes.push(ingrediente);
                    contador++;
                }
            }

O problema desse código (que foi o mesmo problema que respondi nesse tópico) é que a verificação ingredientes[i] == ingrediente é realizada para cada um dos itens do array. Se houverem 3 itens no array, por exemplo, essa verificação poderá ser realizada até 3 vezes.

Então para cada vez que essa verificação for false, entraremos no bloco else, e assim o item poderá ser adicionado diversas vezes.

Em vez disso, queremos garantir que o comando ingredientes.push(ingrediente); seja executado uma única vez (ou nenhuma) após percorrermos o array, ou seja, fora da estrutura for.

Por coincidência, o tópico que linkei acima possui uma solução de outro aluno, que encontrou uma solução sem utilizar booleans. Eu particularmente achei mais complicado de entender, mas achei bem interessante pelo fato de funcionar, você pode dar uma olhada ;)

Espero ter ajudado! Bons estudos :)