Resolvendo Problemas Clássicos e Explorando Programação Dinâmica com JavaScript

Resolvendo Problemas Clássicos e Explorando Programação Dinâmica com JavaScript

Programar é uma atividade cheia de desafios. Neste artigo vamos explorar problemas clássicos e programação dinâmica, utilizando exemplos práticos em JavaScript. 

Quais os problemas que serão abordados neste artigo?

  • Torre de Hanói
  • Dois Números com Soma Alvo
  • Elemento Mais Frequente de um Array
  • O Problema da Mochila
  • Maior Subsequência Crescente
  • Fibonacci Otimizado

 

 

A Torre de Hanói

 

A Torre de Hanói é um quebra-cabeça matemático que foi criado em 1883 pelo matemático francês Édouard Lucas. Ele apresentou o problema sob o nome "Torre de Brâmanes" e o associou a uma lenda fascinante para torná-lo mais intrigante.

Segundo a lenda, havia um templo em Benares (atualmente Varanasi, na Índia), onde sacerdotes realizavam um ritual envolvendo três pinos e 64 discos de ouro de tamanhos diferentes. A tarefa dos sacerdotes era mover todos os discos de um pino para outro, seguindo as mesmas regras do quebra-cabeça moderno:

 

- Apenas um disco pode ser movido por vez.

- Um disco maior não pode ser colocado sobre um menor.

- Todos os discos devem ser transferidos de uma torre para outra.

 

Dizia-se que quando os sacerdotes completassem a tarefa, o universo chegaria ao fim. No entanto, a matemática por trás do problema mostra que isso levaria uma quantidade de tempo extraordinária para acontecer. Mesmo que os sacerdotes trabalhassem a uma velocidade de um movimento por segundo, levariam cerca de 585 bilhões de anos para concluir a tarefa — muito mais do que a idade atual do universo!

Este problema é excelente para entender conceitos de recursão.

 

function hanoi(n, from, to, aux) {

    if (n === 1) {

        console.log(`Move o disco 1 de ${from} para ${to}`);

        return;

    }

    hanoi(n - 1, from, aux, to);

    console.log(`Move o disco ${n} de ${from} para ${to}`);

    hanoi(n - 1, aux, to, from);

}

hanoi(3, \'A\', \'C\', \'B\'); // Exemplo com 3 discos

 

Esse problema ajuda a entender como dividir uma tarefa complexa em subtarefas menores, um conceito crucial em algoritmos.

 

Dois Números com Soma Alvo

 

Dado um array de números e um valor alvo, o objetivo é encontrar dois números cuja soma seja igual ao valor alvo.

 

function twoSum(nums, target) {

    const map = new Map();

    for (let i = 0; i < nums.length; i++) {

        const complement = target - nums[i];

        if (map.has(complement)) {

            return [map.get(complement), i];

        }

        map.set(nums[i], i);

    }

    return [];

}

console.log(twoSum([2, 7, 11, 15], 9)); // Saída: [0, 1]

 

Esse é um problema comum em entrevistas e destaca a eficiência de usar estruturas de dados como Map para resolver problemas em tempo linear.

 

Elemento Mais Frequente

 

O desafio é encontrar o elemento que aparece mais vezes em um array.

 

function mostFrequent(nums) {

    const freqMap = {};

    let maxCount = 0, mostFrequentNum = null;

 

    for (let num of nums) {

        freqMap[num] = (freqMap[num] || 0) + 1;

        if (freqMap[num] > maxCount) {

            maxCount = freqMap[num];

            mostFrequentNum = num;

        }

    }

    return mostFrequentNum;

}

console.log(mostFrequent([1, 3, 2, 3, 3, 1, 2, 1, 1])); // Saída: 1

 

Esse problema introduz o uso de mapas de frequência, uma técnica comum para analisar conjuntos de dados.

 

O problema da mochila

 

O problema da mochila foi formalizado no campo da teoria da computação e da pesquisa operacional. Ele apareceu inicialmente em estudos matemáticos sobre programação linear e teoria dos grafos no início do século XX, mas se popularizou no século XX com a crescente demanda por algoritmos eficientes para resolver problemas reais.

A primeira referência clara ao problema como o conhecemos hoje é encontrada nos trabalhos de pesquisadores como George Dantzig, que também é famoso por desenvolver o método Simplex.

A ideia básica é simples: você é um aventureiro com uma mochila de capacidade limitada. Diante de você estão vários itens, cada um com um peso e um valor. O desafio é escolher quais itens levar para maximizar o valor total sem ultrapassar o peso máximo que a mochila pode suportar.

Este problema é um clássico para aprender sobre otimização e ele é uma metáfora para muitas decisões práticas, como Gestão de Recursos, Planejamento de Investimentos, Logística e Jogos e Simulações.

 

function knapsack(values, weights, capacity) {

    const n = values.length;

    const dp = Array.from({ length: n + 1 }, () => Array(capacity + 1).fill(0));

 

    for (let i = 1; i <= n; i++) {

        for (let w = 1; w <= capacity; w++) {

            if (weights[i - 1] <= w) {

                dp[i][w] = Math.max(dp[i - 1][w], values[i - 1] + dp[i - 1][w - weights[i - 1]]);

            } else {

                dp[i][w] = dp[i - 1][w];

            }

        }

    }

    return dp[n][capacity];

}

console.log(knapsack([60, 100, 120], [10, 20, 30], 50)); // Saída: 220

 

Este problema ensina como usar tabelas para armazenar soluções intermediárias, um conceito essencial na programação dinâmica.

 

Maior Subsequência Crescente

 

O objetivo deste problema é encontrar a maior subsequência crescente dentro de um array de números.

 

 

function longestIncreasingSubsequence(nums) {

    const dp = Array(nums.length).fill(1);

 

    for (let i = 1; i < nums.length; i++) {

        for (let j = 0; j < i; j++) {

            if (nums[i] > nums[j]) {

                dp[i] = Math.max(dp[i], dp[j] + 1);

            }

        }

    }

    return Math.max(...dp);

}

console.log(longestIncreasingSubsequence([10, 9, 2, 5, 3, 7, 101, 18])); // Saída: 4

 

Esse problema mostra como identificar relações entre elementos e usar técnicas iterativas para resolvê-lo eficientemente.

 

Fibonacci Otimizado

 

A sequência de Fibonacci foi introduzida ao mundo ocidental pelo matemático italiano Leonardo de Pisa, conhecido como Fibonacci, em seu livro Liber Abaci (1202). No livro, ele usou a sequência para resolver um problema sobre o crescimento de uma população de coelhos em condições ideais.

Imagine que:

- Você começa com um par de coelhos.

- Cada par de coelhos atinge a maturidade em um mês.

- Após o primeiro mês, cada par maduro gera um novo par de coelhos a cada mês.

- Nenhum coelho morre.

- Quantos pares de coelhos existirão após um determinado número de meses?

Ao modelar o crescimento, Fibonacci descobriu a sequência que leva seu nome.

O desafio é calcular o n-ésimo número de Fibonacci de forma eficiente, evitando a recursão simples.

 

function fibonacci(n) {

    if (n <= 1) return n;

    let prev = 0, curr = 1;

 

    for (let i = 2; i <= n; i++) {

        [prev, curr] = [curr, prev + curr];

    }

    return curr;

}

console.log(fibonacci(10)); // Saída: 55

 

O problema de Fibonacci demonstra como otimizar soluções ao reduzir o uso de memória sem comprometer a eficiência.

 

 

Está começando e deseja saber o que precisa estudar de HTML e JavaScript? Não deixe de conferir os roteiros de estudo de HTML e JavaScript!. São dezenas de conteúdos para você melhorar suas habilidades.

Roteiro de estudos - HTML e CSS

Roteiro de estudos - Javascript

 

Outros conteudos que podem ser de seu interesse

Ler arquivo PDF com NodeJS
01/12/2019JAVASCRIPT

Ler arquivo PDF com NodeJS

Veja como extrair o texto de um arquivo PDF usando NodeJS

Saiba mais...
Compactar arquivos com JavaScript
24/06/2023JAVASCRIPT

Compactar arquivos com JavaScript

Veja como compactar artigos utilizando JavaScript

Saiba mais...
Percorrer as propriedades de um objeto com JavaScript
25/11/2019JAVASCRIPT

Percorrer as propriedades de um objeto com JavaScript

Veja as várias formas de fazer loop nas propriedades de um objeto

Saiba mais...

Conteúdo sobre banco de dados sem complicação!


Warning: Cannot modify header information - headers already sent by (output started at /home/storage/f/7d/a9/dbins/public_html/blog/post.php:101) in /home/storage/f/7d/a9/dbins/public_html/blog/ga4_track.php on line 11