]> Untitled Git - axy/ft/pushswap.git/commitdiff
Working splitsort, only needs slight tweaking!
authorAxy <gilliardmarthey.axel@gmail.com>
Sun, 14 Dec 2025 02:08:56 +0000 (03:08 +0100)
committerAxy <gilliardmarthey.axel@gmail.com>
Sun, 14 Dec 2025 02:08:56 +0000 (03:08 +0100)
_res_leaf_sort_lookup.h
algorithm_splitsort.c
leaf_sort.c
output.c
output_inner.h

index 365fde3cb1f47421a4e9c1e4281a129435c31959..487d7d628cf464f094e4250afb8b7dde4f4cc587 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2025/12/10 16:53:22 by agilliar          #+#    #+#             */
-/*   Updated: 2025/12/10 17:07:25 by agilliar         ###   ########.fr       */
+/*   Updated: 2025/12/12 13:22:56 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -19,32 +19,32 @@ ra ra ra
 ra sa ra ra
 sa ra ra ra
 pb sa ra pa ra ra
-pb sa ra ra pa ra
 sa ra sa ra ra
+pb sa ra ra pa ra
 ra ra ra ra
 ra ra sa ra ra
 ra sa ra ra ra
 ra pb sa ra pa ra ra
-ra pb sa ra ra pa ra
 ra sa ra sa ra ra
+ra pb sa ra ra pa ra
 sa ra ra ra ra
 sa ra ra sa ra ra
 pb sa ra pa ra ra ra
 pb pb sa ra pa pa ra ra ra
-pb pb ss ra pa ra ra pa ra
 sa pb sa ra ra ra pa ra
-pb sa ra ra pa ra ra
-pb pb sa ra pa ra pa ra ra
+pb pb ss ra pa ra ra pa ra
 sa ra sa ra ra ra
 pb ra sa ra pa ra ra
+pb sa ra ra pa ra ra
+pb pb sa ra pa ra pa ra ra
 pb sa ra sa ra pa ra ra
 pb pb sa ra ra pa pa ra ra
-pb pb sa ra pa ra ra pa ra
+pb ra ra ra pa ra
+pb ra sa ra ra pa ra
 pb sa ra ra ra pa ra
-pb pb sa ra ra pa ra pa ra
+pb pb sa ra pa ra ra pa ra
 pb sa ra sa ra ra pa ra
-pb ra sa ra ra pa ra
-pb ra ra ra pa ra
+pb pb sa ra ra pa ra pa ra
 
 pb
 sa pb pb
@@ -53,30 +53,30 @@ sa pb sa pb sb pb
 sa pb sa pb pb
 pb sa pb sb pb
 sa pb pb pb
-pb pb pb
 pb sa pb pb
+pb pb pb
 sa pb rr sa pb pb rrr pb
 sa pb rr pb pb rrr pb
 pb pb ss rb pb sb pb rrb
 sa pb sa pb ss pb pb
-pb rb pb pb pb rrb
 pb pb ss pb sb pb sb
+pb rb pb pb pb rrb
 pb rr sa pb pb rrr pb
 pb rr pb pb rrr pb
 sa pb pb rr pb sb rrr pb
 sa pb sa pb sb pb pb
-sa pb sa pb pb pb
 pb pb ss pb sb pb
-pb pb rr pb sb rrr pb
-pb sa pb sb pb pb
+sa pb sa pb pb pb
 pb sa pb rr pb sb rrr pb
 pb sa pb ss pb pb
+pb pb rr pb sb rrr pb
+pb sa pb sb pb pb
 pb pb ss pb pb
 sa pb pb pb pb
-pb sa pb pb pb
+pb sa pb sa pb sb pb
+pb sa pb sa pb pb
 pb pb sa pb sb pb
-pb pb pb pb
+pb sa pb pb pb
 pb pb sa pb pb
-pb sa pb sa pb pb
-pb sa pb sa pb sb pb
+pb pb pb pb
 */
index fdd84f40ae6807b658847a0a4266f6fced9f63ec..c34c645d6d6c8ae9d4041d5b44df46f43ef73ef2 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2025/12/11 12:45:16 by agilliar          #+#    #+#             */
-/*   Updated: 2025/12/12 00:07:33 by agilliar         ###   ########.fr       */
+/*   Updated: 2025/12/14 03:07:01 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -19,241 +19,259 @@ typedef struct s_splitsort
        size_t                  blocks;
 }      t_splitsort;
 
-// MODE_NORMAL: sort current elements in ascending order
-//  top < bottom
-//  top ascending
-//  bottom descending
-// MODE_REV: sort current elements in descending order
-//  top > bottom
-//  top descending
-//  bottom ascending
-// MODE_WRAP: sort current elements in descending order, without unwind
-//  top < bottom
-//  top descending
-//  bottom ascending
-typedef enum e_mode
-{
-       MODE_NORMAL,
-       MODE_REV,
-       MODE_WRAP,
-}      t_mode;
-
 typedef struct s_iter
 {
-       t_list  top;
-       t_list  bottom;
-       size_t  top_blocks;
-       size_t  bottom_blocks;
-       bool    top_rev;
-       bool    bottom_rev;
+       t_list  range;
+       size_t  blocks;
+       bool    rev;
 }      t_iter;
 
-static t_iter  splitsort_iter_new(t_splitsort sort, t_mode mode, t_list range)
+static t_iter  iter_new(t_list range, size_t blocks, bool rev)
 {
        t_iter  res;
-       size_t  top_len;
-       size_t  bottom_len;
-
-       if (sort.blocks == 0)
-               cheatexit(1);
-       res.top_blocks = sort.blocks / 2;
-       res.bottom_blocks = sort.blocks - res.top_blocks;
-       top_len = range.len * res.top_blocks / sort.blocks;
-       bottom_len = range.len - top_len;
-       if (mode == MODE_REV)
-               res.bottom = list_split(&range, bottom_len);
-       else
-               res.top = list_split(&range, top_len);
-       if (mode == MODE_REV)
-               res.top = range;
-       else
-               res.bottom = range;
-       res.top_rev = mode != MODE_NORMAL;
-       res.bottom_rev = mode == MODE_NORMAL;
+
+       res.range = range;
+       res.blocks = blocks;
+       res.rev = rev;
        return (res);
 }
 
-static t_list  splitsort_split_start(t_list *range, size_t blocks)
+static t_list  iter_next(t_iter *self)
 {
+       t_list  res;
        size_t  count;
 
-       count = 0;
-       if (blocks)
-               count = range->len / blocks + ((range->len % blocks) != 0);
-       return (list_split(range, count));
+       if (!self->blocks)
+               return (list_split(&self->range, 0));
+       count = self->range.len / self->blocks;
+       if (self->rev)
+       {
+               res = self->range;
+               self->range = list_split(&res, res.len - count);
+       }
+       else
+       {
+               if (self->range.len % self->blocks)
+                       count++;
+               res = list_split(&self->range, count);
+       }
+       self->blocks--;
+       return (res);
 }
 
-static t_list  splitsort_split_end(t_list *range, size_t blocks)
+static bool    iter_nexti(t_iter *self, t_list *dst)
 {
-       size_t  count;
-       t_list  res;
-
-       count = 0;
-       if (blocks)
-               count = range->len / blocks + ((range->len % blocks) != 0);
-       res = *range;
-       *range = list_split(&res, res.len - count);
-       return (res);
+       *dst = iter_next(self);
+       return (dst->len != 0);
 }
 
-static void    splitsort_iter_next(t_iter *self, t_list *top, t_list *bottom)
+// Takes the self iterator, skip n elements, and return an iterator which only
+// yields said elements
+static t_iter  iter_splitoff(t_iter *self, size_t n)
 {
-       if (self->top_rev)
-               *top = splitsort_split_end(&self->top, self->top_blocks);
-       else
-               *top = splitsort_split_start(&self->top, self->top_blocks);
-       if (self->bottom_rev)
-               *bottom = splitsort_split_end(&self->bottom, self->bottom_blocks);
-       else
-               *bottom = splitsort_split_start(&self->bottom, self->bottom_blocks);
-       if (self->top_blocks)
-               self->top_blocks--;
-       if (self->bottom_blocks)
-               self->bottom_blocks--;
+       t_iter  res;
+
+       res = *self;
+       while (n--)
+               iter_next(self);
+       res.range.len -= self->range.len;
+       res.blocks -= self->blocks;
+       if (res.rev)
+               res.range.ptr += self->range.len;
+       return (res);
 }
 
 typedef struct s_part
 {
-       t_mode  mode;
        t_list  top;
        t_list  bottom;
        bool    rev;
+       bool    mirror;
 }      t_part;
 
 static void    splitsort_part_once(t_part self, t_splitsort sort, size_t count)
 {
        const t_stack   *src;
-       bool                    mirror;
        t_psval                 val;
 
-       mirror = self.mode == MODE_NORMAL;
-       src = stacks_geta(sort.stacks, mirror);
+       src = stacks_geta(sort.stacks, self.mirror);
        while (count--)
        {
                if (self.rev)
-                       closure_callm(sort.cb, OP_RRA, mirror);
+                       closure_callm(sort.cb, OP_RRA, self.mirror);
                val = clist_get_at(src->list, 0);
                if (list_get_sorted(self.top, val) != -1)
                {
-                       closure_callm(sort.cb, OP_PB, mirror);
-                       closure_callm(sort.cb, OP_RB, mirror);
+                       closure_callm(sort.cb, OP_PB, self.mirror);
+                       closure_callm(sort.cb, OP_RB, self.mirror);
                }
                else if (list_get_sorted(self.bottom, val) != -1)
-                       closure_callm(sort.cb, OP_PB, mirror);
+                       closure_callm(sort.cb, OP_PB, self.mirror);
                else if (!self.rev)
-                       closure_callm(sort.cb, OP_RA, mirror);
+                       closure_callm(sort.cb, OP_RA, self.mirror);
        }
 }
 
-static void    splitsort_part(t_splitsort *sort, t_mode mode, t_list range)
+// Parts range elements from stack a (which is in ascending order) onto stack b
+// in descending order
+static void    splitsort_part_a(t_splitsort sort, t_list range)
 {
+       t_iter  topi;
+       t_iter  bottomi;
        t_part  part;
-       t_iter  iter;
        size_t  top_count;
        size_t  bottom_count;
 
-       part.mode = mode;
+       bottomi = iter_new(range, sort.blocks, true);
+       topi = iter_splitoff(&bottomi, sort.blocks / 2);
+       bottomi.rev = false;
+       top_count = 0;
+       bottom_count = 0;
        part.rev = false;
-       iter = splitsort_iter_new(*sort, mode, range);
+       part.mirror = false;
+       while (iter_nexti(&topi, &part.top) | iter_nexti(&bottomi, &part.bottom))
+       {
+               splitsort_part_once(part, sort, range.len - top_count - bottom_count);
+               part.rev = !part.rev;
+               top_count += part.top.len;
+               bottom_count += part.bottom.len;
+       }
+       while (top_count--)
+               closure_call(sort.cb, OP_RRB);
+}
+
+// Parts range elements from stack a (which is in ascending order) onto stack b
+// in descending order, assuming that stack b is initially empty
+static void    splitsort_part_a_wrap(t_splitsort sort, t_list range)
+{
+       t_iter  topi;
+       t_iter  bottomi;
+       t_part  part;
+       size_t  top_count;
+       size_t  bottom_count;
+
+       bottomi = iter_new(range, sort.blocks, false);
+       topi = iter_splitoff(&bottomi, sort.blocks / 2);
+       topi.rev = true;
        top_count = 0;
        bottom_count = 0;
-       while (splitsort_iter_next(&iter, &part.top, &part.bottom),
-               part.top.len || part.bottom.len)
+       part.rev = false;
+       part.mirror = false;
+       while (iter_nexti(&topi, &part.top) | iter_nexti(&bottomi, &part.bottom))
        {
-               splitsort_part_once(part, *sort, range.len - top_count - bottom_count);
-               part.rev = !part.rev && mode != MODE_WRAP;
+               splitsort_part_once(part, sort, range.len - top_count - bottom_count);
+               part.rev = !part.rev;
                top_count += part.top.len;
                bottom_count += part.bottom.len;
        }
-       while (mode != MODE_WRAP && top_count--)
-               closure_callm(sort->cb, OP_RRB, mode == MODE_NORMAL);
 }
 
-static void    splitsort_fortop(t_splitsort sort, t_mode mode,
-               t_list range, t_closure func)
+
+// Parts range elements from stack b (which is in descending order) onto stack
+// a in ascending order
+static void    splitsort_part_b(t_splitsort sort, t_list range)
 {
-       t_iter  iter;
-       t_list  top;
-       t_list  bottom;
+       t_iter  topi;
+       t_iter  bottomi;
+       t_part  part;
+       size_t  top_count;
+       size_t  bottom_count;
 
-       iter = splitsort_iter_new(sort, mode, range);
-       while (splitsort_iter_next(&iter, &top, &bottom), top.len)
-               (func.func)(func.data, top);
+       bottomi = iter_new(range, sort.blocks, false);
+       topi = iter_splitoff(&bottomi, sort.blocks / 2);
+       bottomi.rev = true;
+       top_count = 0;
+       bottom_count = 0;
+       part.rev = false;
+       part.mirror = true;
+       while (iter_nexti(&topi, &part.top) | iter_nexti(&bottomi, &part.bottom))
+       {
+               splitsort_part_once(part, sort, range.len - top_count - bottom_count);
+               part.rev = !part.rev;
+               top_count += part.top.len;
+               bottom_count += part.bottom.len;
+       }
+       while (top_count--)
+               closure_call(sort.cb, OP_RRA);
 }
 
-static void    splitsort_forbottom_rev(t_splitsort sort, t_mode mode,
-               t_list range, t_closure func)
+typedef void (t_layer_func) (t_splitsort, t_list);
+
+void   splitsort_leaf_a(t_splitsort sort, t_list range)
 {
-       t_iter  iter;
-       t_list  top;
-       t_list  bottom;
+               leaf_sort_local(sort.stacks, sort.cb, false, range.len);
+}
 
-       iter = splitsort_iter_new(sort, mode, range);
-       iter.bottom_rev ^= true;
-       while (splitsort_iter_next(&iter, &top, &bottom), bottom.len)
-               (func.func)(func.data, bottom);
+static void    splitsort_leaf_b(t_splitsort sort, t_list range)
+{
+               leaf_sort_other(sort.stacks, sort.cb, true, range.len);
+}
+
+static t_layer_func    *layer_from_info(size_t depth, size_t blocks, size_t len)
+{
+       size_t  i;
+       size_t  state;
+
+       i = 0;
+       state = 4;
+       while (i++ < depth)
+               state *= blocks;
+       if (len <= state)
+       {
+               if (depth % 2 == 0)
+                       return (&splitsort_leaf_a);
+               return (&splitsort_leaf_b);
+       }
+       if (depth == 0)
+               return (&splitsort_part_a_wrap);
+       if (depth % 2 == 0)
+               return (&splitsort_part_a);
+       return (&splitsort_part_b);
 }
 
 typedef struct s_visit
 {
-       t_splitsort     sort;
-       t_closure       callback;
-       size_t          depth;
-       t_mode          mode;
+       t_list                  range;
+       size_t                  depth;
+       t_layer_func    *cb;
+       bool                    rev;
 }      t_visit;
 
-static void    splitsort_visit_inner(t_visit *self, t_list range)
+static void    splitsort_visit_layer(t_visit self, t_splitsort sort)
 {
-       t_visit         subdata;
-       t_closure       subvisit;
-
-       if (self->depth == 0)
-               return ((self->callback.func)(self->callback.data, self->mode, range));
-       subdata = *self;
-       subdata.depth--;
-       if (subdata.mode == MODE_NORMAL)
-               subdata.mode = MODE_REV;
-       else
-               subdata.mode = MODE_NORMAL;
-       subvisit.data = &subdata;
-       subvisit.func = &splitsort_visit_inner;
-       if (self->mode != MODE_WRAP)
-               splitsort_fortop(self->sort, self->mode, range, subvisit);
-       splitsort_forbottom_rev(self->sort, self->mode, range, subvisit);
-       if (self->mode == MODE_WRAP)
-               splitsort_fortop(self->sort, self->mode, range, subvisit);
+       t_iter  iter;
+
+       if (self.depth == 0)
+       {
+               return (self.cb(sort, self.range));
+       }
+       self.depth--;
+       iter = iter_new(self.range, sort.blocks, self.rev);
+       while (iter_nexti(&iter, &self.range))
+               splitsort_visit_layer(self, sort);
 }
 
-void   splitsort_visit(t_splitsort sort, t_list range,
-               size_t depth, t_closure callback)
+void   splitsort_part_layer(t_splitsort sort, t_list range, size_t depth)
 {
        t_visit visit;
 
-       visit.sort = sort;
-       visit.callback = callback;
+       visit.range = range;
        visit.depth = depth;
-       visit.mode = MODE_WRAP;
-       splitsort_visit_inner(&visit, range);
+       visit.cb = layer_from_info(depth, sort.blocks, range.len);
+       visit.rev = depth % 2 == 1;
+       splitsort_visit_layer(visit, sort);
 }
 
-typedef struct s_layer
-{
-       t_splitsort sort;
-}      t_layer;
-
 void   test_splitsort(const t_stacks *stacks, t_closure cb)
 {
        t_splitsort     sort;
        t_list          range;
-       t_closure       part;
 
        sort.stacks = stacks;
        sort.cb = cb;
        sort.blocks = 5;
        range = list_new(stacks->a);
        list_sort(range);
-       part.func = &splitsort_part;
-       part.data = &sort;
-       for (size_t depth = 0; depth < 2; depth++)
-               splitsort_visit(sort, range, depth, part);
+       for (size_t i = 0; i < 4; i++)
+               splitsort_part_layer(sort, range, i);
 }
index 3abfc2c61faee3acee134cd3731b5d01db9178f2..2b5f58647b2c5a9534193237e29ca19008c7e7e6 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2025/12/11 00:27:32 by agilliar          #+#    #+#             */
-/*   Updated: 2025/12/11 17:21:30 by agilliar         ###   ########.fr       */
+/*   Updated: 2025/12/12 12:27:42 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
index 7239040e79fb8b8a49fc66ee1a65a98911b7a5d5..29bc7219c8b8cc44aa8aac61c68ecbf47afae3ef 100644 (file)
--- a/output.c
+++ b/output.c
@@ -6,7 +6,7 @@
 /*   By: agilliar <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2025/12/02 16:47:00 by agilliar          #+#    #+#             */
-/*   Updated: 2025/12/03 12:35:06 by agilliar         ###   ########.fr       */
+/*   Updated: 2025/12/12 00:36:01 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
index 6d327882027dbbd326f30014d411e952ecb404b8..9f23cd6e60d587162f7dd077c55ed1eeaab51af3 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2025/12/02 16:51:14 by agilliar          #+#    #+#             */
-/*   Updated: 2025/12/03 09:51:35 by agilliar         ###   ########.fr       */
+/*   Updated: 2025/12/12 00:39:57 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -14,7 +14,7 @@
 # define OUTPUT_INNER_H
 
 # ifndef OUTPUT_STORE_SIZE
-#  define OUTPUT_STORE_SIZE 1024
+#  define OUTPUT_STORE_SIZE 16384
 # endif
 # include <stddef.h>