// Executa o Problema de Josephus. void executaJosephus(TListaCirc* lista) { // Verifica se a lista está vazia if(!verificaCircVazio(lista)) { int tamanho = verificaQteSoldados(lista); if(tamanho == 1) { printf("Existe apenas um Soldado, então, %s deverá montar no cavalo e escapar", lista->dado); } else { TListaCirc* soldadoAnterior = lista; int contador = 0; inicializaRand(); int numeroSorteado = sorteiaNumero(); TListaCirc* soldadoSorteado = sorteiaSoldado(lista); printf("Número sorteado: %d\n", numeroSorteado); printf("Soldado sorteado para iniciar a contagem: %s\n", soldadoSorteado->dado); printf("#############################################################\n\n"); while(tamanho > 1) { contador = 0; printf("Soldados no círculo: %d\n", tamanho); do { soldadoAnterior=soldadoSorteado; soldadoSorteado = soldadoSorteado->proxima; if (++contador == numeroSorteado) { if (soldadoSorteado == lista) { lista = soldadoSorteado->proxima; } printf("O soldado %s foi retirado do círculo\n", soldadoSorteado->dado); soldadoAnterior->proxima = soldadoSorteado->proxima; // reinicia contagem com o Soldado seguinte lista = soldadoSorteado->proxima; printf("Contagem iniciará à partir do soldado %s\n\n", lista->dado); free(soldadoSorteado); soldadoSorteado = lista; tamanho = verificaQteSoldados(lista); } } while(contador != numeroSorteado); }; printf("#############################################################\n"); printf("Como o soldado %s é o único restante, ele deverá montar no cavalo e escapar", lista->dado); } } else { printf("Nenhum soldado no círculo\n"); } }
// Imprime soldados da Lista Circular. void imprimeSoldadosCirc(TListaCirc* lista) { if(!verificaCircVazio(lista)) { TListaCirc* aux = lista; do { printf("-> %s\n", aux->dado); aux = aux->proxima; } while (aux != lista); } else { printf("Lista vazia\n"); } }
/* * Função que imprime na tela a lista com os soldados inseridos */ void imprimeSoldadosCirc(SLista* lista) { SLista* aux = lista; if ( !verificaCircVazio(lista) ) { do { printf("[Num. %d] %s [%p]->[%p]\n", aux->num, aux->nome, aux, aux->prox); aux = aux->prox; } while (aux != lista); } }
// Verifica quantidade de Soldados na Lista Circular. int verificaQteSoldados(TListaCirc* lista) { int cont = 0; if(!verificaCircVazio(lista)) { TListaCirc* aux = lista; do { cont++; aux = aux->proxima; } while (aux != lista); } return cont; }
/* * Função que verifica a quantidade de soldados na lista */ int verificaQteSoldados(SLista* lista) { int qtd = 0; SLista* aux = lista; if ( !verificaCircVazio(lista) ) { qtd++; while (aux->prox != lista) { qtd++; aux = aux->prox; } } return qtd; }
/* * Função Josephus */ SLista* executaJosephus(SLista* lista, int quantidade) { int i, num_soldado, num_iteracoes; // Verifica se o circulo esta vazio if (verificaCircVazio(lista)) { printf("\n[-] Ops! Círculo esta vazio.\n"); return lista; } // Verifica se há apenas um soldado na lista if (quantidade == 1) { printf("\n[!] Soldado escolhido: %s\n", lista->nome); return lista; } num_iteracoes = rand() % 20; num_soldado = rand() % quantidade; SLista* aux = lista; printf("Quantidade de soldados: %d\n\n", quantidade); imprimeSoldadosCirc(lista); printf("\nSorteando o soldado para iniciar a contagem...\nSorteado %da posição.\n", num_soldado + 1); // O soldado sorteado vai ser a X iteração do número sorteado for (i = 0; i < num_soldado; i++) aux = aux->prox; printf("Soldado inicial: %s\nNum. de iterações na adedanha: %d\n", aux->nome, num_iteracoes); // Percorre a lista X vezes a partir do soldado sorteado e elimina um soldado da lista for (i = 0; i < num_iteracoes; i++) aux = aux->prox; printf("Soldado eliminado: %s\n", aux->nome); lista = remove_soldado(lista, aux); printf("\n-----------------------------------------\n"); return executaJosephus(lista, quantidade - 1); }
// Insere Soldado na Lista Circular. TListaCirc* insereSoldadoNoCirc(TListaCirc *lista, Nome soldado) { TListaCirc* aux1; aux1 = (TListaCirc *) malloc(sizeof(TListaCirc)); strcpy(aux1->dado, soldado); if(!verificaCircVazio(lista)) { TListaCirc* aux2 = lista; // Encontra o último registro da lista. do { aux2 = aux2->proxima; } while (aux2->proxima != lista); aux2->proxima = aux1; aux1->proxima = lista; } else { aux1->proxima = aux1; } return aux1; }
/* * Função que insere um soldado na lista */ SLista* insereSoldadoNoCirc(SLista* lista, char* nome, int num) { // Alocação do soldado na memória SLista* soldado = cria_soldado(nome, num); /* Se lista existir (se não estiver vazia), * percorre até encontrar o último elemento. * Liga o 'prox' do último soldado no novo soldado, * liga o 'prox' do novo soldado na lista. */ if (!verificaCircVazio(lista)) { SLista* aux = lista; while (aux->prox != lista) aux = aux->prox; aux->prox = soldado; // Liga o último elemento da lista no novo registro soldado->prox = lista; // Fecha a lista circular, ligando o novo registro na lista } return soldado; }