Ir ao conteúdo

Posts recomendados

Postado

Sei que deveria verificar se os arquivos abriram corretamente, se os números foram gravados corretamente e se as informações lidas são coerentes, mas pelo menos funcionando parece estar.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    FILE *inteiros, *piramide;
    int n[20];
    inteiros = fopen("seqinteiros.dat", "r");
    for(int i = 0; i < 20; i++)
        fscanf(inteiros, "%d", &n[i]);
    fclose(inteiros);
    piramide = fopen("piramidif.dat", "w");
    for (int c1 = 18; c1 >= 0; c1--) {
        for (int c2 = 0; c2 <= c1; c2++) {
            n[c2] = n[c2 + 1] - n[c2];
            fprintf(piramide, "%d ", n[c2]);
        }
        fprintf(piramide, "\n");
    }
    fclose(piramide);
    return 0;
}

 

O programa para gravar os 20 números:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    FILE *inteiros;
    int n[20] = {32, 3, 41, 22, 96, 19, 7, 69, 82, 1, 4, 12, 8, 56, 25, 94, 65, 5, 20, 73};
    inteiros = fopen("seqinteiros.dat", "w");
    for(int i = 0; i < 20; i++) {
        fprintf(inteiros, "%d ", n[i]);
    }
    fclose(inteiros);
    return 0;
}

É preciso colocar o arquivo seqinteiros.dat na pasta do programa que vai gerar a pirâmide.

 

E novamente eu repito, o enunciado não diz se a diferença entre n1 e n2 seria n1 - n2 ou n2 - n1, e isso faz diferença

  • Amei 2
Postado
1 hora atrás, JorgeGus disse:

 

E novamente eu repito, o enunciado não diz se a diferença entre n1 e n2 seria n1 - n2 ou n2 - n1, e isso faz diferença

 

Enunciado que são consecutivos. Se escolheu para exemplificar números aleatórios beleza, mas agora não confunda.

Postado
3 horas atrás, RafaLorenzzo disse:

cheguei ate aqui, nao to conseguindo fazer as contas

 

 

Tem, vários exemplos nessa discussão onde pode ver essas "contas"  discutidas. Como eu disse, esse é um troço comum conhecido como reduce() em linguagens como java , javascript e C++, e consiste na aplicação de uma função em uma série de valores. Nesse caso a operação é a subtração e a função pode ser algo simples como eu escrevi:

 

int encolhe_serie(int N, int* S)
{
    for (int i = 0; i < N; i += 1) S[i] = S[i+1] - S[i];
    return N-1;
}

 

Onde S é o vetor com N valores...

Postado
3 horas atrás, JorgeGus disse:

E novamente eu repito, o enunciado não diz se a diferença entre n1 e n2 seria n1 - n2 ou n2 - n1, e isso faz diferença

@JorgeGusVocê tem razão, claro. O enunciado não é assim uma beleza e fica essa ambiguidade. Mas não é muito relevante eu creio.

  •  O senso comum de progressão de uma série sugere que a diferença seja x[n] - x[n-1] para n>0 e não o contrário
     
  • O valor em si da operação --- reduce, como é conhecida em outras linguagens --- vai claro ser alterado. Se esse resultado for ser validado por um programa,  tipo esses sistemas de desafio como o URI do RS (Erechim) aí temos um problema. Mas fosse esse o caso e o enunciado não seria assim ambíguo e já teria sido corrigido ou excluído. E se fosse o caso de correção mecânica o enunciado ia pedir claro apenas o valor final que é o que faz reduce afinal.
     
  • O objetivo provável aqui é testar a capacidade do aluno de entender e aplicar esse paradigma importante, e ler e gravar arquivos no disco.
     
  • 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765

     
  • A redução usa uma operação simples e pode ser um simples loop
        for (int i = 0; i < N; i += 1) S[i] = S[i+1] - S[i]; // [1]
    
       	// ou
                              
        for (int i = 0; i < N; i += 1) S[i] = S[i] - S[i-1]; // [2]

    Para uma série S com N valores.

@mauro_b Entendo que se possa ver esses problemas do forum como um desafio ou como uma oportunidade de mostrar conhecimento e tal, mas postar um resultado de um programa rodando em um compilador online e cujo código original sequer foi discutido aqui é curioso. Não falo em nome do forum claro. Apenas mais um palpite espontâneo.

 

trecho.png.0365e473dc00f46b73ccfc9fb96e4210.png

 

De todo modo, em relação a esse programa e essa figura, note que:

  • O problema proposto pelo autor apenas cita um arquivo de entrada com 20 números inteiros. Pode ter qualquer coisa lá e não é assim importante para o algoritmo --- reduce --- ou para o conceito de ler e gravar arquivos.
     
  • A série discutida aqui sequer veio com o tópico e foi apresentada por outro usuário depois @Vandin Camposque parece ter o mesmo problema. O usuário em questão pode ter usado os primeiros números da sequência de Fibonacci apenas porque achou bonitinho e para usar uma sequência reproduzível facilmente. 
     
  • considerando que os primeiros números são 1 1 2 3 e 5 no exemplo que você citou, como chegou a esse resultado na primeira linha: 0 1 1 2 3 5 subtraindo valores consecutivos?
    image.png.2afa04bb0e8a90bd4771d01e89e41030.png
  • no final por exemplo como chegou a partir do par 1597 2594 ao resultado 2584? 🤔
     

@RafaLorenzzoVocê leu os exemplos que eu postei e as coisas que eu expliquei? Entendeu aquilo?

 

Lá pra cima eu mostrei uma função de exemplo, de umas 3 linhas, com uma instrução só, que cria a nova série, para qualquer tamanho, por exemplo 20:
 

int encolhe_serie(int N, int* S)
{
    for (int i = 0; i < N; i += 1) S[i] = -(S[i + 1] - S[i]);
    return N-1;
}

 

Considerando a série S com N elementos. E a conta como sendo a[n] = a[n] - a[n-1] para n>0. Se preferir a diferença ao contrário inverta as parcelas ou o sinal. Simples assim.
 

Para ler a série inicial eu até postei um programa que lê uma série de qualquer tamanho e aceita o nome do arquivo como parâmetro, E mostrei o resultado. Bem conveniente porque pode testar com uma série curtinha e digitar uns arquivos de teste no próprio IDE. E ainda pode usar um por linha ou todos na linha ou de qualquer jeito. Testou isso ao menos?
 

Para ajudar a testar eu mostrei uma função que põe na tela a série. Até com uma linha de título opcional pra ficar mais fácil identificar os testes. E mostrei como usar. Outros usuários mostraram contribuições significativas e programas possíveis.
 

int         mostra_serie(int N, int* V, const char* mensagem)
{
    if (mensagem != NULL) printf("%s\n", mensagem);
    printf("[%4d]\t",N);
    for (int i = 0; i < N; i += 1)
        printf("%d ", V[i]);
    printf("\n");
    return N;
}

 

Essa coisa acima mostra a série na tela e pode até ter um título para separar. Mostrei como usar no programa também...
 

Clube do Hardware
[  20]  1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765

 

Seria a saída desse singelo comando
 

    mostra_serie(lidas, serie, "Clube do Hardware");

 

onde, sem surpresas, lidas é um int com o total de valores lidos, serie é o vetor onde eles foram gravados e a string é o que aparece na tela como vê acima... Ah , o número entre colchetes na saída é o tamanho do vetor

 

O que falta pra você entender e escrever seu programa? Pergunte algo objetivo para que a gente possa ajudar melhor.

 

Tem vários programas aqui então pode somar um e ver esse 

 

EXEMPLO

 

Spoiler

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int         encolhe_serie(int, int*);
int         grava_serie(int, int*, FILE*);
int         mostra_serie(int, int*, const char*);

int main(int argc, char** argv)
{
    const char* padrão = "seqinteiros.dat";
    char        arquivo[80];
    if (argc > 1)
        strcpy(arquivo, argv[1]);
    else
        strcpy(arquivo, padrão);
    printf("Vai abrir \"%s\"\n", arquivo);
    FILE* E = fopen(arquivo, "r");
    if (E == 0) return -1; // nao abriu

    const unsigned   limite = 20;
    int         serie[20];
    const char* mascara = "%d"; // para scanf()
    unsigned    lidas = 0;
    int         res = res = fscanf(E, mascara, &serie[lidas]);
    if (res != 1) return -2; // bobagem: nao veio o primeiro numero
    lidas = 1;
    while (!feof(E))
    {
        res = fscanf(E, mascara, &serie[lidas]);
        if (res != 1) break; // acabou?
        lidas += 1;
        if (lidas >= limite) break; // nao cabe mais
    };  // while()
    printf("\n");
    fclose(E);
    printf("Lidos %d numeros de \"%s\"\n",
        lidas, arquivo);
    mostra_serie(lidas, serie, "Clube do Hardware");
    // reduz a serie e grava a saida
    FILE* piramide = fopen("piramidif.dat", "w");
    if (piramide == NULL) return -1;
    while ((lidas = encolhe_serie(lidas, serie)) >= 1) grava_serie(lidas, serie, piramide);
    fclose(piramide); // nada mais
    return 0;
}


int encolhe_serie(int N, int* S)
{
    for (int i = 0; i < N; i += 1) S[i] = -(S[i + 1] - S[i]);
    return N-1;
}

int grava_serie(int N, int* serie, FILE* saida)
{
    if (saida == NULL) return -1;
    for (int i = 0; i < N - 1; i += 1) fprintf(saida, "%d ", serie[i]);
    fprintf(saida, "%d\n", serie[N-1]);
    mostra_serie(N, serie, NULL);
    return 0;
}

int         mostra_serie(int N, int* V, const char* mensagem)
{
    if (mensagem != NULL) printf("%s\n", mensagem);
    printf("[%4d]\t",N);
    for (int i = 0; i < N; i += 1)
        printf("%d ", V[i]);
    printf("\n");
    return N;
}
// fim do texto

 

 

Que aceita arquivos de entrada como esse
 

    1    1    2    3    5 
    8   13   21   34   55
   89  144  233  377  610
  987 1597 2584 4181 6765

 

mas você pode dar o nome do arquivo na hora de rodar o programa.

 

E gera arquivos como esse

 

0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584
1 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
-1 1 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
2 -1 1 0 1 1 2 3 5 8 13 21 34 55 89 144
-3 2 -1 1 0 1 1 2 3 5 8 13 21 34 55
5 -3 2 -1 1 0 1 1 2 3 5 8 13 21
-8 5 -3 2 -1 1 0 1 1 2 3 5 8
13 -8 5 -3 2 -1 1 0 1 1 2 3
-21 13 -8 5 -3 2 -1 1 0 1 1
34 -21 13 -8 5 -3 2 -1 1 0
-55 34 -21 13 -8 5 -3 2 -1
89 -55 34 -21 13 -8 5 -3
-144 89 -55 34 -21 13 -8
233 -144 89 -55 34 -21
-377 233 -144 89 -55
610 -377 233 -144
-987 610 -377
1597 -987
-2584

 

Para quem gosta de números e matemática

 

Note que os números da entrada exemplo, que são os 20 primeiros valores da sequência de Fibonacci, vão se deslocando duas posições para a direita a cada iteração. O primeiro par, 1,1 gera um zero e assim fica fácil ver na saída acima.

Deslocando os números e alinhando pelo 0:
 

                         0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584
1                        0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
-1 1                     0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
2 -1 1                   0 1 1 2 3 5 8 13 21 34 55 89 144
-3 2 -1 1                0 1 1 2 3 5 8 13 21 34 55
5 -3 2 -1 1              0 1 1 2 3 5 8 13 21
-8 5 -3 2 -1 1           0 1 1 2 3 5 8
13 -8 5 -3 2 -1 1        0 1 1 2 3
-21 13 -8 5 -3 2 -1 1    0 1 1
34 -21 13 -8 5 -3 2 -1 1 0
-55 34 -21 13 -8 5 -3 2 -1
89 -55 34 -21 13 -8 5 -3
-144 89 -55 34 -21 13 -8
233 -144 89 -55 34 -21
-377 233 -144 89 -55
610 -377 233 -144
-987 610 -377
1597 -987
-2584


E como somem 2 por vez depois de 10 iterações os valores iniciais são consumidos.

 

  • mas uma nova sequência tipo Fibonacci começa a aparecer invertida e com sinas alternados :D por força das subtrações sucessivas e da álgebra que inverte os sinais.

Que significa isso?

 

Nada. Ou melhor, nada que eu entenda só de olhar assim :) Desculpem a viagem. Gosto de números.

 

 

Postado
1 hora atrás, arfneto disse:

O problema proposto pelo autor apenas cita um arquivo de entrada com 20 números inteiros. Pode ter qualquer coisa lá e não é assim importante para o algoritmo --- reduce --- ou para o conceito de ler e gravar arquivos

Discordo, não é um entrada de quais quer números inteiros, porém de uma sequência.

 

Em 27/04/2021 às 18:07, RafaLorenzzo disse:

contendo uma sequência de 20 números inteiros

 

 

1 hora atrás, arfneto disse:

problema proposto pelo autor apenas cita um arquivo de entrada com 20 números inteiros. Pode ter qualquer coisa lá e não é assim importante para o algoritmo --- reduce --- ou para o conceito de ler e gravar arquivos.
 

 

Discordo, mais uma vez se faz parte do enunciado é importante tanto quando reduzir o tamanho do vetor ou aplicação da subtração nos termos certos.

 

1 hora atrás, arfneto disse:

A série discutida aqui sequer veio com o tópico e foi apresentada por outro usuário depois @Vandin Camposque parece ter o mesmo problema. O usuário em questão pode ter usado os primeiros números da sequência de Fibonacci apenas porque achou bonitinho e para usar uma sequência reproduzível facilmente. 

 

Entretanto, é posteriormente acrescida, tornando-se parte da discussão e conteúdo do arquivo de entrada.

 

1 hora atrás, arfneto disse:

considerando que os primeiros números são 1 1 2 3 e 5 no exemplo que você citou, como chegou a esse resultado na primeira linha: 0 1 1 2 3 5 subtraindo valores consecutivos?

 

Claro que entendi;  a cada laço, depois o vetor tem as diferenças dos elementos dois a dois consecutivos, tem reduzido o seu tamanho em 1.  Qual a dúvida? Suas explicações serviram para confirmar o que já tinha, mas não na ocasião não sabia como explicar, você também é pouco eficiente nesse quesito, vendo que não tinha mais argumento apelou, lhe dando uma resposta (como é costume). Aprosito, não se dê o trabalho de fazer peder tempo... dê a resposta de uma vez se, tanto "blablabla".

 

E eu já tinha a minha.

FILE *arq= fopen( "piramidif.dat","a" );
#define in (20)
                for( int i= 0, jn= in - 1; i < in; ++i, --jn ){
                        for( int j= 0; j < jn; ++j ){
                               inteiros[j]= inteiros[j + 1] - inteiros[j];
                                fprintf( stdout, "%d ", inteiros[j] );
                        }
                        fprintf( stdout, "\n" );
                }

 

1 hora atrás, arfneto disse:

no final por exemplo como chegou a partir do par 1597 2594 ao resultado 2584? 

 

Não, não... esse é o último número da sequência e não é de uma resposta. Eu só mudei a apresentação. Até então não tinha notada nada na sequência, e notei a sequência com bricadeiras, só isso.

 

1 hora atrás, arfneto disse:

Que significa isso?

 

Nada

 

É, mas você pareceu MUDO, não tinha mais nada para falar ou maneiras de levar o autor a programar a uma resposta.

Daí aproveitei para expor essa minha descoberta kkkkkk porque eu posso.

Postado

 

 

 

1 hora atrás, mauro_b disse:

Claro que entendi;  a cada laço, depois o vetor tem as diferenças dos elementos dois a dois consecutivos, tem reduzido o seu tamanho em 1.

 

Ainda não consigo explicar!

 

 

No total de T repetições, a cada repetição a diferença entre cada par de números na sequência é atribuído o vetor no índice do primeiro número do par. No final da repetição, o tamanho do vetor é decrementado.

 

 

Penso que melhorei,  essas coisas são muito importante.

Eu pretendo explicar, conduzir o leitor a resposta sem responder POR ele no final, ao contrário dessa discussão que terminou com quem já sabe, e provavelmente só faz isso na vida, respondendo POR ele. O que talvez seja  o objetivo do fórum... responder atividades escolares.

 

É difícil, estou tentando, ignorando as críticas maldosas, eu chego lá, caso não fosse assim qualquer um se tornaria Professor.

Postado
3 horas atrás, arfneto disse:

Entendo que se possa ver esses problemas do forum como um desafio ou como uma oportunidade de mostrar conhecimento e tal, mas postar um resultado de um programa rodando em um compilador online e cujo código original sequer foi discutido aqui é curioso. Não falo em nome do forum claro. Apenas mais um palpite espontâneo.

 

Está curioso com quê?

 

E por qual razão você acredita que penso em você falando em nome do forum, ou além de você mesmo, ou coisa do tipo?

 

Continue assim por favor.

 

Toda critica é bem-vinda.

 

Os moderadores me dizem para ser mais objetivo com assunto, se é isso então...

Obrigado.

 

No começo fiquei constrangido, depois de quase 1 meses eu nem ligava mais.

Se atrapalhar tem as denúncias.

Postado

Deixar mais uma versão completa do programa, eu acredito que faz conforme enunciado. No mínimo é uma boa aproximação da responta. Daí você edita para atender suas necessidades.

 

 

#include <stdio.h>
int main( void ){
        #define in (20)
        int inteiros[in];
        {
                FILE *arq= fopen( "seqinteiros.dat","r" );
                for( int i= 0; i < in; ++i ){
                        fscanf( arq, "%d ", &inteiros[i] );
                }
                fclose(arq);
        }
        {
                /*
                   No total de IN repetições, a cada repetição 
                   a diferença entre cada par de números na sequência é atribuído
                   o vetor no índice do primeiro número do par.
                   
                   No final da repetição, o tamanho do vetor é decrementado.
                */
                FILE *arq= fopen( "piramidif.dat","w" );
                for( int i= 0, jn= in - 1; i < in; ++i, --jn ){
                        
                        for( int j= 0; j < jn; ++j ){
                               inteiros[j]= inteiros[j + 1] - inteiros[j];
                               fprintf( arq, "%d ", inteiros[j] );
                        }
                        fprintf( arq, "\n" );
                }
                fclose(arq);
        }
}

 

 

Se comparar com a sugestão

 

9 horas atrás, JorgeGus disse:

 


for (int c1 = 18; c1 >= 0; c1--) {
  
  for (int c2 = 0; c2 <= c1; c2++) {
    n[c2] = n[c2 + 1] - n[c2];
    fprintf(piramide, "%d ", n[c2]);
  }
  fprintf(piramide, "\n");
}

 

 

 

Apresenta vantagens, pois não necessita de um contador extra, ao aloca variáveis desnecessárias.

 

c1, contador do ‘loop’ externo, fornece o limite para ‘loop’ interno. O que é bem mais inteligente porque economiza operações e memória.

 

Mais simples e eficiente.

Postado

Apresentou vantagens, pois não necessita de um contador extra ou aloca variáveis desnecessárias.

 

Observe c1, o contador do ‘loop’ externo, que fornece o limite para ‘loop’ interno. O que é bem mais inteligente porque economiza operações e memória.

 

Mais simples e eficiente: gostaria de ter pensado nessa solução, mas não me ocorreu ideia de usar o contador de laço, no outro laço.

 

><

Postado
Em 30/04/2021 às 01:41, arfneto disse:

Que significa isso?

 

Nada. Ou melhor, nada que eu entenda só de olhar assim :) Desculpem a viagem. Gosto de números.

 

 

Ainda sobre os números, alterei outro dia o programa que eu tinha postado. A ideia era deixar mais fácil experimentar com arquivos diferentes, e assim o programa abaixo serie.c se chamado assim sem argumentos apenas cria piramidif.dat a partir de seqinteiros.dat.

 

E vou deixar aqui essa versão alterada.
 

Mas

  • se chamar com um argumento será o arquivo de entrada.
  • se chamar com 2 serão os arquivos de entrada e saida.
  • se chamar com 3 serão os arquivos de entrada e saida e o limite de elementos

O programa como eu escrevi simplesmente conta os elementos na entrada, mas pode ser legar experimentar um mesmo arquivo usando menos números, por exemplo, para ver a diferença entre a progressão par ou ímpar.

 

Exemplos
 

[1]	serie
[2]	serie um
[3]	serie entrada.txt saida.txt
[4]	serie entrada.txt saida.txt 8
	

 

[1] faz como o enunciado, [2] cria piramidif.dat a partir de um., [3] cria saida.txt com os dados de entrada.txt e [4] faz a mesma coisa mas limita a série a 8 números

 

Isso acrescenta umas 12 linhas ao programa

 

Exemplo: Rodando o programa para todos os arquivos .dat na pasta

 

No windows uma linha assim faz isso

 

@ECHO OFF
FOR %%F IN  ( *.DAT ) DO ( serie %%F %%F.txt )

 

apenas salve com a extensão .BAT e mande rodar

 

No Linux use

 

gcc -o serie -Wall -O3 -std=c17 serie.c
for i  in *.dat 
 do
    echo -e "\n==========> Usando $i\n"
    cat $i
    echo -e "\n"
    ./serie $i $i.txt 
    echo -e "\n\t$i.txt\n\n"
    cat $i.txt
done

 

Uns arquivos
 

10 20 31 43 56
70 85 101 118 136

 

Esse é interessante. A diferença vai aumentando de um em um
 

Esse outro

 

1048576 524288 262144 131072 65536
  32768  16384   8192   4096  2048
   1024    512    256    128    64
     32     16      8      4     2

    metade.dat

 

vai dividindo os elementos por dois e pela progressão vai gerar 

 

image.thumb.png.2562a76e45e51fbba28ee5fb90df56fd.png

 

E a sequência vai se reduzindo até sobrar -2. Veja que os sinais se alternam já que 
 

	(A - B) = -(B - A)

 

Note que do modo como o programa le os valores pode escrever no meio do arquivo ou no fim.

 

Veja a mesma coisa para o dobro:
 

    2      4      8     16      32
   64    128    256    512    1024 
 2048   4096   8192  16384   32768 
65536 131072 262144 524288 1048576

 

vai gerar
 

image.thumb.png.9d2ec7656425ba83a86384703ec2d366.png

 

e claro que aqui não inverte os sinais.

 

Esse gera uma pirâmide
 

1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1 

 

Esse aqui reduz até zerar

1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1

 

Eis o programa

 

Spoiler




#define LIMITE_ 20

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int         le_serie(unsigned, int*, const char*);
int         encolhe_serie(int, int*);
int         grava_serie(int, int*, FILE*);
int         mostra_serie(int, int*, const char*);

int main(int argc, char** argv)
{
    int         serie[LIMITE_];

    const char* e_padrao = "seqinteiros.dat"; // entrada padrão
    const char* s_padrao = "piramidif.dat"; // saida padrão
    unsigned    limite = LIMITE_; // limite padrão

    char    arquivo_e[80];
    char    arquivo_s[80];

    // limite
    if (argc > 3) limite = atoi(argv[3]);
    // saida
    if (argc > 2)
        strcpy(arquivo_s, argv[2]);
    else
        strcpy(arquivo_s, s_padrao);
    // entrada
    if (argc > 1)
        strcpy(arquivo_e, argv[1]);
    else
        strcpy(arquivo_e, e_padrao);

    fprintf(stderr, "Entrada: \"%s\" Saida: \"%s\" Limite de %d numeros\n",
        arquivo_e, arquivo_s, limite);

    unsigned lidas = le_serie(limite, serie, arquivo_e);
    if (lidas <= 0) return -1; // nao abriu
    printf("Lidos %d numeros de \"%s\"\n", lidas, arquivo_e);
    mostra_serie(lidas, serie, "Serie lida do arquivo:");
    FILE* piramide = fopen(arquivo_s, "w"); // reduz e grava a serie toda
    if (piramide == NULL) return -2;
    while ((lidas = encolhe_serie(lidas, serie)) >= 1) grava_serie(lidas, serie, piramide);
    fclose(piramide); // nada mais
    return 0;
};  // main()


int         encolhe_serie(int N, int* S)
{
    for (int i = 0; i < N; i += 1) S[i] = (S[i + 1] - S[i]);
    return N-1;
}


int         grava_serie(int N, int* serie, FILE* saida)
{
    if (saida == NULL) return -1;
    for (int i = 0; i < N - 1; i += 1) fprintf(saida, "%6d ", serie[i]);
    fprintf(saida, "%6d\n", serie[N-1]);
    //mostra_serie(N, serie, NULL);
    return 0;
}


int         le_serie(unsigned limite, int* serie, const char* nome_arquivo)
{
    FILE* E = fopen(nome_arquivo, "r");
    if (E == 0) return -1; // nao abriu
    const char* mascara = "%d"; // para scanf()
    unsigned    lidas = 0;
    int         res = res = fscanf(E, mascara, &serie[lidas]);
    if (res != 1) return -2; // bobagem: nao veio o primeiro numero
    lidas = 1;
    while (!feof(E))
    {
        res = fscanf(E, mascara, &serie[lidas]);
        if (res != 1) break; // acabou?
        lidas += 1;
        if (lidas >= limite) break; // nao cabe mais
    };  // while()
    fclose(E);
    return lidas;
}


int         mostra_serie(int N, int* V, const char* mensagem)
{
    if (mensagem != NULL) printf("%s\n", mensagem);
    printf("[%4d]\t",N);
    for (int i = 0; i < N; i += 1)
        printf("%d ", V[i]);
    printf("\n");
    return N;
}

 

 

:D 

Eis a saída do exemplo, rodando em Windows. Claro. os arquivos de saída estarão no disco ao final
 

PS C:\src\mapa> ./list
Entrada: "1-10-1.dat" Saida: "1-10-1.dat.txt" Limite de 20 numeros
Lidos 19 numeros de "1-10-1.dat"
Serie lida do arquivo:
[  19]  1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1
Entrada: "1-10-10-1.dat" Saida: "1-10-10-1.dat.txt" Limite de 20 numeros
Lidos 20 numeros de "1-10-10-1.dat"
Serie lida do arquivo:
[  20]  1 2 3 4 5 6 7 8 9 10 10 9 8 7 6 5 4 3 2 1
Entrada: "5-1-5.dat" Saida: "5-1-5.dat.txt" Limite de 20 numeros
Lidos 9 numeros de "5-1-5.dat"
Serie lida do arquivo:
[   9]  5 4 3 2 1 2 3 4 5
Entrada: "dobro.dat" Saida: "dobro.dat.txt" Limite de 20 numeros
Lidos 20 numeros de "dobro.dat"
Serie lida do arquivo:
[  20]  2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288 1048576
Entrada: "metade.dat" Saida: "metade.dat.txt" Limite de 20 numeros
Lidos 20 numeros de "metade.dat"
Serie lida do arquivo:
[  20]  1048576 524288 262144 131072 65536 32768 16384 8192 4096 2048 1024 512 256 128 64 32 16 8 4 2
Entrada: "outros.dat" Saida: "outros.dat.txt" Limite de 20 numeros
Lidos 10 numeros de "outros.dat"
Serie lida do arquivo:
[  10]  10 20 31 43 56 70 85 101 118 136
Entrada: "seqinteiros.dat" Saida: "seqinteiros.dat.txt" Limite de 20 numeros
Lidos 20 numeros de "seqinteiros.dat"
Serie lida do arquivo:
[  20]  1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
PS C:\src\mapa>

 

Em 30/04/2021 às 01:41, arfneto disse:

Que significa isso?

 

Nada. Ou melhor, nada que eu entenda só de olhar assim :) Desculpem a viagem. Gosto de números.

 

Exato. São só números. Mas achei divertido. Mais que os 20 valores da série de Fibonacci.

 

 

Em 30/04/2021 às 02:10, mauro_b disse:

Discordo, não é um entrada de quais quer números inteiros, porém de uma sequência.

 

 

:D entendo. Acredito que chamar uma "entrada de quaisquer números inteiros" de sequência seja uma boa denominação. Ou de série, ou de "uns números". 
 

Em 30/04/2021 às 02:10, mauro_b disse:
Em 30/04/2021 às 01:41, arfneto disse:

no final por exemplo como chegou a partir do par 1597 2594 ao resultado 2584? 

 

Não, não... esse é o último número da sequência e não é de uma resposta. Eu só mudei a apresentação. Até então não tinha notada nada na sequência, e notei a sequência com bricadeiras, só isso.

 

Então postou um resultado de um programa, rodando em um compilador online e sem postar o código, apenas como uma brincadeira 🤔
 

image.png.6a28e7e248d90313f7fc900948b91845.png

 

 

 

 

Eu achei que você não tinha entendido ao certo a progressão e escrito o programa errado. 

 

Foi por isso que tentei "corrigir"

 

 

 

 

 

 

 

Postado
1 hora atrás, arfneto disse:

Então postou um resultado de um programa, rodando em um compilador online e sem postar o código, apenas como uma brincadeira

kkkkkkkkk, Desculpa ai

 

 

1 hora atrás, arfneto disse:

entendo. Acredito que chamar uma "entrada de quaisquer números inteiros" de sequência seja uma boa denominação. Ou de série, ou de "uns números".

Discordo, quando disse sequência me refiro a uma sucessão de números,

 

Não que isso ajude com sua explicação ou melhorasse seu código, porque está bom pelas razões que já mencionei:

não alocar memoria extra, não usa funções desnecessárias,  um simples par de laços com inteligência de reutilizar o contador do laço das operações no  que seleciona os termos.

 

Como já foi dito, reitero gostei da solução.

Em 30/04/2021 às 07:21, mauro_b disse:

Observe c1, o contador do ‘loop’ externo, que fornece o limite para ‘loop’ interno. O que é bem mais inteligente porque economiza operações e memória.

 

 

Em 29/04/2021 às 21:31, JorgeGus disse:

Sei que deveria verificar se os arquivos abriram corretamente, se os números foram gravados corretamente e se as informações lidas são coerentes, mas pelo menos funcionando parece estar.


#include <stdio.h>
#include <stdlib.h>

int main(void) {
    FILE *inteiros, *piramide;
    int n[20];
    inteiros = fopen("seqinteiros.dat", "r");
    for(int i = 0; i < 20; i++)
        fscanf(inteiros, "%d", &n[i]);
    fclose(inteiros);
    piramide = fopen("piramidif.dat", "w");
    for (int c1 = 18; c1 >= 0; c1--) {
        for (int c2 = 0; c2 <= c1; c2++) {
            n[c2] = n[c2 + 1] - n[c2];
            fprintf(piramide, "%d ", n[c2]);
        }
        fprintf(piramide, "\n");
    }
    fclose(piramide);
    return 0;
}

 

O programa para gravar os 20 números:


#include <stdio.h>
#include <stdlib.h>

int main(void) {
    FILE *inteiros;
    int n[20] = {32, 3, 41, 22, 96, 19, 7, 69, 82, 1, 4, 12, 8, 56, 25, 94, 65, 5, 20, 73};
    inteiros = fopen("seqinteiros.dat", "w");
    for(int i = 0; i < 20; i++) {
        fprintf(inteiros, "%d ", n[i]);
    }
    fclose(inteiros);
    return 0;
}

É preciso colocar o arquivo seqinteiros.dat na pasta do programa que vai gerar a pirâmide.

 

E novamente eu repito, o enunciado não diz se a diferença entre n1 e n2 seria n1 - n2 ou n2 - n1, e isso faz diferença

 

  • Curtir 1
Postado
48 minutos atrás, mauro_b disse:

kkkkkkkkk, Desculpa ai

 

🤣🤣🤣🤣🤣

 

49 minutos atrás, mauro_b disse:
1 hora atrás, arfneto disse:

entendo. Acredito que chamar uma "entrada de quaisquer números inteiros" de sequência seja uma boa denominação. Ou de série, ou de "uns números".

Discordo, quando disse sequência me refiro a uma sucessão de números,

 

Vou estender (mais)  então a definição:

Acredito que chamar uma "entrada de quaisquer números inteiros" de sequência seja uma boa denominação. Ou de série, ou de "uns números". Ou "uma sucessão de números" como descrita pelo @mauro_b 
 

53 minutos atrás, mauro_b disse:

Observe c1, o contador do ‘loop’ externo, que fornece o limite para ‘loop’ interno. O que é bem mais inteligente porque economiza operações e memória.

 

 

A função é como eu disse o clássico reduce(), uma linha em C++, Python ou java ou javascript ou sei la. Em C ou Pascal ou FORTRAN algo assim
 

int         encolhe_serie(int N, int* S)
{
    for (int i = 0; i < N; i += 1) S[i] = (S[i + 1] - S[i]);
    return N-1;
}

 

Em COBOL seria um PERFORM :) 

  • Curtir 1
Postado
1 hora atrás, arfneto disse:

A função é como eu disse o clássico reduce(), uma linha em C++, Python ou java ou javascript ou sei la. Em C ou Pascal ou FORTRAN algo assim
 







int         encolhe_serie(int N, int* S)
{
    for (int i = 0; i < N; i += 1) S[i] = (S[i + 1] - S[i]);
    return N-1;
}

 

Mas não há motivos  ser assim é só um desperdício quando a maneira mais inteligentes de se fazer o mesmo.

 

 

1 hora atrás, arfneto disse:

Vou estender (mais)  então a definição:

Acredito que chamar uma "entrada de quaisquer números inteiros" de sequência seja uma boa denominação. Ou de série, ou de "uns números". Ou "uma sucessão de números" como descrita pelo @mauro_b 

Discordo, números aleatórios não são https://www.todamateria.com.br/sequencia-numerica/ . Você está distorcendo que falei, outra vez.

 

 

1 hora atrás, arfneto disse:

Em COBOL seria um PERFORM

kkkkkkkkkkkkkkkk 😆 e daí, você está bem?

 

 

Foco no que interessa! 

Em 29/04/2021 às 21:31, JorgeGus disse:

Sei que deveria verificar se os arquivos abriram corretamente, se os números foram gravados corretamente e se as informações lidas são coerentes, mas pelo menos funcionando parece estar.





#include <stdio.h>
#include <stdlib.h>

int main(void) {
    FILE *inteiros, *piramide;
    int n[20];
    inteiros = fopen("seqinteiros.dat", "r");
    for(int i = 0; i < 20; i++)
        fscanf(inteiros, "%d", &n[i]);
    fclose(inteiros);
    piramide = fopen("piramidif.dat", "w");
    for (int c1 = 18; c1 >= 0; c1--) {
        for (int c2 = 0; c2 <= c1; c2++) {
            n[c2] = n[c2 + 1] - n[c2];
            fprintf(piramide, "%d ", n[c2]);
        }
        fprintf(piramide, "\n");
    }
    fclose(piramide);
    return 0;
}

 

O programa para gravar os 20 números:





#include <stdio.h>
#include <stdlib.h>

int main(void) {
    FILE *inteiros;
    int n[20] = {32, 3, 41, 22, 96, 19, 7, 69, 82, 1, 4, 12, 8, 56, 25, 94, 65, 5, 20, 73};
    inteiros = fopen("seqinteiros.dat", "w");
    for(int i = 0; i < 20; i++) {
        fprintf(inteiros, "%d ", n[i]);
    }
    fclose(inteiros);
    return 0;
}

É preciso colocar o arquivo seqinteiros.dat na pasta do programa que vai gerar a pirâmide.

 

E novamente eu repito, o enunciado não diz se a diferença entre n1 e n2 seria n1 - n2 ou n2 - n1, e isso faz diferença

  • Curtir 1
Postado

tenho outro programa que nao consigo fazer sobre codificação e decodificação com XOR, alguém me ajuda?

agora, RafaLorenzzo disse:

Considerando o método de decodificação por XOR explicado abaixo, utilize seu número como a chave K e escreva o código em linguagem C que decodifique a mensagem
codificada contida no arquivo .dat cujo nome é o seu número. Tenha em mente
que a mensagem codificada contida no arquivo.dat tem tamanho de 200 números inteiros. Após
decodificada, a mensagem exibirá um número de 7 dígitos .
Decodificação O método a ser aplicado utiliza uma operação matemática simples aplicada

entre cada letra da mensagem codificada C e da chave K, progressivamente. A operação mate-
mática que será utilizada na codificação chama-se XOR, matematicamente é simbolizada por ⊕

e na linguagem C é executado utilizando o símbolo de acento circunflexo (^).
Quando estamos de posse da mensagem codificada C e da chave K e temos o interesse de gerar
a mensagem M, este processo é chamado de decodificação. Este processo é feito aplicando a
mesma operação XOR, uma a uma, entre cada número da mensagem codificada C e cada letra
da chave K, gerando assim cada letra da mensagem M.

 

@JorgeGus tenho outro programa que nao consigo fazer sobre codificação e decodificação com XOR, alguém me ajuda?

agora, RafaLorenzzo disse:

Considerando o método de decodificação por XOR explicado abaixo, utilize seu número como a chave K e escreva o código em linguagem C que decodifique a mensagem
codificada contida no arquivo .dat cujo nome é o seu número. Tenha em mente
que a mensagem codificada contida no arquivo.dat tem tamanho de 200 números inteiros. Após
decodificada, a mensagem exibirá um número de 7 dígitos .
Decodificação O método a ser aplicado utiliza uma operação matemática simples aplicada

entre cada letra da mensagem codificada C e da chave K, progressivamente. A operação mate-
mática que será utilizada na codificação chama-se XOR, matematicamente é simbolizada por ⊕

e na linguagem C é executado utilizando o símbolo de acento circunflexo (^).
Quando estamos de posse da mensagem codificada C e da chave K e temos o interesse de gerar
a mensagem M, este processo é chamado de decodificação. Este processo é feito aplicando a
mesma operação XOR, uma a uma, entre cada número da mensagem codificada C e cada letra
da chave K, gerando assim cada letra da mensagem M.

 

Postado
44 minutos atrás, RafaLorenzzo disse:

tenho outro programa que nao consigo fazer sobre codificação e decodificação com XOR, alguém me ajuda?

 

Eu  não compreendo o enunciado, ora temos números depois explica-se o mesmo usando a palavra letras.

Diz que seu número é a chave K, o seu número é o nome do arquivo com 200 inteiros.

 

44 minutos atrás, RafaLorenzzo disse:

gerando assim cada letra da mensagem M.

VS

44 minutos atrás, RafaLorenzzo disse:

decodificada, a mensagem exibirá um número de 7 dígitos .

Isso só confundiu.

 

Qual o número/chave/nome do arquivo?

Se supor que M foi gerada pelas iterações com K resultando em C

Mi  XOR  K= Ci

 

Para obter decodificação Ci faça o mesmo.

Ci  XOR  K= Mi.

 

 

 

Postado

@mauro_b o numero é "2018104009"

 

Exemplo de decodicação Supondo que o valor da mensagem codicada C e da chave K
sejam C = {18, 17, 14, 4, 12, 0, 14, 55, 0, 71, 55, 36, 54, 59, 22} e K = "Segredo", a
decodicação seria a seguinte.
18 17 14 4 12 0 14 55 0 71 55 36 54 59 22
⊕ ⊕ ⊕ ⊕ ⊕ ⊕ ⊕ ⊕ ⊕ ⊕ ⊕ ⊕ ⊕ ⊕ ⊕
'S' 'e' 'g' 'r' 'e' 'd' 'o' 'S' 'e' 'g' 'r' 'e' 'd' 'o' 'S'
'A' 't' 'i' 'v' 'i' 'd' 'a' 'd' 'e' ' ' 'E' 'A' 'R' 'T' 'E'
Com isso produzimos a mensagem M, que neste exemplo tem o seguinte valor. M = "Atividade
EARTE".

 

Postado
int main() {
   int mc[] = {18, 17, 14, 4, 12, 0, 14, 55, 0, 71, 55, 36, 54, 59, 22} ;
   char chave[] = "Segredo";
   int k = 0;
   for (int c = 0; c < 15; c++) {
      printf("%c", mc[c] ^ chave[k]);
      if (k == 6)
         k = 0;
      else
         k++;
   }
   return 0;
}

Isso é com base no seu exemplo, para resolver o seu exercício faça a leitura dos valores para o vetor como no exercício anterior, altere o limite do for para 200, e use sua chave.

 

Se tiver alguma dúvida pergunte que alguém responde.

 

E acho que teria sido melhor criar outro tópico, já que se trata de outro problema.

 

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades 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

×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!