leet-code/max-sum-pair/maxSumPair.c
2025-02-13 20:36:18 -06:00

150 lines
3.1 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* 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;
}