#include #include #include /* Types */ typedef struct { int key, num; } HashMapEntry; typedef struct EntryList { HashMapEntry *entry; struct EntryList *next; } EntryList; typedef struct { int size; EntryList **entries; } HashMap; /* HashMapEntry functions */ HashMapEntry *makeHashMapEntry(int key, int num) { HashMapEntry *e = malloc(sizeof(HashMapEntry)); e->key = key; e->num = num; return e; } /* EntryList functions */ EntryList *makeEntryList(HashMapEntry *e) { EntryList *l = malloc(sizeof(EntryList)); l->entry = e; l->next = NULL; return l; } void freeEntryList(EntryList *l) { while (l != NULL) { EntryList *next = l->next; free(l->entry); free(l); l = next; } } void appendEntryList(EntryList *l, HashMapEntry *e) { while (l->next != NULL) l = l->next; l->next = makeEntryList(e); } /* HashMap functions */ int hashCode(HashMap *m, int key) { return ((unsigned int) key * 2654435761U) % m->size; } HashMap *makeHashMap(int size) { HashMap *m = malloc(sizeof(HashMap)); m->size = size; m->entries = malloc(size * sizeof(EntryList *)); for (int i = 0; i < size; i++) { m->entries[i] = NULL; } return m; } void putAt(HashMap *m, HashMapEntry *e, int index) { if (m->entries[index] == NULL) { m->entries[index] = makeEntryList(e); } else { appendEntryList(m->entries[index], e); } } void put(HashMap *m, int key, int num) { int hash = hashCode(m, key); HashMapEntry *e = makeHashMapEntry(key, num); putAt(m, e, hash); } HashMapEntry *get(HashMap *m, int key) { int hash = hashCode(m, key); EntryList *el = m->entries[hash]; while (el != NULL) { if (el->entry->key == key) { return el->entry; } else { el = el->next; } } return NULL; } void freeHashMap(HashMap *m) { for (int i = 0; i < m->size; i++) { freeEntryList(m->entries[i]); } free(m->entries); free(m); } /* Problem functions */ int addDigits(int num) { int sum = 0; while (num != 0) { sum += num % 10; num /= 10; } return sum; } int maximumSum(int* nums, int numsSize) { HashMap *m = makeHashMap(numsSize / 0.7); int maximum = 0; for (int i = 0; i < numsSize; i++) { int num = nums[i]; int added = addDigits(num); HashMapEntry *e = get(m, added); if (e != NULL) { int maybeMax = e->num + num; if (maybeMax > maximum) { maximum = maybeMax; } if (e->num < num) { e->num = num; } } else { put(m, added, num); } } freeHashMap(m); return maximum == 0 ? -1 : maximum; } /* main */ int main(int argc, char *argv[]) { int *nums = malloc((argc - 1) * sizeof(int)); for (int i = 1; i < argc; i++) { nums[i - 1] = atoi(argv[i]); } int result = maximumSum(nums, argc - 1); free(nums); printf("result: %i\n", result); return 0; }