Added a bunch of exercises

This commit is contained in:
Abreu 2023-02-11 20:42:14 -03:00
parent fa336b47ff
commit ecde13ada2
No known key found for this signature in database
GPG Key ID: 64835466FF55F7E1
83 changed files with 6195 additions and 4 deletions

View File

@ -48,7 +48,7 @@
- [ ] Endereços e ponteiros
- [ ] Alocação dinâmica d ememória
- [ ] Alocação dinâmica de memória
- [ ] Leitura de linhas de texto
@ -66,6 +66,4 @@
- [ ] Pré-processamento
- [ ] Ferramentas e utilitários
- [ ] Ferramentas e utilitários

View File

@ -0,0 +1,94 @@
# Logaritmos
## Exercícios 2
**1.** Prove os dois invariantes da primeira versão da função lg:
```c
int lg (int N)
{
int i, n;
i = 0;
n = 1;
while (n <= N/2) {
n = 2 * n;
i += 1;
}
return i;
}
```
Um invariante é uma propriedade a qual invariavelmente é verdadeira durante toda a execução de um *loop*, de tal forma que a corretude deste pode ser demonstrada se a invariante se mantêm verdadeira
- antes da iteração inicial ($i = 0$),
- para cada iteração subsequente (se verdadeira em $i = k$, também o é para $i = k + 1$)
- e ao término do *loop* ($i = n$, onde $n$ é o valor de parada)
Para o algoritmo acima, seja $N \in \N$, temos como invariantes que $n \le N$ e $i = \log_2n$.
**Prova**
Para $n$ temos:
- **Inicialização:** Para $N = 1$, $n_0 = 1$, então $n_0 \le N$.
- **Manutenção:** Para $N = k$ na iteração $x$, $x > 0$, assumimos $n_x \le k/2$. Ai para iteração $x + 1$ temos que o valor de $n_{x + 1} = 2n_x$. Como $n_x \le k/2$, tem-se que $n_{x + 1} \le k$, ou seja, $n_{x + 1} \le N$.
- **Término:** Para se encerrar na iteração $x$ tem-se que $n_x > N/2$ seja porque $n = N = 1$ ou, senão, porque $n_x > N \div 2$ quando $n_{x - 1} \le N/2$. No primeiro caso nada resta a demonstrar, mas no segundo caso segue que $n_x = 2n_{x - 1}$, então
$$
n_{x - 1} \le N/2 \stackrel{\times 2}{\implies} 2n_{x - 1} \le N \implies n_x \le N
$$
Para $i$ temos:
- **Inicialização:** Para $N = 1$, $n_0 = 1$ e $i_0 = 0$, então $i_0 = \log_2 n_0$.
- **Manutenção:** Para $N = k$ na iteração $x$ assumimos que $n_x \le k/2$ e $i_x = \log n_x$, para a iteração $x + 1$ temos que o valor de $n_{x+1} = 2n_x$ e $i_{x+ 1} = i_x + 1$. Logo,
$$
\log_2n_{x + 1} = \log_22n_x = \log_2n_x + \log_22
= i_x + 1 = i_{x + 1}
$$
- **Término:** Para se encerrar na iteração $x$ tem-se que $n_x > N/2$ seja porque $n = N = 1$ ou, senão, porque $n_x > N \div 2$ quando $n_{x - 1} \le N/2$. No primeiro caso $i = 0$ nada resta a demonstrar, mas no segundo caso segue que $n_x = 2n_{x - 1}$ e $i_{x - 1} = \log_2n_{x - 1}$, então
$$
\log_2n_x = \log_22n_{x - 1} = \log_2n_{x - 1} + \log_22
= i_{x - 1} + 1 = i_x
$$
**2.** Invariantes: $1 \le n \le N$ e $i \le \log_2N$. A demonstração é análoga a anterior. Pode ser feita aqui subsequentemente havendo tempo.
**3.** Vide `lg.c`
**4.** O que faz a função abaixo? Escreva o invariante que explica a função.
```c
int tlg (int N) {
int i = 0, n = 1;
while (n < N) {
n *= 2;
i += 1;
}
return i;
}
```
Essa é a função que apresenta o resultado de $\lceil \log_2N \rceil$. Os invariantes são $n < 2N$ e $i = \log_2 n$.
**5.** O que é o *teto* de um número real $r$?  Se $R$ é um número estritamente positivo, qual a relação entre o teto de  $log_{10} R$  e  $R$?  Escreva uma função recursiva que receba um número inteiro estritamente positivo $N$ e devolva o teto de $log_{10} N$.
O menor número inteiro $i$ tal que $i \ge r$. O teto do $\log_{10}R$ fornece o número de dígitos necessários a representar a parte inteira de $R$ em números decimais. Vide `lg.c`.
## Exercícios 3
1. Sim.
2. Vide `overflow.c`
3.

View File

@ -0,0 +1,46 @@
#include <stdio.h>
#include <string.h>
int getValue(char *varName) {
int i = -1;
printf("Type in a value to %s: ", varName);
scanf(" %d", &i);
return i;
}
int flg(int n, int base) { return (n > 1) ? flg(n / base, base) + 1 : 0; }
int clg(int n, int base) {
return flg(n, base) + ((n > base && n % base > 0) ? 1 : 0);
}
int main() {
int n, b;
char option[8];
printf("This program calculates the floor or ceiling of the logarithm of n "
"with a "
"base of b, n and b being natural numbers, and b > 2.\n");
if ((n = getValue("n")) < 1) {
printf("Invalid value for n: not a natural number\n");
return 1;
}
if ((b = getValue("b")) < 2) {
printf("Invalid value for b: not a valid logarithm base\n");
return 1;
}
printf("Which would you like to calculate? The [f]loor or [c]eiling? ");
scanf("%7s", option);
if (!strcmp("f", option) || !strcmp("floor", option))
printf("%d\n", flg(n, b));
else if (!strcmp("c", option) || !strcmp("ceiling", option))
printf("%d\n", clg(n, b));
else {
printf("Invalid option: \"%s\"\n", option);
return 1;
}
return 0;
}

View File

@ -0,0 +1,46 @@
#include <ctype.h>
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
void clearJunk(char *c) {
*c = getchar();
if (!isdigit(*c))
clearJunk(c);
}
char *readNumber(int *n) {
int i = 0, size = 1;
char c, *number = malloc(sizeof(char));
errno = INT_MAX;
clearJunk(&c);
while (isdigit(c)) {
if (i == size - 1) {
size *= 2;
number = realloc(number, size * sizeof(char));
}
number[i++] = c;
c = getchar();
}
number[i] = '\0';
*n = strtoimax(number, NULL, 10);
return number;
}
int main() {
char *number;
int n;
printf("This piece of code detects if the square power of a number "
"produces an overflow, otherwise it is printed normaly.\nType in a "
"number to test it: ");
number = readNumber(&n);
if (n > INT_MAX / n)
printf("%s ⨉ %s produces an overflow.\n", number, number);
else
printf("%d ⨉ %d = %d\n", n, n, n * n);
return 0;
}

View File

@ -0,0 +1,113 @@
#include <stdio.h>
#include <stdlib.h>
void flushInput() {
int c;
if ((c = getchar()) != '\n' && c != EOF)
flushInput();
}
int *resizeArray(int *array, int *buffer) {
*buffer *= 2;
return realloc(array, *buffer * sizeof(int));
}
int *readInput(int *size, int *buffer) {
int i, value, *array = NULL;
*buffer = 1;
for (i = 0; scanf(" %d", &value); array[i++] = value)
if (i == *buffer - 1)
array = resizeArray(array, buffer);
flushInput();
*size = i;
return array;
}
void shift(int *array, int start, int end, int increment) {
if (start == end)
return;
array[start] = array[start + increment];
shift(array, start + increment, end, increment);
}
int pop(int **array, int index, int *size) {
int value;
if (index >= *size || index < 0)
return EOF;
value = (*array)[index];
if (index > *size - index)
shift(*array, index, *size - 1, 1);
else
shift((*array)++, index, 0, -1);
(*size)--;
return value;
}
int *insert(int value, int index, int *array, int *size, int *buffer) {
if (index > *size) {
printf("Invalid index: index not in range 0 to %d", *size);
} else {
if (*size == *buffer - 1)
array = resizeArray(array, buffer);
shift(array, (*size)++, index, -1);
array[index] = value;
}
return array;
}
int iteractiveRemoveZeroes(int *array, int size) {
int i, j;
for (i = j = 0; j < size; j++)
if (array[j] != 0)
array[i++] = array[j];
return i;
}
int removeZeroes(int *array, int size) {
int pivot;
if (size == 0)
return 0;
pivot = removeZeroes(array, --size);
if (array[size] != 0)
array[pivot++] = array[size];
return pivot;
}
void printArray(int *array, int size) {
int i;
for (i = 0; i < size; i++)
printf("%d ", array[i]);
printf("\n");
}
int main() {
int value, index, size, buffer, *array;
printf("This program tests the functionality of functions to insert and "
"remove content of an array. Type in a sequence of numbers ended "
"with \".\" and press enter: ");
array = readInput(&size, &buffer);
printf("Select an index to insert a value: ");
scanf(" %d", &index);
printf("Select a value to be inserted: ");
scanf(" %d", &value);
array = insert(value, index, array, &size, &buffer);
printf("Resulting array: ");
printArray(array, size);
printf("Select an index to remove a value: ");
scanf(" %d", &index);
printf("Value removed: %d\nResulting array:", pop(&array, index, &size));
printArray(array, size);
size = removeZeroes(array, size);
printf("With all null elements removed, the resulting array is:\n");
printArray(array, size);
return 0;
}

View File

@ -0,0 +1,38 @@
#include <stdio.h>
int countZeroes(long number, int currentCount) {
if (number == 0)
return currentCount;
return countZeroes(number / 10, currentCount) + ((number % 10) ? 0 : 1);
}
void printMostZeroes(long max, int maxCount) {
long current;
int currentCount = 0;
if (!scanf(" %ld", &current)) {
if (!maxCount)
printf("There are no numbers containing zeroes in the sequence "
"provided.\n");
else
printf(
"The number with the longest sequence of zeroes is %ld, with "
"%d zeroes in total.\n",
max, maxCount);
return;
}
currentCount = (!current) ? 1 : countZeroes(current, currentCount);
if (currentCount > maxCount)
printMostZeroes(current, currentCount);
else
printMostZeroes(max, maxCount);
}
int main() {
printf("This program counts the number of following zeroes in an array of "
"numbers and yields a number with the greatest number of them. "
"Type in a series of numbers ended with '.' and press ENTER:\n");
printMostZeroes(0, 0);
return 0;
}

View File

@ -0,0 +1,62 @@
#include <stdio.h>
#include <stdlib.h>
char *resizeString(char *string, int *size) {
*size *= 2;
return realloc(string, *size * sizeof(char));
}
char *readInput(int *size) {
char c, *string = malloc(sizeof(char));
int i;
*size = 1;
for (i = 0; (c = getchar()) != '\n' || c == EOF; string[i++] = c)
if (i == *size - 1)
string = resizeString(string, size);
string[i++] = '\0';
*size = i;
return string;
}
int recursiveDeleteCharacter(char *string, char c, int size) {
int pivot;
if (size == 0)
return 0;
pivot = recursiveDeleteCharacter(string, c, --size);
if (string[size] != c)
string[pivot++] = string[size];
return pivot;
}
int deleteCharacters(char *string, int size, char *chars) {
int i;
for (i = 0; chars[i] != '\0'; i++)
size = recursiveDeleteCharacter(string, chars[i], size);
return size;
}
void deleteCharacter(char *string, char c) {
int i, j;
for (i = j = 0; string[j] != '\0'; j++)
if (string[j] != c)
string[i++] = string[j];
string[i] = string[j];
}
int main() {
char *string;
int stringSize, charQuantity;
printf("This program deletes given characters from a given string. Type "
"in a string and press ENTER:\n");
string = readInput(&stringSize);
printf("Type in characters to be deleted: ");
stringSize = deleteCharacters(string, stringSize, readInput(&charQuantity));
printf("This is the resulting string:\n%s\n", string);
return 0;
}

View File

@ -0,0 +1,130 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *next;
} Node;
typedef struct {
Node *start;
} List;
Node *newNode(int value, Node *next) {
Node *n = malloc(sizeof(Node));
n->value = value;
n->next = next;
return n;
}
Node *freeNode(Node *n) {
Node *next = n->next;
free(n);
return next;
}
void freeAllNodes(Node *n) {
if (!n)
return;
freeAllNodes(n->next);
free(n);
}
List *newList() {
List *l = malloc(sizeof(List));
l->start = NULL;
return l;
}
void freeList(List *l) {
freeAllNodes(l->start);
free(l);
}
bool push(Node *n, int value) {
if (n->value == value)
return false;
if (!n->next || n->next->value > value) {
n->next = newNode(value, n->next);
return true;
}
return push(n->next, value);
}
Node *pull(Node *n, int value, bool *found) {
if (n) {
if (n->value == value) {
*found = true;
return freeNode(n);
}
if (n->value < value)
n->next = pull(n->next, value, found);
}
return n;
}
bool insert(List *l, int value) {
if (!l)
return false;
if (!l->start || l->start->value > value) {
l->start = newNode(value, l->start);
return true;
}
return push(l->start, value);
}
bool take(List *l, int value) {
bool found = false;
if (l)
l->start = pull(l->start, value, &found);
return found;
}
void printNodes(Node *n) {
if (!n)
printf("\n");
else {
printf("%d ", n->value);
printNodes(n->next);
}
}
void printList(List *l) {
printf("List contents: ");
printNodes(l->start);
}
void readCommands() {
char option;
int value;
List *l = newList();
while (scanf(" %[ir]", &option)) {
if (option == 'i') {
while (scanf(" %d", &value))
if (!insert(l, value))
printf(
"Value %d already present in the list, ignoring...\n",
value);
} else
while (scanf(" %d", &value))
if (!take(l, value))
printf("Value %d not present in the list, ignoring...\n",
value);
printList(l);
}
printf("Terminating execution...\n");
freeList(l);
}
int main() {
printf("This program stores unique integer values in an ordered linked "
"list. Let n be an integer or a set of integers separated by "
"spaces, type i n to insert it in the list, r n to remove it from "
"it, or type in any other character to stop the execution of the "
"program. Don't forget to press ENTER after passing a command.\n");
readCommands();
}

View File

@ -0,0 +1,46 @@
#include <stdio.h>
#include <stdlib.h>
#define LENGTH 10
int *readNumbers(int size) {
int i = 0, value, *v = calloc(size, sizeof(int));
while (i < size && scanf(" %d", &value)) {
if (value > 9 || value < 0) {
printf("Value %d out of range: ignoring...\n", value);
continue;
}
v[i++] = value;
}
return v;
}
void printNumbers(int *v, int size) {
int i;
printf("Array contents: ");
for (i = 0; i < size; i++)
printf("%d ", v[i]);
printf("\n");
}
int *permutate(int *v, int size) {
int i, *w = calloc(size, sizeof(int));
for (i = 0; i < size; i++)
w[v[i]] = i;
return w;
}
int main() {
int *v;
printf("This program takes integers from 0 through 9 and stores it in an "
"array v of length 10. Later, it swaps the number positions in such "
"a way that for each v[i] = j there will be a v[j] = i after the "
"numbers are swapped. Positions left unspecified will be set to "
"0.\nType in a sequence of 10 numbers:\n");
printNumbers(v = readNumbers(LENGTH), LENGTH);
printf("Permutation.\n");
printNumbers(permutate(v, LENGTH), LENGTH);
return 0;
}

View File

@ -0,0 +1,82 @@
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
void swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
int partition(int *array, int pivot, int size) {
int i, j;
swap(array + pivot, array + --size);
for (i = j = 0; i < size; i++)
if (array[i] <= array[size])
swap(array + i, array + j++);
swap(array + i, array + j);
return j;
}
int quickSelect(int *array, int size, int i) {
int pivot;
if (size <= 1)
return *array;
pivot = partition(array, i, size);
if (pivot == i)
return array[i];
if (i < pivot)
return quickSelect(array, size, i);
pivot++;
return quickSelect(array + pivot, size - pivot, i - pivot);
}
int *createArray(int size) {
int i, *array = malloc(size * sizeof(int));
for (i = 0; i < size; i++)
array[i] = rand();
return array;
}
int max(int *array, int size) {
int m;
if (!size)
return INT_MIN;
m = max(array + 1, size - 1);
return (m > *array) ? m : *array;
}
void printArray(int *array, int size) {
int i;
printf("Array's contents: ");
for (i = 0; i < size; i++)
printf(" %d", array[i]);
printf("\n");
}
int main() {
int *array, size;
printf("This program evaluates the correctness of a function to get the "
"maximum value in an array by using another function that is much "
"more complex and prone to error in its implementation (albeit it "
"executes much faster): the quick select. Let's see how that "
"goes.\n\nFirst we generate an array containing randomly generated "
"values. Choose a size for that array: ");
scanf(" %d", &size);
if (size < 0) {
printf("Invalid size.\n");
return 1;
}
array = createArray(size);
printArray(array, size);
printf("The maximum function indicates the maximum value is: %d\n",
max(array, size));
printf("While the quick select says it is: %d\n",
quickSelect(array, size, size - 1));
return 0;
}

View File

@ -0,0 +1,12 @@
#include <stdio.h>
#include <stdlib.h>
int mdc(int a, int b) {
int r = a % b;
return r ? mdc(b, r) : b;
}
int main(int argc, char *argv[]) {
printf("%d\n", mdc(atoi(argv[1]), atoi(argv[2])));
return 0;
}

View File

@ -0,0 +1,27 @@
#include <stdio.h>
void printNext(int a, int b, int n) {
if (n <= 0)
return;
printf("%d ", b);
printNext(b, a + b, n - 1);
}
void fibonacci(int n) {
printf("Sequência Fibonacci até o %dº elemento: 0 ", n);
printNext(0, 1, n - 1);
printf("\n");
}
int main() {
int n;
printf("Este programa calcula os valores até o enésimo número na sequência "
"Fibonacci.\nDigite um valor inteiro n tal que n < 47: ");
if (!scanf(" %d", &n) || n < 0 || n > 47) {
printf("Valor inválido.\n");
return 1;
}
fibonacci(n);
return 0;
}

View File

@ -0,0 +1,264 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *next;
} List;
List *newList(int value, List *next) {
List *l = malloc(sizeof(List));
l->value = value;
l->next = next;
return l;
}
void freeList(List *l) {
if (!l)
return;
freeList(l->next);
free(l);
}
List *freeNode(List *l) {
List *next = l->next;
free(l);
return next;
}
bool listCmp(List *l1, List *l2) {
if (l1 == l2)
return true;
if (!(l1 && l2) || !listCmp(l1->next, l2->next))
return false;
return (l1->value == l2->value);
}
List *listCopy(List *l) { return l ? newList(l->value, listCopy(l->next)) : l; }
List *invert(List *current) {
List *prev = NULL, *next;
while (current) {
next = current->next;
current->next = prev;
prev = current;
current = next;
}
return prev;
}
List *swap(List *prev, List *current) {
List *HEAD;
if (!current)
return prev;
HEAD = swap(current, current->next);
current->next = prev;
return HEAD;
}
List *recInvert(List *l) { return swap(NULL, l); }
List *recListCat(List *l1, List *l2) {
if (!l1)
return l2;
l1->next = recListCat(l1->next, l2);
return l1;
}
void listCat(List *l1, List *l2) {
if (!l1)
l1 = l2;
else {
while (l1->next)
l1 = l1->next;
l1->next = l2;
}
}
bool isCrescent(List *l) {
if (!l->next)
return true;
return (l->value <= l->next->value) ? isCrescent(l->next) : false;
}
List *minimum(List *l) {
List *min;
if (!l->next)
return l;
min = minimum(l->next);
return (l->value <= min->value) ? l : min;
}
List *middle(List *l) {
List *slow, *fast;
slow = fast = l;
while (fast) {
fast = fast->next;
if (!fast)
break;
fast = fast->next;
slow = slow->next;
}
return slow;
}
List *push(List *l, int value) {
if (!l)
l = newList(value, l);
else
l->next = push(l->next, value);
return l;
}
List *pull(List *l, int value) {
if (l) {
if (l->value == value)
return freeNode(l);
l->next = pull(l->next, value);
}
return l;
}
List *pullAll(List *l, int value) {
if (l) {
if (l->value == value)
return pullAll(freeNode(l), value);
l->next = pullAll(l->next, value);
}
return l;
}
void flushInput() {
int c;
if ((c = getchar()) != '\n' && c != EOF)
flushInput();
}
List *readList() {
int value;
char c;
if (scanf("%d%c", &value, &c))
return newList(value, (c == '\n') ? NULL : readList());
flushInput();
return NULL;
}
List *insertAfter(List *l, int value, int n) {
List *prev;
if (!l || n <= 0)
return newList(value, l);
for (prev = l; prev->next && n > 0; n--)
prev = prev->next;
prev->next = newList(value, prev->next);
return l;
}
List *recInsertAfter(List *l, int value, int n) {
if (!l || n <= 0)
return newList(value, l);
l->next = insertAfter(l->next, value, n - 1);
return l;
}
List *exchange(List *prev, List *next) {
List *tmp = prev->next;
prev->next = next->next->next;
next->next->next = tmp;
tmp = next->next;
next->next = prev;
return tmp;
}
List *findPair(List *prev, List *next, int offset) {
if (offset > 1)
return findPair(prev, next->next, offset - 1);
return (offset == 1) ? exchange(prev, next) : prev;
}
List *moveByIndex(List *l, int index, int offset) {
if (l) {
if (index < 1)
return findPair(l, l, offset);
l->next = moveByIndex(l->next, index - 1, offset);
}
return l;
}
void printList(List *l) {
if (!l)
printf("\n");
else {
printf("%d ", l->value);
printList(l->next);
}
}
void listInfo(List *l) {
printf("List's contents: ");
printList(l);
printf("Is crescent: %s; Minimum value: %d; Middle value: %d.\n",
isCrescent(l) ? "Yes" : "No", minimum(l)->value, middle(l)->value);
}
int main() {
List *l1, *l2, *l3;
l1 = l2 = NULL;
int i1, i2;
printf("This program reads a couple of linked lists and compares them. For "
"the first linked list, type in a sequence of numbers to store and "
"press ENTER:\n");
listInfo(l1 = readList());
printf("Now for the contents of the second list:\n");
listInfo(l2 = readList());
printf("Is list 1 equal to list 1: %s; is list 1 equal to list 2: %s\n",
listCmp(l1, l1) ? "Yes" : "No", listCmp(l1, l2) ? "Yes" : "No");
printf("This list is a copy of the first list:");
printList(l3 = listCopy(l1));
printf(
"As it can be seen in their different addresses: l1 -> %p; l3 -> %p\n",
l1, l3);
printf("This is a concatenation of lists 1 and 2:");
listCat(l1, l2);
printList(l1);
l1 = recInvert(l1);
printf("This the list inverted by a recursive function: ");
printList(l1);
printf("And inverted again by a iteractive function: ");
printList(l1 = invert(l1));
printf("Type a value to be inserted to that array and an index in which to "
"put it: ");
scanf(" %d %d", &i1, &i2);
flushInput();
l1 = recInsertAfter(l1, i1, i2);
printf("Resulting linked list: ");
printList(l1);
printf("Again, to test the iteractive version: ");
scanf(" %d %d", &i1, &i2);
flushInput();
l1 = insertAfter(l1, i1, i2);
printf("Resulting linked list: ");
printList(l1);
printf("Now a function to change the position of two values based on their "
"indexes. Choose to indexes to have their values swapped: ");
scanf(" %d %d", &i1, &i2);
l1 = moveByIndex(l1, i1, i2);
printList(l1);
printf("Test removing the first occurence of a value: ");
scanf(" %d", &i1);
l1 = pull(l1, i1);
printList(l1);
printf("Now test removing all occurences: ");
scanf(" %d", &i1);
l1 = pullAll(l1, i1);
printList(l1);
return 0;
}

View File

@ -0,0 +1,69 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node {
char *string;
int length, count;
struct node *next;
} List;
List *addWord(char *string, List *next) {
List *l = malloc(sizeof(List));
l->length = strlen(string);
l->string = malloc((l->length + 1) * sizeof(char));
strcpy(l->string, string);
l->count = 1;
l->next = next;
return l;
}
void freeList(List *l) {
if (!l)
return;
freeList(l->next);
free(l->string);
free(l);
}
List *push(List *l, char *string) {
int order;
if (!l || (order = strcmp(string, l->string)) < 0)
return addWord(string, l);
if (order > 0)
l->next = push(l->next, string);
else
l->count++;
return l;
}
void printList(List *l) {
if (l) {
if (l->length > 35)
printf("%-36.36s... %d\n", l->string, l->count);
else
printf("%-40.40s%d\n", l->string, l->count);
printList(l->next);
}
}
List *readFile(FILE *f, List *l) {
char string[64];
while (fscanf(f, " %s", string) != EOF)
l = push(l, string);
return l;
}
int main(int argc, char *argv[]) {
List *l = NULL;
FILE *f = fopen(argv[1], "r");
if (!f)
return 1;
l = readFile(f, l);
fclose(f);
printList(l);
freeList(l);
return 0;
}

View File

@ -0,0 +1,122 @@
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *next;
} List;
List *newList(int value, List *next) {
List *l = malloc(sizeof(List));
l->value = value;
l->next = next;
return l;
}
void freeList(List *l) {
if (!l)
return;
freeList(l->next);
free(l);
}
List *freeNode(List *l) {
List *next = l->next;
free(l);
return next;
}
List *push(List *l, int value) {
if (!l || l->value > value)
return newList(value, l);
if (l->value < value)
l->next = push(l->next, value);
return l;
}
List *pull(List *l, int value) {
if (l && l->value <= value) {
if (l->value == value)
return freeNode(l);
l->next = pull(l->next, value);
}
return l;
}
List *concatenate(List *l1, List *l2) {
if (!l1)
return l2;
if (!l2)
return l1;
if (l1->value <= l2->value) {
l1->next = concatenate(l1->next, l2);
return l1;
}
l2->next = concatenate(l1, l2->next);
return l2;
}
int length(List *l) { return l ? length(l->next) + 1 : 0; }
void printList(List *l) {
if (!l)
printf("\n");
else {
printf("%d ", l->value);
printList(l->next);
}
}
void flushInput() {
int c;
if ((c = getchar()) != '\n' && c != EOF)
flushInput();
}
List *readList() {
int value;
char c;
List *l = NULL;
while (scanf(" %d%c", &value, &c)) {
l = push(l, value);
if (c == '\n')
break;
}
return l;
}
void readCommands() {
char option, c;
int value;
List *l = NULL;
while (scanf(" %[irc\n]", &option)) {
if (option == '\n')
break;
if (option == 'i')
l = readList();
else if (option == 'r')
while (scanf("%d%c", &value, &c) && c != '\n')
l = pull(l, value);
else
l = concatenate(l, readList());
printf("Resulting list: ");
printList(l);
printf("List length: %d\n", length(l));
}
printf("Terminating execution...\n");
freeList(l);
}
int main() {
printf(
"This program stores unique integer values in an ordered linked "
"list. Let n be an integer or a set of integers separated by "
"spaces:\nType i n to insert it in the list;\nType r n to remove it "
"from it;\nType c to concatenate it with another set of following "
"integers;\n, or type in any other character to stop the execution of "
"the program. Don't forget to press ENTER after passing a command.\n");
readCommands();
}

View File

@ -0,0 +1,59 @@
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int i;
struct node *next;
} List;
List *newList(int i, List *next) {
List *l = malloc(sizeof(List));
l->i = i;
l->next = next;
return l;
}
List *insert(int total, int left, List **end) {
if (left > 0)
return newList(total - left, insert(total, left - 1, end));
return (*end = newList(total - left, NULL));
}
List *createCircle(int n) {
List *start, *end;
start = insert(n, n - 1, &end);
end->next = start;
return start;
}
List *pull(List *l) {
List *next = l->next;
free(l);
return next;
}
List *josephus(List *l, int interval) {
int skip = interval;
while (l != l->next) {
while (skip-- > 0)
l = l->next;
l->next = pull(l->next);
skip = interval;
}
return l;
}
List *push(List *l, int value) {
if (!l)
l = newList(value, l);
else
l->next = push(l->next, value);
return l;
}
int main(int argc, char *argv[]) {
printf("%d\n", josephus(createCircle(atoi(argv[1])), atoi(argv[2]))->i);
return 0;
}

View File

@ -0,0 +1,214 @@
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define NORTH 0
#define EAST 1
#define SOUTH 2
#define WEST 3
#define SIDES 4
typedef struct tile {
int x, y, g, f;
struct tile *prev;
char c;
} Tile;
typedef struct queue {
Tile *t;
struct queue *next;
} Queue;
typedef struct {
int height, width;
Tile ***tiles, *start, *end;
} Map;
Tile *newTile(int x, int y, int g, char c) {
Tile *t = malloc(sizeof(Tile));
t->x = x;
t->y = y;
t->g = g;
t->c = c;
return t;
}
Queue *newQueue(Tile *t, Queue *next) {
Queue *q = malloc(sizeof(Queue));
q->t = t;
q->next = next;
return q;
}
Queue *freeNode(Queue *q) {
Queue *next = q->next;
free(q);
return next;
}
void freeQueue(Queue *q) {
if (!q)
return;
freeQueue(q->next);
free(q);
}
Tile **readTiles(FILE *f, Map *m, int row) {
int i;
char c;
Tile **tiles = malloc((m->width + 2) * sizeof(Tile *));
tiles[0] = NULL;
tiles++;
for (i = 0; i < m->width; i++) {
if ((c = getc(f)) == '#')
tiles[i] = NULL;
else if (c == 's') {
m->start = tiles[i] = newTile(i, row, 0, c);
tiles[i]->prev = NULL;
} else {
tiles[i] = newTile(i, row, INT_MAX, c);
if (c == 'e')
m->end = tiles[i];
}
}
getc(f);
tiles[i] = NULL;
return tiles;
}
Tile ***readRows(FILE *f, Map *m) {
int i;
Tile ***rows = malloc((m->height + 2) * sizeof(Tile **));
rows[0] = calloc(m->width + 2, sizeof(Tile *));
rows++;
for (i = 0; i < m->height; i++)
rows[i] = readTiles(f, m, i);
rows[i] = calloc(m->width + 2, sizeof(Tile *));
return rows;
}
Map *newMap(FILE *f) {
Map *m = malloc(sizeof(Map));
fscanf(f, "%d %d\n", &(m->width), &(m->height));
m->tiles = readRows(f, m);
return m;
}
Queue *push(Queue *q, Tile *t) {
if (!q)
return newQueue(t, NULL);
if (q->t != t) {
if (q->t->f > t->f)
return newQueue(t, q);
q->next = push(q->next, t);
}
return q;
}
Tile *pop(Queue **q) {
Tile *t;
if (!(*q))
return NULL;
t = (*q)->t;
*q = freeNode(*q);
return t;
}
Tile **listNeighbors(Map *m, Tile *t) {
Tile **neighbors = malloc(SIDES * sizeof(Tile *));
neighbors[NORTH] = m->tiles[t->y - 1][t->x];
neighbors[EAST] = m->tiles[t->y][t->x + 1];
neighbors[SOUTH] = m->tiles[t->y + 1][t->x];
neighbors[WEST] = m->tiles[t->y][t->x - 1];
return neighbors;
}
int manhattan(Tile *start, Tile *end) {
return abs(start->x - end->x) + abs(start->y + end->y);
}
Tile *Astar(Map *m) {
int i, distance;
Queue *openSet = newQueue(m->start, NULL);
Tile *t, **neighbors;
while ((t = pop(&openSet)) && t != m->end) {
neighbors = listNeighbors(m, t);
for (i = 0; i < SIDES; i++) {
if (!neighbors[i])
continue;
distance = t->g + 1;
if (distance >= neighbors[i]->g)
continue;
neighbors[i]->prev = t;
neighbors[i]->g = distance;
neighbors[i]->f = distance + manhattan(neighbors[i], m->end);
openSet = push(openSet, neighbors[i]);
}
free(neighbors);
}
freeQueue(openSet);
return t;
}
void printMap(Map *m) {
int i, j;
Tile *t;
for (i = 0; i < m->height; i++) {
for (j = 0; j < m->width; j++) {
t = m->tiles[i][j];
if (t)
printf("%c", t->c);
else
printf("#");
}
printf("\n");
}
printf("\n");
}
int path(Tile *end, int count) {
if (!end->prev)
printf("Start");
else {
count = path(end->prev, count + 1);
end->c = 'O';
if (end->prev->y > end->y)
printf(" -> North");
else if (end->prev->y < end->y)
printf(" -> South");
else if (end->prev->x < end->x)
printf(" -> East");
else
printf(" -> West");
}
return count;
}
int main(int argc, char *argv[]) {
int length = 0;
FILE *f = fopen(argv[1], "r");
Map *m = newMap(f);
fclose(f);
if (!Astar(m)) {
printf("There's no viable path from start to goal.\n");
return 1;
}
printf("From start to goal, there's the path: ");
length = path(m->end, length);
printf("\n");
m->end->c = 'e';
printf("\nHere its representation:\n");
printMap(m);
return 0;
}

View File

@ -0,0 +1,62 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *next;
} Node;
typedef struct {
Node *start, *end;
} List;
List *createList() {
List *l = malloc(sizeof(List));
l->start = l->end = NULL;
return l;
}
bool isEmpty(List *l) { return !l->start; }
Node *createNode(int value) {
Node *n = malloc(sizeof(Node));
n->value = value;
n->next = NULL;
return n;
}
Node *freeNode(Node *n) {
Node *next = n->next;
free(n);
return next;
}
void freeList(List *l) {
Node *n = l->start;
while (n)
n = freeNode(n);
free(l);
}
void insert(List *l, int value) {
Node *new = createNode(value);
if (l->end)
l->end->next = new;
if (!l->start)
l->start = new;
l->end = new;
}
int pull(List *l) {
int value;
if (!l->start)
return EOF;
value = l->start->value;
if (!(l->start = freeNode(l->start)))
l->end = l->start;
return value;
}

View File

@ -0,0 +1,32 @@
#include "./circArray.h"
bool isFull(circQueue *q) { return (q->head == (q->tail + 1) % q->size); }
bool isEmpty(circQueue *q) { return (q->head == q->tail); }
bool insert(circQueue *q, int i) {
if (isFull(q))
return false;
q->array[q->tail] = i;
q->tail = (q->tail + 1) % q->size;
return false;
}
circQueue *newQueue(int size) {
circQueue *q = malloc(sizeof(circQueue));
q->array = malloc(size * sizeof(int));
q->size = size;
q->head = q->tail = 0;
return q;
}
int pop(circQueue *q) {
int i;
if (isEmpty(q))
return EOF;
i = q->array[q->head];
q->head = (q->head + 1) % q->size;
return i;
}

View File

@ -0,0 +1,58 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *prev, *next;
} List;
List *newNode(int value) {
List *l = malloc(sizeof(List));
l->value = value;
return l;
}
List *freeNode(List *l) {
List *next = l->next;
if (l->next == l)
next = NULL;
else {
next->prev = l->prev;
l->prev->next = next;
}
free(l);
return next;
}
List *newList(int value) {
List *l = newNode(value);
l->prev = l->next = l;
return l;
}
void push(List *l, int value) {
List *prev = l->prev, *new = newNode(value);
prev->next = new;
new->prev = prev;
new->next = l;
l->prev = new;
}
int pull(List **l) {
int value;
if (!l)
return EOF;
value = (*l)->prev->value;
*l = freeNode((*l)->prev);
return value;
}
bool isEmpty(List *l) { return !l; }
void freeList(List **l) {
while (*l)
*l = freeNode(*l);
}

View File

@ -0,0 +1,55 @@
#include "./circList.h"
// Implementation of a Circular Queue with no head node;
CircQueue *newQueue(int value) {
CircQueue *c = malloc(sizeof(CircQueue));
c->value = value;
c->next = c;
return c;
}
CircQueue *push(CircQueue *c, int value) {
CircQueue *new = newQueue(value);
if (c) {
new->next = c->next;
c->next = new;
}
return new;
}
bool isEmpty(CircQueue *c) { return c; }
int pull(CircQueue **c) {
CircQueue *old;
int value;
if (!*c)
return EOF;
old = (*c)->next;
value = old->value;
if (*c == old)
*c = NULL;
else
(*c)->next = old->next;
free(old);
return value;
}
void freeCircQueue(CircQueue **c) {
if (!*c)
return;
freeQueue(*c, *c);
*c = NULL;
}
void freeQueue(CircQueue *start, CircQueue *current) {
CircQueue *next = current->next;
free(current);
if (next != start)
freeQueue(start, next);
}

View File

@ -0,0 +1,50 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *next;
} CircList;
CircList *newList() {
CircList *c = malloc(sizeof(CircList));
c->next = c;
return c;
}
CircList *freeNode(CircList *c) {
CircList *next = c->next;
free(c);
return next;
}
void freeList(CircList **c) {
CircList *current = *c;
while ((current = freeNode(current)) != *c) {
}
*c = NULL;
}
bool isEmpty(CircList *c) { return c->next == c; }
CircList *push(CircList *c, int value) {
CircList *new = malloc(sizeof(CircList)), *next;
c->value = value;
next = c->next;
c->next = new;
new->next = next;
return new;
}
int pull(CircList *c) {
int value;
if (isEmpty(c))
return EOF;
value = c->next->value;
c->next = freeNode(c->next);
return value;
}

View File

@ -0,0 +1,24 @@
#include "./dynamicArray.h"
bool isEmpty(array *a) { return a->end == a->start; }
array *resize(array *a) {
a->capacity *= 2;
a->end -= a->start;
a->start = 0;
return realloc(a, a->capacity * sizeof(array));
}
void insert(array *a, int i) {
a->end++;
if (a->end == a->capacity)
a = resize(a);
a->values[a->end] = i;
}
int pop(array *a) { return isEmpty(a) ? EOF : a->values[a->start++]; }
void freeArray(array *a) {
free(a->values);
free(a);
}

View File

@ -0,0 +1,105 @@
#include "./queueArray.h"
#include <stdio.h>
Queue *newQueue(int capacity) {
Queue *q = malloc(sizeof(Queue));
q->array = malloc(capacity * sizeof(int));
q->start = 0;
q->end = -1;
q->capacity = capacity;
return q;
}
void freeQueue(Queue *q) {
free(q->array);
free(q);
}
Queue *resize(Queue *q) {
q->capacity *= 2;
return realloc(q, q->capacity * sizeof(Queue));
}
int length(Queue *q) { return q->end - q->start + 1; }
bool isFull(Queue *q) { return length(q) == q->capacity; }
bool isEmpty(Queue *q) { return !length(q); }
void shift(Queue *q) {
int i, offset;
for (i = offset = q->start; i <= q->end; i++)
q->array[i - offset] = q->array[i];
q->start = 0;
q->end -= offset;
}
bool insert(Queue *q, int value) {
if (isFull(q))
return false;
if (q->end == q->capacity - 1)
shift(q);
q->array[++q->end] = value;
return true;
}
int dequeue(Queue *q) {
int i = q->array[q->start++];
q->start %= q->capacity;
return i;
}
int minimum(int a, int b) { return (b > a) ? a : b; }
bool blocked(char **map, int height, int width, int x, int y) {
return (x < 0 || x >= width || y < 0 || y >= height || map[x][y] == '#');
}
int distance(int size, int dist[][size], int a, int b) {
int i, min;
if (dist[a][b] > 0)
return dist[a][b];
min = size;
for (i = 0; i < size; i++)
if (dist[a][i] > 0)
min = minimum(min, dist[a][i] + distance(size, dist, i, b));
return min;
}
int *distanceFrom(int size, int dist[][size], int to) {
int from, *distFrom = malloc(size * sizeof(int));
Queue *points = newQueue(size);
for (from = 0; from < size; from++)
distFrom[from] = size;
distFrom[to] = 0;
insert(points, to);
while (!isEmpty(points)) {
from = dequeue(points);
for (to = 0; to < size; to++) {
if (dist[from][to] != 1 || distFrom[to] < size)
continue;
distFrom[to] = distFrom[from] + 1;
insert(points, to);
}
}
return distFrom;
}
int main() {
int i, dist[6][6] = {{0, 1, 0, 0, 0, 0}, {0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 1, 0}, {0, 0, 1, 0, 1, 0},
{1, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0}};
int *distFrom = distanceFrom(6, dist, 3);
for (i = 0; i < 6; i++)
printf("%d ", distFrom[i]);
printf("\n");
printf("%d\n", distance(6, dist, 3, 0));
return 0;
}

View File

@ -0,0 +1,60 @@
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
typedef struct node {
char c;
struct node *prev;
} Stack;
Stack *push(Stack *prev, char c) {
Stack *new = malloc(sizeof(Stack));
new->c = c;
new->prev = prev;
return new;
}
Stack *freeNode(Stack *s) {
Stack *prev = s->prev;
free(s);
return prev;
}
void freeStack(Stack *s) {
Stack *prev;
if (!s)
return;
prev = s->prev;
free(s);
freeStack(prev);
}
char pop(Stack **s) {
char c;
if (!*s)
return '\0' c = (*s)->c;
*s = freeNode(*s);
return c;
}
char *infix2postfix(char *infix) {
int n = strlen(infix);
char *postfix = malloc((n + 1) * sizeof(char)), x;
Stack *s = NULL;
push(s, infix[0]);
int j = 0;
for (int i = 1; infix[i] != '\0'; i++) {
switch (infix[i]) {
case '(':
push('(');
break;
case ')':
x = pop(&s);
while (x != '(')
}
}
}

View File

@ -0,0 +1,19 @@
#include <stdio.h>
void invertWord(char *c) {
if (!*c)
return;
invertWord(c + 1);
printf("%c", *c);
}
int main(int argc, char *argv[]) {
int i;
for (i = 1; i < argc; i++) {
invertWord(argv[i]);
printf(" ");
}
printf("\n");
return 0;
}

View File

@ -0,0 +1,8 @@
// The following functions takes a stack of characters as an argument and
// removes from it all trailing 'A's before inserting a 'B' into it.
void Sledgewick(Stack *s) {
while (!isEmpty(s) && peek(s) == 'A')
pull(s);
push(s, 'B');
}

View File

@ -0,0 +1,34 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *c;
int top, size;
} Stack;
Stack *newStack(int size) {
Stack *s = malloc(sizeof(Stack));
s->c = malloc(size * sizeof(char));
s->size = size;
s->top = 0;
return s;
}
bool isFull(Stack *s) { return s->top == s->size; }
bool isEmpty(Stack *s) { return !s->top; }
void resize(Stack *s) {
s->size *= 2;
s->c = realloc(s->c, s->size * sizeof(char));
}
void push(Stack *s, char c) {
if (isFull(s))
resize(s);
s->c[(s->top)++] = c;
}
char pop(Stack *s) { return (isEmpty(s)) ? '\0' : s->c[--(s->top)]; }

View File

@ -0,0 +1,60 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node {
char c;
struct node *prev;
} Stack;
Stack *push(Stack *prev, char c) {
Stack *new = malloc(sizeof(Stack));
new->c = c;
new->prev = prev;
return new;
}
Stack *freeNode(Stack *s) {
Stack *prev = s->prev;
free(s);
return prev;
}
void freeStack(Stack *s) {
Stack *prev;
if (!s)
return;
prev = s->prev;
free(s);
freeStack(prev);
}
bool close(Stack **s, char c) {
if (!*s || (c == '}' && (*s)->c != '{') || (c == ']' && (*s)->c != '[') ||
(c == ')' && (*s)->c != '('))
return false;
*s = freeNode(*s);
return true;
}
bool wellFormed(Stack *s, char *string) {
if (!*string)
return !s;
if (strchr("([{", *string))
s = push(s, *string);
else if (strchr("}])", *string) && !close(&s, *string))
return false;
return wellFormed(s, string + 1);
}
int main(int argc, char *argv[]) {
int i;
Stack *s = NULL;
for (i = 1; i < argc; i++)
if (!wellFormed(s, argv[i]))
return 1;
return 0;
}

View File

@ -0,0 +1,35 @@
#include <stdio.h>
#include <stdlib.h>
// Return an index x from an array a such that for a given value v the following
// condition is satisfied: a[x - 1] < v ≤ a[x]. As such, if we consider *(array
// + size) = ∞ (or INT_MAX for that matter) and *(array - 1) = -∞ (or INT_MIN)
// it is true for each interaction of this function that *array < value ≤
// *(array + size).
int binarySearch(int value, int *array, int size) {
int index;
if (size <= 0)
return 0;
index = size / 2;
if (array[index] >= value)
return binarySearch(value, array, index);
index++;
return index + binarySearch(value, array + index, size - index);
}
int *char2int(char *args[], int size) {
int i, *array = malloc(size * sizeof(int));
for (i = 0; i < size; i++)
array[i] = atoi(args[i + 2]);
return array;
}
int main(int argc, char *argv[]) {
int size = argc - 2;
printf("Index: %d\n",
binarySearch(atoi(argv[1]), char2int(argv, size), size));
return 0;
}

View File

@ -0,0 +1,33 @@
#include <malloc.h>
typedef struct {
int low, high;
} Interval;
Interval *newInterval(int low, int high) {
Interval *i = malloc(sizeof(Interval));
i->low = low;
i->high = high;
return i;
}
int binarySearch(int value, Interval **i, int size) {
int index;
if (size <= 0)
return 0;
index = size / 2;
if (i[index]->low >= value)
return binarySearch(value, i, index);
index++;
return index + binarySearch(value, i, size - index);
}
Interval *searchInterval(int value, Interval **i, int size) {
int index = binarySearch(value, i, size);
Interval *result = i[index];
if (index >= size || value <= result->low || value >= result->high)
return NULL;
return result;
}

View File

@ -0,0 +1,32 @@
#include <stdio.h>
#include <stdlib.h>
int indexIsValue(int *array, int size) {
int first = 0, pivot = size / 2;
while (first < size) {
if (array[pivot] == pivot)
return pivot;
if (array[pivot] < pivot)
first = pivot + 1;
else
size = pivot;
pivot = first + (size - first) / 2;
}
return -1;
}
int *char2int(char *args[], int size) {
int i, *array = malloc(size * sizeof(int));
for (i = 0; i < size; i++)
array[i] = atoi(args[i + 1]);
return array;
}
int main(int argc, char *argv[]) {
int size = argc - 1, *array = char2int(argv, size);
printf("%d\n", indexIsValue(array, size));
free(array);
return 0;
}

View File

@ -0,0 +1,14 @@
#include <stdlib.h>
#include <string.h>
int binarySearch(char *string, char **array, int size) {
int index;
if (size <= 0)
return 0;
index = size / 2;
if (strcmp(string, array[index]) <= 0)
return binarySearch(string, array, index);
index++;
return index + binarySearch(string, array + index, size - index);
}

View File

@ -0,0 +1,18 @@
#include <stdio.h>
#include <stdlib.h>
int power(int base, int exp) {
int sqrt;
if (exp == 0)
return 1;
if (exp == 1)
return base;
sqrt = power(base, exp / 2);
return sqrt * sqrt * (exp % 2 ? base : 1);
}
int main(int argc, char *argv[]) {
printf("%d\n", power(atoi(argv[1]), atoi(argv[2])));
return 0;
}

View File

@ -0,0 +1,21 @@
typedef struct {
int nUSP;
char *name;
} Student;
int binarySearch(int nUSP, Student **s, int size) {
int index;
if (size <= 0)
return 0;
index = size / 2;
if (s[index]->nUSP >= nUSP)
return binarySearch(nUSP, s, index);
index++;
return index + binarySearch(nUSP, s + index, size - index);
}
char *searchStudent(int nUSP, Student **s, int size) {
int i = binarySearch(nUSP, s, size);
return (i < size && s[i]->nUSP == nUSP) ? s[i]->name : "";
}

View File

@ -0,0 +1,45 @@
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
int binarySearch(int value, int *array, int size) {
int index;
if (size <= 0)
return 0;
index = size / 2;
if (array[index] >= value)
return binarySearch(value, array, index);
index++;
return index + binarySearch(value, array + index, size - index);
}
void twoSum(int sum, int *array, int size) {
int i, j;
int last = binarySearch(sum, array, size);
int mid = binarySearch(sum / 2, array, last);
if (last == size)
last--;
for (i = ++mid; i <= last; i++) {
j = binarySearch(sum - array[i], array, mid);
mid = j + 1;
if (array[j] + array[i] == sum)
printf("%d + %d = %d\n", array[j], array[i], sum);
}
}
int *char2int(char *args[], int size) {
int i, *array = malloc(size * sizeof(int));
for (i = 0; i < size; i++)
array[i] = atoi(args[i + 2]);
return array;
}
int main(int argc, char *argv[]) {
int size = argc - 2, *array = char2int(argv, size);
twoSum(atoi(argv[1]), array, size);
free(array);
return 0;
}

View File

@ -0,0 +1,52 @@
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
int binarySearch(int value, int *array, int size) {
int index;
if (size <= 0)
return 0;
index = size / 2;
if (array[index] >= value)
return binarySearch(value, array, index);
index++;
return index + binarySearch(value, array + index, size - index);
}
void twoSum(int sum, int *array, int size) {
int pivot, first, last = binarySearch(sum, array, size);
if (last == size)
last--;
pivot = first = 0;
while (first < last) {
if (array[first] + array[last] == sum)
printf("%d + %d = %d\n", array[first++], array[last--], sum);
else if (pivot == first) {
first +=
binarySearch(sum - array[last], array + first, last - first);
pivot = last;
} else {
last = first + binarySearch(sum - array[first], array + first,
last - first);
pivot = first;
}
}
}
int *char2int(char *args[], int size) {
int i, *array = malloc(size * sizeof(int));
for (i = 0; i < size; i++)
array[i] = atoi(args[i + 2]);
return array;
}
int main(int argc, char *argv[]) {
int size = argc - 2, *array = char2int(argv, size);
twoSum(atoi(argv[1]), array, size);
free(array);
return 0;
}

View File

@ -0,0 +1,108 @@
# Ordenação: algoritmos elementares
> Resolução dos exercícios propostos
## Exercícios 1
**1.** Vide arquivo `isSorted.c` nesta pasta.
**2.** O algoritmo proposto, descrito abaixo, é adequado a verificação da ordenação crescente.
```c
int verifica (int v[], int n) {
if (n > 1)
for (int i = 1; i < n; i++)
if (v[i-1] > v[i]) return 0;
return 1; }
```
- Caso base: um ou nenhum elemento. Um arranjo nestas condições está trivialmente ordenado em ordem crescente, não há necessidade que comparações de valores sejam feitas. O algoritmo verifica se este é o caso na linha 2 e, este sendo, pula as comparações e retorna verdadeiro (1) na linha 5.
- Para $n > 1$: A repetição descrita na linha 3 faz com que na linha três cada valor do arranjo do segundo ao último seja comparado ao seu antecessor imediato, interrompendo a verificação e retornando falso (0) assim que um antecessor de maior valor é encontrado. Doutra forma o algoritmo procede e retorna verdadeiro na linha 5.
**3.** O algoritmo proposto, descrito abaixo, é inadequado a verificação da ordenação crescente.
```
int verifica (int v[], int n) {
int sim;
for (int i = 1; i < n; i++)
if (v[i-1] <= v[i]) sim = 1;
else {
sim = 0;
break; }
return sim; }
```
No caso base $n >= 1$, o que faz com que a repetição com a verificação nunca ocorra. Ora, mas apenas pela verificação a variável `sim` é designada um valor (1) verdadeiro ou (0) falso. Assim, ao executar este algoritmo com um arranjo trivialmente ordenado o seu resultado é imprevisível: ele retornará qualquer valor que esteja armazenado na posição de memória alocada para armazenar o valor da variável `sim`.
**4.** Vide arquivo `Sorts.c` na pasta da disciplina de Análise de Algoritmos e Estruturas de Dados I.
**5.** Vide arquivo `isSorted.c` nesta pasta.
## Exercícios 2
**1.** Vide arquivo `sorts.c` na pasta da disciplina de Análise de Algoritmos e Estruturas de Dados I.
**2.** Continua, entretanto a função perderá sua propriedade de _estabilidade_, isso é, os valores iguais não aparecerão na mesma ordem quem que foram inseridos (estes figurarão em ordem reversa). Para ordenar valores inteiros isso não é de maior consequência senão por mais algumas comparações desnecessárias, mas quando estes valores são chaves para a ordenação de estruturas de dados, isso pode ser indesejável.
**3.**
**a)** Esta modificação não alterará o resultado, apenas adicionará uma repetição do loop descrito na linha 3 onde o valor em `v[j]` é copiado à `x` e em seguida sobrescrito à `v[j]`, pois nestas condições $i + 1 = j$.
**b)** Esta modificação comprometerá a funcionalidade do algoritmo. Fazendo com que o valor em `v[j]` seja armazenado uma posição antes do que deveria, possivelmente extrapolando o limite inferior do arranjo.
**4.** As consequências para a alteração
```diff
6,7c5
< v[i+1] = x;
< }
---
> v[i] = x; } }
\ No newline at end of file
>
```
São discutidas no item **b)** do exercício anterior.
**5.** Esta versão não alterará o resultado final do algoritmo, mas realizará um número maior de atribuições para alcançá-lo, o que prejudica seu desempenho.
**6.** Sim, a única diferença deste modelo com o algoritmo anteriormente descrito é o uso de um loop `while` em vez de um `for`. Assim, o invés de constar em uma única linha, temos que o contador é inicializado na linha 3, a condição de repetição na linha 4 e a incrementação do contador se dá na linha 6.
**7.** Vide o arquivo `backwards_insertion_sort.c`
**8.** Mas, isso pressupõe um vetor já ordenado. O resultado de se realizar esta operação terminaria por manter o vetor embaralhado.
**9.** O pior caso corresponde a qualquer instância em que os valores do vetor encontram-se ordenados em ordem decrescente. Assim, para um vetor de tamanho $n$ as comparações feitas ao final encontram-se em progressão aritmética:
$$1 + 2 + \dots + n - 1 = \dfrac{(n - 1)(n - 1 + 1)}2 = \dfrac{n^2 - n}2 \equiv O(n^2) $$
**10.** O melhor caso é aquele em que os valores já encontram-se em ordem crescente. Assimpara um vetor de tamanho $n$ cada valor desde o segundo ao último é comparado com seu antecessor uma única vez, um total de $n - 1 \equiv O(n)$ comparações realizadas .
**11.** No pior caso, todas as comparações levam à movimentação de dados, portanto, são $\frac{n^2 - n}2$ movimentações no total. No melhor caso, também. Neste os dados são copiados a uma variável temporária e em seguida sobrescritos sobre a posição donde advieram, totalizando $n - 1$ movimentações.
**12.** Vide o arquivo `backwards_insertion_sort.c`.
**13.**
**14.** Vide o arquivo `descrescent_insertion_sort.c`
## Exercícios 3
**1.** Vide arquivo `sorts.c` na pasta da disciplina de Análise de Algoritmos e Estruturas de Dados I.
**2.**
**a)** O primeiro elemento da lista não é ordenado.
**b)** Acrescenta-se uma repetição desnecessária, já que não à outro elemento com que comparar com o elemento final do vetor.
**3.** Sim, está correta, mas o algoritmo perde sua estabilidade. Elementos de mesmo valor são ordenados na ordem reversa daquela em que figuraram originalmente no vetor.
**4, 5 e 6.** Em ambos o melhor e o pior caso, o mesmo número de comparações são feitas, $\frac{n^2 - n}2$ o que diferencia estes dois casos é o número de movimentações feitas: respectivamente, $n - 1$ (os dados são copiados a uma variável temporária e em seguida sobrescritos sobre a posição donde advieram) e $\frac{n^2 - n}2$ (o último elemento vai para a primeira posição, o penúltimo a segunda, e assim por diante).
**7.** Vide o arquivo `descrescent_selection_sort.c`
## Exercícios 4
**1.** Vide o arquivo `string_insertion_sort.c`
**2.** Vide o arquivo `string_radix_sort.c`
**3 e 4.** Vide o arquivo `data_sort.c`

View File

@ -0,0 +1,53 @@
#include <stdlib.h>
#include <stdio.h>
#define array int*
array readArray (int *size) {
int d, i = 0;
char c;
array A;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf(" %d", &d))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
A[i++] = d;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
void swap (int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
void shuffle(array A, int size) {
if (--size < 1)
return;
swap(&A[rand() % size], &A[size]);
shuffle(A, size);
}
int main () {
array A;
int i, size;
printf("This program shuffles integer values according to the "
"Fisher-Yates algorithm.\nType in a sequence of values separated "
"by spaces and press ENTER:\n");
A = readArray(&size);
shuffle(A, size);
printf("\nNew sequence:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,227 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int count, size;
char **words;
} Array;
typedef struct node {
char *word;
struct node *next;
} Stack;
typedef struct {
Stack **words, *max;
int size, maxCount, *count, *order;
} Dict;
/* Initializers */
Array *newArray() {
Array *a = malloc(sizeof(Array));
a->words = malloc(sizeof(char *));
a->count = 0;
a->size = 1;
return a;
}
Stack *newStack(char *word, Stack *next) {
Stack *s = malloc(sizeof(Stack));
s->word = word;
s->next = next;
return s;
}
Dict *newDict(int size) {
Dict *d = malloc(sizeof(Dict));
d->words = calloc(size, sizeof(Stack *));
d->count = malloc(size * sizeof(int));
d->maxCount = 0;
d->size = size;
return d;
}
/* Freeing memory */
void freeArray(Array *a) {
int i;
for (i = 0; i < a->size; i++)
free(a->words[i]);
free(a->words);
free(a);
}
void freeStack(Stack *s) {
if (!s)
return;
freeStack(s->next);
free(s);
}
void freeDict(Dict *d) {
int i = 0;
while (i < d->size)
freeStack(d->words[i++]);
free(d->words);
free(d->count);
free(d);
}
/* Array insertion functions */
void insert(Array *a, char *buffer, int size) {
char *new = malloc((size + 1) * sizeof(char));
if (a->count == a->size - 1) {
a->size *= 2;
a->words = realloc(a->words, a->size * sizeof(char *));
}
a->words[a->count++] = strcpy(new, buffer);
}
Array *readWords(FILE *f) {
int size;
char *buffer = malloc(64 * sizeof(char));
Array *a = newArray();
while ((size = fscanf(f, " %s", buffer)) != EOF)
insert(a, buffer, size);
free(buffer);
return a;
}
/* Stack insertion algorithm */
void push(Stack *head, char *word) {
Stack *s = newStack(word, head->next);
head->next = s;
}
/* Sorting algorithm: quicksort */
void swap(char *a, char *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
char *median(char *a, char *b, char *c) {
if ((*a > *b) ^ (*a > *c))
return a;
if ((*b < *a) ^ (*b < *c))
return b;
return c;
}
int partition(char *word, int size) {
int i, j, last = size - 1;
swap(word + last, median(word, word + size / 2, word + last));
for (i = j = 0; i < last; i++)
if (word[i] <= word[last])
swap(word + i, word + j++);
swap(word + i, word + j);
return j;
}
void quickSort(char *word, int size) {
int pivot;
if (size <= 1)
return;
pivot = partition(word, size);
quickSort(word, pivot++);
quickSort(word + pivot, size - pivot);
}
/* Hash and rehash functions */
int key(char *word, int *i) {
int k;
for (*i = k = 0; word[*i]; (*i)++)
k += word[*i];
return k * (*i);
}
int bits(int n) {
n >>= 1;
return (n) ? 1 + bits(n) : 1;
}
int hash(int key, int mask, int b) {
int index = key & mask;
key >>= b;
return (key) ? index ^ hash(key, mask, b) : index;
}
int rehash(int index, int i, int mask) { return (index + i * i) & mask; }
/* Dictionary insertion algorithm */
void add(Dict *d, char *word, int mask, int b) {
int size, i, index = hash(key(word, &size), mask, b);
char *charSet = malloc((size + 1) * sizeof(char));
quickSort(strcpy(charSet, word), size);
for (i = 1; d->words[index] && strcmp(d->words[index]->word, charSet) != 0;
i += 2)
index = hash(index + i * i, mask, b);
if (!d->words[index]) {
d->count[index] = 0;
d->words[index] = newStack(charSet, NULL);
} else
free(charSet);
push(d->words[index], word);
d->count[index]++;
if (d->count[index] > d->maxCount) {
d->maxCount = d->count[index];
d->max = d->words[index];
}
}
Dict *buildDict(Array *a) {
int i, mask = a->size - 1, b = bits(mask);
Dict *d = newDict(a->size);
for (i = 0; i < a->count; i++)
add(d, a->words[i], mask, b);
return d;
}
/* Printing functions */
void printStack(Stack *s, char *terminator) {
if (!s)
return;
printStack(s->next, ", ");
printf("%s%s", s->word, terminator);
}
void printMax(Dict *d) {
printf(
"O conjunto de caracteres que possibilita o maior número de anagramas "
"na lingua portuguesa é \"%s\", que permite formar %d anagramas: ",
d->max->word, d->maxCount);
printStack(d->max->next, ".\n");
}
/* Main function */
int main(int argc, char *argv[]) {
FILE *f = fopen(argv[1], "r");
Array *a = readWords(f);
Dict *d = buildDict(a);
printMax(d);
fclose(f);
freeArray(a);
freeDict(d);
return 0;
}

View File

@ -0,0 +1,267 @@
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int count, size;
char **words;
} Array;
typedef struct node {
char *word;
struct node *next;
} Stack;
typedef struct {
Stack **words, *max;
int size, sets, maxCount, *count, *order;
} Dict;
/* Initializers */
Array *newArray() {
Array *a = malloc(sizeof(Array));
a->words = malloc(sizeof(char *));
a->count = 0;
a->size = 1;
return a;
}
Stack *newStack(char *word, Stack *next) {
Stack *s = malloc(sizeof(Stack));
s->word = word;
s->next = next;
return s;
}
Dict *newDict(int size) {
Dict *d = malloc(sizeof(Dict));
d->words = calloc(size, sizeof(Stack *));
d->count = malloc(size * sizeof(int));
d->order = malloc(size * sizeof(int));
d->maxCount = d->sets = 0;
d->size = size;
return d;
}
/* Freeing memory */
void freeArray(Array *a) {
int i;
for (i = 0; i < a->size; i++)
free(a->words[i]);
free(a->words);
free(a);
}
void freeStack(Stack *s) {
if (!s)
return;
freeStack(s->next);
free(s);
}
void freeDict(Dict *d) {
int i = 0;
while (i < d->size)
freeStack(d->words[i++]);
free(d->words);
free(d->count);
free(d);
}
/* Array insertion functions */
void insert(Array *a, char *buffer, int size) {
char *new = malloc((size + 1) * sizeof(char));
if (a->count == a->size - 1) {
a->size *= 2;
a->words = realloc(a->words, a->size * sizeof(char *));
}
a->words[a->count++] = strcpy(new, buffer);
}
Array *readWords(FILE *f) {
int size;
char *buffer = malloc(64 * sizeof(char));
Array *a = newArray();
while ((size = fscanf(f, " %s", buffer)) != EOF)
insert(a, buffer, size);
free(buffer);
return a;
}
/* Stack insertion algorithm */
void push(Stack *head, char *word) {
Stack *s = newStack(word, head->next);
head->next = s;
}
/* Sorting algorithms */
void swap(char *a, char *b) {
char tmp = *a;
*a = *b;
*b = tmp;
}
char *median(char *a, char *b, char *c) {
if ((*a > *b) ^ (*a > *c))
return a;
if ((*b < *a) ^ (*b < *c))
return b;
return c;
}
int partition(char *word, int size) {
int i, j, last = size - 1;
swap(word + last, median(word, word + size / 2, word + last));
for (i = j = 0; i < last; i++)
if (word[i] <= word[last])
swap(word + i, word + j++);
swap(word + i, word + j);
return j;
}
void quickSort(char *word, int size) {
int pivot;
if (size <= 1)
return;
pivot = partition(word, size);
quickSort(word, pivot++);
quickSort(word + pivot, size - pivot);
}
char *countingSort(char *word, int size, int mask) {
int i, j;
char *sorted = malloc(size * sizeof(char));
for (i = j = 0; i < size; i++)
if (!(word[i] & mask))
sorted[j++] = word[i];
for (i = 0; i < size; i++)
if (word[i] & mask)
sorted[j++] = word[i];
free(word);
return sorted;
}
char *radixSort(char *word, int size, int length) {
while (length >> 1)
word = countingSort(word, size, length);
return word;
}
/* Hash and rehash functions */
int key(char *word, int *i) {
int k;
for (*i = k = 0; word[*i]; (*i)++)
k += word[*i];
return k * (*i);
}
int bits(int n) {
n >>= 1;
return (n) ? 1 + bits(n) : 1;
}
int hash(int key, int mask, int b) {
int index = key & mask;
key >>= b;
return (key) ? index ^ hash(key, mask, b) : index;
}
int rehash(int index, int i, int mask) { return (index + i * i) & mask; }
/* Dictionary insertion algorithm */
void add(Dict *d, char *word, int mask, int b) {
int size, i, index = hash(key(word, &size), mask, b);
char *charSet = malloc((size + 1) * sizeof(char));
quickSort(strcpy(charSet, word), size);
// Alternative:
// char *charSet = radixSort(strcpy(malloc((size + 1) * sizeof(char)),
// word), size, CHAR_BIT * sizeof(char));
for (i = 1; d->words[index] && strcmp(d->words[index]->word, charSet) != 0;
i += 2)
index = hash(index + i * i, mask, b);
if (!d->words[index]) {
d->words[index] = newStack(charSet, NULL);
d->order[d->sets++] = index;
d->count[index] = 0;
} else
free(charSet);
push(d->words[index], word);
d->count[index]++;
if (d->count[index] > d->maxCount) {
d->maxCount = d->count[index];
d->max = d->words[index];
}
}
Dict *buildDict(Array *a) {
int i, mask = a->size - 1, b = bits(mask);
Dict *d = newDict(a->size);
for (i = 0; i < a->count; i++)
add(d, a->words[i], mask, b);
return d;
}
/* Printing functions */
void printStack(Stack *s, char *terminator) {
if (!s)
return;
printStack(s->next, ", ");
printf("%s%s", s->word, terminator);
}
void printMax(Dict *d) {
printf(
"O conjunto de caracteres que possibilita o maior número de anagramas "
"na lingua portuguesa é \"%s\", que permite formar %d anagramas: ",
d->max->word, d->maxCount);
printStack(d->max->next, ".\n");
}
void printSets(Dict *d) {
int i;
printf("\nOs conjuntos de anagramas com mais de um item são:\n");
for (i = 0; i < d->sets; i++) {
if (d->count[d->order[i]] < 2)
continue;
printf("Conjunto \"%s\", %d anagramas: ", d->words[d->order[i]]->word,
d->count[d->order[i]]);
printStack(d->words[d->order[i]]->next, ".\n");
}
}
/* Main function */
int main(int argc, char *argv[]) {
FILE *f = fopen(argv[1], "r");
Array *a = readWords(f);
Dict *d = buildDict(a);
printMax(d);
printSets(d);
fclose(f);
freeArray(a);
freeDict(d);
return 0;
}

View File

@ -0,0 +1,224 @@
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int count, size;
char **words;
} Array;
typedef struct node {
char *word;
struct node *next;
} Stack;
typedef struct {
Stack **words, *max;
int size, sets, maxCount, *count, *order;
} Dict;
/* Initializers */
Array *newArray() {
Array *a = malloc(sizeof(Array));
a->words = malloc(sizeof(char *));
a->count = 0;
a->size = 1;
return a;
}
Stack *newStack(char *word, Stack *next) {
Stack *s = malloc(sizeof(Stack));
s->word = word;
s->next = next;
return s;
}
Dict *newDict(int size) {
Dict *d = malloc(sizeof(Dict));
d->words = calloc(size, sizeof(Stack *));
d->count = malloc(size * sizeof(int));
d->order = malloc(size * sizeof(int));
d->maxCount = d->sets = 0;
d->size = size;
return d;
}
/* Freeing memory */
void freeArray(Array *a) {
int i;
for (i = 0; i < a->size; i++)
free(a->words[i]);
free(a->words);
free(a);
}
void freeStack(Stack *s) {
if (!s)
return;
freeStack(s->next);
free(s);
}
void freeDict(Dict *d) {
int i = 0;
while (i < d->size)
freeStack(d->words[i++]);
free(d->words);
free(d->count);
free(d);
}
/* Array insertion functions */
void insert(Array *a, char *buffer, int size) {
char *new = malloc((size + 1) * sizeof(char));
if (a->count == a->size - 1) {
a->size *= 2;
a->words = realloc(a->words, a->size * sizeof(char *));
}
a->words[a->count++] = strcpy(new, buffer);
}
Array *readWords(FILE *f) {
int size;
char *buffer = malloc(64 * sizeof(char));
Array *a = newArray();
while ((size = fscanf(f, " %s", buffer)) != EOF)
insert(a, buffer, size);
free(buffer);
return a;
}
/* Stack insertion algorithm */
void push(Stack *head, char *word) {
Stack *s = newStack(word, head->next);
head->next = s;
}
/* Sorting algorithms */
void insertionSort(char *word, int size) {
int i, tmp;
if (size-- <= 1)
return;
insertionSort(word, size);
tmp = word[size];
for (i = size; i > 0 && word[i - 1] > tmp; i--)
word[i] = word[i - 1];
word[i] = tmp;
}
/* Hash and rehash functions */
int key(char *word, int *i) {
int k;
for (*i = k = 0; word[*i]; (*i)++)
k += word[*i];
return k * (*i);
}
int bits(int n) {
n >>= 1;
return (n) ? 1 + bits(n) : 1;
}
int hash(int key, int mask, int b) {
int index = key & mask;
key >>= b;
return (key) ? index ^ hash(key, mask, b) : index;
}
int rehash(int index, int i, int mask) { return (index + i * i) & mask; }
/* Dictionary insertion algorithm */
void add(Dict *d, char *word, int mask, int b) {
int size, i, index = hash(key(word, &size), mask, b);
char *charSet = malloc((size + 1) * sizeof(char));
insertionSort(strcpy(charSet, word), size);
// Alternative:
// char *charSet = radixSort(strcpy(malloc((size + 1) * sizeof(char)),
// word), size, CHAR_BIT * sizeof(char));
for (i = 1; d->words[index] && strcmp(d->words[index]->word, charSet) != 0;
i += 2)
index = hash(index + i * i, mask, b);
if (!d->words[index]) {
d->words[index] = newStack(charSet, NULL);
d->order[d->sets++] = index;
d->count[index] = 0;
} else
free(charSet);
push(d->words[index], word);
d->count[index]++;
if (d->count[index] > d->maxCount) {
d->maxCount = d->count[index];
d->max = d->words[index];
}
}
Dict *buildDict(Array *a) {
int i, mask = a->size - 1, b = bits(mask);
Dict *d = newDict(a->size);
for (i = 0; i < a->count; i++)
add(d, a->words[i], mask, b);
return d;
}
/* Printing functions */
void printStack(Stack *s, char *terminator) {
if (!s)
return;
printStack(s->next, ", ");
printf("%s%s", s->word, terminator);
}
void printMax(Dict *d) {
printf(
"O conjunto de caracteres que possibilita o maior número de anagramas "
"na lingua portuguesa é \"%s\", que permite formar %d anagramas: ",
d->max->word, d->maxCount);
printStack(d->max->next, ".\n");
}
void printSets(Dict *d) {
int i;
printf("\nOs conjuntos de anagramas com mais de um item são:\n");
for (i = 0; i < d->sets; i++) {
if (d->count[d->order[i]] < 2)
continue;
printf("Conjunto \"%s\", %d anagramas: ", d->words[d->order[i]]->word,
d->count[d->order[i]]);
printStack(d->words[d->order[i]]->next, ".\n");
}
}
/* Main function */
int main(int argc, char *argv[]) {
FILE *f = fopen(argv[1], "r");
Array *a = readWords(f);
Dict *d = buildDict(a);
printMax(d);
printSets(d);
fclose(f);
freeArray(a);
freeDict(d);
return 0;
}

View File

@ -0,0 +1,51 @@
#include <stdlib.h>
#include <stdio.h>
#define array int*
void insertionSort (array A, int size) {
int i, tmp;
if (size <= 1)
return;
--size;
insertionSort(A + 1, size);
tmp = A[0];
for (i = 0; i < size && A[i + 1] < tmp; i++)
A[i] = A[i + 1];
A[i] = tmp;
}
array readArray (int *size) {
int d, i = 0;
char c;
array A;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf(" %d", &d))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
A[i++] = d;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
int main () {
array A;
int i, size;
printf("This program performs an insertion sort.\nType in a sequence of values separated by spaces and press ENTER: ");
A = readArray(&size);
insertionSort(A, size);
printf("New sequence:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,55 @@
#include <stdlib.h>
#include <stdio.h>
#define array int*
void swap (int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
void bubbleSort (array A, int size) {
int i;
if (size-- <= 1)
return;
for (i = 0; i < size; i++)
if (A[i] > A[i + 1])
swap(&A[i], &A[i + 1]);
bubbleSort(A, size);
}
array readArray (int *size) {
int d, i = 0;
char c;
array A;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf(" %d", &d))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
A[i++] = d;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
int main () {
array A;
int i, size;
printf("This program performs an insertion sort.\nType in a sequence of values separated by spaces and press ENTER: ");
A = readArray(&size);
bubbleSort(A, size);
printf("New sequence:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,171 @@
#include <locale.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
typedef struct {
int key;
wchar_t *data;
} Node;
typedef struct {
Node *items;
int size;
} Array;
/* Freeing memory*/
void freeArray(Array *A) {
int i;
for (i = 0; i < A->size; i++)
free(A->items[i].data);
free(A->items);
free(A);
}
/* Read functions */
bool readLine(wchar_t **line) {
int i = 0, length = 1;
wchar_t c;
*line = malloc(sizeof(wchar_t));
while ((c = getwchar()) != WEOF && c != '\n') {
if (i == length - 1) {
length *= 2;
*line = realloc(*line, length * sizeof(wchar_t));
}
(*line)[i++] = c;
}
(*line)[i] = '\0';
if (i)
return true;
return false;
}
Array *readText() {
Array *A = malloc(sizeof(Array));
int i;
A->items = malloc(sizeof(Node));
A->size = 1;
for (i = 0; readLine(&(A->items[i].data)); i++) {
A->items[i].key = i;
if (i < A->size - 1)
continue;
A->size *= 2;
A->items = realloc(A->items, A->size * sizeof(Node));
}
A->size = i;
return A;
}
/* Sort wchars */
void swap(Node *a, Node *b) {
Node tmp = *a;
*a = *b;
*b = tmp;
}
bool compareRadix (wchar_t *a, wchar_t *b) {
int i;
for (i = 0; a[i] != '\0'; i++) {
if (a[i] > b[i] || b[i] == '\0')
return true;
if (a[i] < b[i])
return false;
}
return false;
}
Node * medianOfDatasets(Node *a, Node *b, Node *c) {
if (compareRadix(a->data, b->data) ^ compareRadix(a->data, b->data))
return a;
if (compareRadix(a->data, b->data) ^ compareRadix(c->data, b->data))
return b;
return c;
}
int partitionByData (Node *n, int size) {
int i, j, last = size - 1;
swap(n + last, medianOfDatasets(n, n + size / 2, n + last));
for (i = j = 0; i < last; i++)
if (compareRadix(n[last].data, n[i].data))
swap(&n[i], &n[j++]);
swap(&n[i], &n[j]);
return j;
}
void quickSortData (Node *n, int size) {
int pivot;
if (size <= 1)
return;
pivot = partitionByData(n, size);
quickSortData(n, pivot++);
quickSortData(n + pivot, size - pivot);
}
/* Sort ints */
Node * medianOfKeys(Node *a, Node *b, Node *c) {
if ((a->key > b->key) ^ (a->key > c->key))
return a;
if ((b->key < a->key) ^ (b->key < c->key))
return b;
return c;
}
int partitionByKey (Node *n, int size) {
int i, j, last = size - 1;
swap(n + last, medianOfKeys(n, n + size / 2, n + last));
for (i = j = 0; i < last; i++)
if (n[i].key <= n[last].key)
swap(&n[i], &n[j++]);
swap(&n[i], &n[j]);
return j;
}
void quickSortKeys (Node *n, int size) {
int pivot;
if (size <= 1)
return;
pivot = partitionByKey(n, size);
quickSortKeys(n, pivot++);
quickSortKeys(n + pivot, size - pivot);
}
/* Driver function */
int main () {
setlocale(LC_ALL, "pt_BR.UTF-8");
Array *A;
int i;
wprintf(L"This program orders the lines of a text in lexicographic "
L"order, and then by their insertion order.\nType in a sequence "
L"of lines and press Enter twice:\n");
A = readText();
quickSortData(A->items, A->size);
wprintf(L"\nSort by data:\n");
for (i = 0; i < A->size; i++)
wprintf(L"%ls\n", A->items[i].data);
quickSortKeys(A->items, A->size);
wprintf(L"\nSort by key:\n");
for (i = 0; i < A->size; i++)
wprintf(L"%ls\n", A->items[i].data);
freeArray(A);
return 0;
}

View File

@ -0,0 +1,51 @@
#include <stdlib.h>
#include <stdio.h>
#define array int*
void insertionSort (array A, int size) {
int i, tmp;
if (size <= 1)
return;
--size;
insertionSort(A + 1, size);
tmp = A[0];
for (i = 0; i < size && A[i + 1] > tmp; i++)
A[i] = A[i + 1];
A[i] = tmp;
}
array readArray (int *size) {
int d, i = 0;
char c;
array A;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf(" %d", &d))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
A[i++] = d;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
int main () {
array A;
int i, size;
printf("This program performs an insertion sort.\nType in a sequence of values separated by spaces and press ENTER: ");
A = readArray(&size);
insertionSort(A, size);
printf("New sequence:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,61 @@
#include <stdio.h>
#include <stdlib.h>
#define array int *
void swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
int *maximalValue(array A, int size) {
int i, pos = 0;
for (i = 1; i < size; i++)
if (A[i] > A[pos])
pos = i;
return A + pos;
}
void selectionSort(array A, int size) {
if (size <= 1)
return;
swap(A, maximalValue(A, size));
selectionSort(A + 1, size - 1);
}
array readArray(int *size) {
int d, i = 0;
char c;
array A;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf(" %d", &d))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
A[i++] = d;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
int main() {
array A;
int i, size;
printf("This program performs a selection sort.\nType in a sequence of "
"values separated by spaces and press ENTER: ");
A = readArray(&size);
selectionSort(A, size);
printf("New sequence:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,75 @@
#include <stdlib.h>
#include <stdio.h>
#define array int*
void swap (int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
void heapify (array A, int size, int i) {
int max = i, left = 2 * max + 1, right = left + 1;
if (left >= size)
return;
if (A[left] > A[max])
max = left;
if (right < size && A[right] > A[max])
max = right;
else if (max == i)
return;
swap(A + i, A + max);
heapify(A, size, max);
}
void heapSort (array A, int size) {
int i;
if (size <= 1)
return;
for (i = (size - 1) / 2; i <= 0; i--)
heapify(A, size, i);
for (i = size - 1; i > 0; i--) {
swap(A, A + i);
heapify(A, i, 0);
}
}
array readArray (int *size) {
int d, i = 0;
char c;
array A;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf(" %d", &d))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
A[i++] = d;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
int main () {
array A;
int i, size;
printf("This program performs an insertion sort.\nType in a sequence of values separated by spaces and press ENTER: ");
A = readArray(&size);
heapSort(A, size);
printf("New sequence:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,50 @@
#include <stdlib.h>
#include <stdio.h>
#define array int*
void insertionSort (array A, int size) {
int i, tmp;
if (size-- <= 1)
return;
insertionSort(A, size);
tmp = A[size];
for (i = size; i > 0 && A[i - 1] > tmp; i--)
A[i] = A[i - 1];
A[i] = tmp;
}
array readArray (int *size) {
int d, i = 0;
char c;
array A;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf(" %d", &d))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
A[i++] = d;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
int main () {
array A;
int i, size;
printf("This program performs an insertion sort.\nType in a sequence of values separated by spaces and press ENTER: ");
A = readArray(&size);
insertionSort(A, size);
printf("New sequence:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,90 @@
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
typedef struct array{
int *values;
int size, buffer;
} Array;
Array * readArray () {
int d, i = 0;
char c;
Array *A = malloc(sizeof(Array));
A->buffer = 1;
A->values = malloc(sizeof(int));
do {
if (!scanf(" %d", &d))
continue;
if (i == A->buffer - 1) {
A->buffer *= 2;
A->values = realloc(A->values, A->buffer * sizeof(int));
}
A->values[i++] = d;
} while ((c = getchar()) != EOF && c != '\n');
A->size = i;
return A;
}
bool isSorted(int* A, int size) {
if (size <= 1)
return true;
if (*A > *(A + 1))
return false;
return isSorted(A + 1, size - 1);
}
void insertIn (Array **A, int value) {
int i;
Array *B;
if ((*A)->size + 1 > (*A)->buffer) {
B = malloc(sizeof(Array));
B->size = (*A)->size + 1;
B->buffer = (*A)->buffer * 2;
B->values = malloc(B->buffer * sizeof(int));
for (i = 0; i < (*A)->size && (*A)->values[i] <= value; i++)
B->values[i] = (*A)->values[i];
B->values[i] = value;
while(++i <= (*A)->size)
B->values[i] = (*A)->values[i - 1];
free(*A);
*A = B;
}
else {
for (i = (*A)->size - 1; i >= 0 && (*A)->values[i] > value; i--)
(*A)->values[i + 1] = (*A)->values[i];
(*A)->values[i + 1] = value;
(*A)->size++;
}
}
int main () {
Array *A;
int i, value;
printf("This program evaluates if a sequence of integer values is sorted in crescent order and, if it is, allows for the insertion of a new integer value to it.\nType in a sequence of values separated by spaces and press ENTER: ");
A = readArray();
if (!isSorted(A->values, A->size)) {
printf("Not sorted in crescent order.\n");
return 1;
}
printf("Sorted in crescent order. Type a integer value to be added to it: ");
if (!scanf(" %d", &value)) {
printf("Not an integer\n");
return 1;
}
insertIn(&A, value);
printf("New sequence:\n");
for (i = 0; i < A->size; i++)
printf("%d ", A->values[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,74 @@
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int key;
struct node *next;
} Node;
Node * read() {
int key;
char c;
Node *HEAD, *current, *prev;
if (!scanf(" %d", &key))
return NULL;
HEAD = malloc(sizeof(Node));
HEAD->key = key;
prev = HEAD;
current = NULL;
while ((c = getchar()) != EOF && c != '\n') {
if (!scanf("%d", &key))
break;
current = malloc(sizeof(Node));
current->key = key;
prev->next = current;
prev = current;
}
if (current)
current->next = NULL;
else
HEAD->next = NULL;
return HEAD;
}
Node * insert (Node *HEAD) {
Node *tmp = HEAD, *prev = tmp->next, *next;
HEAD = prev;
for (next = prev->next; next && tmp->key > next->key; next = next->next)
prev = next;
prev->next = tmp;
tmp->next = next;
return HEAD;
}
Node * insertionSort (Node *HEAD) {
if (HEAD) {
HEAD->next = insertionSort(HEAD->next);
if (HEAD->next && HEAD->key > HEAD->next->key)
return insert(HEAD);
}
return HEAD;
}
void printList(Node *n) {
printf("\nNew sequence:\n");
while (n) {
printf("%d ", n->key);
n = n->next;
}
printf("\n");
}
int main () {
printf("This program sorts a linked list based on its nodes' keys values."
"\nType in a sequence of integer values separated by spaces and "
"press ENTER: ");
printList(insertionSort(read()));
return 0;
}

View File

@ -0,0 +1,87 @@
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int key;
struct node *next;
} Node;
Node * read() {
int key;
char c;
Node *HEAD, *current, *prev;
if (!scanf(" %d", &key))
return NULL;
HEAD = malloc(sizeof(Node));
HEAD->key = key;
prev = HEAD;
current = NULL;
while ((c = getchar()) != EOF && c != '\n') {
if (!scanf("%d", &key))
break;
current = malloc(sizeof(Node));
current->key = key;
prev->next = current;
prev = current;
}
if (current)
current->next = NULL;
else
HEAD->next = NULL;
return HEAD;
}
Node * minimalValue(Node *HEAD, Node **prev) {
Node *current, *min;
*prev = NULL;
for (current = min = HEAD; current->next; current = current->next) {
if (current->next->key >= min->key)
continue;
min = current->next;
*prev = current;
}
return min;
}
Node * swap (Node *HEAD, Node *prev, Node *min) {
Node *next;
if (HEAD != min) {
next = min->next;
prev->next = HEAD;
min->next = HEAD->next;
HEAD->next = next;
}
return min;
}
Node * selectionSort (Node *HEAD) {
Node *prev;
if (HEAD){
HEAD = swap(HEAD, prev, minimalValue(HEAD, &prev));
HEAD->next = selectionSort(HEAD->next);
}
return HEAD;
}
void printList(Node *n) {
printf("\nNew sequence:\n");
while (n) {
printf("%d ", n->key);
n = n->next;
}
printf("\n");
}
int main () {
printf("This program sorts a linked list based on its nodes' keys "
"values.\nType in a sequence of integer values and press ENTER: ");
printList(selectionSort(read()));
return 0;
}

View File

@ -0,0 +1,81 @@
#include <stdlib.h>
#include <stdio.h>
#define array int*
int findMax(array A, int size) {
int i, max = A[0];
for(i = 1; i < size; i++)
if (A[i] > max)
max = A[i];
return max;
}
array cumulativeFreq (array A, int size, int exp) {
int i, radix;
array frequency = calloc(19, sizeof(int));
for (i = 0; i < size; i++) {
radix = A[i] / exp % 10;
frequency[10 + radix]++;
}
for (i = 1; i < 18; i++)
frequency[i] += frequency[i - 1];
return frequency;
}
void countingSort (array *A, int size, int exp) {
int i, radix;
array count = cumulativeFreq(*A, size, exp);
array sorted = malloc(size * sizeof(int));
for (i = 0; i < size; i++) {
radix = (*A)[i] / exp % 10;
sorted[count[9 + radix]++] = (*A)[i];
}
free(*A);
free(count);
*A = sorted;
}
void radixSort(array *A, int size) {
int exp, max = findMax(*A, size);
for (exp = 1; max / exp > 0; exp *= 10)
countingSort(A, size, exp);
}
array readArray (int *size) {
int d, i = 0;
char c;
array A;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf(" %d", &d))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
A[i++] = d;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
int main () {
array A;
int i, size;
printf("This program performs an insertion sort.\nType in a sequence of values separated by spaces and press ENTER: ");
A = readArray(&size);
radixSort(&A, size);
printf("New sequence:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,11 @@
#include <malloc.h>
int *set(int *orderedArray, int size, int *count) {
int i, *result = malloc(size * sizeof(int));
*result = *orderedArray;
for (i = *count = 1; i < size; i++)
if (orderedArray[i] != orderedArray[i - 1])
result[*count++] = orderedArray[i];
return result;
}

View File

@ -0,0 +1,85 @@
#include <locale.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
typedef struct {
wchar_t **lines;
int lineCount;
} Text;
bool readLine(wchar_t **line) {
int i = 0, length = 1;
wchar_t c;
*line = malloc(sizeof(wchar_t));
while ((c = getwchar()) != WEOF && c != '\n') {
if (i == length - 1) {
length *= 2;
*line = realloc(*line, length * sizeof(wchar_t));
}
(*line)[i++] = c;
}
(*line)[i] = '\0';
if (i)
return true;
return false;
}
void freeLines(wchar_t **lines, int i, int size) {
while (i < size)
free(lines[i++]);
}
Text *readText() {
Text *t = malloc(sizeof(Text));
int i;
t->lines = malloc(sizeof(wchar_t *));
t->lineCount = 1;
for (i = 0; readLine(t->lines + i); i++) {
if (i < t->lineCount - 1)
continue;
t->lineCount *= 2;
t->lines = realloc(t->lines, t->lineCount * sizeof(wchar_t *));
}
freeLines(t->lines, i, t->lineCount);
t->lineCount = i;
return t;
}
void insertionSort(wchar_t **lines, int size) {
int i;
wchar_t *tmp;
if (size <= 1)
return;
--size;
insertionSort(lines, size);
tmp = lines[size];
for (i = size; i > 0 && wcscmp(lines[i - 1], tmp) > 0; i--)
lines[i] = lines[i - 1];
lines[i] = tmp;
}
int main() {
setlocale(LC_ALL, "pt_BR.UTF-8");
Text *t;
int i;
wprintf(L"This program orders the lines of a text in lexicographic "
L"order.\nType in a sequence of lines and press Enter twice:\n");
t = readText();
insertionSort(t->lines, t->lineCount);
wprintf(L"New sequence:\n");
for (i = 0; i < t->lineCount; i++)
wprintf(L"%ls\n", t->lines[i]);
freeLines(t->lines, 0, t->lineCount);
free(t->lines);
free(t);
return 0;
}

View File

@ -0,0 +1,72 @@
#include <locale.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
void freeLines(wchar_t **lines) {
int i;
for (i = 0; lines[i][0] != '\0'; i++)
free(lines[i]);
free(lines[i]);
}
void readLine(wchar_t **line, wchar_t c, int i, int length) {
if (c == '\n' || c == WEOF) {
(*line)[i] = '\0';
return;
}
(*line)[i] = c;
if (i == length - 1) {
length *= 2;
*line = realloc(*line, length * sizeof(wchar_t));
}
readLine(line, getwchar(), i + 1, length);
}
wchar_t **readLines() {
int i = 0, lines = 1;
wchar_t **text = malloc(sizeof(wchar_t *));
do {
text[i] = malloc(sizeof(wchar_t));
readLine(text + i, getwchar(), 0, 1);
if (i < lines - 1)
continue;
lines *= 2;
text = realloc(text, lines * sizeof(wchar_t *));
} while (text[i++][0] != '\0');
return text;
}
void insertionSort(wchar_t **lines) {
int i;
wchar_t *tmp;
if (lines[1][0] == '\0')
return;
insertionSort(lines + 1);
tmp = *lines;
for (i = 0; lines[i + 1][0] != '\0' && wcscmp(lines[i + 1], tmp) < 0; i++)
lines[i] = lines[i + 1];
lines[i] = tmp;
}
int main() {
setlocale(LC_ALL, "pt_BR.UTF-8");
wchar_t **t;
int i;
wprintf(L"This program orders the lines of a text in lexicographic "
L"order.\nType in a sequence of lines and press Enter twice:\n");
t = readLines();
insertionSort(t);
wprintf(L"New sequence:\n");
for (i = 0; t[i][0] != '\0'; i++)
wprintf(L"%ls\n", t[i]);
freeLines(t);
free(t);
return 0;
}

View File

@ -0,0 +1,97 @@
#include <locale.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
typedef struct {
wchar_t **lines;
int lineCount;
} Text;
bool readLine(wchar_t **line) {
int i = 0, length = 1;
wchar_t c;
*line = malloc(sizeof(wchar_t));
while ((c = getwchar()) != WEOF && c != '\n') {
if (i == length - 1) {
length *= 2;
*line = realloc(*line, length * sizeof(wchar_t));
}
(*line)[i++] = c;
}
(*line)[i] = '\0';
if (i)
return true;
return false;
}
void freeLines(wchar_t **lines, int i, int size) {
while (i < size)
free(lines[i++]);
}
Text *readText() {
Text *t = malloc(sizeof(Text));
int i;
t->lines = malloc(sizeof(wchar_t *));
t->lineCount = 1;
for (i = 0; readLine(t->lines + i); i++) {
if (i < t->lineCount - 1)
continue;
t->lineCount *= 2;
t->lines = realloc(t->lines, t->lineCount * sizeof(wchar_t *));
}
freeLines(t->lines, i, t->lineCount);
t->lineCount = i;
return t;
}
bool compareRadix (wchar_t *a, wchar_t *b) {
int i;
for (i = 0; a[i] != '\0'; i++) {
if (a[i] > b[i] || b[i] == '\0')
return true;
if (a[i] < b[i])
return false;
}
return false;
}
void insertionSort(wchar_t **lines, int size) {
int i;
wchar_t *tmp;
if (size <= 1)
return;
--size;
insertionSort(lines, size);
tmp = lines[size];
for (i = size; i > 0 && compareRadix(lines[i - 1], tmp); i--)
lines[i] = lines[i - 1];
lines[i] = tmp;
}
int main() {
setlocale(LC_ALL, "pt_BR.UTF-8");
Text *t;
int i;
wprintf(L"This program orders the lines of a text in lexicographic "
L"order.\nType in a sequence of lines and press Enter twice:\n");
t = readText();
insertionSort(t->lines, t->lineCount);
wprintf(L"New sequence:\n");
for (i = 0; i < t->lineCount; i++)
wprintf(L"%ls\n", t->lines[i]);
freeLines(t->lines, 0, t->lineCount);
free(t->lines);
free(t);
return 0;
}

View File

@ -0,0 +1,127 @@
**2.** Sim, em ambos os casos. Isso, em função dos loops redundantes nas linhas 8 e 9, respectivamente.
**3.** Não. Na eventualidade de haverem valores entre $q$ e $r$ os quais não foram transcritos ao vetor $w$ na linha 7, em função de a transcrição de $p$ a $q$ já ter sido encerrada ($i == q$), estes não serão incorporados deste ponto em diante.
**4.** A troca é sem efeito para o resultado final, mas o desempenho do algoritmo será pior em função da adição de uma comparação desnecessária (neste caso, a comparação $v[i] > v[j]$).
**5.** Sim, na verdade esse é o método de comparação do qual faço uso.
**6.** Não, deste modo será feita a inclusão de valores de $p$ à $q$, enquanto $v[i] <= v[j]$ e, em seguida, de $q$ à $r$, enquanto $v[j] <= v[i]$, sem que a inclusão destes se dê de forma intercalada, tal qual o problema exige.
**7.** Este while ocorre enquanto ambas as "metades" do vetor houverem valores a serem intercalados no vetor resultante $w$ os quais ainda não foram percorridos.
---
Feitos mas não salvos **8, 9, 10**
---
**12.** Sim, ela o é. O que não seria o caso fosse feita a alteração proposta, já que os valores repetidos posteriores (depositados nos endereços de $q$ a $r$, percorridos pelo contador $j$) seriam inseridos no vetor resultante antes de suas contrapartes anteriores (depositadas nos endereços $p$ a $q$, percorridas pelo contador $i$) em função da colocação da comparação "v[i] < v[j]" na linha 6.
**13.** Vide arquivo `merge_lists.c`
## Exercícios 3
**1.** Ao chegarmos a linha 2, necessariamente passamos pela verificação na linha 1, então temos:
$$
\begin{cases} p < r - 1\ (\text I)\\ \\\ q = \dfrac{p + r}2\ (\text{II}) \end{cases}
$$
Seja $f$ uma variável de "folga", $f \in \mathbb N, f \ge 1,$ tal que $p = r - 1 - f$, então
$$
q = \dfrac{p + p + f + 1}2 = p + \underbrace{\dfrac{f + 1}2}_{\ge 1} \implies q > p
$$
e
$$
q = \dfrac{r + r - f - 1}2 = r - \underbrace{\dfrac{f + 1}2}_{\ge 1} \implies q < r
$$
Logo, $p < q < r$. $\blacksquare$
**2.** Ao trocarmos `(p + r) / 2` por `(p + r - 1) / 2` o vetor ao ser recursivamente subdividido e eventualmente alcançar um tamanho $r - p = 2$ teremos, em função da divisão inteira:
$$
\displaystyle q = \frac{p + r - 1}2 = \frac{2p + 2 - 1}2 = p + \underbrace{\frac 12}_{= 0} = p
$$
Assim, nas duas próximas chamadas ao mergesort, teremos algo equivalente à `mergesort(p, p, v)` o que compreende nenhum elemento e `mergesort(p, r, v)`, o que compreende os mesmos dois elementos da atual invocação. Ou seja, temos uma recursão infinita. $\square$
A mesma situação não se observa para `(p + r + 1) / 2`. Seja $r = p + \text{tam}, \text{tam} \ge 2$ então
$$
\displaystyle q = \frac{p + r + 1}2 = \frac{2p + \text{tam} + 1}2 = p + \underbrace{\frac{\text{tam} + 1}2}_{\ge 1} \therefore p < q < r
$$
Assim, o vetor será sempre repartido em uma posição intermediária aos seus elementos, o que conduzirá o algoritmo a sua resolução. $\blacksquare$
**3.**
```c
mergesort(1,4, v)
mergesort(1,2, v)
mergesort(1,1, v)
mergesort(2,2, v)
mergesort(3,4, v)
mergesort(3,3, v)
mergesort(4,4, v)
```
**4.**
```c
void mergeSort (array A, int size) {
int pivot;
if (size <= 1)
return;
pivot = size / 2;
mergeSort(A, pivot);
mergeSort(A + pivot, size - pivot)
merge(A, pivot, size);
}
```
Temos que o tamanho do vetor é sempre maior que 1, e assim o pivô sempre assume um valor intermediário entre o tamanho do vetor (ou subvetor) e o início deste, subdividindo-o, (em porções menores até se alcançar o tamanho 1) e a intercalação de vetores é possível.
**5.** Sim ela o é tendo em vista que a comparação entre os elementos presentes no primeiro e segundo subvetores se dá por $A[i] <= A[j]$, onde $i < j$, o valor equivalente que se apresenta primeiro é inserido, também primeiramente, no vetor resultante.
**6.** Pode-se fazer uso da solução que apresentei anteriormente, no exercício quatro, fazendo-se uso de um único numerador.
**7.** Feito conforme exigência da disciplina de Introdução a Análise de Algoritmos.
## Exercícios 4
**1.** Não está correto pois o pivô foi deslocado em uma posição (`q + 1`) ao passá-lo a função intercala. Isso fará que o menor valor do segundo subvetor seja incluído no vetor resultante apenas após todos os valores do primeiro subvetor terem sido incluídos neste, o que pode incluir valores maiores que este. Por exemplo, para $1\ 3\ 5\ |\ 2\ 4\ 6$ teríamos um vetor resultante: $1\ 3\ 4\ 5\ 2\ 6$.
**2.** Não. Quando o subvetor alcança tamanho 1, este é subdivido em um subvetor de tamanho 0 e mais outro de tamanho 1, e assim indefinidamente.
**3.** Não, falamos sobre isso no exercício 2 do bloco anterior (3).
**4.** Não em ambos os casos. Para um vetor de tamanho 2 temos que $q = 0$, gerando dois vetores: um de tamanho nulo e outro de tamanho 2; e assim indefinidamente.
**5.** Definitivamente não. Podemos fazer uma demonstração de caso com o vetor $1\ 3\ 5\ 2\ 4\ 6$ para atestarmos isso. Este não será intercalado corretamente.
**6.** Sim, mas muito mais lentamente, em tempo quadrático.
**7, 8.** Feito.
## Exercícios 5
**1.**
```c
int c = 1 ← T(1)
for (int i = 0; i < n; i *=2) T(n/2)
for (int j = 1; j < n; j++) T(n)
c += 1; ← T(1)
```
O tempo de execução em função de n é, portanto
$$
T \left(1 + n \cdot \frac n2 \cdot 1 \right) = T \left(\frac{n^2}2 + 1 \right)
$$
**2.** Feito no

View File

@ -0,0 +1,28 @@
#include "./merge_shell_sort.c"
#include <limits.h>
int main () {
int i = 0, size, index;
array A;
if (!scanf(" %d", &size) || size < 1 || size > INT_MAX) {
printf("Tamanho inválido: não se encontra desde 1 a %d.\n", INT_MAX);
return 1;
}
A = malloc(size * sizeof(int));
while (i < size && scanf(" %d", A + i))
i++;
if (i < size) {
printf("Lista mal formatada: apenas %d valores foram encontrados.\n", i);
return 1;
}
if (!scanf(" %d", &index) || index < 1 || index >= size) {
printf("Índice invalido: não se encontra desde 1 a %d.\n", size);
return 1;
}
mergeSort(A, size);
printf("O %dº elemento de menor valor: %d\n", index, A[index - 1]);
free(A);
return 0;
}

View File

@ -0,0 +1,66 @@
#include <stdlib.h>
#include <stdio.h>
#define array int*
void merge (array A, array tmp, int pivot, int size) {
int i, k, j = pivot;
for (i = k = 0; k < size; k++)
tmp[k] = (j == size || (i < pivot && A[i] >= A[j])) ?
A[i++] : A[j++];
for (k = 0; k < size; k++)
A[k] = tmp[k];
}
void mergeSort (array A, array tmp, int size) {
int pivot;
if (size <= 1)
return;
pivot = size / 2;
mergeSort(A, tmp, pivot);
mergeSort(A + pivot, tmp + pivot, size - pivot);
merge(A, tmp, pivot, size);
}
void sort (array A, int size) {
array tmp = malloc(size * sizeof(int));
mergeSort(A, tmp, size);
free(tmp);
}
array readArray (int *size) {
int i = 0;
char c;
array A;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf("%d", A + i))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
i++;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
int main () {
array A;
int i, size;
printf("This program performs a merge sort.\nType in a sequence of values separated by spaces and press ENTER: ");
A = readArray(&size);
sort(A, size);
printf("New sequence:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,61 @@
#include <stdio.h>
#include <stdlib.h>
#define Array int *
Array readArray(int *size) {
int d, i = 0;
char c;
Array A;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf(" %d", &d))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
A[i++] = d;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
void interleave(Array A, int pivot, int size) {
int i, tmp = A[pivot];
if (pivot == size)
return;
for (i = pivot; i > 0 && A[i - 1] > tmp; i--)
A[i] = A[i - 1];
A[i] = tmp;
interleave(A, pivot + 1, size);
}
void mergeSort(Array A, int size) {
int pivot;
if (size <= 1)
return;
pivot = size / 2;
mergeSort(A, pivot);
mergeSort(A + pivot, size - pivot);
interleave(A, pivot, size);
}
int main() {
Array A;
int i, size;
printf("This program performs an in-place merge sort.\nType in a sequence "
"of values separated by spaces and press ENTER: ");
A = readArray(&size);
mergeSort(A, size);
printf("New sequence:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,70 @@
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int key;
struct node *next;
} Node;
Node * readList() {
int key;
char c;
Node *HEAD, *current, *prev;
printf("\nType in a sequence of ascending integer values separated by spaces"
"and press ENTER:\n");
if (!scanf(" %d", &key))
return NULL;
HEAD = malloc(sizeof(Node));
HEAD->key = key;
prev = HEAD;
current = NULL;
while ((c = getchar()) != EOF && c != '\n') {
if (!scanf("%d", &key))
break;
current = malloc(sizeof(Node));
current->key = key;
prev->next = current;
prev = current;
}
if (current)
current->next = NULL;
else
HEAD->next = NULL;
return HEAD;
}
Node * mergeLists (Node *a, Node *b) {
if (!a && !b)
return NULL;
if (a) {
if (!b)
return a;
if (a->key <= b->key) {
a->next = mergeLists (a->next, b);
return a;
}
b->next = mergeLists (a, b->next);
}
return b;
}
void printList(Node *n) {
printf("\nNew sequence:\n");
while (n) {
printf("%d ", n->key);
n = n->next;
}
printf("\n");
}
int main () {
printf("This program merges two linked lists with keys in ascending order."
"\n");
printList(mergeLists(readList(), readList()));
return 0;
}

View File

@ -0,0 +1,56 @@
#include <stdlib.h>
#include <stdio.h>
#define array int*
/* Shell sort */
void insertionSort (array A, int size, int start, int gap) {
int i = start + gap, tmp;
if (i >= size)
return;
tmp = A[i];
while (i >= gap && A[i - gap] > tmp) {
A[i] = A[i - gap];
i-= gap;
}
A[i] = tmp;
insertionSort(A, size, start + gap, gap);
}
void shellSort (array A, int size) {
int i, sublist_lenght;
for (sublist_lenght = size /2; sublist_lenght > 0; sublist_lenght /= 2)
for (i = 0; i < sublist_lenght; i++)
insertionSort(A, size, i, sublist_lenght);
}
/* Merge Sort */
void merge (array A, int pivot, int size) {
int i, k, j = pivot;
array tmp = malloc(size * sizeof(int));
for (i = k = 0; k < size; k++)
tmp[k] = (j == size || (i < pivot && A[i] <= A[j])) ?
A[i++] : A[j++];
for (k = 0; k < size; k++)
A[k] = tmp[k];
free(tmp);
}
void mergeSort (array A, int size) {
int pivot;
if (size <= 1)
return;
if (size <= 10)
shellSort(A, size);
else {
pivot = size / 2;
mergeSort(A, pivot);
mergeSort(A + pivot, size - pivot);
merge(A, pivot, size);
}
}

View File

@ -0,0 +1,61 @@
#include <stdlib.h>
#include <stdio.h>
#define array int*
void merge (array A, int pivot, int size) {
int i, k, j = pivot;
array tmp = malloc(size * sizeof(int));
for (i = k = 0; k < size; k++)
tmp[k] = (j == size || (i < pivot && A[i] <= A[j])) ?
A[i++] : A[j++];
for (k = 0; k < size; k++)
A[k] = tmp[k];
free(tmp);
}
void mergeSort (array A, int size) {
int pivot;
if (size <= 1)
return;
pivot = (size + 1)/ 2;
mergeSort(A, pivot);
mergeSort(A + pivot, size - pivot);
merge(A, pivot, size);
}
array readArray (int *size) {
int i = 0;
char c;
array A;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf("%d", &A[i]))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
i++;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
int main () {
array A;
int i, size;
printf("This program performs an insertion sort.\nType in a sequence of values separated by spaces and press ENTER: ");
A = readArray(&size);
mergeSort(A, size);
printf("New sequence:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,85 @@
#include <stdio.h>
#include <stdlib.h>
#define array int *
typedef struct node {
int key;
struct node *next;
} Node;
Node *newNode(int key) {
Node *new = malloc(sizeof(Node));
new->key = key;
return new;
}
Node *read() {
int key;
char c;
Node *HEAD, *current, *prev;
if (!scanf(" %d", &key))
return NULL;
HEAD = newNode(key);
prev = HEAD;
current = NULL;
while ((c = getchar()) != EOF && c != '\n' && scanf("%d", &key)) {
current = newNode(key);
prev->next = current;
prev = current;
}
if (current)
current->next = NULL;
else
HEAD->next = NULL;
return HEAD;
}
Node *mid(Node *slow) {
Node *fast = slow->next;
while (fast && (fast = fast->next)) {
fast = fast->next;
slow = slow->next;
}
fast = slow->next;
slow->next = NULL;
return fast;
}
Node *merge(Node *a, Node *b) {
if (a) {
if (!b)
return a;
if (a->key <= b->key) {
a->next = merge(a->next, b);
return a;
}
b->next = merge(a, b->next);
}
return b;
}
Node *mergeSort(Node *n) {
return (n) ? merge(mergeSort(n), mergeSort(mid(n))) : n;
}
void printList(Node *n) {
printf("\nNew sequence:\n");
while (n) {
printf("%d ", n->key);
n = n->next;
}
printf("\n");
}
int main() {
printf("This program sorts a linked list based on its nodes' keys values."
"\nType in a sequence of integer values separated by spaces and "
"press ENTER: ");
printList(mergeSort(read()));
return 0;
}

View File

@ -0,0 +1,66 @@
#include <stdlib.h>
#include <stdio.h>
#define array int*
void merge (array A, array tmp, int pivot, int size) {
int i, k, j = pivot;
for (i = k = 0; k < size; k++)
tmp[k] = (j == size || (i < pivot && A[i] <= A[j])) ?
A[i++] : A[j++];
for (k = 0; k < size; k++)
A[k] = tmp[k];
}
void mergeSort (array A, array tmp, int size) {
int pivot;
if (size <= 1)
return;
pivot = size / 2;
mergeSort(A, tmp, pivot);
mergeSort(A + pivot, tmp + pivot, size - pivot);
merge(A, tmp, pivot, size);
}
void sort (array A, int size) {
array tmp = malloc(size * sizeof(int));
mergeSort(A, tmp, size);
free(tmp);
}
array readArray (int *size) {
int i = 0;
char c;
array A;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf("%d", A + i))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
i++;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
int main () {
array A;
int i, size;
printf("This program performs a merge sort.\nType in a sequence of values separated by spaces and press ENTER: ");
A = readArray(&size);
sort(A, size);
printf("New sequence:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,67 @@
#include <stdio.h>
#include <stdlib.h>
#define array int *
void merge(array A, int pivot, int size) {
int i = 0, j = size - 1, k;
array tmp = malloc(size * sizeof(int));
while (i < pivot) {
tmp[i] = A[i];
i++;
}
while (i < size) {
tmp[i] = A[j - (i - pivot)];
i++;
}
for (i = k = 0; k < size; k++)
A[k] = (tmp[i] <= tmp[j]) ? tmp[i++] : tmp[j--];
free(tmp);
}
void mergeSort(array A, int size) {
int pivot;
if (size <= 1)
return;
pivot = size / 2;
mergeSort(A, pivot);
mergeSort(A + pivot, size - pivot);
merge(A, pivot, size);
}
array readArray(int *size) {
int i = 0;
char c;
array A;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf("%d", A + i))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
i++;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
int main() {
array A;
int i, size;
printf("This program performs a merge sort.\nType in a sequence of values "
"separated by spaces and press ENTER: ");
A = readArray(&size);
mergeSort(A, size);
printf("New sequence:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,57 @@
# Respostas aos exercícios
## Exercícios 2
**4.** Conforme a seguinte implementação
```c
01 | static int separa (int v[], int p, int r) {
02 | int c = v[r]; //pivô
03 | int t, j = p;
04 | for (int k = p; k < r; k++) {
05 | if (v[k] <= c) {
06 | t = v[j];
07 | v[j] = v[k];
08 | v[k] = t;
09 | j++;
10 | }
11 | t = v[j];
12 | v[j] = v[r];
13 | v[r] = t;
14 | }
15 | }
```
Verifiquemos se os seguintes invariantes são verdadeiros:
1. $p \le j \le k$
O valor de $j$ é tido inicialmente na linha 03 como sendo igual a $p$, equivalente portanto também à $k$ tal qual este último é definido na linha 04. Para cada iteração da repetição `for` o valor de $k$ é incrementado, enquanto o valor de j neste mesmo loop é incrementado se, e somente se, a comparação posta pela linha 05 é tida verdadeira.
Sendo este o único ponto no algoritmo em que o valor de j é modificado tem-se que j pode assumir valores tais que $p \le j \le k$ apenas. $\blacksquare$
2. $v[p \dots j - 1] \le c$
Inicialmente, $j = p$, então $v[p \dots j - 1]$ compreende um conjunto vazio. Feita a primeira iteração, tem-se a manutenção do invariante para compreender o primeiro elemento da lista que, para a iteração seguinte, corresponde à posição `j - 1`. O mesmo processo se repete para cada repetição subsequente. $\blacksquare$
3. $v[j \dots k - 1] > c$
Inicialmente, $k = p$ e $j = p$, então $v[j \dots k - 1]$ compreende um conjunto vazio. Feita a primeira iteração, tem-se a manutenção do invariante para compreender o primeiro elemento da lista que, para a iteração seguinte, corresponde à posição `k - 1`. Se este for menor ou igual a $c$, $j = k$ e $v[j \dots k - 1]$ continua vazio. Senão, $j = k - 1$ e $v[j \dots k - 1]$ compreende mais este valor. O mesmo processo se repete para cada repetição subsequente. $\blacksquare$
4. $v[p \dots r]$ é uma permutação do vetor original.
O quickSort é um algoritmo de ordenação o qual não faz uso de memória auxiliar. Suas operações são feitas com base em substituições (linhas 6 à 13) sobre o vetor original. Assim o sendo, segue que o resultado desta operação produz, a cada etapa, uma permutação deste vetor.
**7.** Não. Isso pois o elemento aquele selecionado enquanto pivô é *sempre* posicionado no vetor ao final do processo de partição após valores maiores ou iguais a ele. Isso, ainda que ele possa ter figurado antes doutros elementos de mesmo valor.
## Exercícios 3
```
quicksort (v, 1, 6)
quicksort (v, 1, 2)
quicksort (v, 1, 0)
quicksort (v, 2, 2)
quicksort (v, 4, 6)
quicksort (v, 4, 4)
quicksort (v, 6, 6)
```

View File

@ -0,0 +1,52 @@
#include <stdio.h>
#include <stdlib.h>
int *readArray(int *size) {
int i = 0;
char c;
int *A;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf(" %d", A + i))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
i++;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
void swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
void partition(int *v, int size) {
int i, j;
for (i = j = 0; i < size; i++)
if (v[i] == 0)
swap(&v[i], &v[j++]);
}
int main() {
int *A;
int i, size;
printf("This program sorts an array of 0s and 1s in crescent order.\nType "
"in a sequence of values separated by spaces and press ENTER: ");
A = readArray(&size);
partition(A, size);
printf("New sequence:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,105 @@
#include <stdlib.h>
#include <stdio.h>
typedef struct node{
int key;
struct node *next;
} Node;
Node * newNode (int key) {
Node * new = malloc(sizeof(Node));
new->key = key;
return new;
}
Node * read() {
int key;
char c;
Node *HEAD, *current, *prev;
if (!scanf(" %d", &key))
return NULL;
HEAD = newNode(key);
prev = HEAD;
current = NULL;
while ((c = getchar()) != EOF && c != '\n' && scanf("%d", &key)) {
current = newNode(key);
prev->next = current;
prev = current;
}
if (current)
current->next = NULL;
else
HEAD->next = NULL;
return HEAD;
}
Node * median (Node *start) {
Node *slow = start->next, *fast = slow->next;
if (!fast)
return slow;
while (fast->next && fast->next->next) {
fast = fast->next->next;
slow = slow->next;
}
if ((start->key > slow->key) ^ (start->key > fast->key))
return start;
if ((slow->key < start->key) ^ (slow->key < fast->key))
return slow;
return fast;
}
void partition (Node *n, Node *pivot, Node **le, Node **gt) {
if (!n)
*le = *gt = NULL;
else if (n == pivot)
partition(n->next, pivot, le, gt);
else if (n->key <= pivot->key) {
*le = n;
partition(n->next, pivot, &n->next, gt);
}
else {
*gt = n;
partition(n->next, pivot, le, &n->next);
}
}
Node * append (Node *le, Node *pivot, Node *gt) {
if (le) {
le->next = append(le->next, pivot, gt);
return le;
}
pivot->next = gt;
return pivot;
}
Node * quickSort (Node * HEAD) {
Node *le, *gt, *pivot;
if (!HEAD || !HEAD->next)
return HEAD;
pivot = median(HEAD);
partition(HEAD, pivot, &le, &gt);
return append(quickSort(le), pivot, quickSort(gt));
}
void printList(Node *n) {
printf("\nNew sequence:\n");
while (n) {
printf("%d ", n->key);
n = n->next;
}
printf("\n");
}
int main () {
printf("This program sorts a linked list based on its nodes' keys values."
"\nType in a sequence of integer values separated by spaces and "
"press ENTER: ");
printList(quickSort(read()));
return 0;
}

View File

@ -0,0 +1,52 @@
#include <stdio.h>
#include <stdlib.h>
#define array int*
array readArray (int *size) {
int i = 0;
char c;
array A;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf(" %d", &A[i]))
continue;
if (i++ == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
void swap (int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
void partition (array A, int size) {
int i, j;
for (i = j = 0; i < size; i++)
if (A[i] < 0)
swap(&A[i], &A[j++]);
}
int main () {
array A;
int i, size;
printf("This program performs a partition of a list of integer values.\n"
"Type in a sequence of values separated by spaces and press ENTER:\n");
A = readArray(&size);
partition(A, size);
printf("New sequence:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,77 @@
#include <stdlib.h>
#include <stdio.h>
typedef struct node{
int key;
struct node *next;
} Node;
Node * newNode (int key) {
Node * new = malloc(sizeof(Node));
new->key = key;
return new;
}
Node * read() {
int key;
char c;
Node *HEAD, *current, *prev;
if (!scanf(" %d", &key))
return NULL;
HEAD = newNode(key);
prev = HEAD;
current = NULL;
while ((c = getchar()) != EOF && c != '\n' && scanf("%d", &key)) {
current = newNode(key);
prev->next = current;
prev = current;
}
if (current)
current->next = NULL;
else
HEAD->next = NULL;
return HEAD;
}
void partition (Node *n, Node **pairs, Node **odds) {
if (!n)
*pairs = *odds = NULL;
else if (n->key % 2 == 0) {
*pairs = n;
partition(n->next, &n->next, odds);
}
else {
*odds = n;
partition(n->next, pairs, &n->next);
}
}
void printList(Node *n) {
while (n) {
printf("%d ", n->key);
n = n->next;
}
printf("\n");
}
int main () {
Node *pairs, *odds;
printf("This program partitions a linked list into two, onde containing "
"all nodes with pair values and another containing other nodes.\n"
"Type in a sequence of integer values separated by spaces and "
"press ENTER:\n");
partition(read(), &pairs, &odds);
printf("\nPair values:\n");
printList(pairs);
printf("\nOdd values:\n");
printList(odds);
return 0;
}

View File

@ -0,0 +1,77 @@
#include <stdio.h>
#include <stdlib.h>
#define Array int *
Array readArray(int *size) {
int d, i = 0;
char c;
Array A;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf(" %d", &d))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
A[i++] = d;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
void swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
void heapify(Array A, int size, int i) {
int min = i, left = 2 * min + 1, right = left + 1;
if (left >= size)
return;
if (A[left] < A[min])
min = left;
if (right < size && A[right] < A[min])
min = right;
else if (min == i)
return;
swap(A + i, A + min);
heapify(A, size, min);
}
void heapSort(Array A, int size) {
int i;
if (size <= 1)
return;
for (i = (size - 1) / 2; i <= 0; i--)
heapify(A, size, i);
for (i = size - 1; i > 0; i--) {
swap(A, A + i);
heapify(A, i, 0);
}
}
int main() {
Array A;
int i, size;
printf("This program uses a min heap to sort integers in crecreasing "
"order.\nType in a sequence of values separated by spaces and press "
"ENTER: ");
A = readArray(&size);
heapSort(A, size);
printf("New sequence:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,73 @@
#include <stdio.h>
#include <stdlib.h>
#define Array int *
Array readArray(int *size) {
int d, i = 0;
char c;
Array A;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf(" %d", &d))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
A[i++] = d;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
int pivot(Array A, int size, int mask) {
int i, pivot;
for (i = pivot = 0; i < size; i++)
if ((A[i] & mask) == 0)
pivot++;
return pivot;
}
Array countingSort(Array A, int size, int mask) {
int i, j = pivot(A, size, mask), k;
Array sorted;
if (!j || j == size)
return A;
sorted = malloc(size * sizeof(int));
for (i = k = 0; k < size; k++)
if (A[k] & mask)
sorted[j++] = A[k];
else
sorted[i++] = A[k];
free(A);
return sorted;
}
Array radixSort(Array A, int size) {
int mask;
for (mask = 1; mask; mask <<= 1)
A = countingSort(A, size, mask);
return A;
}
int main() {
Array A;
int i, size;
printf("This program performs a binary radix sort.\nType in a sequence "
"of integer values separated by spaces and press ENTER: ");
A = readArray(&size);
A = radixSort(A, size);
printf("New sequence:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,109 @@
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#define Array int *
Array readArray(int *size) {
int d, i = 0;
char c;
Array A;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf(" %d", &d))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
A[i++] = d;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
int max(Array a, int size) {
int i, max = *a;
for (i = 1; i < size; i++)
if (a[i] > max)
max = a[i];
return max;
}
int bits(int n) { return (n >>= 1) ? 1 + bits(n) : 0; }
int pivot(Array A, int size, unsigned int mask) {
int i, pivot;
for (i = pivot = 0; i < size; i++)
if ((A[i] & mask) == 0)
pivot++;
return pivot;
}
Array append(Array a, Array b, int p, int size) {
int i, *result = malloc(size * sizeof(int));
for (i = 0; i < p; i++)
result[i] = a[i];
while (i < size) {
result[i] = b[i - p];
i++;
}
free(a);
free(b);
return result;
}
void distribute(Array A, Array zeroes, Array ones, int mask, int size) {
if (size <= 0)
return;
if (*A & mask) {
*ones = *A;
ones += 1;
} else {
*zeroes = *A;
zeroes += 1;
}
distribute(A + 1, zeroes, ones, mask, size - 1);
}
Array radixSort(Array A, int size, unsigned int mask) {
int p, *zeroes, *ones;
if (!mask || size <= 1)
return A;
p = pivot(A, size, mask);
if (!p || p == size)
return radixSort(A, size, mask >> 1);
zeroes = malloc(p * sizeof(int));
ones = malloc((size - p) * sizeof(int));
distribute(A, zeroes, ones, mask, size);
free(A);
zeroes = radixSort(zeroes, p, mask >> 1);
ones = radixSort(ones, size - p, mask >> 1);
return append(zeroes, ones, p, size);
}
int main() {
Array A;
int i, size;
printf("This program performs a binary radix sort.\nType in a sequence "
"of integer values separated by spaces and press ENTER: ");
A = readArray(&size);
A = radixSort(A, size, 1 << bits(max(A, size)));
printf("New sequence:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
return 0;
}

View File

@ -0,0 +1,103 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define array int *
typedef struct node {
int key;
struct node *next;
} List;
List *newList(int key, List *next) {
List *new = malloc(sizeof(List));
new->key = key;
new->next = next;
return new;
}
List *read() {
int key;
char c;
List *HEAD, *current, *prev;
if (!scanf(" %d", &key))
return NULL;
HEAD = newList(key, NULL);
prev = HEAD;
current = NULL;
while ((c = getchar()) != EOF && c != '\n' && scanf("%d", &key)) {
current = newList(key, NULL);
prev->next = current;
prev = current;
}
if (current)
current->next = NULL;
else
HEAD->next = NULL;
return HEAD;
}
void printList(List *n) {
printf("\nNew sequence:\n");
while (n) {
printf("%d ", n->key);
n = n->next;
}
printf("\n");
}
List *append(List *a, List *pivot, List *b) {
pivot->next = b;
return a;
}
List *headless(List *l) {
List *next = l->next;
free(l);
return next;
}
List *partition(List *l, List *zeroes, List *ones, int mask) {
while (l) {
if (l->key & mask) {
ones->next = l;
ones = ones->next;
} else {
zeroes->next = l;
zeroes = zeroes->next;
}
l = l->next;
}
ones->next = NULL;
return zeroes;
}
List *countingSort(List *l, int mask) {
List *zeroes = newList(0, NULL), *ones = newList(1, NULL),
*pivot = partition(l, zeroes, ones, mask);
zeroes = headless(zeroes);
ones = headless(ones);
return (zeroes && ones) ? append(zeroes, pivot, ones) : l;
}
List *radixSort(List *l) {
int mask;
if (l)
for (mask = 1; mask; mask <<= 1)
l = countingSort(l, mask);
return l;
}
int main() {
printf("This program sorts a linked list based on its nodes' keys values."
"\nType in a sequence of integer values separated by spaces and "
"press ENTER: ");
printList(radixSort(read()));
return 0;
}

View File

@ -0,0 +1,116 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define array int *
typedef struct node {
int key;
struct node *next;
} List;
List *newList(int key, List *next) {
List *new = malloc(sizeof(List));
new->key = key;
new->next = next;
return new;
}
List *read() {
int key;
char c;
List *HEAD, *current, *prev;
if (!scanf(" %d", &key))
return NULL;
HEAD = newList(key, NULL);
prev = HEAD;
current = NULL;
while ((c = getchar()) != EOF && c != '\n' && scanf("%d", &key)) {
current = newList(key, NULL);
prev->next = current;
prev = current;
}
if (current)
current->next = NULL;
else
HEAD->next = NULL;
return HEAD;
}
void printList(List *n) {
printf("\nNew sequence:\n");
while (n) {
printf("%d ", n->key);
n = n->next;
}
printf("\n");
}
int max(List *l) {
int max = l->key;
for (l = l->next; l; l = l->next)
if (l->key > max)
max = l->key;
return max;
}
int bits(int n) { return (n >>= 1) ? 1 + bits(n) : 0; }
List *append(List *a, List *b) {
while (a->next)
a = a->next;
a->next = b;
return a;
}
List *headless(List *l) {
List *next = l->next;
free(l);
return next;
}
void partition(List *l, List *zeroes, List *ones, int mask) {
while (l) {
if (l->key & mask) {
ones->next = l;
ones = ones->next;
} else {
zeroes->next = l;
zeroes = zeroes->next;
}
l = l->next;
}
zeroes->next = ones->next = NULL;
}
List *radixSort(List *l, unsigned int mask) {
List *zeroes, *ones;
if (!l->next || !mask)
return l;
zeroes = newList(0, NULL);
ones = newList(1, NULL);
partition(l, zeroes, ones, mask);
zeroes = headless(zeroes);
ones = headless(ones);
if (!zeroes || !ones)
return l;
zeroes = radixSort(zeroes, mask >> 1);
ones = radixSort(ones, mask >> 1);
return append(zeroes, ones);
}
int main() {
List *l;
printf("This program sorts a linked list based on its nodes' keys values."
"\nType in a sequence of integer values separated by spaces and "
"press ENTER: ");
l = read();
printList(radixSort(l, 1 << bits(max(l))));
return 0;
}

View File

@ -0,0 +1,152 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <sys/param.h>
typedef struct node{
int key, height;
struct node *lt, *gt;
} Node;
/* Tree balancing */
int height (Node *root) {
return (root) ? root->height : -1;
}
int getBalance (Node *root) {
return height(root->lt) - height(root->gt);
}
void updateHeight (Node *root) {
root->height = MAX(height(root->lt), height(root->gt)) + 1;
}
Node * rotateLeft (Node *root) {
Node *newRoot = root->gt, *child = newRoot->lt;
newRoot->lt = root;
root->gt = child;
updateHeight(root);
updateHeight(newRoot);
return newRoot;
}
Node * rotateRight (Node *root) {
Node *newRoot = root->lt, *child = newRoot->gt;
newRoot->gt = root;
root->lt = child;
updateHeight(root);
updateHeight(newRoot);
return newRoot;
}
Node * balanceTree (Node *root) {
int balance = getBalance(root);
/* Left heavy */
if (balance > 1) {
if (getBalance(root->lt) < 0)
root->lt = rotateLeft(root->lt);
return rotateRight(root);
}
/* Right heavy */
if (balance < -1) {
if (getBalance(root->gt) > 0)
root->gt = rotateRight(root->gt);
return rotateLeft(root);
}
updateHeight(root);
return root;
}
/* Node insertion */
Node * newNode(int key){
Node *new = malloc(sizeof(Node));
new->key = key;
new->height = 0;
new->lt = new->gt = NULL;
return new;
}
bool insertNode(Node **root, int key) {
Node **n;
if (!*root) {
*root = newNode(key);
return true;
}
if (key == (*root)->key)
return false;
n = (key < (*root)->key) ? &(*root)->lt : &(*root)->gt;
if (!insertNode(n, key))
return false;
*root = balanceTree(*root);
return true;
}
Node * read() {
int key;
char c;
Node *root = NULL;
while ((c = getchar()) != EOF && c != '\n' && scanf("%d", &key))
insertNode(&root, key);
return root;
}
/* Find next */
Node * nextKey (Node * root, int key) {
Node *n;
if (!root)
return root;
n = nextKey((key < root->key) ? root->lt : root->gt, key);
return (n && n->key > key) ? n : root;
}
/* Destroy tree after use */
void destroy (Node * root) {
if (root->lt)
destroy(root->lt);
if (root->gt)
destroy(root->gt);
free(root);
}
bool destroyTree (Node **root) {
if (!*root)
return false;
destroy(*root);
*root = NULL;
return true;
}
int main () {
int key;
Node *root;
printf("This program allows for the creation of a Binary Search Tree "
"(BST) and then finds the node with the smallest key that is greater than "
"a given number.\nType in a sequence of integers separated by space to be "
"added as keys in the BST and press ENTER to confirm:\n");
root = read();
printf("\nType in an integer to search for a key: ");
if (!scanf("%d", &key)) {
printf("Invalid input\n");
return 1;
}
printf("\nNext smallest key: %d\n", nextKey(root, key)->key);
destroyTree(&root);
}

View File

@ -0,0 +1,69 @@
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#define array int*
array readArray (int *size, int *max) {
int d, i = 0;
char c;
array A;
*max = 0;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf(" %d", &d))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
if (d > *max)
*max = d;
A[i++] = d;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
array cumulativeFrequency(array A, int size, int max) {
int i;
array frequency = calloc((max + 1), sizeof(int));
for (i = 0; i < size; i++)
frequency[A[i] + 1]++;
for (i = 1; i <= max; i++)
frequency[i] += frequency[i - 1];
return frequency;
}
void countingSort (array* A, int size, int max) {
int i;
array count = cumulativeFrequency(*A, size, max);
array sorted = malloc(size * sizeof(int));
for (i = 0; i < size; i++) {
sorted[count[(*A)[i]]] = (*A)[i];
count[(*A)[i]]++;
}
free(*A);
free(count);
*A = sorted;
}
int main () {
int i, size, max;
array A;
printf("Este programa admite uma lista de valores inteiros x tais que %d ≤ x ≤ %d e os ordena em ordem crescente.\nDigite uma série de valores inteiros separadas entre si por espaço e pressione ENTER:\n", 0, INT_MAX);
A = readArray(&size, &max);
countingSort(&A, size, max);
printf("Arranjo ordenado:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
free(A);
return 0;
}

View File

@ -0,0 +1,79 @@
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#define array int*
array readArray (int *size, int *max) {
int d, i = 0;
char c;
array A;
*max = 0;
*size = 1;
A = malloc(sizeof(int));
do {
if (!scanf(" %d", &d))
continue;
if (i == *size - 1) {
*size *= 2;
A = realloc(A, *size * sizeof(int));
}
if (d > *max)
*max = d;
A[i++] = d;
} while ((c = getchar()) != EOF && c != '\n');
*size = i;
return A;
}
array cumulativeFrequency(array A, int size, int exp) {
int i, radix;
array frequency = calloc(11, sizeof(int));
for (i = 0; i < size; i++) {
radix = A[i] / exp % 10;
frequency[radix + 1]++;
}
for (i = 1; i <= 10; i++)
frequency[i] += frequency[i - 1];
return frequency;
}
void countingSort (array *A, int size, int exp) {
int i, radix;
array count = cumulativeFrequency(*A, size, exp);
array sorted = malloc(size * sizeof(int));
for (i = 0; i < size; i++) {
radix = (*A)[i] / exp % 10;
sorted[count[radix]] = (*A)[i];
count[radix]++;
}
free(*A);
free(count);
*A = sorted;
}
void radixSort(array *A, int size, int max) {
int exp;
for (exp = 1; max / exp > 0; exp *= 10)
countingSort(A, size, exp);
}
int main () {
int i, size, max;
array A;
printf("Este programa admite uma lista de valores inteiros x tais que %d ≤ x ≤ %d e os ordena em ordem crescente.\nDigite uma série de valores inteiros separadas entre si por espaço e pressione ENTER:\n", 0, INT_MAX);
A = readArray(&size, &max);
radixSort(&A, size, max);
printf("Arranjo ordenado:\n");
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
free(A);
return 0;
}

View File

@ -0,0 +1,70 @@
# Bytes, números e caracteres
## Exercícios 1
**1.** Mostre que todo número natural pode ser escrito em notação binária.
Por notação binária admitimos números compostos unicamente por dígitos 0 e 1, tal que o dígito 1 representa a ocorrência de uma distinta potência de 2 (a base, também denominada "base 2") em um somatório. Por exemplo:
$$
0101_2 \equiv 0 \times 2^3 + 1 \times 2^2 + 0 \times 2^1 + 1 \times 2^0 = 5_{10}
$$
Provemos por indução forte que para cada $n \in \mathbb N$ é possível sua representação em forma binária.
1. Base de indução
$0_2 = 0 \times 2^0 \equiv 0$ e $1 = 1 \times 2^0 \equiv 1_{10}$.
2. Hipótese de indução
Sejam $n, m \in \mathbb N$, $0 \le m < n$ números naturais que, tais quais aqueles em nossa base de indução, podem ser representados por números binários. Se $n$ pode ser representado enquanto número binário, $n + 1$ também deve poder.
3. Passo de indução
O número $n + 1$ pode ser par ou ímpar e, portanto, pode ser representado enquanto $2m$ ou $2m + 1$. Sabemos que $m$ é um número da forma $1 \times 2^k + \dots + 1 \times 2^0$ ou $1 \times 2^k + \dots + 0 \times 2^0$, $k \in \mathbb N$. Logo,
- se $n = 2m$: $n = 1 \times 2^{k + 1} + \dots + 1 \times 2^1 + 0 \times 2^0$, ou $n = 1 \times 2^{k + 1} + \dots + 0 \times 2^1 + 0 \times 2^0$, um número passível de representação binária. $\square$
- se $n = 2m + 1$: $n = 1 \times 2^{k + 1} + \dots + 1 \times 2^1 + 1 \times 2^0$, ou $n = 1 \times 2^{k + 1} + \dots + 0 \times 2^1 + 1 \times 2^0$, outro número passível de representação binária. $\blacksquare$
**2.** Mostre que $2^k + 2^{k 1} + \dots + 2^1 + 2^0 = 2^{k + 1} 1$, qualquer que seja o número natural $k$.
1. Base de indução
Seja $k = 0$, então:
$\displaystyle \sum^k_{i = 0} 2^i = \sum^0_{i = 0} 2^i = 2^0 = 1 = 2^1 - 1$
2. Hipótese de indução:
Se $\displaystyle \sum^k_{i = 0} 2^i = 2^{k + 1} - 1$ para todo $k \in \mathbb N$, então também $\displaystyle \sum^{k + 1}_{i = 0} 2^i = 2^{k + 2} - 1$.
3. Passo de indução:
$\displaystyle \sum^{k + 1}_{i = 0} 2^i = \sum^k_{i = 0} 2^i + 2^{k + 1} = 2^{k + 1} - 1 + 2^{k + 1} = 2 \cdot 2^{k + 1} - 1 = 2^{k + 2} - 1\ \blacksquare$
**3.** Escreva os números $2^8$, $2^8 1$, $2^{16}$, $2^{16} 1$, $2^{32}$ e $2^{32} 1$ em notação hexadecimal.
São os dígitos da base hexadecimal: 0 1 2 3 4 5 6 7 8 9 A B C D E F
- $2^8_{10} \equiv 10_{16}$
- $(2^8 - 1) \equiv \text F_{16}$
- $2^{16}_{10} \equiv 100_{16}$
- $(2^{16} - 1)_{10} \equiv \text{FF}_{16}$
- $2^{32}_{10} \equiv 1000_{16}$
- $(2^{32} - 1)_{10} \equiv \text{FFF}_{16}$
## Exercícios 2
**1.** Complemento de $n$.  Mostramos acima como a notação complemento-de-dois transforma em um inteiro negativo qualquer sequência de $s$ bytes que começa com um bit 1. Agora considere a operação inversa. Dado um inteiro n no intervalo $2^{8s1}\dots1$, mostre que a sequência de $s$ bytes que representa $n$ em notação complemento-de-dois é a mesma sequência de bytes que representa $n + 2^{8s}$ em notação binária.
Seja $n$ um número inteiro negativo equivalente à $-m$. O número $m$ em notação binária de complemento-de-dois tem seu negativo com representação equivalente àquela de $m - 2^{8s}$. Logo, tem-se que:
$$
m_2 \equiv (m - 2^{8s}) \stackrel{\times -1}{\implies}
(-m)_2 \equiv (-m + 2^{8s}) \stackrel{n\ =\ -m}{\implies}
n_2 \equiv (n + 2^{8s})_2\ \blacksquare
$$
**2.** Complemento-de-dois.  A notação complemento-de-dois transforma qualquer sequência de $s$ bytes que começa com um bit 1 em um inteiro negativo. Agora considere a operação inversa. Suponha que $n$ é um inteiro no intervalo $2^{8s1}\dots1$. Tome a sequência de bits que representa o valor absoluto de $n$ em notação binária, complemente todos os bits (ou seja, toque 0 por 1 e 1 por 0), e some 1, em binário, ao resultado. Mostre que essa operação produz a sequência de $s$ bits que representa n em notação complemento-de-dois.

View File

@ -0,0 +1,19 @@
#include <stdio.h>
#include <stdlib.h>
#include "headers.h"
int main () {
char * bin = NULL;
printf("Este programa lê um número natural em notação binária e o converte em notação hexadecimal. Digite uma série de uns e zeros, separados ou não entre si por espaços, e pressione ENTER para realizar a conversão:\n");
switch (readBin(&bin)) {
case EOF:
printf("Valor inválido detectado\n");
case 0:
return 1;
}
printf("\nNotação hexadecimal: 0x%s\n", toHex(bin));
return 0;
}

View File

@ -0,0 +1,65 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int digit;
struct node *next;
} Node;
Node *binary(Node *stack, int dec) {
Node *n = malloc(sizeof(Node));
n->digit = dec % 2;
n->next = stack;
return (dec == 0) ? n : binary(n, dec / 2);
}
bool twoComplement(Node *stack) {
if (!stack)
return false;
stack->digit = (stack->digit == 0) ? 1 : 0;
/* "false" indicates the recursive binary sum hasn't completed */
if (!twoComplement(stack->next)) {
if (stack->digit == 1) {
stack->digit = 0;
return false;
}
stack->digit = 1;
}
return true;
}
Node *base2(int dec) {
Node *stack = binary(NULL, abs(dec));
if (dec < 0)
twoComplement(stack);
return stack;
}
void printStack(Node *stack) {
if (!stack)
printf("\n");
else {
printf("%d", stack->digit);
printStack(stack->next);
}
}
int main() {
int dec;
printf("This program reads an integer number and converts it to its "
"equivalent binary number using the two's complement model.\nType "
"in a number: ");
if (!scanf("%d", &dec)) {
printf("Invalid input.\n");
return 1;
}
printf("Binary equivalent: ");
printStack(base2(dec));
return 0;
}