Skip to content

Commit 8f35377

Browse files
committed
Loop infinito?
1 parent 5e39d1d commit 8f35377

File tree

5 files changed

+422
-10
lines changed

5 files changed

+422
-10
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ erl_crash.dump
2121

2222
# Ignore package tarball (built via "mix hex.build").
2323
primos_em_pi-*.tar
24+
pi-1M.txt
2425

2526

2627
# Temporary files for e.g. tests

c/a.out

17.4 KB
Binary file not shown.

c/primospi.c

+259
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
// compilar no unix/linux
2+
// > gcc -Ofast primospi.c -o primospi -lm
3+
//
4+
// compilado no MINGW64 (Windows)
5+
// $ gcc -Ofast primospi.c -o primospi -lm
6+
//
7+
#include <stdio.h>
8+
#include <stdlib.h>
9+
#include <string.h>
10+
11+
#define ORGANIZE 1000 // a cada ORGANIZE em primos eu vejo a maior sequencia e apago a array de primos
12+
13+
typedef struct pilist_st
14+
{
15+
char *start;
16+
char *end;
17+
} pilist_t; // lista de números primos extraídos de PI
18+
19+
//// Variáveis globais
20+
pilist_t maior; // maior início e final
21+
int *primos_list = NULL; // lista de números primos de 2 até 9973
22+
char *buffer = NULL; // arquivo do número PI
23+
size_t buffer_size = 0; // tamanho do arquivo do número PI
24+
pilist_t *lista = NULL; // lista de primos de PI
25+
size_t lista_size = 0; // tamanho da lista
26+
//// Fim das variáveis globais
27+
28+
void free_all() // limpeza de toda a memória alocada
29+
{
30+
if (lista)
31+
free(lista);
32+
if (primos_list)
33+
free(primos_list);
34+
if (buffer)
35+
free(buffer);
36+
}
37+
38+
void primos_init() // construtor dos primos de 1 a 9973 (solução do desafio 2)
39+
{
40+
int primos_size = 4, j = 0;
41+
primos_list = (int *)malloc(sizeof(int) * 1230);
42+
if (!primos_list)
43+
{
44+
printf("Memória insuficiente para alocar a lista de números primos\n");
45+
exit(1);
46+
}
47+
primos_list[0] = 2;
48+
primos_list[1] = 3;
49+
primos_list[2] = 5;
50+
primos_list[3] = 7;
51+
for (int i = 11; i < 9974; i += 2)
52+
{
53+
if ((i % 5) == 0 || (i % 3) == 0)
54+
continue;
55+
for (j = 3; j < primos_size; j++)
56+
{
57+
if ((i % primos_list[j]) == 0)
58+
break;
59+
60+
if ((i / primos_list[j]) < primos_list[j])
61+
{
62+
j = primos_size;
63+
break;
64+
}
65+
}
66+
if (j == primos_size)
67+
{
68+
primos_size++;
69+
primos_list[primos_size - 1] = i;
70+
}
71+
}
72+
primos_list[primos_size] = 0;
73+
}
74+
75+
int primos_isprimo(int i) // retorna se um número está na lista de primos ou não
76+
{
77+
int *p = primos_list;
78+
if (i < 2)
79+
return 0;
80+
while (*p && *p < i)
81+
p++;
82+
if (*p > i || *p == 0)
83+
return 0;
84+
return 1;
85+
}
86+
87+
char *processar_maiorprimo_r(char *in_end, int k) // processo recursivo para achar a maior sequencia de primos possível
88+
{
89+
char *max = in_end, *resp = NULL;
90+
91+
for (; k < lista_size - 1; k++)
92+
{
93+
if ((in_end + 1) < lista[k].start) // como está em ordem de início, se o início ficou mais alto que o final procurado, não existe mais sequencia
94+
break;
95+
if ((in_end + 1) == lista[k].start) // se o início é igual ao final, aumenta a sequencia para verificar
96+
{
97+
resp = processar_maiorprimo_r(lista[k].end, k + 1);
98+
if (max < resp)
99+
max = resp;
100+
}
101+
}
102+
return max;
103+
}
104+
105+
void processar_maiorprimo() // analise das recursões
106+
{
107+
char *resp = NULL;
108+
109+
for (int k = 0; k < lista_size - 1; k++)
110+
{
111+
resp = processar_maiorprimo_r(lista[k].end, k + 1);
112+
if ((maior.end - maior.start) < (resp - lista[k].start))
113+
{
114+
maior.start = lista[k].start;
115+
maior.end = resp;
116+
}
117+
}
118+
119+
// uso a primeira posição para anotar o resultado até agora e saber se ele tem continuidade
120+
// no próximo processamento
121+
lista[0].start = maior.start;
122+
lista[0].end = maior.end;
123+
lista_size = 1;
124+
}
125+
void processar_quicksort(int l, int r) //sort da array de primos pelo menor endereço de "start"
126+
{
127+
pilist_t *v = &lista[r];
128+
pilist_t tmp;
129+
int i = l - 1, j = r;
130+
if (r <= l)
131+
return;
132+
while (1)
133+
{
134+
while (lista[++i].start < v->start)
135+
;
136+
while (v->start < lista[--j].start)
137+
{
138+
if (j == l)
139+
break;
140+
}
141+
if (i >= j)
142+
break;
143+
memcpy(&tmp, &lista[i], sizeof(pilist_t));
144+
memcpy(&lista[i], &lista[j], sizeof(pilist_t));
145+
memcpy(&lista[j], &tmp, sizeof(pilist_t));
146+
}
147+
memcpy(&tmp, &lista[i], sizeof(pilist_t));
148+
memcpy(&lista[i], &lista[r], sizeof(pilist_t));
149+
memcpy(&lista[r], &tmp, sizeof(pilist_t));
150+
151+
processar_quicksort(l, i - 1);
152+
processar_quicksort(i + 1, r);
153+
}
154+
155+
void processar() // ler o arquivo de PI, separar os primos e chamar as funcoes que calculam as sequencias
156+
{
157+
char s1[2] = {0, 0}, s2[3] = {0, 0, 0}, s3[4] = {0, 0, 0, 0}, s4[5] = {0, 0, 0, 0, 0};
158+
char *p = buffer;
159+
160+
lista = (pilist_t *)malloc(sizeof(pilist_t) * (ORGANIZE + 4));
161+
if (!lista)
162+
{
163+
printf("Memória insuficiente para alocar a lista de números primos de PI\n");
164+
free_all();
165+
exit(1);
166+
}
167+
168+
while (*p != '.')
169+
p++;
170+
p++;
171+
172+
fprintf(stdout, "%03d%%", 0);
173+
while (*p)
174+
{
175+
s1[0] = *p;
176+
s2[0] = s2[1], s2[1] = *p;
177+
s3[0] = s3[1], s3[1] = s3[2], s3[2] = *p;
178+
s4[0] = s4[1], s4[1] = s4[2], s4[2] = s4[3], s4[3] = *p;
179+
180+
if (primos_isprimo(atoi(s1))) // somente 1 char
181+
{
182+
lista[lista_size].end = p;
183+
lista[lista_size].start = p;
184+
lista_size++;
185+
}
186+
if (s2[0] && primos_isprimo(atoi(s2))) // somente 2 chars
187+
{
188+
lista[lista_size].end = p;
189+
lista[lista_size].start = p - 1;
190+
lista_size++;
191+
}
192+
if (s3[0] && primos_isprimo(atoi(s3))) // somente 3 chars
193+
{
194+
lista[lista_size].end = p;
195+
lista[lista_size].start = p - 2;
196+
lista_size++;
197+
}
198+
if (s4[0] && primos_isprimo(atoi(s4))) // somente 4 chars
199+
{
200+
lista[lista_size].end = p;
201+
lista[lista_size].start = p - 3;
202+
lista_size++;
203+
}
204+
if (ORGANIZE < lista_size) // a cada ORGANIZE primos na lista ele faz o processamento e apaga a lista
205+
{
206+
fprintf(stdout, "\b\b\b\b%03ld%%", ((p - buffer) / 10000)); // esperar sem saber o progresso cansa
207+
fflush(stdout);
208+
processar_quicksort(0, lista_size - 1); // sort da array
209+
processar_maiorprimo(); // processa a array
210+
}
211+
212+
p++;
213+
}
214+
fprintf(stdout, "\b\b\b\b100%%");
215+
processar_quicksort(0, lista_size - 1);
216+
processar_maiorprimo(); // caso ainda tenha algum número incluído na lista, processa antes de retornar
217+
}
218+
219+
int main()
220+
{
221+
FILE *fs = NULL;
222+
223+
fs = fopen("pi-1M.txt", "r"); // abrir o arquivo e alocar na memória para processar
224+
if (!fs)
225+
{
226+
printf("Erro ao ler o arquivo\n");
227+
exit(1);
228+
}
229+
fseek(fs, 0, SEEK_END);
230+
buffer_size = ftell(fs);
231+
fseek(fs, 0, SEEK_SET);
232+
buffer = (char *)malloc(sizeof(char) * (buffer_size + 1));
233+
if (!buffer)
234+
{
235+
printf("Memória insuficiente para abrir o arquivo\n");
236+
fclose(fs);
237+
free_all();
238+
exit(1);
239+
}
240+
buffer_size = fread(buffer, 1, buffer_size, fs);
241+
if (buffer_size == 0)
242+
{
243+
printf("Erro ao ler o arquivo\n");
244+
fclose(fs);
245+
free_all();
246+
exit(1);
247+
}
248+
fclose(fs);
249+
250+
primos_init();
251+
processar();
252+
253+
*++maior.end = 0; // para mostrar entre maior inicio e maior fim eu sinalizo que a string acabou em maior.end+1
254+
printf("\b\b\b\b%s\n", maior.start);
255+
256+
free_all();
257+
258+
return 0;
259+
}

0 commit comments

Comments
 (0)