Ir ao conteúdo
  • Comunicados

    • Gabriel Torres

      Seja um moderador do Clube do Hardware!   12-02-2016

      Prezados membros do Clube do Hardware, Está aberto o processo de seleção de novos moderadores para diversos setores ou áreas do Clube do Hardware. Os requisitos são:   Pelo menos 500 posts e um ano de cadastro; Boa frequência de participação; Ser respeitoso, cordial e educado com os demais membros; Ter bom nível de português; Ter razoável conhecimento da área em que pretende atuar; Saber trabalhar em equipe (com os moderadores, coordenadores e administradores).   Os interessados deverão enviar uma mensagem privada para o usuário @Equipe Clube do Hardware com o título "Candidato a moderador". A mensagem deverá conter respostas às perguntas abaixo:   Qual o seu nome completo? Qual sua data de nascimento? Qual sua formação/profissão? Já atuou como moderador em algo outro fórum, se sim, qual? De forma sucinta, explique o porquê de querer ser moderador do fórum e conte-nos um pouco sobre você.   OBS: Não se trata de função remunerada. Todos que fazem parte do staff são voluntários.
    • DiF

      Poste seus códigos corretamente!   21-05-2016

      Prezados membros do Fórum do Clube do Hardware, O Fórum oferece um recurso chamado CODE, onde o ícone no painel do editor é  <>     O uso deste recurso é  imprescindível para uma melhor leitura, manter a organização, diferenciar de texto comum e principalmente evitar que os compiladores e IDEs acusem erro ao colar um código copiado daqui. Portanto convido-lhes para ler as instruções de como usar este recurso CODE neste tópico:  
Diego_Soares

VisualG Algoritmo pra número primo

Recommended Posts

Boa noite,

Estou com uma questão pra elaborar um algoritmo que calcule o total de números primos entre 1 e 1000 utilizando a estrutura de repetição para.

E depois de um dia batendo cabeça, o máximo que eu consegui foi a seguinte solução: o programa apresenta o resultado correto, porém durante a execução do algoritmo ele para de responder cerca de 5 segundos.

 

Var
   Cont1, N, divisores, Cont2, primo: inteiro

Inicio
   para Cont1 de 1 ate 1000 faca
      N <- Cont1
      divisores <- 0
      para Cont2 de 1 ate N faca
         se (N % Cont2 = 0) então
            divisores <- divisores + 1
         fimse
      fimpara
      se (divisores = 2) então
         primo <- primo + 1
      fimse
   fimpara

   escreval("Total de números primos: ", primo)

Fimalgoritmo

 

Alguém tem uma forma melhor de fazer, ou de ajustar/otimizar?

Qualquer dica adicional quanto a elaborar um código é muito bem vinda também.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bem vindo, Sr. @Diego_Soares!

Observei no seu algoritmo que a variável 'primo' não foi inicializada antes de 'primo <- primo+1'. Como o programa não tem esse valor inicial para a variável, acho que o programa fica sem saber "ao que somar 1". Talvez isso esteja causando a demora observada.

Desejo sucesso!

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá a todos.

 

Creio que o programa está correto. Apenas precisa de alguns refinamentos.

 

 

11 horas atrás, Diego_Soares disse:

porém durante a execução do algoritmo ele para de responder cerca de 5 segundos.

Normal, isso é o tempo do processamento, já que são mais de 500.000 cálculos!!! (basta efetuar a "soma da PA".)

 

Obs.: é possível reduzir esse número, como por exemplo diminuindo o valor máximo do divisor... por exemplo, você está dividindo até o N, mas muuuuito antes disso a divisão já é impossível que seja divisível, ou seja, está fazendo muita conta sem necessidade... basta achar qual seria o maior divisor possível para cada número e aplicar no algoritmo. Outra forma de melhor seria apenas dividindo por número primos. Daí, como o próprio programa já vai encontrando, você pode ir armazenando os primos e utilizando eles na conta, para isso pode usar vetores.

 

ADENDO:

10 horas atrás, André Ferreira da Silva disse:

Observei no seu algoritmo que a variável 'primo' não foi inicializada antes de 'primo <- primo+1'

Apesar de ser recomendado inicializar as variáveis, no Visualg não se faz necessário, pois elas são zeradas automaticamente (assim como no Pascal/Delphi). O números ficam com 0 e as "caractere" ficam com '' (sem letras armazenadas), assim por diante. Já em outras linguagens como Java, C/C++ dão de fato problema, pois lá o gerenciamento é diferente...

 

obs.: em funções e procedimento também podem dar problema no Visualg e Pascal, pois as variáveis globais só são inicializadas automaticamente.

 

Para testes, experimentem ir pressionando F8, quando as variáveis forem declaradas, verás que apareceram "zeradas" na "Área de Variáveis" que fica no canto superior direito.

 

No aguardo.

  • Curtir 2
  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • Autor do tópico
  • Bom dia a todos.

     

    Obrigado @André Ferreira da Silva ! Toda dica já me ajuda muito! A intenção é manter as práticas mais recomendadas.

     

    @Simon Viegas , bem que eu suspeitava que tinha conta sem necessidade sendo feita :D. Obrigado por esclarecer perfeitamente minhas dúvidas. 

     

    22 horas atrás, Simon Viegas disse:

    basta achar qual seria o maior divisor possível para cada número e aplicar no algoritmo

    Vou seguir essa recomendação e depois vou tentar a outra forma de dividir apenas por números primos.

     

    • Curtir 2

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Olá.

     

    31 minutos atrás, Diego_Soares disse:

    Vou seguir essa recomendação e depois vou tentar a outra forma de dividir apenas por números primos.

     

    Dica inicial: efetue testes com um universo menor... por exemplo com apenas 100 números. A depender com apenas 10... a base é a mesma, ou seja, as regras do algoritmo para primos independe do valor de N, daí com um N menor é mais fácil efetuar as comparações do resultado retornado com o real.

     

    A ideia é ir tentando entender o como funciona os primos e ir aplicando melhorias, ex.:

     

    - verifique apenas o possíveis candidatos: com exceção do 2, se for par não tem como ser primo, logo já reduz pela metade (ou aproximadamente) o número de cálculos. Ajuste o código para apenas verificar os número 3, 5, 7, 9, 11..., 995, 997, 999. Encontre uma forma de ter essa sequência;

     

    - utilize no máximo o máximo MDC possível para reduzir o número de verificações para cada número: uma certeza básica é que não pode ser maior que a metade de N, já que o menor divisor primo é o 2, logo o "divisor do outro lado" seria o maior divisor, correto? Por exemplo: 210. Seu maior divisor é 210/2, ou seja, 105. Logo, não faz sentido verificar o 106, 107, 108... (se já considerar a ideia acima, só será por ímpar, logo não necessitando do 107, 109, 111...). RESUMINDO: verificando apenas de 1 a N/2 já reduz pela metade. Faça isso e testa os resultados. Daí, vai analisando e entendendo os conceitos para tentar encontrar um máximo MDC ainda menor. Quando menor o máximo MDC melhor.

     

    - utilizar divisores primo: acho que você já entendeu...

     

    - pare de verificar se já identificar um "não primo": se encontrar um divisor extra (se atente que todo número tem 2 divisores, no caso 1 e ele mesmo), não precisa continuar verificando, ou seja, não importa se tem outros ou não. Para de verificar e vai para o próximo.

     

    Etc.

     

    Vá fazendo por partes... Não tente fazer tudo de uma vez. Insere uma melhora e testa. Se tiver dúvidas, posta aqui. Após, insere outra... repete processo... (tira dúvidas, vai pro próximo, tira dúvidas, vai pro próximo).

     

     

    Tente fazer uma implementação e posta o código aqui.

     

    No aguardo.

    • Curtir 2

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • Muito boas as dicas. Tá trabalhoso, mas com as recomendações consegui progredir. Falta mudar algumas coisas ainda no código.

    A minha dificuldade tá em aplicar o máximo divisor sem acabar criando mais contas para o algoritmo executar. Uma coisa que eu tive que fazer foi  mudar a estrutura "para" para outra (no caso, a "enquanto").

     

    Var
       Cont1, divisores, C, primo: inteiro
    
    
    Inicio
       primo <- 0
       para Cont1 de 1 ate 100 faca
          se Cont1 % 2 <> 0 então
             divisores <- 0
             C <- 0
             enquanto (C < Cont1) faca
                C <- C + 1
                se Cont1 % C = 0 então
                   divisores <- divisores + 1
                   se divisores > 2 então
                   C <- Cont1
                   fimse
                fimse
                se C * 2 >= Cont1 então
                   se divisores = 1 então
                      divisores <- divisores + 1
                      C <- Cont1
                   fimse
                fimse
             fimenquanto
             se divisores = 2 então
                primo <- primo + 1
             fimse
          fimse
       fimpara
       escreval("Total de números primos: ", primo)
    Fimalgoritmo

     

    2 horas atrás, Simon Viegas disse:

    Ajuste o código para apenas verificar os número 3, 5, 7, 9, 11..., 995, 997, 999. Encontre uma forma de ter essa sequência;

     

     Daí, vai analisando e entendendo os conceitos para tentar encontrar um máximo MDC ainda menor. Quando menor o máximo MDC melhor.

     

     

    Próximo passo é esse.

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Olá.

     

    2 horas atrás, Diego_Soares disse:

    A minha dificuldade tá em aplicar o máximo divisor sem acabar criando mais contas para o algoritmo executar.

     

    Obs. 1: eu utilizei o termo MDC, mas na verdade seria apenas MD, já que está se verificando apenas o "maior divisor" do número! Não cabe aqui o termo "comum", pois para ser "comum" teria que ter os divisores de outro(s) número(s) (para ai encontrar "o maior divisor comum entre eles").

     

    Obs. 2: Na verdade não é exatamente o MD, já que o maior divisor sempre será o próprio número... como você mesmo trata no seu código:

    2 horas atrás, Diego_Soares disse:
    
                   se divisores = 1 então
                      divisores <- divisores + 1
                      C <- Cont1
                   fimse

    Ou seja, como não está dividindo por ele mesmo, a quantidade de divisores ficará com um a menos. Resumindo: você precisa encontrar o SMD (Segundo Maior Divisor), rs. Está dando para compreender até aqui? 

     

     

    Vamos lá... o trecho abaixo:

             enquanto (C < Cont1) faca

    Pode ser traduzido como:

    enquanto (divisor_atual < limite_de_valor_para_o_divisor_que_eu_tenho_certeza_que_após_ele_NÃO_pode_ser_um_divisor)

    Ou seja, o valor do "divisor atual" não precisa ser maior que esse limite, pois sei que não será divisível.

     

    No seu caso, você deixou o limite como sendo o próprio número (Cont1), mas dentro do trecho faz uma verificação que impede passa da metade.

                se C * 2 >= Cont1 então
                //obs.: se fosse seguir o que o texto define, seria algo como "se C >= Cont1/2 então", entende? Matematicamente é mesma coisa

     

    Se observar o comentário acima, poderá perceber que poderia simplesmente fazer algo como:

       enquanto (C < Cont1/2) faca

    ou

    limite<-Cont1/2
    enquanto (C < limite) faca

     

    Pronto.. primeiro tente ajustar o código para que façam testes até a metade do valor de N. Depois que tiver rodando liso, tenta encontrar um limite menor.

     

    Obs.:

    Para simplificar, em vez de usar:

                   se divisores = 1 então
                      divisores <- divisores + 1
                      C <- Cont1

    Use lá em baixo:

             se divisores+1 = 2 então
                primo <- primo + 1
             fimse

    Sacou?

     

    Ou mesmo inicialize o C com 1, para que comece a dividir a partir de 2, pois por um sempre será divisível (cálculo desnecessário). Daí, o se acima ficaria com "divisores+2" (pois como já citado, todo número tem 2 divisores!, daí só interessa achar se tem mais de 2).

     

    Se fosse fazer uma interpretação, poderia ser algo como:

             se quantidade_de_divisores_além_dos_divisores_que_todo_número_é_divisível = 0 então
                primo <- primo + 1
             fimse

     

    Por ai vai...

     

    Qualquer dúvida é só perguntar.

     

    No aguardo.

    Editado por Simon Viegas
    • Curtir 1

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • @Simon Viegas

    Muito bom. Seguindo um passo de cada vez, refazendo, etc, deu pra progredir bastante.
     
    Vamos lá: 
    Depois que alterei para a estrutura 'enquanto' (a estrutura 'para' tava 'parando' o programa, desculpa rs), o programa não travou mais. Porém, demorava muito para concluir os cálculos (praticamente igual antes).

     

    Então fiz os seguintes ajustes, seguindo as recomendações:
    1 - Conferir apenas os números: ímpares (com exceção do 2), e os não divisíveis por primos (2, 3, 5, 7...).
    2 - Dividir até a metade do valor de cada número. "enquanto (divisor_de_n < n/2) faca"
    3 - Ir para o próximo número assim que for identificado um divisor extra (3 ou mais, logo 'não primo')
    O programa ficou bem melhor e fazia menos conta. 

     

    Agora o próximo passo era encontrar um MD (máximo divisor) que identificasse se um número é primo ou não ainda menor (menor possível). 

    Em 15/12/2017 às 16:19, Simon Viegas disse:

    Pronto.. primeiro tente ajustar o código para que façam testes até a metade do valor de N. Depois que tiver rodando liso, tenta encontrar um limite menor.


    Eu observei que quando o número era primo, ele continuava fazendo muitas verificações, pois, no caso do primo, a condição que fazia o programa parar de verificar era quando (divisor_de_n > n/2)

     

    Pesquisando encontrei que pra saber se um número é primo (tem apenas dois divisores) você pode fazer tentativas de divisão até o valor da raiz dele. Você verifica enquanto (divisor_de_n < raiz_de_n). // pulo do gato

    Bom, com isso, eu procurei como usar raiz quadrada e deixar o resultado como inteiro no visualg; depois de testes ficou assim: "enquanto divisor_de_n < int(raizq(n)) faca"

     

    O código está assim:

    Var
       n1, C, primo, divisores: inteiro
    
    Inicio
       primo <- 8 // Inicializa com o valor de '8' enquanto "para n1 de 1 ate 23 ou mais"
       para n1 de 1 ate 1000 faca
          se n1 % 2<>0 então
             se n1 % 3<>0 então
                se n1 % 5<>0 então
                   se n1 % 7<>0 então
                      se n1 % 11<>0 então
                         se n1 % 13<>0 então
                            se n1 % 17<>0 então
                               se n1 % 19<>0 então
                                  se n1 % 23<>0 então
                                     divisores <- 0
                                     C <- 0
                                     enquanto C < int(raizq(n1)) faca
                                        C <- C + 1
                                        se n1 % C = 0 então
                                           divisores <- divisores + 1
                                        fimse
                                     fimenquanto
                                     se divisores = 1 então
                                        primo <- primo + 1
                                     fimse
                                  fimse
                               fimse
                            fimse
                         fimse
                      fimse
                   fimse
                fimse
             fimse
          fimse
       fimpara
       escreval ("Total de números primos: ", primo)
    
    Fimalgoritmo

    Obs. Será que ainda dá pra inicializar "C" com o valor de 1? Eu não consegui implementar.

    Qualquer dica é bem vinda. Muito obrigado pela ajuda até aqui!

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Olá.

     

    Vamos direto a um ponto importante:

    primo <- 8 // Inicializa com o valor de '8' enquanto "para n1 de 1 ate 23 ou mais"

    O objetivo do programa é justamente encontrar os primos... daí não seria interessante utilizar primos já conhecidos... a proposta seria utilizar primos que o próprio programa já encontrou... veja, se você já está utilizando 8, o que te impediria de utilizar os X primos que existem do 1 ao 1000? daí nem precisaria de um programa, entende? Poderia por exemplo pegar essa lista e apenas contar quantos são menores que 1000. Mas não! Você precisa pegar cada um os 1000 números e verificar se é primo... ou por aí...

     

    Em relação as melhoras, deixe a parte do uso da divisão por primos para final. Por enquanto os outros pontos que já sabe:

     

    - o segundo maior divisor de um número natural é no máximo a raiz desse número (utilizar a "raiz de N" no processo);

    - com exceção do 2, todo número primo é ímpar (gerar lista de número ímpares);

     

    Tenta fazer o código com essas características posta aqui.

     

     

     

     

    No aguardo.

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • Boa tarde

     

    Em 17/12/2017 às 15:46, Simon Viegas disse:

    Em relação as melhoras, deixe a parte do uso da divisão por primos para final

     

     Não entendi bem essa parte, mas o código ficou assim

     

    Var
       n1, C, primo, divisores: inteiro
    
    Inicio
       primo <- 0
       para n1 de 1 ate 1000 faca
          se n1 < 24 então
             divisores <- 0
             C <- 0
             enquanto C < int(raizq(n1)) faca
                C <- C + 1
                se n1 % C = 0 então
                   divisores <- divisores + 1
                fimse
             fimenquanto
             se divisores = 1 então
                se n1 <> 1 então
                   primo <- primo + 1
                fimse
             fimse
          senao
             se n1 % 2<>0 então
                se n1 % 3<>0 então
                   se n1 % 5<>0 então
                      se n1 % 7<>0 então
                         se n1 % 11<>0 então
                            se n1 % 13<>0 então
                               se n1 % 17<>0 então
                                  se n1 % 19<>0 então
                                     se n1 % 23<>0 então
                                        divisores <- 0
                                        C <- 0
                                        enquanto C < int(raizq(n1)) faca
                                           C <- C + 1
                                           se n1 % C = 0 então
                                              divisores <- divisores + 1
                                           fimse
                                        fimenquanto
                                        se divisores = 1 então
                                           primo <- primo + 1
                                        fimse
                                     fimse
                                  fimse
                               fimse
                            fimse
                         fimse
                      fimse
                   fimse
                fimse
             fimse
          fimse
       fimpara
       escreval ("Total de números primos: ", primo)
    
    Fimalgoritmo

     

    • Curtir 1

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Olá.

     

    Essa parte:

    13 horas atrás, Diego_Soares disse:
    
             se n1 % 2<>0 então
                se n1 % 3<>0 então
                   se n1 % 5<>0 então
                      se n1 % 7<>0 então
                         se n1 % 11<>0 então
                            se n1 % 13<>0 então
                               se n1 % 17<>0 então
                                  se n1 % 19<>0 então
                                     se n1 % 23<>0 então

     

    não pode está no seu código... você está usando uma sequência de números primos! Onde encontrou eles? Como você sabe que 3, 5, 7 etc são primos se é o seu programa é que deveria encontrar eles? Como disse:

     

    Em 17/12/2017 às 14:46, Simon Viegas disse:

    veja, se você já está utilizando 8 [no caso 9], o que te impediria de utilizar os X primos que existem do 1 ao 1000?

    Não é coerente utilizar alguns primos já conhecidos para elaborar um algoritmo para encontrar outros primos, pois de onde veio esses 9 primos, poderia vir logo todos os outros primos que o programa iria encontrar!! No final das contas o programa não ia ter utilidade, já que já se teria a lista e poderia simplesmente contar os menores que 1000!

     

     

     

    Em 17/12/2017 às 14:46, Simon Viegas disse:

    Em relação as melhoras, deixe a parte do uso da divisão por primos para final. Por enquanto os outros pontos que já sabe:

    13 horas atrás, Diego_Soares disse:

    Não entendi bem essa parte, mas o código ficou assim

    Talvez tenha me expressado mal. Estou dizendo que um das possíveis de melhorias seria tentar fazer a divisão apenas por primos... mas que essa parte pode ser deixada para depois... ou mesmo não ser usada. A base do seu algoritmo está no primeiro código, teoricamente ela já funciona, ai você poderia ir inserindo possíveis melhorias, como as já encontradas.

     

     

    RESUMINDO:

    Seu primeiro programa já calcula os números, correto?... teoricamente ele já é EFICAZ (acha o resultado), mas pelo que foi observado não é EFICIENTE (demora muito).

     

    Daí, foi sugerido efetuar melhorias, como:

    1. - só verificar se um número é divisível até no máximo a raiz quadrada desse número (pois o segundo maior divisor não é maior que a raiz do próprio número);
    2. - a partir do 2, só verificar números ímpares (pois o único primo par é o 2);
    3. - ao encontra o terceiro divisor (além do 1 e ele mesmo), parar de tentar dividir (pois já não será mais primo);
    4. - efetuar divisões apenas por números primos (pois...)); <-- Essa melhoria por enquanto deve ser evitada (seria um desafio bônus!)

     

    obs.: Lembrando que segundo o que foi dito na primeira postagem, terá que utilizar PARA (não pode enquanto). Coloquei os itens acima em ordem de dificuldade, do mais fácil para o mais complexo.

     

    Ou seja, cada uma das MELHORIAS são INDEPENDENTES, cada uma delas tendem a tornar o algoritmo mais eficiente.

     

    Por exemplo, para testes, use esse código como base:

    Algoritmo "Contador de primos contidos numa faixa de números"
    Var
       Cont1, N, divisores, Cont2, primo: inteiro
    Inicio
    CRONOMETRO ON
    //para Cont1 de 1 ate 1000 faca
    para Cont1 de 1 ate 100 faca
       N <- Cont1
       divisores <- 0
       para Cont2 de 1 ate N faca
          se (N % Cont2 = 0) ENTÃO
             divisores <- divisores + 1
          fimse
       fimpara
       se (divisores = 2) ENTÃO
          escreval(cont1)
          primo <- primo + 1
       fimse
    fimpara
    escreval("Total de números primos: ", primo)
    CRONOMETRO OFF
    Fimalgoritmo

    Aqui, apenas inserindo o item 1, o algoritmo ficou 300ms mais rápido (de aprox. 800ms para 500ms). Cada item vai deixar o código mais rápido (ou não, é preciso testar)... como dito, são independentes, mas quanto mais itens implementar, mais rápido ficará...

     

    Experimente só inserir o 1 e ver a diferença. Depois só o 2 e ver a diferença... etc. Depois, tente combinar e ver quanto ganha em eficiência.

     

     

    DICAS:

    - item 1: "int(raizq(N)"

    - item 2: "N <- Cont1*2+1";

    - item 3: "interrompa";

     

     

    No aguardo.

    Editado por Simon Viegas

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • Olá

     

    Inseri os três primeiros itens (não sei se da maneira correta)

    O último código que eu postei era executado em aproximadamente 17 segundos. Esse de agora não chega a 1 segundo. :o (números de 1 a 1000 ambos os programas)

     

    Inicio
       CRONOMETRO ON
       //para Cont1 de 1 ate 1000 faca
       para Cont1 de 1 ate 1000 faca
          se (Cont1 % 2 <> 0) ou (Cont1 = 2) então
             N <- int(raizq(Cont1))
             divisores <- 0
             para Cont2 de 1 ate N faca
                N <- Cont1
                se (N % Cont2 = 0) então
                   divisores <- divisores + 1
                   se divisores > 1 então
                      interrompa
                   fimse
                fimse
             fimpara
             se (divisores = 1) então
                se Cont1 <> 1 então
                   primo <- primo + 1
                fimse
             fimse
          fimse
       fimpara
       escreval("Total de números primos: ", primo)
       CRONOMETRO OFF
    Fimalgoritmo

     

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Olá.

     

    19 minutos atrás, Diego_Soares disse:

    Inseri os três primeiros itens (não sei se da maneira correta)

    O último código que eu postei era executado em aproximadamente 17 segundos. Esse de agora não chega a 1 segundo. :o (números de 1 a 1000 ambos os programas)

     

    Show de bola... Agora só refinar!

     

     

    Inicialmente segue algumas "correções":

          para Cont2 de 1 ate N faca
             N <- Cont1 //N está sendo utilizado no for. Deve evitar tentar alterar o valor dele* (apaga essa linha)
             se (N % Cont2 = 0) ENTÃO //use o próprio Cont1 no lugar do N

    *Não sei exatamente o comportamento do para no Visualg, pelo visto, pois mesmo alterando o valor de N, o programa está dando o resultado correto. Mas observe que esse N é o limite do laço, e ao dar um novo valor, teoricamente estaria alterando esse limite. Acho que em outras linguagens possa dar problema.

     

    Sugestões:

    - tente usar nomenclaturas de variáveis mais próximos do seu uso; (eu usaria "atual" no lugar de "cont1" e "divisor" no lugar de "cont2"...); obs.: com o "Ctrl+u" dá para substituir fácil fácil.

    - deixe o recurso de exibir os primos disponível, algo como:

                {escreval(Cont1)} //exibe na tela os primos
                primo <- primo + 1

    No caso, caso queira visualizar os primos e fazer uma comparação ou algo do tipo, bastaria tirar as {}... ou mesmo deixa imprimindo mesmo (apesar de não ser solicitado);

     

    Acho que seria isso..

     

     

    Ai, caso queira tentar implementar a tal divisão por primos, você poderia utilizar um vetor para ir armazenando o primos a medida que ia encontrando (lá mesmo onde está contando)... aí utilizaria o vetor na hora das divisões.

     

    PS: existe outra forma de achar primos, pelo Crivo de Eratóstenes, se quiser tentar também... :)

     

    Resumindo:

    O código já está excelente! Ai:

    - tentar implementar a divisão por primos;

    - tentar fazer outro algoritmo utilizando o Crivo de Erastóstenes.

     

    No aguado.

     

    • Obrigado 1

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • 2 horas atrás, Simon Viegas disse:

    Inicialmente segue algumas "correções":

    
          para Cont2 de 1 ate N faca
             N <- Cont1 //N está sendo utilizado no for. Deve evitar tentar alterar o valor dele* (apaga essa linha)
             se (N % Cont2 = 0) ENTÃO //use o próprio Cont1 no lugar do N

     

    Perfeito! Fiz essa e as outras correções. 
    Em relação as nomenclaturas, devido as alterações no programa ficou meio confuso mesmo, mas agora que o programa está praticamente finalizado, vou ver se altero.

     

    2 horas atrás, Simon Viegas disse:

    *Não sei exatamente o comportamento do para no Visualg, pelo visto, pois mesmo alterando o valor de N, o programa está dando o resultado correto. Mas observe que esse N é o limite do laço, e ao dar um novo valor, teoricamente estaria alterando esse limite. Acho que em outras linguagens possa dar problema.

     

    Eu havia percebido quando tentei alterar o valor dele dentro da própria estrutura. Eu não conseguia.

     

    2 horas atrás, Simon Viegas disse:

    Acho que seria isso..

     

    Melhor impossível. Muita dica que eu não sabia e consegui pegar aqui (CtrlU, Interrompa, {}, CRONOMETRO, e tantas outras), fora a força na elaboração do código. Valeu mesmo!

     

    2 horas atrás, Simon Viegas disse:

    Ai, caso queira tentar implementar a tal divisão por primos, você poderia utilizar um vetor para ir armazenando o primos a medida que ia encontrando (lá mesmo onde está contando)... aí utilizaria o vetor na hora das divisões.

     

    PS: existe outra forma de achar primos, pelo Crivo de Eratóstenes, se quiser tentar também... :)

    O da divisão por primos eu vou tentar em breve. E o do Crivo de Eratóstenes, eu quero tentar futuramente sim, caso precise eu até posto um tópico específico. 
    Obrigado pela força! E estarei acompanhando o forum. :thumbsup:

    adicionado 1 minuto depois

    Esqueci o código

    Var
       Cont1, N, divisores, Cont2, primo: inteiro
    Inicio
       CRONOMETRO ON
       //para Cont1 de 1 ate 1000 faca
       para Cont1 de 1 ate 1000 faca
          se (Cont1 % 2 <> 0) ou (Cont1 = 2) então
             N <- int(raizq(Cont1))
             divisores <- 0
             para Cont2 de 1 ate N faca
                se (Cont1 % Cont2 = 0) então
                   divisores <- divisores + 1
                   se divisores > 1 então
                      interrompa
                   fimse
                fimse
             fimpara
             se (divisores = 1) então
                se Cont1 <> 1 então
                   {escreval(Cont1)} //exibe na tela os primos
                   primo <- primo + 1
                fimse
             fimse
          fimse
       fimpara
       escreval("Total de números primos: ", primo)
       CRONOMETRO OFF
    Fimalgoritmo

     

    • Amei 1

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Crie uma conta ou entre para comentar

    Você precisar ser um membro para fazer um comentário






    Sobre o Clube do Hardware

    No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

    Direitos autorais

    Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

    ×