Add solution to second part of day 7.
authorLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Thu, 7 Dec 2023 09:30:28 +0000 (10:30 +0100)
committerLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Thu, 7 Dec 2023 09:30:28 +0000 (10:30 +0100)
7/7b.c [new file with mode: 0644]

diff --git a/7/7b.c b/7/7b.c
new file mode 100644 (file)
index 0000000..4c26f09
--- /dev/null
+++ b/7/7b.c
@@ -0,0 +1,245 @@
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#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);
+}