From: Lukáš Jiřiště Date: Thu, 7 Dec 2023 09:30:28 +0000 (+0100) Subject: Add solution to second part of day 7. X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=19d5c672c607f9444d10e8ac79f7e9104af780ea;p=AoC_2023.git Add solution to second part of day 7. --- diff --git a/7/7b.c b/7/7b.c new file mode 100644 index 0000000..4c26f09 --- /dev/null +++ b/7/7b.c @@ -0,0 +1,245 @@ + +#include +#include +#include +#include "libft.h" + +#define HAND_SIZE 5 + +enum e_card +{ + joker, + two, + three, + four, + five, + six, + seven, + eight, + nine, + ten, + queen, + king, + ace, + unknown, +}; +typedef enum e_card t_card; + +enum e_type +{ + high_card, + one_pair, + two_pair, + three_ok, + full_house, + four_ok, + five_ok, +}; +typedef enum e_type t_type; + +struct s_hand +{ + t_card cards[5]; + int bid; +}; +typedef struct s_hand t_hand; + +t_card c_to_card(char c) +{ + if (ft_isdigit(c)) + return (two + c - '2'); + if (c == 'T') + return (ten); + if (c == 'J') + return (joker); + if (c == 'Q') + return (queen); + if (c == 'K') + return (king); + if (c == 'A') + return (ace); + return (unknown); +} + +t_hand *parse(const char *str) +{ + t_hand *hand; + size_t i; + + i = 0; + hand = malloc(sizeof(t_hand)); + if (!hand) + return (hand); + while (i < HAND_SIZE) + { + hand->cards[i] = c_to_card(str[i]); + ++i; + } + hand->bid = ft_atoi(str + HAND_SIZE); + return (hand); +} + +t_type counts_to_type(size_t counts[HAND_SIZE], t_card cards[HAND_SIZE]) +{ + size_t i; + size_t jokers; + size_t max; + size_t max_ind; + + i = 0; + jokers = 0; + max = 0; + max_ind = 0; + while (i < HAND_SIZE) + { + if (cards[i] == joker) + jokers = counts[i]; + else if(max < counts[i]) + { + max = counts[i]; + max_ind = i; + } + ++i; + } + counts[max_ind] += jokers; + max += jokers; + if (max == 5) + return (five_ok); + if (max == 4) + return (four_ok); + i = 0; + if (max == 3) + { + while (i < HAND_SIZE) + { + if (counts[i] == 2 && cards[i] != joker) + return (full_house); + ++i; + } + return (three_ok); + } + if (max == 2) + { + while (i < HAND_SIZE) + if (counts[i++] == 2) + while (i < HAND_SIZE) + if (counts[i++] == 2) + return (two_pair); + return (one_pair); + } + return (high_card); +} + +t_type type(t_hand *hand) +{ + t_card cards[HAND_SIZE]; + size_t counts[HAND_SIZE]; + size_t i; + size_t j; + + i = 0; + while (i < HAND_SIZE) + { + cards[i] = unknown; + counts[i] = 0; + ++i; + } + i = 0; + while (i < HAND_SIZE) + { + j = 0; + while (j < HAND_SIZE) + { + if (hand->cards[i] == cards[j] || cards[j] == unknown) + { + cards[j] = hand->cards[i]; + ++counts[j]; + break; + } + ++j; + } + ++i; + } + return (counts_to_type(counts, cards)); +} + +int compare_hand(t_hand *first, t_hand *second) +{ + size_t i; + + if (type(first) != type(second)) + return (type(first) - type(second)); + i = 0; + while (first->cards[i] == second->cards[i]) + ++i; + return (first->cards[i] - second->cards[i]); +} + +void hand_to_str(char *str, t_hand *hand) +{ + size_t i; + char c; + + i = 0; + while (i < HAND_SIZE) + { + c = '2'; + while (c < 'Z') + { + if (c_to_card(c) == hand->cards[i]) + { + str[i] = c; + break; + } + ++c; + } + ++i; + } + return ; +} + +int total_winnings(t_list *games) +{ + size_t rank; + int result; + char str[5]; + + rank = 1; + result = 0; + while (games) + { + hand_to_str(str, games->content); + ft_printf("Hand %.5s has rank %u, bid %i and type %i.\n", str, rank, ((t_hand *)(games->content))->bid, type((t_hand *)(games->content))); + result += rank * ((t_hand *)(games->content))->bid; + games = games->next; + ++rank; + } + return (result); +} + +int main(int argc, char **argv) +{ + int fd; + t_list *list; + t_list *new; + char *line; + + fd = open(argv[1], O_RDONLY); + if (fd < 0) + return (2); + line = get_next_line(fd); + list = NULL; + while (line) + { + new = ft_lstnew(parse(line)); + if (!new) + return (3); + ft_lst_sorted_insert(&list, new, compare_hand); + free(line); + line = get_next_line(fd); + } + ft_printf("The total winnings are %i.\n", total_winnings(list)); + close(fd); + ft_lstclear(&list, free); + return (0); +}