From d3e84fa8d0ab41ba82dc93e77865fd61932bdcfd Mon Sep 17 00:00:00 2001 From: Jonathan Chan Date: Wed, 23 Dec 2020 01:41:25 -0800 Subject: [PATCH] Day 23: Attempt with C, but I don't think it's working... --- src/23.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 src/23.c diff --git a/src/23.c b/src/23.c new file mode 100644 index 0000000..3a70706 --- /dev/null +++ b/src/23.c @@ -0,0 +1,121 @@ +#include +#include +#include + +int CUPS = 1000000; +int MOVES = 10000000; + +struct link { + int cup; + struct link* next; +}; + +// Precondition: head is not NULL +void freeLoop(struct link* head) { + struct link* curr = head; + do { + struct link* next = curr->next; + free(curr); + curr = next; + } while (curr && curr != head); +} + +// Precondition: head is not NULL +void printLoop(struct link* head) { + struct link* curr = head; + do { + printf("%d", curr->cup); + curr = curr->next; + } while (curr && curr != head); + printf("\n"); +} + +// Builds a chain starting from the given link, +// with each subsequent link containing ints start to end +// Returns the last link in the chain +struct link* buildChain(struct link* curr, int start, int end) { + for (int i = start; i <= end; i++) { + struct link* next = malloc(sizeof(struct link)); + next->cup = i; + next->next = NULL; + curr->next = next; + curr = next; + } + return curr; +} + +// Builds a chain from the given ints in the array, +// setting the given link address to point to the first link +// Returns the last link in the chain +// Precondition: arr has at least one int +struct link* buildArrayChain(struct link** head, int* arr, int length) { + *head = malloc(sizeof(struct link)); + struct link* curr = *head; + curr->cup = arr[0]; + for (int i = 1; i < length; i++) { + struct link* next = malloc(sizeof(struct link)); + next->cup = arr[i]; + next->next = NULL; + curr->next = next; + curr = next; + } + return curr; +} + +// Returns the link in the chain with the given cup +// Precondition: The cup must exist in the chain +struct link* findLink(struct link* curr, int cup) { + while (curr->cup != cup) { + curr = curr->next; + } + return curr; +} + +// Precondition: 1 <= cup <= CUPS +int prevCup(int cup) { + if (cup == 1) { + return CUPS; + } else { + return cup - 1; + } +} + +struct link* move(struct link* head) { + struct link* firstLink = head->next; + struct link* secondLink = head->next->next; + struct link* thirdLink = head->next->next->next; + int first = firstLink->cup; + int second = secondLink->cup; + int third = thirdLink->cup; + head->next = thirdLink->next; + + int destCup = prevCup(head->cup); + while (destCup == first || destCup == second || destCup == third) { + destCup = prevCup(destCup); + } + + struct link* dest = findLink(head, destCup); + thirdLink->next = dest->next; + dest->next = firstLink; + return head->next; +} + +int main() { + int arr[9] = {3, 6, 2, 9, 8, 1, 7, 5, 4}; + int length = 9; + struct link* head; + struct link* tail = buildArrayChain(&head, arr, length); + tail = buildChain(tail, 10, 1000000); + tail->next = head; + printf("Loop has been built.\n"); + + for (int i = 0; i < MOVES; i++) { + head = move(head); + } + head = findLink(head, 1); + + int first = head->next->cup; + int second = head->next->next->cup; + printf("Product of two cups after cup 1 is %d * %d = %d\n", first, second, first * second); + freeLoop(head); +}