]> Untitled Git - axy/ft/pushswap.git/commitdiff
Moved algorithms and fixed norm
author= <=>
Tue, 16 Dec 2025 13:56:30 +0000 (14:56 +0100)
committer= <=>
Tue, 16 Dec 2025 13:56:30 +0000 (14:56 +0100)
12 files changed:
Makefile
algorithm_complex.c [new file with mode: 0644]
algorithm_quicksort.c [deleted file]
algorithm_simple.c [moved from algorithm_selection_sort.c with 89% similarity]
algorithm_splitsort.c [deleted file]
main_pushswap.c
pushswap.h
splitsort.c [new file with mode: 0644]
splitsort.h
splitsort_final.c [new file with mode: 0644]
splitsort_iter.c
splitsort_part.c [new file with mode: 0644]

index 2d5cfc52a3485e8f75a2d08a492054eca2ffc1a2..f90e9ea3664963a3d0d151eeea658c7bf050f3e7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 NAME=push_swap
 
-SRCS=algorithm_leafsort.c algorithm_quicksort.c algorithm_selection_sort.c algorithm_splitsort.c cheatalloc.c clist.c closure.c leaf_sort.c leaf_sort_index.c leaf_sort_parse.c list.c main_pushswap.c op_output.c op_p.c op_parse.c op_r.c op_rr.c op_s.c ops.c ops_groups.c ops_optimizer.c output.c psval.c slice.c stack.c stacks.c stacks_get.c
+SRCS=algorithm_complex.c algorithm_leafsort.c algorithm_simple.c cheatalloc.c clist.c closure.c leaf_sort.c leaf_sort_index.c leaf_sort_parse.c list.c main_pushswap.c op_output.c op_p.c op_parse.c op_r.c op_rr.c op_s.c ops.c ops_groups.c ops_optimizer.c output.c psval.c slice.c splitsort.c splitsort_final.c splitsort_iter.c splitsort_part.c stack.c stacks.c stacks_get.c
 
 RESSRCS=_res_leaf_sort_lookup.h
 
diff --git a/algorithm_complex.c b/algorithm_complex.c
new file mode 100644 (file)
index 0000000..f19f357
--- /dev/null
@@ -0,0 +1,18 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   algorithm_complex.c                                :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/12/16 14:52:06 by agilliar          #+#    #+#             */
+/*   Updated: 2025/12/16 14:55:13 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "pushswap.h"
+
+void   algorithm_complex(const t_stacks *stacks, t_closure cb)
+{
+       splitsort(stacks, cb, 5);
+}
diff --git a/algorithm_quicksort.c b/algorithm_quicksort.c
deleted file mode 100644 (file)
index 377c0a3..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/* ************************************************************************** */
-/*                                                                            */
-/*                                                        :::      ::::::::   */
-/*   algorithm_quicksort.c                              :+:      :+:    :+:   */
-/*                                                    +:+ +:+         +:+     */
-/*   By: agilliar <marvin@42.fr>                    +#+  +:+       +#+        */
-/*                                                +#+#+#+#+#+   +#+           */
-/*   Created: 2025/12/05 19:07:14 by agilliar          #+#    #+#             */
-/*   Updated: 2025/12/11 01:12:14 by agilliar         ###   ########.fr       */
-/*                                                                            */
-/* ************************************************************************** */
-
-#include "pushswap.h"
-
-static void    quicksort_sift(const t_stacks *stacks, t_closure cb, t_list range)
-{
-       size_t  a;
-       size_t  b;
-       t_psval pivot;
-
-       a = 0;
-       b = 0;
-       pivot = range.ptr[range.len / 2];
-       while (a + b < range.len)
-       {
-               if (clist_get_at(stacks->a.list, 0) < pivot)
-               {
-                       a++;
-                       closure_call(cb, OP_RA);
-               }
-               else
-               {
-                       b++;
-                       closure_call(cb, OP_PB);
-               }
-       }
-}
-
-static void    quicksort_rec(const t_stacks *stacks, t_closure cb, t_list range)
-{
-       size_t  i;
-       size_t  pivot;
-
-       if (range.len == 2
-               && clist_get_at(stacks->a.list, 0) > clist_get_at(stacks->a.list, -1))
-               closure_call(cb, OP_SA);
-       if (range.len <= 2)
-               return ;
-       pivot = range.len / 2;
-       quicksort_sift(stacks, cb, range);
-       i = 0;
-       while (i++ < range.len - pivot)
-               closure_call(cb, OP_PA);
-       quicksort_rec(stacks, cb, list_sub(range, pivot, range.len));
-       i = 0;
-       while (i++ < pivot)
-               closure_call(cb, OP_RRA);
-       quicksort_rec(stacks, cb, list_sub(range, 0, pivot));
-}
-
-void   algorithm_quicksort(const t_stacks *stacks, t_closure cb)
-{
-       t_list  sorted;
-
-       sorted = list_new(stacks->a);
-       list_sort(sorted);
-       quicksort_rec(stacks, cb, sorted);
-}
similarity index 89%
rename from algorithm_selection_sort.c
rename to algorithm_simple.c
index d164d54561f868963baa30fa6e2160c22e44ecb7..887046f3ad4c03554b172891d9c93d685bcca9bd 100644 (file)
@@ -6,13 +6,13 @@
 /*   By: clefrere <clefrere@student.42.fr>          +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2025/12/09 15:43:09 by clefrere          #+#    #+#             */
-/*   Updated: 2025/12/11 01:12:26 by agilliar         ###   ########.fr       */
+/*   Updated: 2025/12/16 14:54:44 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "pushswap.h"
 
-void   algorithm_selection_sort(const t_stacks *stacks, t_closure cb)
+void   algorithm_simple(const t_stacks *stacks, t_closure cb)
 {
        t_list  sorted;
 
diff --git a/algorithm_splitsort.c b/algorithm_splitsort.c
deleted file mode 100644 (file)
index 236e3cb..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-/* ************************************************************************** */
-/*                                                                            */
-/*                                                        :::      ::::::::   */
-/*   algorithm_splitsort.c                              :+:      :+:    :+:   */
-/*                                                    +:+ +:+         +:+     */
-/*   By: agilliar <marvin@42.fr>                    +#+  +:+       +#+        */
-/*                                                +#+#+#+#+#+   +#+           */
-/*   Created: 2025/12/11 12:45:16 by agilliar          #+#    #+#             */
-/*   Updated: 2025/12/16 12:55:57 by agilliar         ###   ########.fr       */
-/*                                                                            */
-/* ************************************************************************** */
-
-#include "splitsort.h"
-
-static t_iter  iter_new(t_list range, size_t blocks, bool rev)
-{
-       t_iter  res;
-
-       if (blocks > range.len)
-               blocks = range.len;
-       res.range = range;
-       res.blocks = blocks;
-       res.rev = rev;
-       return (res);
-}
-
-static t_list  iter_next(t_iter *self)
-{
-       t_list  res;
-       size_t  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 bool    iter_nexti(t_iter *self, t_list *dst)
-{
-       *dst = iter_next(self);
-       return (dst->len != 0);
-}
-
-// 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)
-{
-       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);
-}
-
-static void    splitsort_part_once(t_part self, t_splitsort sort, size_t count)
-{
-       const t_stack   *src;
-       t_psval                 val;
-
-       src = stacks_geta(sort.stacks, self.mirror);
-       while (count--)
-       {
-               if (self.rev)
-                       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, 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, self.mirror);
-               else if (!self.rev)
-                       closure_callm(sort.cb, OP_RA, self.mirror);
-       }
-}
-
-static void    splitsort_part(t_splitsort sort, t_list range, t_mode mode)
-{
-       t_iter  topi;
-       t_iter  bottomi;
-       t_part  part;
-       size_t  top_count;
-
-       bottomi = iter_new(range, sort.blocks, mode == MODE_A);
-       topi = iter_splitoff(&bottomi, sort.blocks / 2);
-       bottomi.rev = mode == MODE_B;
-       topi.rev = !bottomi.rev;
-       top_count = 0;
-       part.mirror = mode == MODE_B;
-       part.rev = false;
-       while (iter_nexti(&topi, &part.top) | iter_nexti(&bottomi, &part.bottom))
-       {
-               splitsort_part_once(part, sort, range.len - top_count);
-               part.rev = !part.rev;
-               top_count += part.top.len;
-               range.len -= part.bottom.len;
-       }
-       while (mode != MODE_A_WRAP && top_count--)
-               closure_callm(sort.cb, OP_RRB, mode == MODE_B);
-}
-
-// Paritions b while also sorting the leaves of a
-void   splitsort_final_mixed(t_splitsort sort, t_list range)
-{
-       t_iter  iter;
-       t_part  part;
-
-       iter = iter_new(range, sort.blocks, true);
-       part.mirror = true;
-       part.rev = false;
-       while (iter_nexti(&iter, &part.bottom) | iter_nexti(&iter, &part.top))
-       {
-               splitsort_part_once(part, sort, range.len);
-               part.rev = !part.rev;
-               range.len -= part.bottom.len + part.top.len;
-               leaf_top_a_a(sort.stacks, sort.cb, part.bottom.len);
-               leaf_bot_a_a(sort.stacks, sort.cb, part.top.len);
-       }
-}
-
-void   splitsort_final_simple(t_splitsort sort, t_list range)
-{
-       leaf_top_b_a(sort.stacks, sort.cb, range.len);
-}
-
-// 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)
-{
-       splitsort_part(sort, range, MODE_A);
-}
-
-// 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)
-{
-       splitsort_part(sort, range, MODE_A_WRAP);
-}
-
-// 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)
-{
-       splitsort_part(sort, range, MODE_B);
-}
-
-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 (depth == 0)
-               return (&splitsort_part_a_wrap);
-       if (depth % 2 == 0)
-               return (&splitsort_part_a);
-       if (len <= state)
-               return (&splitsort_final_simple);
-       if (len <= state * blocks)
-               return (&splitsort_final_mixed);
-       return (&splitsort_part_b);
-}
-
-static void    splitsort_visit_layer(t_visit self, t_splitsort sort)
-{
-       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_part_layer(t_splitsort sort, t_list range, size_t depth)
-{
-       t_visit visit;
-
-       visit.range = range;
-       visit.depth = depth;
-       visit.cb = layer_from_info(depth, sort.blocks, range.len);
-       visit.rev = depth % 2 == 1;
-       splitsort_visit_layer(visit, sort);
-}
-
-void   test_splitsort(const t_stacks *stacks, t_closure cb)
-{
-       t_splitsort     sort;
-       t_list          range;
-       size_t          i;
-
-       sort.stacks = stacks;
-       sort.cb = cb;
-       sort.blocks = 5;
-       range = list_new(stacks->a);
-       list_sort(range);
-       i = 0;
-       while (!stacks_is_solved(stacks))
-               splitsort_part_layer(sort, range, i++);
-}
index f8028e4d52d7cd1edc009f12224924758d9bfb1d..b9c59bdbe76eed9f3ca225008e37657881f33105 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: clefrere <clefrere@student.42.fr>          +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2025/12/02 22:15:12 by agilliar          #+#    #+#             */
-/*   Updated: 2025/12/16 13:03:28 by agilliar         ###   ########.fr       */
+/*   Updated: 2025/12/16 14:55:34 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -22,22 +22,18 @@ static bool ft_streq(char *str1, char *str2)
        return (str1[i] == '\0' && str2[i] == '\0');
 }
 
-void   test_splitsort(const t_stacks *stacks, t_closure cb);
-
 static void    arg_step(char *str, t_args *arg)
 {
        if (ft_streq(str, "--simple"))
-               arg->algo = &algorithm_selection_sort;
+               arg->algo = &algorithm_simple;
        else if (ft_streq(str, "--medium"))
                arg->algo = NULL;
        else if (ft_streq(str, "--complex"))
-               arg->algo = &algorithm_quicksort;
+               arg->algo = &algorithm_complex;
        else if (ft_streq(str, "--adaptive"))
                arg->algo = NULL;
        else if (ft_streq(str, "--leaf"))
                arg->algo = &algorithm_leafsort;
-       else if (ft_streq(str, "--split"))
-               arg->algo = &test_splitsort;
        else if (ft_streq(str, "--bench"))
                arg->bench = true;
        else
index 8b42dbdfb4c0a30d34ebfa896475d73102ce21dd..16b06f1cbd5e1abbb718b54d495c80c78a180035 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: clefrere <clefrere@student.42.fr>          +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2025/12/02 11:02:44 by agilliar          #+#    #+#             */
-/*   Updated: 2025/12/15 20:28:36 by agilliar         ###   ########.fr       */
+/*   Updated: 2025/12/16 14:54:32 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -178,7 +178,10 @@ void                       leaf_bot_a_a(const t_stacks *stacks, t_closure cb,
 void                   leaf_top_b_a(const t_stacks *stacks, t_closure cb,
                                        size_t size);
 
-void                   algorithm_selection_sort(const t_stacks *stacks, t_closure cb);
-void                   algorithm_quicksort(const t_stacks *stacks, t_closure cb);
+void                   splitsort(const t_stacks *stacks, t_closure cb, size_t blocks);
+
+void                   algorithm_simple(const t_stacks *stacks, t_closure cb);
+void                   algorithm_complex(const t_stacks *stacks, t_closure cb);
 void                   algorithm_leafsort(const t_stacks *stacks, t_closure cb);
+
 #endif
diff --git a/splitsort.c b/splitsort.c
new file mode 100644 (file)
index 0000000..a614a54
--- /dev/null
@@ -0,0 +1,74 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   splitsort.c                                        :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/12/11 12:45:16 by agilliar          #+#    #+#             */
+/*   Updated: 2025/12/16 14:46:51 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "splitsort.h"
+
+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 (depth == 0)
+               return (&splitsort_part_a_wrap);
+       if (depth % 2 == 0)
+               return (&splitsort_part_a);
+       if (len <= state)
+               return (&splitsort_final_simple);
+       if (len <= state * blocks)
+               return (&splitsort_final_mixed);
+       return (&splitsort_part_b);
+}
+
+static void    splitsort_visit_layer(t_visit self, t_splitsort sort)
+{
+       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);
+}
+
+static void    splitsort_part_layer(t_splitsort sort, t_list range, size_t depth)
+{
+       t_visit visit;
+
+       visit.range = range;
+       visit.depth = depth;
+       visit.cb = layer_from_info(depth, sort.blocks, range.len);
+       visit.rev = depth % 2 == 1;
+       splitsort_visit_layer(visit, sort);
+}
+
+void   splitsort(const t_stacks *stacks, t_closure cb, size_t blocks)
+{
+       t_splitsort     sort;
+       t_list          range;
+       size_t          i;
+
+       sort.stacks = stacks;
+       sort.cb = cb;
+       sort.blocks = blocks;
+       if (blocks < 2)
+               cheatexit(1);
+       range = list_new(stacks->a);
+       list_sort(range);
+       i = 0;
+       while (!stacks_is_solved(stacks))
+               splitsort_part_layer(sort, range, i++);
+}
index 29d67b2ba40d70ead5cee10262b17f2b4ab7c8fb..44f0b46f03790640aaf0b767c4d281a8036c7a11 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2025/12/16 12:54:11 by agilliar          #+#    #+#             */
-/*   Updated: 2025/12/16 12:56:36 by agilliar         ###   ########.fr       */
+/*   Updated: 2025/12/16 14:49:37 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -54,4 +54,18 @@ typedef struct s_visit
        bool                    rev;
 }      t_visit;
 
+t_iter iter_new(t_list range, size_t blocks, bool rev);
+t_list iter_next(t_iter *self);
+bool   iter_nexti(t_iter *self, t_list *dst);
+t_iter iter_splitoff(t_iter *self, size_t n);
+
+void   splitsort_part_once(t_part self, t_splitsort sort, size_t count);
+void   splitsort_part(t_splitsort sort, t_list range, t_mode mode);
+void   splitsort_part_a(t_splitsort sort, t_list range);
+void   splitsort_part_a_wrap(t_splitsort sort, t_list range);
+void   splitsort_part_b(t_splitsort sort, t_list range);
+
+void   splitsort_final_mixed(t_splitsort sort, t_list range);
+void   splitsort_final_simple(t_splitsort sort, t_list range);
+
 #endif
diff --git a/splitsort_final.c b/splitsort_final.c
new file mode 100644 (file)
index 0000000..5b3d047
--- /dev/null
@@ -0,0 +1,37 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   splitsort_final.c                                  :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/12/16 14:43:59 by agilliar          #+#    #+#             */
+/*   Updated: 2025/12/16 14:51:41 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "splitsort.h"
+
+// Paritions b while also sorting the leaves of a
+void   splitsort_final_mixed(t_splitsort sort, t_list range)
+{
+       t_iter  iter;
+       t_part  part;
+
+       iter = iter_new(range, sort.blocks, true);
+       part.mirror = true;
+       part.rev = false;
+       while (iter_nexti(&iter, &part.bottom) | iter_nexti(&iter, &part.top))
+       {
+               splitsort_part_once(part, sort, range.len);
+               part.rev = !part.rev;
+               range.len -= part.bottom.len + part.top.len;
+               leaf_top_a_a(sort.stacks, sort.cb, part.bottom.len);
+               leaf_bot_a_a(sort.stacks, sort.cb, part.top.len);
+       }
+}
+
+void   splitsort_final_simple(t_splitsort sort, t_list range)
+{
+       leaf_top_b_a(sort.stacks, sort.cb, range.len);
+}
index 2b6e3458a4e4ba9434bf062e6fe1c8e7c7052e91..603fdf6d43cba15a0f7ffd3bd01f5ce49aadae42 100644 (file)
@@ -6,8 +6,65 @@
 /*   By: agilliar <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2025/12/16 12:57:22 by agilliar          #+#    #+#             */
-/*   Updated: 2025/12/16 12:57:29 by agilliar         ###   ########.fr       */
+/*   Updated: 2025/12/16 14:39:19 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "splitsort.h"
+
+t_iter iter_new(t_list range, size_t blocks, bool rev)
+{
+       t_iter  res;
+
+       if (blocks > range.len)
+               blocks = range.len;
+       res.range = range;
+       res.blocks = blocks;
+       res.rev = rev;
+       return (res);
+}
+
+t_list iter_next(t_iter *self)
+{
+       t_list  res;
+       size_t  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);
+}
+
+bool   iter_nexti(t_iter *self, t_list *dst)
+{
+       *dst = iter_next(self);
+       return (dst->len != 0);
+}
+
+// Takes the self iterator, skip n elements, and return an iterator which only
+// yields said elements
+t_iter iter_splitoff(t_iter *self, size_t n)
+{
+       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);
+}
diff --git a/splitsort_part.c b/splitsort_part.c
new file mode 100644 (file)
index 0000000..98e7b55
--- /dev/null
@@ -0,0 +1,82 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   splitsort_part.c                                   :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/12/16 14:42:51 by agilliar          #+#    #+#             */
+/*   Updated: 2025/12/16 14:44:49 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "splitsort.h"
+
+void   splitsort_part_once(t_part self, t_splitsort sort, size_t count)
+{
+       const t_stack   *src;
+       t_psval                 val;
+
+       src = stacks_geta(sort.stacks, self.mirror);
+       while (count--)
+       {
+               if (self.rev)
+                       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, 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, self.mirror);
+               else if (!self.rev)
+                       closure_callm(sort.cb, OP_RA, self.mirror);
+       }
+}
+
+void   splitsort_part(t_splitsort sort, t_list range, t_mode mode)
+{
+       t_iter  topi;
+       t_iter  bottomi;
+       t_part  part;
+       size_t  top_count;
+
+       bottomi = iter_new(range, sort.blocks, mode == MODE_A);
+       topi = iter_splitoff(&bottomi, sort.blocks / 2);
+       bottomi.rev = mode == MODE_B;
+       topi.rev = !bottomi.rev;
+       top_count = 0;
+       part.mirror = mode == MODE_B;
+       part.rev = false;
+       while (iter_nexti(&topi, &part.top) | iter_nexti(&bottomi, &part.bottom))
+       {
+               splitsort_part_once(part, sort, range.len - top_count);
+               part.rev = !part.rev;
+               top_count += part.top.len;
+               range.len -= part.bottom.len;
+       }
+       while (mode != MODE_A_WRAP && top_count--)
+               closure_callm(sort.cb, OP_RRB, mode == MODE_B);
+}
+
+// Parts range elements from stack a (which is in ascending order) onto stack b
+// in descending order
+void   splitsort_part_a(t_splitsort sort, t_list range)
+{
+       splitsort_part(sort, range, MODE_A);
+}
+
+// Parts range elements from stack a (which is in ascending order) onto stack b
+// in descending order, assuming that stack b is initially empty
+void   splitsort_part_a_wrap(t_splitsort sort, t_list range)
+{
+       splitsort_part(sort, range, MODE_A_WRAP);
+}
+
+// Parts range elements from stack b (which is in descending order) onto stack
+// a in ascending order
+void   splitsort_part_b(t_splitsort sort, t_list range)
+{
+       splitsort_part(sort, range, MODE_B);
+}