Advertisement
Guest User

Untitled

a guest
Jan 17th, 2020
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 65.01 KB | None | 0 0
  1.  
  2. /// TRABALHO REALIZADO POR:
  3. /// 36431 - João Vargas
  4. /// 36763 - Pedro Pinheiro
  5.  
  6.  
  7. /// O QUE FALTA FAZER !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  8. /// FALTA IMPLEMENTAR A FILA
  9. /// FALTA R14 E R15 (BIN E TXT, NÓS JÁ TEMOS MAS É EM METRIZ, TEMOS DE FAZER COM LINKED LIST AGORA )
  10. /// QUANDO UM TABULEIRO FOR IMPOSSIVEL TEMOS DE TER UMA CONDICAO NO ALGORITMO MELHORADO QUE PARE A EXECUCAO DO ALGORITMO E IMPRIMA A MENSAGEM DE SUDOKU IMPOSSIVEL
  11. /// FAZER MAIS 2 PESQUISAS PARA MELHORAR O ALGORITMO
  12. /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  13.  
  14. #include "projeto.h"
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <time.h>
  18. #include <math.h>
  19.  
  20. /// VARIÁVEIS GLOBAIS ///
  21. int count_global =0; /// contador de numero de ciclos feitos por cada algoritmo
  22. int mudar_algoritmo = 0;
  23. int num_tab_memoria = 0;
  24. int num_zeros=0;
  25. ///
  26.  
  27.  
  28.  
  29. struct fila addFila(struct fila *f, struct node *head){
  30. if(f->size == 0){
  31. /// se o size = 0 , então a fila está vazia
  32. f->tabuleiro = malloc(sizeof(struct tabuleiros));
  33. f->inicio = malloc(sizeof(struct tabuleiros));
  34. f->fim = malloc(sizeof(struct tabuleiros));
  35. f->tabuleiro->no = head;
  36. f->inicio = f->tabuleiro;
  37. f->tabuleiro->next = NULL;
  38. f->tabuleiro->prev = NULL;
  39. f->fim = f->tabuleiro;
  40. f->size++;
  41. f->tabuleiro->index = f->size ;
  42. return *f;
  43. }else{
  44. struct tabuleiros *aux =NULL;
  45. struct fila *faux = f;
  46. aux = malloc(sizeof(struct tabuleiros) );
  47. aux->no = head; // aux é o novo nó para inserir
  48. aux->next = f->tabuleiro;
  49. aux->prev = NULL;
  50. f->tabuleiro->prev = aux;
  51. f->inicio = aux; //o inicio vai ficar a apontar para o novo nó
  52. f->size++;
  53. f->tabuleiro->index = f->size;
  54. return *f;
  55. }
  56. }
  57. void printfila(struct fila *f){
  58. f->tabuleiro = f->inicio;
  59. while(f->tabuleiro != NULL){
  60. printf("%d \n",f->tabuleiro->index);
  61. f->tabuleiro = f->tabuleiro->next;
  62. }
  63. }
  64. struct fila * createFila(){
  65. struct fila * f=NULL;
  66. f = malloc(sizeof(struct fila));
  67. f->size=0;
  68. return f;
  69. }
  70.  
  71.  
  72.  
  73. /**
  74. *
  75. * @param matriz
  76. * @param lin
  77. * @param col
  78. * @return
  79. */
  80. struct node *encontra_zeros(struct node *tab)
  81. {
  82. struct node * current = tab;
  83. struct node * pcs = tab;
  84. int lin=0, col=0;
  85. while(pcs != NULL) {
  86. while(current != NULL) {
  87. current->col = col;
  88. current->lin = lin;
  89. if (current->data == 0) {
  90. return current;
  91. }
  92. current = current->pnext;
  93. count_global ++;
  94. col++;
  95. }
  96. lin ++;
  97. col = 0;
  98. current = pcs->S;
  99. pcs = pcs->S;
  100. }
  101. free(current);
  102. free(pcs);
  103. return 0;
  104. }
  105. /**
  106. *
  107. * @param matriz
  108. * @param lin
  109. * @param col
  110. * @param num
  111. * @return
  112. */
  113. int verifica_quadrado(struct node *tab,int num){
  114. int raiz = sqrt(NUM);
  115. struct node *quad = tab;
  116. struct node *aux_quad = tab;
  117. int lin_quad = tab->lin - tab->lin % raiz;
  118. int col_quad = tab->col - tab->col % raiz;
  119. int cel_num = (tab->lin * NUM) + tab->col; /// para verificar em todas as posicoes do quadrado menos nesta, porque nao vai verificar o proprio numero
  120.  
  121. /// percorre o quardrado para veirificar os numeros possiveis
  122.  
  123. while (quad->lin != lin_quad){ /// para quad chegar à celula do inicio do quadrado (lin)
  124. quad = quad->N;
  125. aux_quad = aux_quad->N;
  126. }
  127. while (quad->col != col_quad){ /// para quad chegar à celula do inicio do quadrado (col)
  128. quad = quad->prev_node;
  129. aux_quad = aux_quad->prev_node;
  130. }
  131.  
  132. for (int i = 0; i < raiz; i++) {
  133. for (int j = 0; j < raiz; j++) {
  134. int aux_cel_num = (quad->lin * NUM) + quad->col; /// para verificar em todas as posicoes do quadrado menos nesta, porque nao vai verificar o proprio numero
  135. if (quad->data == num && aux_cel_num != cel_num) {
  136. return 0;
  137. }
  138. quad = quad->pnext;
  139. }
  140. quad = aux_quad->S;
  141. aux_quad = aux_quad->S;
  142. }
  143. free(quad);
  144. free(aux_quad);
  145. return 1;
  146. }
  147.  
  148. int verifica_lin(struct node *tab,int num) {
  149. struct node * norte = tab;
  150. struct node * sul = tab;
  151.  
  152. while (norte != NULL){
  153. if(norte->data == num){
  154. count_global ++;
  155. return 0;
  156. }
  157. norte = norte->N;
  158. }
  159.  
  160. while (sul != NULL){
  161. if(sul->data == num){
  162. count_global ++;
  163. return 0;
  164. }
  165. sul = sul->S;
  166. }
  167. free(norte);
  168. free(sul);
  169. return 1;
  170. }
  171.  
  172. int verifica_col(struct node *tab,int num) {
  173. struct node * este = tab;
  174. struct node * oeste = tab;
  175.  
  176. while (este != NULL){
  177. if(este->data == num){
  178. count_global ++;
  179. return 0;
  180. }
  181. este = este->pnext;
  182. }
  183.  
  184. while (oeste != NULL){
  185. if(oeste->data == num){
  186. count_global ++;
  187. return 0;
  188. }
  189. oeste = oeste->prev_node;
  190. }
  191. free(este);
  192. free(oeste);
  193. return 1;
  194. }
  195.  
  196. int verifica_x_principal(struct node *tab,int num){
  197. struct node * diag_prin_no = tab;
  198. struct node * diag_prin_se = tab;
  199.  
  200. while (diag_prin_no != NULL){
  201. if(diag_prin_no->data == num){
  202. count_global ++;
  203. return 0;
  204. }
  205. diag_prin_no = diag_prin_no->NO;
  206. }
  207. while (diag_prin_se != NULL){
  208. if(diag_prin_se->data == num){
  209. count_global ++;
  210. return 0;
  211. }
  212. diag_prin_se = diag_prin_se->SE;
  213. }
  214. free(diag_prin_se);
  215. free(diag_prin_no);
  216. return 1;
  217. }
  218.  
  219. int verifica_x_secundario(struct node * tab,int num){
  220. struct node * diag_prin_so = tab;
  221. struct node * diag_prin_ne = tab;
  222.  
  223. while (diag_prin_so != NULL){
  224. if(diag_prin_so->data == num){
  225. count_global ++;
  226. return 0;
  227. }
  228. diag_prin_so = diag_prin_so->SO;
  229. }
  230. while (diag_prin_ne != NULL){
  231. if(diag_prin_ne->data == num){
  232. count_global ++;
  233. return 0;
  234. }
  235. diag_prin_ne = diag_prin_ne->NE;
  236. }
  237. free(diag_prin_so);
  238. free(diag_prin_ne);
  239. return 1;
  240. }
  241. int verificar_condicoes(struct node * tab,int num){
  242. if(tab->lin == tab->col && (tab->lin + tab->col) == NUM-1) { /// diagonal principal e secundaria
  243. if (verifica_col(tab, num) == 1 &&
  244. verifica_lin(tab, num) == 1 &&
  245. verifica_quadrado(tab, num) == 1 &&
  246. verifica_x_principal(tab, num) == 1 &&
  247. verifica_x_secundario(tab, num) == 1 && tab->data == 0){
  248. return 1;
  249. }
  250. }
  251.  
  252. else if(tab->lin == tab->col) { /// para verificar se os numeros estao posicionados em alguma posicao do "x", (lin = col, para \ )(lin+col ==N-1, para / )
  253. if (verifica_lin(tab, num) == 1 &&
  254. verifica_col(tab, num) == 1 &&
  255. verifica_quadrado(tab, num) == 1 &&
  256. verifica_x_principal(tab, num) == 1 && tab->data == 0) {
  257. return 1;
  258. }
  259. }
  260. /// caso nao esteja posicionado no "x" faz as condicoes normais
  261. else if ((tab->lin + tab->col) == NUM-1){
  262. if (verifica_col(tab, num) == 1 &&
  263. verifica_lin(tab, num) == 1 &&
  264. verifica_quadrado(tab, num) == 1 &&
  265. verifica_x_secundario(tab, num) == 1 && tab->data == 0) {
  266. return 1;
  267. }
  268. }
  269.  
  270. else{
  271. if (verifica_col(tab,num) == 1 &&
  272. verifica_lin(tab, num) == 1 &&
  273. verifica_quadrado(tab, num) == 1 &&
  274. tab->data == 0) {
  275. return 1;
  276. }
  277. }
  278.  
  279. return 0;
  280. }
  281. /**
  282. *
  283. * @param matriz
  284. * @return
  285. */
  286. int sudoku(struct node *head) {
  287. struct node* current = NULL;
  288. current = encontra_zeros(head);
  289.  
  290. if (current == 0) /// encontra todos os zeros da matriz, manda o endereco para a variavel row e col ser incrementada
  291. return 1; /// caso retorne 1, quer dizer que já nao existem zeros na matriz e retorna para de seguida ir para o if(sudoku) e sair da funcao
  292.  
  293. for (int num = 1; num <= NUM; num++){ /// numeros que vao ser inseridos nos zeros encontrados
  294. if(verificar_condicoes(current,num) == 1){
  295. current->data = num;
  296.  
  297. if (sudoku(head)) /// quando terminar o sudoku, este if trata de sair da funcao
  298. return 1;
  299.  
  300. current->data = 0; /// nesta posicao o numero ja esgotou todas as possibilidade (num 1-9) e vai ter de fazer o Back Tracking Search, ou seja vai ter de recuar as posicoes de forma a tentar alterar os numeros anteriores
  301. }
  302. }
  303. return 0;
  304. }
  305.  
  306. void guardar_matriztxt(struct node * tab) {
  307. FILE *fp;
  308. fp=fopen("matrizsolucao.txt","w");
  309. int count_col=1,count_lin = 1;
  310. int raiz = sqrt(NUM);
  311. struct node * current = tab;
  312. for (int lin = 0; lin < NUM; lin++){
  313. for (int col = 0; col < NUM; col++) {
  314. fprintf(fp,"%d",tab->data);
  315. fprintf(fp," ");
  316. if(col+1 == (raiz)*count_col){
  317. count_col ++;
  318. fprintf(fp," ");
  319. }
  320. tab = tab->pnext;
  321. }
  322. count_col =1;
  323. if(lin+1 == (raiz)*count_lin){
  324. count_lin++;
  325. fprintf(fp,"\n");
  326. }
  327. fprintf(fp,"\n");
  328. tab = current->S;
  329. current = current-> S;
  330. }
  331. fclose(fp);
  332. }
  333. void guardar_matrizbin(struct node * tab) {
  334. FILE *fp;
  335. fp=fopen("matrizsolucao.bin","wb");
  336. struct node * current = tab;
  337. int count_col=1,count_lin = 1;
  338. int raiz = sqrt(NUM);
  339. for (int lin = 0; lin < NUM; lin++){
  340. for (int col = 0; col < NUM; col++) {
  341. fwrite(&tab->data, sizeof(int),1,fp);
  342. fwrite(" ",1,1,fp);
  343. if(col+1 == (raiz)*count_col){
  344. count_col ++;
  345. fwrite(" ",1,1,fp);
  346. }
  347. tab = tab->pnext;
  348. }
  349. count_col =1;
  350. if(lin+1 == (raiz)*count_lin){
  351. count_lin++;
  352. fwrite("\n",1,1,fp);
  353. }
  354. fwrite("\n",1,1,fp);
  355. tab = current->S;
  356. current = current-> S;
  357. }
  358. fclose(fp);
  359. }
  360.  
  361. void carregar_matriz(struct node **head){
  362. FILE *fp;
  363. fp=fopen("sudoku_X9x9.txt","r");
  364. //fp=fopen("sudoku_X16x16.txt","r");
  365.  
  366. if (fp==NULL)
  367. printf("Erro ao abrir arquivo!");
  368.  
  369. for (int i = 0; i < NUM; i++){ ///guarda a letra numa variavel e aplica na matriz
  370. for (int j = 0; j < NUM; j++) {
  371. struct node * new_node = (struct node * ) malloc(sizeof(struct node)); /// aloco espaco para no novo node
  372. struct node *current = *head; /// current tem de comecar a percorrer pelo primeiro nó, isto pelo pelo head
  373. struct node * first_lin = NULL; /// node auxiliar, apenas para ajudar a fazer ligacoes com as linhas inferiores (vai estar sempre uma linha a cima)
  374. fscanf(fp, "%d", & new_node->data);
  375. new_node->pnext = NULL; /// o node seguinte vai ser null
  376.  
  377. if(*head == NULL) { /// para o 1 caso, quando é o primeiro node a ser inserido, head ainda é null
  378. new_node->prev_node = NULL; /// node anterior é null
  379. new_node->N = NULL;
  380. new_node->S = NULL;
  381. new_node->NO = NULL;
  382. new_node->NE = NULL;
  383. new_node->SO = NULL;
  384. new_node->SE = NULL;
  385. *head = new_node; /// por isso head tem de passar a ser o primeiro node
  386. }else{
  387. if (i < 1) { /// primeira linha da matriz
  388. while (current->pnext != NULL) {
  389. current = current->pnext;
  390. }
  391. new_node->prev_node = current; /// prev_node vai sempre apontar para o node anterior
  392. new_node->N = NULL; /// norte vai ser sempre NULL na 1 linha
  393. new_node->S = NULL; /// S vai comecar a NULL
  394.  
  395. new_node->NO = NULL;
  396. new_node->NE = NULL;
  397. new_node->SO = NULL;
  398. new_node->SE = NULL;
  399.  
  400. current->pnext = new_node; /// adiciono o novo node
  401.  
  402. }else if(j == 0){ /// para a primeira celula de cada linha
  403. while (current->S != NULL){ /// percorro current até o maximo possivel em S
  404. current= current->S;
  405. }
  406.  
  407. new_node->N = current; /// node N vai ser o node da linha superior
  408. new_node->S = NULL; /// S vai comecar a NULL
  409. new_node->prev_node = NULL; /// prev_node vai ser sempre NULL
  410.  
  411. new_node->NO = NULL;
  412. new_node->NE = current->pnext;
  413. new_node->SO = NULL;
  414. new_node->SE = NULL;
  415.  
  416. current->pnext->SO = new_node;
  417. current->S = new_node; /// adiciono um novo node a S de current
  418.  
  419. }else { /// para os restantes elementos das restantes linhas
  420. while (current->S != NULL){ /// percorre o maximo possivel para s (percorrendo as linhas)
  421. current = current->S;
  422. }
  423.  
  424. first_lin = current->N; /// fist_lin está uma linha a cima do current, isto porque eu quero fazer a ligacao da linha de cima com a de baixo e por isso uso o first_lin
  425.  
  426. while (current->pnext != NULL){ /// percorre o maximo possivel para a frente ( percorre as colunas )
  427. current = current->pnext;
  428. first_lin = first_lin->pnext; /// para ter acesso á celula da linha de cima para fazer o N e o S
  429. }
  430. new_node->prev_node = current;
  431. new_node->N = first_lin->pnext;
  432. new_node->S = NULL;
  433.  
  434. new_node->NO = first_lin;
  435. if(first_lin->pnext->pnext != NULL) { /// so entra aqui nas posicoes do meio da matriz, isto porque a ultima celula de cada linha, a posicao NE tem de ser NULL (no new_node)
  436. new_node->NE = first_lin->pnext->pnext;
  437. }
  438. new_node->SO = NULL;
  439. new_node->SE = NULL;
  440.  
  441.  
  442. current->pnext = new_node;
  443. first_lin->pnext->S = new_node;
  444. first_lin->SE = new_node;
  445. if(first_lin->pnext->pnext != NULL) { /// so entra aqui nas posicoes do meio da matriz, isto porque a ultima celula de cada linha, a posicao NE e se nao tem NE, a posicao correspondente tambem nao pode ter o SO, tem de ser NULL (no first_lin)
  446. first_lin->pnext->pnext->SO = new_node; ///
  447. }
  448. }
  449. }
  450. }
  451. }
  452. fclose(fp);
  453. }
  454.  
  455. void imprimirSudoku(struct node *pcs)
  456. {
  457. /// IMPRIMIR A MATRIZ ( Este-Sul )
  458. printf("\nTabuleiro:\n");
  459. struct node * current = pcs;
  460. int lin=0,col=0,count_col=1,count_lin=1,raiz = sqrt(NUM);
  461. while (pcs != NULL){
  462. while (current != NULL){
  463. printf( "%d ", current->data);
  464. if(col +1 == (raiz) * count_col){
  465. count_col ++;
  466. printf(" ");
  467. }
  468. col ++;
  469. current = current->pnext;
  470. }
  471. count_col = 1;
  472. if(lin +1 == (raiz) * count_lin){
  473. count_lin++;
  474. printf("\n");
  475. }
  476. printf("\n");
  477. lin ++;col=0;
  478. current = pcs->S;
  479. pcs = pcs->S;
  480. }
  481. free(current);
  482. }
  483. void numeros_possiveis(struct node *current) {
  484. struct node *norte = current;
  485. struct node *sul = current;
  486. struct node *este = current;
  487. struct node *oeste = current;
  488. struct node*diag_prin_no = current;
  489. struct node*diag_prin_se = current;
  490. struct node*diag_secundaria_ne = current;
  491. struct node*diag_secundaria_so = current;
  492. struct node * quad = current;
  493. struct node * aux_quad = current;
  494.  
  495. int tam_cel=0;
  496.  
  497. int raiz = sqrt(NUM);
  498. int lin_quad = current->lin - current->lin % raiz;
  499. int col_quad = current->col - current->col % raiz;
  500.  
  501. int aux[NUM*NUM], numeros[NUM], array_possiveis[NUM];
  502. int k = 0;
  503.  
  504. for (int i = 0; i < NUM ; i++) { /// numeros de 1-9
  505. numeros[i] = i+1;
  506. }
  507.  
  508. /// percorre as linhas e colunas para verificar os numeros possiveis
  509. while (norte != NULL){
  510. if(norte->data != 0){
  511. aux[k] = norte->data; /// coloca os valores existentes na linha no array aux
  512. k++;
  513. }
  514. norte = norte->N;
  515. }
  516.  
  517. while (sul != NULL){
  518. if(sul->data != 0){
  519. aux[k] = sul->data; /// coloca os valores existentes na linha no array aux
  520. k++;
  521. }
  522. sul = sul->S;
  523. }
  524.  
  525. while (este != NULL){
  526. if(este->data != 0){
  527. aux[k] = este->data; /// coloca os valores existentes na linha no array aux
  528. k++;
  529. }
  530. este = este->pnext;
  531. }
  532.  
  533. while (oeste != NULL){
  534. if(oeste->data != 0){
  535. aux[k] = oeste->data; /// coloca os valores existentes na linha no array aux
  536. k++;
  537. }
  538. oeste = oeste->prev_node;
  539. }
  540.  
  541. /// percorre o quardrado para veirificar os numeros possiveis
  542.  
  543. while (quad->lin != lin_quad){ /// para quad chegar à celula do inicio do quadrado (lin)
  544. quad = quad->N;
  545. aux_quad = aux_quad->N;
  546. }
  547. while (quad->col != col_quad){ /// para quad chegar à celula do inicio do quadrado (col)
  548. quad = quad->prev_node;
  549. aux_quad = aux_quad->prev_node;
  550. }
  551.  
  552. for (int i = 0; i < raiz; i++) {
  553. for (int j = 0; j < raiz; j++) {
  554. if (quad->data != 0 ) {
  555. aux[k] = quad->data; /// coloca os valores existentes no quadrado no array aux
  556. k++;
  557. }
  558. quad = quad->pnext;
  559. }
  560. quad = aux_quad->S;
  561. aux_quad = aux_quad->S;
  562. }
  563.  
  564. /// caso esteja na diagonal verifica tambem na diagonal
  565.  
  566. if (current->lin == current->col || (current->lin + current->col) == NUM -1) { /// para verificar se os numeros estao posicionados em alguma posicao do "x", (lin = col, para \ )(lin+col ==N-1, para / )
  567. if(current->lin == current->col) { /// na diagonal ( \ )
  568. while (diag_prin_no){
  569. if(diag_prin_no->data != 0){
  570. aux[k] = diag_prin_no->data; /// coloca os valores existentes na linha no array aux
  571. k++;
  572. }
  573. diag_prin_no = diag_prin_no->NO;
  574. }
  575. while (diag_prin_se){
  576. if(diag_prin_se->data != 0){
  577. aux[k] = diag_prin_se->data; /// coloca os valores existentes na linha no array aux
  578. k++;
  579. }
  580. diag_prin_se = diag_prin_se->SE;
  581. }
  582. }else{ /// na diagonal /
  583. while (diag_secundaria_ne){
  584. if(diag_secundaria_ne->data != 0){
  585. aux[k] = diag_secundaria_ne->data; /// coloca os valores existentes na linha no array aux
  586. k++;
  587. }
  588. diag_secundaria_ne = diag_secundaria_ne->NE;
  589. }
  590. while (diag_secundaria_so){
  591. if(diag_secundaria_so->data != 0){
  592. aux[k] = diag_secundaria_so->data; /// coloca os valores existentes na linha no array aux
  593. k++;
  594. }
  595. diag_secundaria_so = diag_secundaria_so->SO;
  596. }
  597. }
  598. }
  599.  
  600. /// agora verifico os numeros que nao foram usados, ou seja os numeros possiveis
  601.  
  602. int contador=0; /// variavel auxiliar usada apenas para percorrer aux
  603.  
  604. for (int i = 0; i < NUM ; i++) { /// percorre o array de numeros de 0-9
  605. while( numeros[i] != aux[contador] && contador <= k) { /// percorre o array aux enquanto este for diferente do numero e o tamanho de contador for menor que o tamanho de aux
  606. contador++;
  607. if(contador == k) /// quer dizer que contador percorreu todos os numeros de aux e que foram todos diferentes por isso esse numero é um dos "possiveis"
  608. {
  609. array_possiveis[tam_cel]=numeros[i];
  610. tam_cel++; /// incrementa contador de numeros possiveis
  611. }
  612. }
  613. contador = 0; /// cada vez que salta so ciclo while contador tem de ser zerado
  614. }
  615.  
  616. current->tam = tam_cel;
  617. for (int l = 0; l < current->tam ; l++) {
  618. current->array[l] = array_possiveis[l];
  619. }
  620.  
  621. free(norte);
  622. free(sul);
  623. free(este);
  624. free(oeste);
  625. free(diag_prin_no);
  626. free(diag_prin_se);
  627. free(diag_secundaria_ne);
  628. free(diag_secundaria_so);
  629. free(aux_quad);
  630. free(quad);
  631.  
  632. }
  633.  
  634. void remover_numero(struct node *current,int cel,struct node *head){
  635. int raiz = sqrt(NUM);
  636. struct node *linhas_N = current->N;
  637. struct node *linhas_S = current->S;
  638. struct node *colunas_E = current->pnext;
  639. struct node *colunas_O = current->prev_node;
  640. struct node *diag_pri_NO = current->NO;
  641. struct node *diag_pri_SE = current->SE;
  642. struct node *diag_secu_NE = current->NE;
  643. struct node *diag_secu_SO = current->SO;
  644. struct node *aux_quad = current;
  645.  
  646. int remove_lin=0, count_aux=0; /// count tem de multiplicar pelas linhas, para ir à posicao correta
  647. int lin_aux=0,col_aux=0; /// array auxiliar usado para colocar o numero que pretendo eliminar na ultima posicao
  648. current->data = current->array[cel]; /// atribui o numero correto à celula da struct ( numero pertencente à celula )
  649.  
  650. /// remover das linhas
  651. while (linhas_N != NULL) { /// remover das linhas
  652. for (int j = 0; j < linhas_N->tam; j++) {
  653. if (linhas_N->array[j] == current->array[cel]) { /// encontra nas linhas, as celulas que contêm os numeros que pretendo remover
  654. linhas_N->array[j] = 0; /// zero o numero que ia "eliminar" e passo-o para ultima posicao do array
  655. remove_lin = j + 1; /// porque j comeca em 0 e nao em 1
  656. count_aux = j; /// auxiliar para ajudar a colocar numero que pretendo eliminar na ultima posicao
  657. while (remove_lin < linhas_N->tam) { /// para trocar até à ultima posicao do array
  658. lin_aux = linhas_N->array[count_aux +1];
  659. linhas_N->array[count_aux +1] = linhas_N->array[count_aux];
  660. linhas_N->array[count_aux] = lin_aux;
  661. count_aux++;
  662. remove_lin++;
  663.  
  664. count_global++;
  665. }
  666. linhas_N->tam = linhas_N->tam - 1; /// removo uma posicao ao array
  667. }
  668. }
  669. linhas_N = linhas_N->N;
  670. }
  671.  
  672. while (linhas_S != NULL) { /// remover das linhas
  673. for (int j = 0; j < linhas_S->tam; j++) {
  674. if (linhas_S->array[j] == current->array[cel]) { /// encontra nas linhas, as celulas que contêm os numeros que pretendo remover
  675. linhas_S->array[j] = 0; /// zero o numero que ia "eliminar" e passo-o para ultima posicao do array
  676. remove_lin = j + 1; /// porque j comeca em 0 e nao em 1
  677. count_aux = j; /// auxiliar para ajudar a colocar numero que pretendo eliminar na ultima posicao
  678. while (remove_lin < linhas_S->tam) { /// para trocar até à ultima posicao do array
  679. col_aux = linhas_S->array[count_aux +1];
  680. linhas_S->array[count_aux +1] = linhas_S->array[count_aux];
  681. linhas_S->array[count_aux] = col_aux;
  682. count_aux++;
  683. remove_lin++;
  684.  
  685. count_global++;
  686. }
  687. linhas_S->tam = linhas_S->tam - 1; /// removo uma posicao ao array
  688. }
  689. }
  690. linhas_S = linhas_S->S;
  691. }
  692.  
  693. /// remover das colunas
  694. while (colunas_E != NULL) { /// remover das linhas
  695. for (int j = 0; j < colunas_E->tam; j++) {
  696. if (colunas_E->array[j] == current->array[cel]) { /// encontra nas linhas, as celulas que contêm os numeros que pretendo remover
  697. colunas_E->array[j] = 0; /// zero o numero que ia "eliminar" e passo-o para ultima posicao do array
  698. remove_lin = j + 1; /// porque j comeca em 0 e nao em 1
  699. count_aux = j; /// auxiliar para ajudar a colocar numero que pretendo eliminar na ultima posicao
  700. while (remove_lin < colunas_E->tam) { /// para trocar até à ultima posicao do array
  701. col_aux = colunas_E->array[count_aux +1];
  702. colunas_E->array[count_aux +1 ] = colunas_E->array[col_aux];
  703. colunas_E->array[count_aux] = col_aux;
  704. count_aux++;
  705. remove_lin++;
  706.  
  707. count_global++;
  708. }
  709. colunas_E->tam = colunas_E->tam - 1; /// removo uma posicao ao array
  710. }
  711. }
  712. colunas_E = colunas_E->pnext;
  713. }
  714.  
  715. while (colunas_O != NULL) {
  716. for (int j = 0; j < colunas_O->tam; j++) {
  717. if (colunas_O->array[j] == current->array[cel]) { /// encontra nas linhas, as celulas que contêm os numeros que pretendo remover
  718. colunas_O->array[j] = 0; /// zero o numero que ia "eliminar" e passo-o para ultima posicao do array
  719. remove_lin = j + 1; /// porque j comeca em 0 e nao em 1
  720. count_aux = j; /// auxiliar para ajudar a colocar numero que pretendo eliminar na ultima posicao
  721. while (remove_lin < colunas_O->tam) { /// para trocar até à ultima posicao do array
  722. col_aux = colunas_O->array[count_aux +1];
  723. colunas_O->array[count_aux +1] = colunas_O->array[col_aux];
  724. colunas_O->array[count_aux] = col_aux;
  725. count_aux++;
  726. remove_lin++;
  727.  
  728. count_global++;
  729. }
  730. colunas_O->tam = colunas_O->tam - 1; /// removo uma posicao ao array
  731. }
  732. }
  733. colunas_O = colunas_O->prev_node;
  734. }
  735.  
  736. /// Elimina na diagonal principal pos SE///
  737. if(current->lin == current->col) {
  738. while (diag_pri_SE != NULL) {
  739. for (int j = 0; j < diag_pri_SE->tam; j++) {
  740. if (diag_pri_SE->array[j] == current->array[cel]) { /// encontra nas linhas, as celulas que contêm os numeros que pretendo remover
  741. diag_pri_SE->array[j] = 0; /// zero o numero que ia "eliminar" e passo-o para ultima posicao do array
  742. remove_lin = j + 1; /// porque j comeca em 0 e nao em 1
  743. count_aux = j; /// auxiliar para ajudar a colocar numero que pretendo eliminar na ultima posicao
  744. while (remove_lin < diag_pri_SE->tam) { /// para trocar até à ultima posicao do array
  745. col_aux = diag_pri_SE->array[count_aux + 1];
  746. diag_pri_SE->array[count_aux +1] = diag_pri_SE->array[count_aux];
  747. diag_pri_SE->array[count_aux] = col_aux;
  748. count_aux++;
  749. remove_lin++;
  750.  
  751. count_global++;
  752. }
  753. diag_pri_SE->tam = diag_pri_SE->tam - 1; /// removo uma posicao ao array
  754. }
  755. }
  756. diag_pri_SE = diag_pri_SE->SE;
  757. }
  758. }
  759.  
  760. /// Elimina na diagonal principal pos NO ///
  761. if(current->lin == current->col) {
  762. while (diag_pri_NO != NULL) {
  763. for (int j = 0; j < diag_pri_NO->tam; j++) {
  764. if (diag_pri_NO->array[j] == current->array[cel]) { /// encontra nas linhas, as celulas que contêm os numeros que pretendo remover
  765. *(diag_pri_NO->array +j) = 0; /// zero o numero que ia "eliminar" e passo-o para ultima posicao do array
  766. remove_lin = j + 1; /// porque j comeca em 0 e nao em 1
  767. count_aux = j; /// auxiliar para ajudar a colocar numero que pretendo eliminar na ultima posicao
  768. while (remove_lin < diag_pri_NO->tam) { /// para trocar até à ultima posicao do array
  769. col_aux = diag_pri_NO->array[count_aux +1];
  770. diag_pri_NO->array[count_aux +1] = diag_pri_NO->array[count_aux];
  771. diag_pri_NO->array[count_aux] = col_aux;
  772. count_aux++;
  773. remove_lin++;
  774.  
  775. count_global++;
  776. }
  777. diag_pri_NO->tam = diag_pri_NO->tam - 1; /// removo uma posicao ao array
  778. }
  779. }
  780. diag_pri_NO = diag_pri_NO->NO;
  781. }
  782. }
  783.  
  784. /// Elimina na diagonal secundaria na pos SO ///
  785. if((current->lin + current->col) == NUM-1) {
  786. while (diag_secu_SO != NULL) {
  787. for (int j = 0; j < diag_secu_SO->tam; j++) {
  788. if (diag_secu_SO->array[j] == current->array[cel]) { /// encontra nas linhas, as celulas que contêm os numeros que pretendo remover
  789. diag_secu_SO->array[j] = 0; /// zero o numero que ia "eliminar" e passo-o para ultima posicao do array
  790. remove_lin = j + 1; /// porque j comeca em 0 e nao em 1
  791. count_aux = j; /// auxiliar para ajudar a colocar numero que pretendo eliminar na ultima posicao
  792. while (remove_lin < diag_secu_SO->tam) { /// para trocar até à ultima posicao do array
  793. col_aux = diag_secu_SO->array[count_aux +1];
  794. diag_secu_SO->array[count_aux +1 ] = diag_secu_SO->array[count_aux];
  795. diag_secu_SO->array[count_aux] = col_aux;
  796. count_aux++;
  797. remove_lin++;
  798.  
  799. count_global++;
  800. }
  801. diag_secu_SO->tam = diag_secu_SO->tam - 1; /// removo uma posicao ao array
  802. }
  803. }
  804. diag_secu_SO = diag_secu_SO->SO;
  805. }
  806. }
  807.  
  808. /// Elimina na diagonal secundaria na pos NE ///
  809. if((current->lin + current->col) == NUM-1) {
  810. while (diag_secu_NE != NULL) {
  811. for (int j = 0; j < diag_secu_NE->tam; j++) {
  812. if (diag_secu_NE->array[j] == current->array[cel]) { /// encontra nas linhas, as celulas que contêm os numeros que pretendo remover
  813. diag_secu_NE->array[j] = 0; /// zero o numero que ia "eliminar" e passo-o para ultima posicao do array
  814. remove_lin = j + 1; /// porque j comeca em 0 e nao em 1
  815. count_aux = j; /// auxiliar para ajudar a colocar numero que pretendo eliminar na ultima posicao
  816. while (remove_lin < diag_secu_NE->tam) { /// para trocar até à ultima posicao do array
  817. col_aux = diag_secu_NE->array[count_aux +1];
  818. diag_secu_NE->array[count_aux +1] = diag_secu_NE->array[count_aux];
  819. diag_secu_NE->array[count_aux] = col_aux;
  820. count_aux++;
  821. remove_lin++;
  822.  
  823. count_global++;
  824. }
  825. diag_secu_NE->tam = diag_secu_NE->tam - 1; /// removo uma posicao ao array
  826. }
  827. }
  828. diag_secu_NE = diag_secu_NE->NE;
  829. }
  830. }
  831.  
  832. /// Eliminar num em todas as celulas do quadrado
  833. int lin_quad = current->lin - current->lin % raiz;
  834. int col_quad = current->col - current->col % raiz;
  835. int cel_num = (current->lin * NUM) + current->col; /// para verificar em todas as posicoes do quadrado menos nesta, porque nao vai verificar o proprio numero
  836.  
  837. while (aux_quad->lin != lin_quad){ /// para quad chegar à celula do inicio do quadrado (lin)
  838. aux_quad = aux_quad->N;
  839. }
  840. while (aux_quad->col != col_quad){ /// para quad chegar à celula do inicio do quadrado (col)
  841. aux_quad = aux_quad->prev_node;
  842. }
  843.  
  844. struct node * quad = aux_quad; /// node auxiliar que anda para sul a partir da 1 celula do quadrado
  845.  
  846. for (int i = 0; i < raiz; i++) {
  847. for (int k = 0; k < raiz; k++) {
  848. for (int j = 0; j < quad->tam; j++) {
  849. int aux_cel_num = (quad->lin * NUM) + quad->col;
  850. if (cel_num != aux_cel_num) {
  851. if (quad->array[j] == current->array[cel]) { /// encontra nas linhas, as celulas que contêm os numeros que pretendo remover
  852. quad->array[j] = 0; /// zero o numero que ia "eliminar" e passo-o para ultima posicao do array
  853. remove_lin = j + 1; /// porque j comeca em 0 e nao em 1
  854. count_aux = j; /// auxiliar para ajudar a colocar numero que pretendo eliminar na ultima posicao
  855. while (remove_lin < quad->tam) { /// para trocar até à ultima posicao do array
  856. col_aux = quad->array[count_aux +1];
  857. quad->array[count_aux +1] = quad->array[count_aux];
  858. quad->array[count_aux] = col_aux;
  859. count_aux++;
  860. remove_lin++;
  861.  
  862. count_global++;
  863. }
  864. quad->tam = quad->tam - 1; /// removo uma posicao ao array
  865. }
  866. }
  867. }
  868. quad = quad->pnext;
  869. }
  870. quad = aux_quad->S;
  871. aux_quad = aux_quad->S;
  872. }
  873.  
  874. /// para numero sozinho, tenho de remover o tamanho do array até este possuir tamanho 1 e passar à matriz o array que pretendo, neste caso vai ser um array de um numero, o numero a que a celula pertence
  875. if(current->array[1] != 0){
  876. for (int i = 0; i < current->tam ; i++) { /// zera as posicoes todas do array
  877. current->array[i] = 0;
  878. }
  879. while (current->tam > 1 ){ /// coloca tam com tamanho 1
  880. current->tam = current->tam-1;
  881. }
  882. }else if(current->tam == 1){
  883. *(current->array+0) = 0; /// atribui o numero correto à celula da matriz tridimensional
  884. }
  885.  
  886. free(linhas_N);
  887. free(linhas_S);
  888. free(colunas_E);
  889. free(colunas_O);
  890. free(diag_pri_NO);
  891. free(diag_pri_SE);
  892. free(diag_secu_NE);
  893. free(diag_secu_SO);
  894. free(aux_quad);
  895. free(quad);
  896. }
  897.  
  898. /// faz as verificacoes, para verificar se o numero é unico na linha, coluna , quadrado ou diagonal
  899.  
  900. int verifica_oculto(struct node *current ,int cel ){ /// retorna 1 caso nao exista nenhum numero igual e 0 caso exista
  901. int aux1=0,aux2=0,aux3=0,aux4=0,aux5=0,raiz = sqrt(NUM);
  902. struct node *coluna_N = current->N;
  903. struct node *coluna_S = current->S;
  904. struct node *linha_E = current->pnext;
  905. struct node *linha_O = current->prev_node;
  906. struct node *diag_prin_SE = current->SE;
  907. struct node *diag_prin_NO = current->NO;
  908. struct node *diag_secu_SO = current->SO;
  909. struct node *diag_secu_NE = current->NE;
  910. struct node * aux_quad = current;
  911.  
  912. /// Verifica nas colunas
  913. while (coluna_N != NULL){
  914. for (int i = 0; i < coluna_N->tam ; ++i) {
  915. if(coluna_N->array[i] == current->array[cel]){
  916. aux1++;
  917. count_global++;
  918. }
  919. }
  920. coluna_N = coluna_N->N;
  921. }
  922.  
  923. while (coluna_S != NULL){
  924. for (int i = 0; i < coluna_S->tam ; ++i) {
  925. if(coluna_S->array[i] == current->array[cel]){
  926. aux1++;
  927. count_global++;
  928. }
  929. }
  930. coluna_S = coluna_S->S;
  931. }
  932.  
  933. /// Verifica nas colunas
  934. while ( linha_E != NULL){
  935. for (int i = 0; i < linha_E->tam ; ++i) {
  936. if(linha_E->array[i] == current->array[cel]){
  937. aux2++;
  938. count_global++;
  939. }
  940. }
  941. linha_E = linha_E->pnext;
  942. }
  943.  
  944. while ( linha_O != NULL){
  945. for (int i = 0; i < linha_O->tam ; ++i) {
  946. if(linha_O->array[i] == current->array[cel]){
  947. aux2++;
  948. count_global++;
  949. }
  950. }
  951. linha_O = linha_O->prev_node;
  952. }
  953.  
  954. /// Verificar nas diagonais
  955. /// Diagonal Principal
  956. if(current->lin == current->col) {
  957. while (diag_prin_SE != NULL) {
  958. for (int i = 0; i < diag_prin_SE->tam; ++i) {
  959. if (diag_prin_SE->array[i] == current->array[cel]) {
  960. aux3++;
  961. count_global++;
  962. }
  963. }
  964. diag_prin_SE = diag_prin_SE->SE;
  965. }
  966.  
  967. while (diag_prin_NO != NULL) {
  968. for (int i = 0; i < diag_prin_NO->tam; ++i) {
  969. if (diag_prin_NO->array[i] == current->array[cel]) {
  970. aux3++;
  971. count_global++;
  972. }
  973. }
  974. diag_prin_NO = diag_prin_NO->NO;
  975. }
  976. }
  977.  
  978. /// Diagonal Secundária
  979. if((current->lin + current->col) == NUM -1 ) {
  980. while (diag_secu_SO != NULL) {
  981. for (int i = 0; i < diag_secu_SO->tam; ++i) {
  982. if (diag_secu_SO->array[i] == current->array[cel]) {
  983. aux4++;
  984. count_global++;
  985. }
  986. }
  987. diag_secu_SO = diag_secu_SO->SO;
  988. }
  989.  
  990. while (diag_secu_NE != NULL) {
  991. for (int i = 0; i < diag_secu_NE->tam; ++i) {
  992. if (diag_secu_NE->array[i] == current->array[cel]) {
  993. aux4++;
  994. count_global++;
  995. }
  996. }
  997. diag_secu_NE = diag_secu_NE->NE;
  998. }
  999. }
  1000.  
  1001.  
  1002. /// quadrado
  1003.  
  1004. int lin_quad = current->lin - current->lin % raiz;
  1005. int col_quad = current->col - current->col % raiz;
  1006. int cel_num = (current->lin * NUM) + current->col; /// para verificar em todas as posicoes do quadrado menos nesta, porque nao vai verificar o proprio numero
  1007.  
  1008. while (aux_quad->lin != lin_quad){ /// para quad chegar à celula do inicio do quadrado (lin)
  1009. aux_quad = aux_quad->N;
  1010. }
  1011. while (aux_quad->col != col_quad){ /// para quad chegar à celula do inicio do quadrado (col)
  1012. aux_quad = aux_quad->prev_node;
  1013. }
  1014.  
  1015. struct node * quad = aux_quad; /// node auxiliar que anda para sul a partir da 1 celula do quadrado
  1016.  
  1017. for (int i = 0; i < raiz; i++) {
  1018. for (int j = 0; j < raiz; j++) {
  1019. int aux_cel_num = (quad->lin * NUM) + quad->col;
  1020. if (cel_num != aux_cel_num) {
  1021. for (int k = 0; k < quad->tam ; ++k) {
  1022. if ( quad->array[k] == current->array[cel] ) {
  1023. aux5++;
  1024. count_global++;
  1025. }
  1026. }
  1027. }
  1028. quad = quad->pnext;
  1029. }
  1030. quad = aux_quad->S;
  1031. aux_quad = aux_quad->S;
  1032. }
  1033.  
  1034. free(coluna_N);
  1035. free(coluna_S);
  1036. free(linha_E);
  1037. free(linha_O);
  1038. free(diag_prin_SE);
  1039. free(diag_prin_NO);
  1040. free(diag_secu_SO);
  1041. free(diag_secu_NE);
  1042. free(aux_quad);
  1043. free(quad);
  1044.  
  1045.  
  1046. if(aux1 == 0 || aux2 == 0 || (aux3 == 0 && current->lin == current->col ) || aux5 == 0 || (aux4 == 0 && ((current->lin + current->col) == NUM-1) )){ /// se contador permanecer a 1 é porque nao existe mais nenhum numero igual na linha,coluna,diagonal e quadrado
  1047. return 1;
  1048. }
  1049. return 0;
  1050. }
  1051.  
  1052. void elimina_par_coluna(struct node *current){
  1053. int count_aux=0,col_aux=0,remove_lin=0;
  1054. struct node *par_coluna = current;
  1055. int cel_num = (current->lin * NUM) + current->col; /// para verificar em todas as posicoes do quadrado menos nesta, porque nao vai verificar o proprio numero
  1056.  
  1057. while (par_coluna->N != NULL){ /// faco o par coluna ir o maximo possivel para norte, para de seguida percorrer a coluna toda para sul e fazer as verificacoes
  1058. par_coluna= par_coluna->N;
  1059. }
  1060. struct node *par_coluna_aux = par_coluna;
  1061.  
  1062. while (par_coluna != NULL){ /// percorro a coluna
  1063. int cel_par_coluna = (par_coluna->lin * NUM) + par_coluna->col;
  1064. if(cel_par_coluna != cel_num){ /// verifico todas as celulas menos a celula do current
  1065. if(par_coluna->tam == 2) { /// verifico se alguma das celulas da coluna do current tem tamanho 2
  1066. if (*(current->array + 0) == *(par_coluna->array + 0) && *(current->array + 1) == *(par_coluna->array + 1)) { /// se tiver tamanho 2 verifico se é igual ao current
  1067. /// se for igual tenho de eliminar todos os numeros iguais na coluna
  1068. while (par_coluna_aux != NULL) {
  1069. int cel_par_coluna_aux = (par_coluna_aux->lin * NUM) + par_coluna_aux->col;
  1070. if(cel_par_coluna_aux != cel_par_coluna && cel_par_coluna_aux != cel_num) {
  1071. for (int j = 0; j < par_coluna_aux->tam; j++) {
  1072. if (*(par_coluna_aux->array + j) == *(current->array + 0) ||*(par_coluna_aux->array + j) == *(current->array +1)) { /// caso as as celulas da coluna possuem numeros iguais às celulas do current, elimina esses numeros
  1073. *(par_coluna_aux->array +j) = 0; /// zero o numero que ia "eliminar" e passo-o para ultima posicao do array
  1074. remove_lin = j + 1; /// porque j comeca em 0 e nao em 1
  1075. count_aux = j; /// auxiliar para ajudar a colocar numero que pretendo eliminar na ultima posicao
  1076. while (remove_lin <par_coluna_aux->tam) { /// para trocar até à ultima posicao do array
  1077. col_aux = *(par_coluna_aux->array + count_aux + 1);
  1078. *(par_coluna_aux->array + count_aux + 1) = *(par_coluna_aux->array + count_aux);
  1079. *(par_coluna_aux->array + count_aux) = col_aux;
  1080. count_aux++;
  1081. remove_lin++;
  1082.  
  1083. count_global++;
  1084. }
  1085. par_coluna_aux->tam = par_coluna_aux->tam - 1; /// removo uma posicao ao array
  1086. }
  1087. }
  1088. }
  1089. par_coluna_aux = par_coluna_aux->S;
  1090. }
  1091. break ; /// ja encontrou um par igual na coluna, nao precisa continuar a percorrer , visto que ja encontrou e nao pode encontrar mais nenhum para igual
  1092. }
  1093. }
  1094. }
  1095. par_coluna = par_coluna->S;
  1096. }
  1097. free(par_coluna);
  1098. free(par_coluna_aux);
  1099. }
  1100.  
  1101. void elimina_par_linha(struct node *current){
  1102. int count_aux=0,col_aux=0,remove_lin=0;
  1103. struct node *par_linha = current;
  1104. int cel_num = (current->lin * NUM) + current->col; /// para verificar em todas as posicoes do quadrado menos nesta, porque nao vai verificar o proprio numero
  1105.  
  1106. while (par_linha->prev_node != NULL){ /// faco o par coluna ir o maximo possivel para norte, para de seguida percorrer a coluna toda para sul e fazer as verificacoes
  1107. par_linha= par_linha->prev_node;
  1108. }
  1109. struct node *par_linha_aux = par_linha;
  1110.  
  1111. while (par_linha != NULL){ /// percorro a coluna
  1112. int cel_par_coluna = (par_linha->lin * NUM) + par_linha->col;
  1113. if(cel_par_coluna != cel_num){ /// verifico todas as celulas menos a celula do current
  1114. if(par_linha->tam == 2) { /// verifico se alguma das celulas da coluna do current tem tamanho 2
  1115. if (*(current->array + 0) == *(par_linha->array + 0) && *(current->array + 1) == *(par_linha->array + 1)) { /// se tiver tamanho 2 verifico se é igual ao current
  1116. /// se for igual tenho de eliminar todos os numeros iguais na coluna
  1117. while (par_linha_aux != NULL) {
  1118. int cel_par_coluna_aux = (par_linha_aux->lin * NUM) + par_linha_aux->col;
  1119. if(cel_par_coluna_aux != cel_par_coluna && cel_par_coluna_aux != cel_num) {
  1120. for (int j = 0; j < par_linha_aux->tam; j++) {
  1121. if (*(par_linha_aux->array + j) == *(current->array + 0) ||*(par_linha_aux->array + j) == *(current->array +1)) { /// caso as as celulas da coluna possuem numeros iguais às celulas do current, elimina esses numeros
  1122. *(par_linha_aux->array +j) = 0; /// zero o numero que ia "eliminar" e passo-o para ultima posicao do array
  1123. remove_lin = j + 1; /// porque j comeca em 0 e nao em 1
  1124. count_aux = j; /// auxiliar para ajudar a colocar numero que pretendo eliminar na ultima posicao
  1125. while (remove_lin <par_linha_aux->tam) { /// para trocar até à ultima posicao do array
  1126. col_aux = *(par_linha_aux->array + count_aux + 1);
  1127. *(par_linha_aux->array + count_aux + 1) = *(par_linha_aux->array + count_aux);
  1128. *(par_linha_aux->array + count_aux) = col_aux;
  1129. count_aux++;
  1130. remove_lin++;
  1131.  
  1132. count_global++;
  1133. }
  1134. par_linha_aux->tam = par_linha_aux->tam - 1; /// removo uma posicao ao array
  1135. }
  1136. }
  1137. }
  1138. par_linha_aux = par_linha_aux->pnext;
  1139. }
  1140. break ; /// ja encontrou um par igual na coluna, nao precisa continuar a percorrer , visto que ja encontrou e nao pode encontrar mais nenhum para igual
  1141. }
  1142. }
  1143. }
  1144. par_linha = par_linha->pnext;
  1145. }
  1146. free(par_linha);
  1147. free(par_linha_aux);
  1148. }
  1149.  
  1150. /// ELIMINA OS PARES NA DIAGONAL PRINCIPAL
  1151. void elimina_par_diag(struct node *current){
  1152. int count_aux=0,col_aux=0,remove_lin=0;
  1153. struct node *par_diag = current;
  1154. int cel_num = (current->lin * NUM) + current->col; /// para verificar em todas as posicoes do quadrado menos nesta, porque nao vai verificar o proprio numero
  1155.  
  1156. while (par_diag->NO != NULL){ /// faco o par coluna ir o maximo possivel para norte, para de seguida percorrer a coluna toda para sul e fazer as verificacoes
  1157. par_diag = par_diag->NO;
  1158. }
  1159. struct node *par_diag_aux = par_diag;
  1160.  
  1161. while (par_diag != NULL){ /// percorro a coluna
  1162. int cel_par_coluna = (par_diag->lin * NUM) + par_diag->col;
  1163. if(cel_par_coluna != cel_num){ /// verifico todas as celulas menos a celula do current
  1164. if(par_diag->tam == 2) { /// verifico se alguma das celulas da coluna do current tem tamanho 2
  1165. if (*(current->array + 0) == *(par_diag->array + 0) && *(current->array + 1) == *(par_diag->array + 1)) { /// se tiver tamanho 2 verifico se é igual ao current
  1166. /// se for igual tenho de eliminar todos os numeros iguais na coluna
  1167. while (par_diag_aux != NULL) {
  1168. int cel_par_coluna_aux = (par_diag_aux->lin * NUM) + par_diag_aux->col;
  1169. if(cel_par_coluna_aux != cel_par_coluna && cel_par_coluna_aux != cel_num) {
  1170. for (int j = 0; j < par_diag_aux->tam; j++) {
  1171. if (*(par_diag_aux->array + j) == *(current->array + 0) ||*(par_diag_aux->array + j) == *(current->array +1)) { /// caso as as celulas da coluna possuem numeros iguais às celulas do current, elimina esses numeros
  1172. *(par_diag_aux->array +j) = 0; /// zero o numero que ia "eliminar" e passo-o para ultima posicao do array
  1173. remove_lin = j + 1; /// porque j comeca em 0 e nao em 1
  1174. count_aux = j; /// auxiliar para ajudar a colocar numero que pretendo eliminar na ultima posicao
  1175. while (remove_lin <par_diag_aux->tam) { /// para trocar até à ultima posicao do array
  1176. col_aux = *(par_diag_aux->array + count_aux + 1);
  1177. *(par_diag_aux->array + count_aux + 1) = *(par_diag_aux->array + count_aux);
  1178. *(par_diag_aux->array + count_aux) = col_aux;
  1179. count_aux++;
  1180. remove_lin++;
  1181.  
  1182. count_global++;
  1183. }
  1184. par_diag_aux->tam = par_diag_aux->tam - 1; /// removo uma posicao ao array
  1185. }
  1186. }
  1187. }
  1188. par_diag_aux = par_diag_aux->SE;
  1189. }
  1190. break ; /// ja encontrou um par igual na coluna, nao precisa continuar a percorrer , visto que ja encontrou e nao pode encontrar mais nenhum para igual
  1191. }
  1192. }
  1193. }
  1194. par_diag = par_diag->SE;
  1195. }
  1196. free(par_diag);
  1197. free(par_diag_aux);
  1198. }
  1199.  
  1200. /// ELIMINA PARES NA DIAGONAL SECUNDÁRIA
  1201. void elimina_par_diag_secun(struct node *current) {
  1202. int count_aux=0,col_aux=0,remove_lin=0;
  1203. struct node *par_diag = current;
  1204. int cel_num = (current->lin * NUM) + current->col; /// para verificar em todas as posicoes do quadrado menos nesta, porque nao vai verificar o proprio numero
  1205.  
  1206. while (par_diag->NE != NULL){ /// faco o par coluna ir o maximo possivel para norte, para de seguida percorrer a coluna toda para sul e fazer as verificacoes
  1207. par_diag = par_diag->NE;
  1208. }
  1209. struct node *par_diag_aux = par_diag;
  1210.  
  1211. while (par_diag != NULL){ /// percorro a coluna
  1212. int cel_par_coluna = (par_diag->lin * NUM) + par_diag->col;
  1213. if(cel_par_coluna != cel_num){ /// verifico todas as celulas menos a celula do current
  1214. if(par_diag->tam == 2) { /// verifico se alguma das celulas da coluna do current tem tamanho 2
  1215. if (*(current->array + 0) == *(par_diag->array + 0) && *(current->array + 1) == *(par_diag->array + 1)) { /// se tiver tamanho 2 verifico se é igual ao current
  1216. /// se for igual tenho de eliminar todos os numeros iguais na coluna
  1217. while (par_diag_aux != NULL) {
  1218. int cel_par_coluna_aux = (par_diag_aux->lin * NUM) + par_diag_aux->col;
  1219. if(cel_par_coluna_aux != cel_par_coluna && cel_par_coluna_aux != cel_num) {
  1220. for (int j = 0; j < par_diag_aux->tam; j++) {
  1221. if (*(par_diag_aux->array + j) == *(current->array + 0) ||*(par_diag_aux->array + j) == *(current->array +1)) { /// caso as as celulas da coluna possuem numeros iguais às celulas do current, elimina esses numeros
  1222. *(par_diag_aux->array +j) = 0; /// zero o numero que ia "eliminar" e passo-o para ultima posicao do array
  1223. remove_lin = j + 1; /// porque j comeca em 0 e nao em 1
  1224. count_aux = j; /// auxiliar para ajudar a colocar numero que pretendo eliminar na ultima posicao
  1225. while (remove_lin <par_diag_aux->tam) { /// para trocar até à ultima posicao do array
  1226. col_aux = *(par_diag_aux->array + count_aux + 1);
  1227. *(par_diag_aux->array + count_aux + 1) = *(par_diag_aux->array + count_aux);
  1228. *(par_diag_aux->array + count_aux) = col_aux;
  1229. count_aux++;
  1230. remove_lin++;
  1231.  
  1232. count_global++;
  1233. }
  1234. par_diag_aux->tam = par_diag_aux->tam - 1; /// removo uma posicao ao array
  1235. }
  1236. }
  1237. }
  1238. par_diag_aux = par_diag_aux->SO;
  1239. }
  1240. break ; /// ja encontrou um par igual na coluna, nao precisa continuar a percorrer , visto que ja encontrou e nao pode encontrar mais nenhum para igual
  1241. }
  1242. }
  1243. }
  1244. par_diag = par_diag->SO;
  1245. }
  1246. free(par_diag);
  1247. free(par_diag_aux);
  1248. }
  1249.  
  1250. void elimina_par_quadrado(struct node *current){
  1251. int raiz = sqrt(NUM),count_aux=0,col_aux=0,remove_lin=0;;
  1252. int lin_quad = current->lin - current->lin % raiz;
  1253. int col_quad = current->col - current->col % raiz;
  1254. int cel_num = (current->lin * NUM) + current->col; /// para verificar em todas as posicoes do quadrado menos nesta, porque nao vai verificar o proprio numero
  1255. struct node *aux_quad = current;
  1256.  
  1257. while (aux_quad->lin != lin_quad){ /// para quad chegar à celula do inicio do quadrado (lin)
  1258. aux_quad = aux_quad->N;
  1259. }
  1260. while (aux_quad->col != col_quad){ /// para quad chegar à celula do inicio do quadrado (col)
  1261. aux_quad = aux_quad->prev_node;
  1262. }
  1263.  
  1264. struct node * quad = aux_quad; /// node auxiliar que anda para sul a partir da 1 celula do quadrado
  1265. struct node * aux_quad_sul = aux_quad;
  1266. struct node *quad_current = aux_quad;
  1267.  
  1268. for (int i = 0; i < raiz; i++) {
  1269. for (int j = 0; j < raiz; j++) {
  1270. int cel_par_coluna = (quad->lin * NUM) + quad->col;
  1271. if(cel_par_coluna != cel_num){ /// verifico todas as celulas menos a celula do current
  1272. if(quad->tam == 2) { /// verifico se alguma das celulas da coluna do current tem tamanho 2
  1273. if (*(current->array + 0) == *(quad->array + 0) && *(current->array + 1) == *(quad->array + 1)) { /// se tiver tamanho 2 verifico se é igual ao current
  1274. /// se for igual tenho de eliminar todos os numeros iguais no quadrado ( para isso tenho de voltar a percorrer o quadrado )
  1275. for (int k = 0; k < raiz ; k++) {
  1276. for (int l = 0; l < raiz ; l++) {
  1277. int cel_par_coluna_aux = (quad_current->lin * NUM) + quad_current->col;
  1278. if (cel_par_coluna_aux != cel_par_coluna && cel_par_coluna_aux != cel_num) {
  1279. for (int r = 0; r < quad_current->tam; r++) {
  1280. if (*(quad_current->array + r) == *(current->array + 0) || *(quad_current->array + r) == *(current->array +1)) { /// caso as as celulas da coluna possuem numeros iguais às celulas do current, elimina esses numeros*(quad_current->array +j) = 0; /// zero o numero que ia "eliminar" e passo-o para ultima posicao do array
  1281. remove_lin = r + 1; /// porque j comeca em 0 e nao em 1
  1282. count_aux = r; /// auxiliar para ajudar a colocar numero que pretendo eliminar na ultima posicao
  1283. while (remove_lin < quad_current->tam) { /// para trocar até à ultima posicao do array
  1284. col_aux = *(quad_current->array + count_aux + 1);
  1285. *(quad_current->array + count_aux + 1) = *(quad_current->array + count_aux);
  1286. *(quad_current->array + count_aux) = col_aux;
  1287. count_aux++;
  1288. remove_lin++;
  1289.  
  1290. count_global++;
  1291. }
  1292. quad_current->tam = quad_current->tam - 1; /// removo uma posicao ao array
  1293. }
  1294. }
  1295. }
  1296. quad_current = quad_current->pnext;
  1297. }
  1298. quad_current = aux_quad_sul->S;
  1299. aux_quad_sul = aux_quad_sul->S;
  1300. }
  1301. return ; /// ja encontrou um par igual na coluna, nao precisa continuar a percorrer , visto que ja encontrou e nao pode encontrar mais nenhum para igual
  1302. }
  1303. }
  1304. }
  1305. quad = quad->pnext;
  1306. }
  1307. quad = aux_quad->S;
  1308. aux_quad = aux_quad->S;
  1309. }
  1310.  
  1311. free(quad);
  1312. free(quad_current);
  1313. free(aux_quad);
  1314. free(aux_quad_sul);
  1315. }
  1316.  
  1317. void pares_sozinhos (struct node * head){
  1318. struct node *current = head;
  1319. struct node * sul = head;
  1320. /// verifico se o current tem tamanho 2
  1321. while (sul != NULL) {
  1322. while (current != NULL) {
  1323. if (current->tam == 2) {
  1324. elimina_par_coluna(current);
  1325. elimina_par_linha(current);
  1326. if(current->lin == current->col) {
  1327. elimina_par_diag(current);
  1328. }
  1329. if ((current->lin + current->col) == NUM - 1) { /// so pode ver as diagonais secundarias se (lin +col ) == N-1
  1330. elimina_par_diag_secun(current);
  1331. }
  1332. elimina_par_quadrado(current);
  1333. }
  1334. current = current->pnext;
  1335. }
  1336. current = sul->S;
  1337. sul = sul->S;
  1338. }
  1339. free(current);
  1340. free(sul);
  1341. }
  1342.  
  1343. /**
  1344. * @param aux_matriz
  1345. * @param aux
  1346. * @param tam
  1347. * @param matriz
  1348. */
  1349. int resolver_matriz(struct node *head){
  1350. struct node * current = head;
  1351. struct node *current_sul = head;
  1352. struct node *current_aux = head;
  1353. struct node *current_sul_aux = head;
  1354.  
  1355. struct node *saltar_este = head;
  1356. struct node *saltar_sul = head;
  1357.  
  1358. int k = 0; /// ser ve para percorrer o array da matriz 3 dimensional
  1359. int count=0;
  1360. while(count != num_zeros) { /// para estar sempre a repetir as funcoes até a matriz estar toda resolvida
  1361. mudar_algoritmo = 0;
  1362. count =0;
  1363.  
  1364. while (current_sul != NULL ){
  1365. while (current != NULL){
  1366. if(current->tam == 1 && current->array[0] != 0) {
  1367. remover_numero(current,0,head); /// zero porque porque so existe o numero no array, entao esse numero está na posicao 0
  1368. mudar_algoritmo ++;
  1369. }
  1370. if (*(current->array +0) != 0 && current->tam > 1) { /// se nao estiver sozinho na celula, para eliminar numeros temos de verificar o numero oculto sozinho
  1371. for (k = 0; k < current->tam ; k++) {
  1372. if (verifica_oculto(current, k) == 1) {
  1373. remover_numero(current,k,head);
  1374. mudar_algoritmo ++;
  1375. }
  1376. }
  1377. while (current_sul_aux != NULL){
  1378. while (current_aux != NULL){
  1379. if(current_aux->tam == 1 && current_aux->array[0] != 0) {
  1380. remover_numero(current_aux,0,head); /// zero porque porque so existe o numero no array, entao esse numero está na posicao 0
  1381. mudar_algoritmo ++;
  1382. }
  1383. current_aux = current_aux->pnext;
  1384. }
  1385. current_aux = current_sul_aux->S;
  1386. current_sul_aux = current_sul_aux->S;
  1387. }
  1388. }
  1389. pares_sozinhos(head);
  1390. current = current->pnext;
  1391.  
  1392. current_aux = head;
  1393. current_sul_aux = head;
  1394.  
  1395. }
  1396. current = current_sul->S;
  1397. current_sul = current_sul->S;
  1398. }
  1399.  
  1400. /// ciclo que percorre array aux, que possui o tamanho de cada celula da matriz, quando todas as celulas tiverem tamanho 1 pode sair desta funcao
  1401. while(saltar_sul != NULL) {
  1402. while(saltar_este != NULL) {
  1403. count = count + saltar_este->tam;
  1404. // if(saltar_este->tam == 0){ /// quando entra aqui, quer dizer que o sudoku é impossivel de resolver, a matriz de tamanhos nunca pode ter tamanho 0
  1405. // return 0;
  1406. // }
  1407. saltar_este = saltar_este->pnext;
  1408. }
  1409. saltar_este = saltar_sul->S;
  1410. saltar_sul = saltar_sul->S;
  1411. }
  1412. if( mudar_algoritmo == 0){
  1413. break;
  1414. }
  1415.  
  1416. /// tenho de voltar a iniciar, porque tem de voltar a percorrer do 0
  1417. current = head;
  1418. current_sul = head;
  1419. }
  1420.  
  1421. free(current);
  1422. free(current_sul);
  1423. free(current_aux);
  1424. free(current_sul_aux);
  1425. free(saltar_este);
  1426. free(saltar_sul);
  1427.  
  1428. return 1;
  1429. }
  1430.  
  1431. /**
  1432. *
  1433. * @param matriz
  1434. * @return
  1435. */
  1436. int alg_sudoku(struct node **head, int ***memoria){ /// só falta realocar espaco, para nao estar sempre a alocar espaco desnecessario (espaco a mais )
  1437. struct node *pcs = *head;
  1438. struct node *current = *head;
  1439.  
  1440. struct node *sudoku = *head;
  1441.  
  1442. count_global = 0; /// sempre que algoritmo é chamado o contador global tem de ser zerado
  1443. int lin=0,col=0;
  1444. /// percorre os zeros todos da matriz e em cada zero vai verificar os numeros possiveis
  1445. while(pcs != NULL) {
  1446. while(current != NULL) {
  1447. current->lin = lin;
  1448. current->col = col;
  1449. if(current->data != 0){ /// quando nao for 0 vai receber os valores da matriz
  1450. current->array[0] = current->data;
  1451. }
  1452. else if (current->data == 0) { /// aux_matriz aonde for 0 vai tomar os valores possveis
  1453. numeros_possiveis(current);
  1454. num_zeros++; /// para saber quantos 0 sao para de seguida saber quando devo para de fazer o ciclo que faz o sudoku_
  1455. }
  1456. current = current->pnext;
  1457. col++;
  1458. }
  1459. current = pcs->S;
  1460. pcs = pcs->S;
  1461. lin++;
  1462. col=0;
  1463. }
  1464.  
  1465. if(resolver_matriz(sudoku) == 0){
  1466. return 0;
  1467. }
  1468.  
  1469. free(pcs);
  1470. free(current);
  1471. free(sudoku);
  1472. return 1;
  1473. }
  1474.  
  1475.  
  1476. int main_projeto(int argc, char **argv){
  1477. struct node *head = NULL;
  1478. int *** memoria = NULL;
  1479. clock_t inicio, fim;
  1480. double tempoexec;
  1481.  
  1482. ///R9 - Leitura dos tabuleiros de números a partir de um ficheiro de texto; PARA JÁ SÓ CARREGA 1, PARA CARREGAR MAIS TEMOS DE FAZER A FILA
  1483. // carregar_matriz(&head);
  1484. // imprimirSudoku(head);
  1485. // free(head);
  1486.  
  1487. ///R12 - Permitir resolver o problema com abordagens brute-force, encontrando as soluções possíveis para os tabuleiros;
  1488. // printf("\n\nBrute Force :\n\n");
  1489. // carregar_matriz(&head);
  1490. // if (sudoku(head) == 1) {
  1491. // imprimirSudoku(head);
  1492. // printf("\n\ncontador: %d\n",count_global);
  1493. // count_global = 0;
  1494. // }
  1495. // else {
  1496. // printf("Sudoku Impossivel de Resolver !!! ");
  1497. // }
  1498. // free(head);
  1499.  
  1500. /// R13 - implementando estratégias que melhorem a eficiência na pesquisa de uma solução, algoritmo melhorado
  1501. // head = NULL;
  1502. // printf("Algoritmo melhorado :\n\n");
  1503. // carregar_matriz(&head);
  1504. // if (alg_sudoku(&head,memoria) == 1 ) {
  1505. // imprimirSudoku(head);
  1506. // printf("\n\ncontador: %d\n",count_global);
  1507. // count_global = 0;
  1508. // } else{
  1509. // printf("Sudoku Impossivel de Resolver !!! ");
  1510. // }
  1511. // free(head);
  1512.  
  1513. /// Analisar e comparar as duas abordagens
  1514. ///BruteForce:
  1515. printf("\n\nBrute Force :\n\n");
  1516. head = NULL;
  1517. carregar_matriz(&head);
  1518. inicio = clock();
  1519. if (sudoku(head) == 1) {
  1520. imprimirSudoku(head);
  1521. printf("\n\ncontador: %d\n",count_global);
  1522. count_global = 0;
  1523. fim = clock();
  1524. tempoexec = ((double) (fim - inicio)) / CLOCKS_PER_SEC;
  1525. printf("Com o algoritmo brute-force a resolucao do tabuleiro foi de: %g segundos.\n\n\n", tempoexec);
  1526. }
  1527. else {
  1528. printf("Sudoku Impossivel de Resolver !!! ");
  1529. }
  1530.  
  1531. free(head);
  1532.  
  1533. /// Algoritmo melhorado:
  1534. printf("Algoritmo melhorado :\n\n");
  1535. head = NULL;
  1536. carregar_matriz(&head);
  1537. inicio = clock();
  1538. if (alg_sudoku(&head,memoria) == 1 ) {
  1539. imprimirSudoku(head);
  1540. printf("\n\ncontador: %d\n",count_global);
  1541. count_global = 0;
  1542. fim = clock();
  1543. tempoexec = ((double) (fim - inicio)) / CLOCKS_PER_SEC;
  1544. printf("Com o algoritmo melhorado a resolucao do tabuleiro foi de: %g segundos.\n\n\n", tempoexec);
  1545. } else{
  1546. printf("Sudoku Impossivel de Resolver !!! ");
  1547. }
  1548. guardar_matriztxt(head);
  1549. guardar_matrizbin(head);
  1550. free(head);
  1551. /// R14 e R15. Permitir gravar para ficheiros de texto e binário as soluções encontradas. AINDA NAO ESTÁ FEITO COM LINKED LIST !!!!!!!!!!!!!!!
  1552.  
  1553. // matriz = matriz_aleatoria();
  1554. // alg_sudoku(matriz);
  1555. // imprimirSudoku(matriz);
  1556. // guardar_matriztxt(matriz);
  1557. // guardar_matrizbin(matriz);
  1558. // free(matriz);
  1559. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement