Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

snowstormdelivery

Melhor código para mostrar números perfeitos

Recommended Posts

Pessoal, estou estudando lógica de programação e a apostila faz um desafio ao estudante, a qual pede que façamos um pseudocódigo que mostre os quatro primeiros números perfeitos.

Como pedido, eu fiz um código que mostra os quatro números, na verdade ele mostra TODOS, porém são muitos cálculos para mostrá-los de imediato. Levaria horas, dias ou meses para mostrar os 47 números perfeitos conhecidos da matemática.

Fiquei curioso para melhorar o código, e descobri no Wikipédia que existe uma fórmula para calcular números perfeitos, mas esta fórmula só calcula os quatro primeiros. Para o meu desafio estaria ótimo, mas eu queria saber como melhorar o primeiro código (que mostra todos), para ele escrever os 47 números (teoricamente, óbvio), sem demorar uma eternidade.

 

 

Aqui está o código que mostra todos os números perfeitos (ajustado para mostrar somente 4):

algoritmo "GeradorDeNúmerosPerfeitos"
var
Dividendo, Divisor, SomaDivis, NumPerfeito:inteiro
inicio
//Executa o código, enquanto a quantidade de números perfeitos não for igual a 4.
      Enquanto nao (NumPerfeito = 4) faca
         //Esta atribuição faz que o divendo aumente 1 número a cada laço.
         Dividendo := Dividendo + 1
         //Esta faz com que a soma de divisores, do dividendo anterior, resete.
         SomaDivis := 0
         //Este laço gera um número diferente a cada loop, verificando se ele é divisor do dividendo anterior.
         Para Divisor := 1 ate (Dividendo - 1) faca
            //Se for um divisor, atribui-se o valor dele a uma variável de soma: SomaDivis.
            Se ( Dividendo % Divisor = 0) entao
               SomaDivis := SomaDivis + Divisor
               //Esta variável verifica se a soma de divisores é maior que o dividendo, se for, ele estoura o loop, acelerando a procura.
               Se (SomaDivis > Dividendo) entao
                  Divisor := (Dividendo - 1)
               FimSe
            FimSe
         FimPara
         //Se a soma de divisores for igual ao dividendo, ele escreve o valor do dividendo e soma 1 na variável de controle DivisPerfeito.
         Se (SomaDivis = Dividendo) entao
            Escreva (Dividendo)
            NumPerfeito := NumPerfeito + 1
         FimSe
      FimEnquanto
      //Fim do algoritmo quando o a quantidade de números perfeitos é igual a 4.
fimalgoritmo

Aqui está o código que mostra somente 4 números perfeitos, se quiserem olhar:

algoritmo "4NúmerosPerfeitos"
var
Primo, Dividendo, Divisor, ContDivis, NumPrimos:inteiro
NumPerfeito: real
inicio
// Este código se repete até o número de primos ser igual a 4, pois utiliza-se
//a fórmula de Euclides, a qual só usa os quatro primeiros primos e só mostra
//os quatro primeiros números perfeitos.
   Repita
      // Estas atribuições resetam o valor das variáveis para o código gerar um
      //novo número primo, sem causar conflitos.
      ContDivis := 0
      Primo := 0
      // Com a variável "Primo" resetada, pode-se iniciar o código para gerar
      //um novo número primo.
      Enquanto (Primo = 0) faca
         // O dividendo é o número que poderá vir a se tonar um primo, caso
         //possua 2 divisores, por isso ele aumenta 1 numero a cada loop.
         Dividendo :=  Dividendo + 1
         ContDivis := 0
         Para Divisor := 1 ate (Dividendo) faca
            //Esta condição conta quantos divisores o dividendo anterior possui.
            Se (Dividendo % Divisor = 0) entao
               ContDivis := ContDivis + 1
            FimSe
         FimPara
         // Se o dividendo anterior possuir dois divisores, ele é primo.
         Se (ContDivis = 2) entao
            Primo := Dividendo
            NumPrimos := NumPrimos + 1
         FimSe
      // Se houver algum número primo, o laço do "Enquanto" estoura.
      FimEnquanto
      // Calcula-se o número perfeito, à partir do número primo com a
      //fórmula de Euclides.
      NumPerfeito := ((2^(Primo - 1)) * ((2 ^ Primo) - 1))
      Se (NumPrimos = 4) entao
         Escreva (NumPerfeito,".")
      Senao
         Escreva (NumPerfeito,",")
      FimSe
   // Se já foi gerado quatro números primos, logo, quatro números perfeitos,
   //o programa encerra.
   Ate (NumPrimos =  4)
fimalgoritmo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Para diminuir o tempo de processamento você pode diminuir a quantidade de laços, comece a usar recursão que é muito mais amigável para o sistema. Cada laço aumenta muito a complexidade e o uso de memória.

 

Evite utilizar strings grandes para concatenar valores de exibição, use principalmente arrays.

 

Separe seu código em rotinas e procedimentos que vão ajudar no reuso da memória e no entendimento. Infelizmente o Portugol é lento mesmo, mas aplicando essas práticas a uma linguagem de alto nível você teria um bom desempenho.

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por sheepziiin
      Boa tarde colegas !
      Estou quebrando a cabeça com um job para tratamento de logradouros. Segue o raciocínio:  
      Tenho uma lista com todos os endereços do estado de São Paulo, onde os mesmos são extraídos da seguinte forma:
       
      Exemplo:
      AL-AFONSO SCHMIDT/CDM:ED. SOPHIS SANTANA_COM PRUMADA/BLC:A-555-AP - Apartamento: 61 A AL-ANAPURUS/EDI:BOULEVARD/BLC:A-777-AP - Apartamento: 131 AL-ARAPANES/EDI:CDOE,6-5ºANDAR-309-AP - Apartamento: 42 AL-ARAPANES/EDI:COND.ED.MOEMA DUPLEX LIFE-1142-AP - Apartamento: 102 AL-ARAPANES/EDI:COND.ED.MOEMA DUPLEX LIFE-1142-AP - Apartamento: 42 AL-ARAPANES/EDI:PARC BRUMENADI-982-AP - Apartamento: 191 AL-BARROS/EDI:PERVAL-186-AP - Apartamento: 1601 AL-BARROS/EDI:PERVAL-186-BL - Blocos: B AP - Apartamento: 1302 AL-CAETANO,S/CDM:ED. GIARDINO_CDOE_1_ANDAR_11 A 13-165-AP - Apartamento: 63 AL-CAETANO,S/EDI:ESPLENDOR-1234-AP - Apartamento: 71 AL-CAETANO,S/EDI:MAGENTA I_CDOE_1_ANDAR_7 A 10-2575-AP - Apartamento: 94 AL-CALCUTA-195-AP - Apartamento: 02 AL-CAMPESTRE-728-CS - Casa: 1 AL-CASA BRANCA/CDM:BRISTOL-851-CJ - Conjunto: 11 AN - Andar: 01 AL-CASA BRANCA/CDM:SAINT SIMON-667-AP - Apartamento: 11
      Notem que os casos "não tem um padrão" (até tem por tipo de residencia). Utilizei inúmeras postagens aqui do fórum e consegui solucionar os casos para residencias (padrão TIPO_LOG;LOG;COMPL;NUM), no entanto as formulas e soluções aqui indicadas por vocês "param" na primeira sequencia numérica, entretanto para a maioria dos casos, o texto continua com letras, números e caracteres.
       
      Segue o padrão final que preciso chegar.
      Exemplo: AL-AFONSO SCHMIDT/CDM:ED. SOPHIS SANTANA_COM PRUMADA/BLC:A-555-AP - Apartamento: 61 A
      Resultado Tratado: AFONSO SCHMIDT 555
       
      Desde de já muito obrigado pelos retornos que certamente virão.
    • Por diegohamaz1
      Pessoal como posso fazer uma formula de maior e menor?
       
       
      Seria mais ou menos assim , o ponto e virgula é como fosse um delimitador.
       
      SEMAIOR(5 ; SEMENOR ( 2 ; 6) o resultado seria 5.
       
      Porem posso ter recursividade tambem SEMAIOR ( 5 ; SEMAIOR(7;8(SEMENOR(5;6))) por exemplo
       
      Alguem tem uma função que faça essa conta? Similar a um excel mas nao quero usar biblioteca excel !
    • Por thiago pereira dos santos
      Fazer um algoritmo que dado um intervalo, informe quantos números primos existem nele.  Observações: a. serão dados como entradas o primeiro e o último número do intervalo em duas linhas subsequentes.  Arquivo fonte: quantosPrimos.py  Entrada: -------------------------------------------------------- 20 30 -------------------------------------------------------- Saída: -------------------------------------------------------- 2     Citar   Editar
    • Por Ericsson Berg
      Iai Pessoal, postando pela primeira vez aqui nesta área!!
       
      Tenho uma situação muito complicada para resolver e gostaria da ajuda de vocês.
       
      Como substituir os dados de uma fórmula que está em string pelo resultado de consultas no banco de dados?
       
      Os números que estão na fórmula correspondem aos dados de uma tabela onde preciso trazer o valor como retorno.
       
      Select codrelatorio, situacao,  formula
      Select 10, "teste", "([981] + [988]) / [700]" formula
       
      Ex.: Pegar o número 981 e realizar uma consulta em uma tabela, retornando assim o valor 1090.01;
      begin @valor = SELECT v.valor FROM table_exemplo WHERE codigo = 981 return @valor; end Fórmula: (1090.01 + [988]) / [700]
       
      E assim por diante até ter todos os números da fórmula substituídos e ter este resultado:
       
      Select 10, "teste", (1090.01 + 150) / 55  formula
       
       
    • Por Gurandao
      Olá galera, preciso criar um cálculo de correção monetária, já criei a tabela com todos os índices e fatores baseados no site https://api.tjsp.jus.br (Abril/2017).
      Vamos ao que interessa:
      Puxei os valores da tabela, a fórmula do cálculo é: Valor  (dividido) pelo fator do mes que venceu (multiplicado) pelo ultimo indice cadastrado (mes anterior).
      Então temos os valores: Valor (270.72), fator do mês que venceu (48.485963) e fator do mês anterior atual (66.839575).
      Eu criei o seguinte cálculo:
      $correcao =$valor / $fator_vcto * $fator_atual;
      ou seja:
      $correcao = 270.72 / 48.485963 * 66.839575;
      O resultado que ele me apresenta é 276.699454107990 sendo que na calculadora e no excel o valor correto calculado é 373.1968723
       
      Desde já agradeço à todos que puderem me ajudar!
       
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.