Skip to content

Instantly share code, notes, and snippets.

@ThePhD

ThePhD/shit.c Secret

Last active August 29, 2015 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ThePhD/c9d2e8364c7a98bdca55 to your computer and use it in GitHub Desktop.
Save ThePhD/c9d2e8364c7a98bdca55 to your computer and use it in GitHub Desktop.
Only one more to go after this travesty.
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
// Singly-linked list node
// Use typedef to avoid `struct` spam everywhere
typedef struct Node_ {
int value;
struct Node_* next;
} Node;
bool contains(Node* list, int v) {
while (list != NULL) {
if (list->value == v)
return true;
list = list->next;
}
return false;
}
void clean(Node* list) {
while (list != NULL) {
// Save next node
Node* target = list->next;
// Blow up current node
free(list);
// Go to the saved next node
list = target;
// Continue until VOMIT
}
}
void print(Node* list) {
if (list == NULL) {
// No specification for what the empty list should look like...
// Just... null I guess?
printf("null");
}
while (list != NULL) {
printf("%d", list->value);
if (list->next != NULL) {
printf(", ");
}
list = list->next;
}
// Gets its own line
printf("\n");
}
Node* add(Node* list, Node n) {
Node* last = list;
if (list == NULL) {
list = malloc(sizeof(Node));
list->value = n.value;
list->next = n.next; // Should always be null, but you know. Just in case.
return list;
}
// If it's already inside the list...
if (contains(list, n.value)) {
// Leave early then
return list;
}
// Go to last node.
// TODO: technically, this is inefficient
// We cycle through the list twice:
// once to check if we have the value,
// once to check to get to the end
// perhaps merge the two together
// ... when you're not doing an exam, derp :v
while (last->next != NULL) {
last = last->next;
}
// Add to the last node
last->next = malloc(sizeof(Node));
last = last->next;
last->next = n.next;
last->value = n.value;
// And then return the full list
return list;
}
Node* intersect(Node* list1, Node* list2) {
Node* intersection = NULL;
Node* list2target = list2;
Node n = { 0, NULL };
if (list1 == NULL || list2 == NULL) {
// Nothing but emptiness
return NULL;
}
// For as long as we have elements to search the space for...
while (list2target != NULL) {
// If they share a value...
if (contains(list1, list2target->value)) {
// then add it to the list
// note that add will reject duplicate elements on principal, so this function will work just fine
// add also creates a new list if the list is null,
// so we can just use and re-use "intersection"
n.value = list2target->value;
n.next = NULL;
intersection = add(intersection, n);
}
list2target = list2target->next;
}
return intersection;
}
int main(int argc, char * const argv[]) {
// We don't need struct if we properly
// use typedef, like a smart library should
Node* list1 = NULL;
Node* list2 = NULL;
Node* list3 = NULL;
Node n = { 0, NULL };
int j = 0;
for (; j < 100; ++j) {
n.value = j;
n.next = NULL;
if ((j % 2) == 0) {
list1 = add(list1, n);
// Redundancy check: add it a second time, watch it fail.
list1 = add(list1, n);
}
if ((j % 3) == 0) {
list2 = add(list2, n);
// Redundancy check: add it a second time, watch it fail.
list2 = add(list2, n);
}
}
list3 = intersect(list1, list2);
print(list1);
print(list2);
print(list3);
// Not required, but proper cleanup is always nice.
clean(list1);
clean(list2);
clean(list3);
list1 = NULL;
list2 = NULL;
list3 = NULL;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment