NAME=push_swap
-SRCS=algorithm_quicksort.c cheatalloc.c clist.c list.c main_pushswap.c ops.c ops_output.c ops_p.c ops_r.c ops_rr.c ops_s.c output.c psval.c stack.c stacks.c
+SRCS=algorithm_quicksort.c cheatalloc.c clist.c list.c main_pushswap.c op_output.c op_p.c op_r.c op_rr.c op_s.c ops.c ops_groups.c ops_optimizer.c output.c psval.c stack.c stacks.c
OBJS=${SRCS:%.c=${OBJDIR}/%.o}
fclean : clean
rm -f ${NAME}
- rmdir ${OBJDIR}
+ rm -fd ${OBJDIR}
re : fclean all
/* By: agilliar <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/12/05 19:07:14 by agilliar #+# #+# */
-/* Updated: 2025/12/08 14:02:02 by agilliar ### ########.fr */
+/* Updated: 2025/12/08 17:57:01 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
size_t i;
size_t pivot;
- if (range.len == 2
+ if (range.len == 2
&& clist_get_at(stacks->a.list, 0) > clist_get_at(stacks->a.list, -1))
(cb.func)(cb.data, OP_SA);
if (range.len <= 2)
/* By: agilliar <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/12/08 11:32:24 by agilliar #+# #+# */
-/* Updated: 2025/12/08 13:02:46 by agilliar ### ########.fr */
+/* Updated: 2025/12/08 17:57:16 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
res.ptr = cheatalloc(sizeof(t_psval) * stack.len);
res.len = stack.len;
i = 0;
- while(i < res.len)
+ while (i < res.len)
{
res.ptr[i++] = stack.list->val;
stack.list = stack.list->prev;
/* By: clefrere <clefrere@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/12/02 22:15:12 by agilliar #+# #+# */
-/* Updated: 2025/12/08 14:02:08 by agilliar ### ########.fr */
+/* Updated: 2025/12/08 20:22:37 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
return (str1[i] == '\0' && str2[i] == '\0');
}
-
static void arg_step(char *str, t_args *arg)
{
if (ft_streq(str, "--simple"))
int main(int argc, char **argv)
{
- t_args args;
- t_ops ops;
+ t_args args;
+ t_ops ops;
+ t_optimizer opt;
args.state = stacks_new();
args.bench = false;
args.algo = NULL;
for (int i = 1; i < argc; i++)
arg_step(argv[i], &args);
- ops = ops_init();
- ops_add_output(&ops);
+ ops = ops_compose(ops_stackops(), ops_optimizer(ops_output(), &opt));
stacks_apply(&args.state, &ops, args.algo);
+ ops_optimizer_commit(&opt, &args.state);
output_flush();
cheatexit(!stacks_is_solved(&args.state));
}
/* ************************************************************************** */
/* */
/* ::: :::::::: */
-/* ops_output.c :+: :+: :+: */
+/* op_output.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: agilliar <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/12/03 12:28:28 by agilliar #+# #+# */
-/* Updated: 2025/12/03 15:01:10 by agilliar ### ########.fr */
+/* Updated: 2025/12/08 18:40:54 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
#include "pushswap.h"
-static void ops_output_inner(const char *data, t_stack stack)
+static void op_output_inner(const char *data, t_stack *stack)
{
(void) stack;
output_str_ln(data);
}
-t_closure ops_output(t_op op)
+t_closure op_output(t_op op)
{
t_closure res;
static char *ops[11] = {
};
res.data = ops[op];
- res.func = &ops_output_inner;
+ res.func = &op_output_inner;
return (res);
}
/* ************************************************************************** */
/* */
/* ::: :::::::: */
-/* ops_p.c :+: :+: :+: */
+/* op_p.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: agilliar <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/12/03 13:20:25 by agilliar #+# #+# */
-/* Updated: 2025/12/08 12:49:35 by agilliar ### ########.fr */
+/* Updated: 2025/12/08 17:39:12 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
#include "pushswap.h"
-static void ops_pa_inner(void *data, t_stacks *stacks)
+static void op_pa_inner(void *data, t_stacks *stacks)
{
(void) data;
if (stacks->b.len)
stack_move(&stacks->b, &stacks->a);
}
-t_closure ops_pa(void)
+t_closure op_pa(void)
{
t_closure res;
res.data = NULL;
- res.func = &ops_pa_inner;
+ res.func = &op_pa_inner;
return (res);
}
-static void ops_pb_inner(void *data, t_stacks *stacks)
+static void op_pb_inner(void *data, t_stacks *stacks)
{
(void) data;
if (stacks->a.len)
stack_move(&stacks->a, &stacks->b);
}
-t_closure ops_pb(void)
+t_closure op_pb(void)
{
t_closure res;
res.data = NULL;
- res.func = &ops_pb_inner;
+ res.func = &op_pb_inner;
return (res);
}
/* ************************************************************************** */
/* */
/* ::: :::::::: */
-/* ops_r.c :+: :+: :+: */
+/* op_r.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: agilliar <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/12/03 13:15:06 by agilliar #+# #+# */
-/* Updated: 2025/12/03 13:17:00 by agilliar ### ########.fr */
+/* Updated: 2025/12/08 17:48:17 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
#include "pushswap.h"
-static void ops_ra_inner(void *data, t_stacks *stacks)
+static void op_ra_inner(void *data, t_stacks *stacks)
{
(void) data;
stack_rotate_n(&stacks->a, 1);
}
-t_closure ops_ra(void)
+t_closure op_ra(void)
{
t_closure res;
res.data = NULL;
- res.func = &ops_ra_inner;
+ res.func = &op_ra_inner;
return (res);
}
-static void ops_rb_inner(void *data, t_stacks *stacks)
+static void op_rb_inner(void *data, t_stacks *stacks)
{
(void) data;
stack_rotate_n(&stacks->b, 1);
}
-t_closure ops_rb(void)
+t_closure op_rb(void)
{
t_closure res;
res.data = NULL;
- res.func = &ops_rb_inner;
+ res.func = &op_rb_inner;
return (res);
}
-t_closure ops_rr(void)
+t_closure op_rr(void)
{
- return (ops_compose(ops_ra(), ops_rb()));
+ return (op_compose(op_ra(), op_rb()));
}
/* ************************************************************************** */
/* */
/* ::: :::::::: */
-/* ops_rr.c :+: :+: :+: */
+/* op_rr.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: agilliar <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/12/03 13:17:23 by agilliar #+# #+# */
-/* Updated: 2025/12/08 12:41:25 by agilliar ### ########.fr */
+/* Updated: 2025/12/08 17:48:23 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
#include "pushswap.h"
-static void ops_rra_inner(void *data, t_stacks *stacks)
+static void op_rra_inner(void *data, t_stacks *stacks)
{
(void) data;
stack_rotate_n(&stacks->a, -1);
}
-t_closure ops_rra(void)
+t_closure op_rra(void)
{
t_closure res;
res.data = NULL;
- res.func = &ops_rra_inner;
+ res.func = &op_rra_inner;
return (res);
}
-static void ops_rrb_inner(void *data, t_stacks *stacks)
+static void op_rrb_inner(void *data, t_stacks *stacks)
{
(void) data;
stack_rotate_n(&stacks->b, -1);
}
-t_closure ops_rrb(void)
+t_closure op_rrb(void)
{
t_closure res;
res.data = NULL;
- res.func = &ops_rrb_inner;
+ res.func = &op_rrb_inner;
return (res);
}
-t_closure ops_rrr(void)
+t_closure op_rrr(void)
{
- return (ops_compose(ops_rra(), ops_rrb()));
+ return (op_compose(op_rra(), op_rrb()));
}
/* ************************************************************************** */
/* */
/* ::: :::::::: */
-/* ops_s.c :+: :+: :+: */
+/* op_s.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: agilliar <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/12/03 12:28:28 by agilliar #+# #+# */
-/* Updated: 2025/12/03 13:14:52 by agilliar ### ########.fr */
+/* Updated: 2025/12/08 17:48:29 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
#include "pushswap.h"
-static void ops_sa_inner(void *data, t_stacks *stacks)
+static void op_sa_inner(void *data, t_stacks *stacks)
{
(void) data;
stack_swap_top(&stacks->a);
}
-t_closure ops_sa(void)
+t_closure op_sa(void)
{
t_closure res;
res.data = NULL;
- res.func = &ops_sa_inner;
+ res.func = &op_sa_inner;
return (res);
}
-static void ops_sb_inner(void *data, t_stacks *stacks)
+static void op_sb_inner(void *data, t_stacks *stacks)
{
(void) data;
stack_swap_top(&stacks->b);
}
-t_closure ops_sb(void)
+t_closure op_sb(void)
{
t_closure res;
res.data = NULL;
- res.func = &ops_sb_inner;
+ res.func = &op_sb_inner;
return (res);
}
-t_closure ops_ss(void)
+t_closure op_ss(void)
{
- return (ops_compose(ops_sa(), ops_sb()));
+ return (op_compose(op_sa(), op_sb()));
}
/* By: agilliar <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/12/03 10:57:30 by agilliar #+# #+# */
-/* Updated: 2025/12/03 15:07:01 by agilliar ### ########.fr */
+/* Updated: 2025/12/08 17:49:07 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
#include "pushswap.h"
#include "ops_inner.h"
-static void ops_compose_fn(t_ops_compose *data, t_stacks *stacks)
+static void op_compose_fn(t_op_compose *data, t_stacks *stacks)
{
(data->first.func)(data->first.data, stacks);
(data->second.func)(data->second.data, stacks);
}
-t_closure ops_compose(t_closure first, t_closure second)
+t_closure op_compose(t_closure first, t_closure second)
{
- t_ops_compose *data;
+ t_op_compose *data;
t_closure closure;
- data = cheatalloc(sizeof(t_ops_compose));
+ data = cheatalloc(sizeof(t_op_compose));
data->first = first;
data->second = second;
- closure.func = &ops_compose_fn;
+ closure.func = &op_compose_fn;
closure.data = data;
return (closure);
}
-t_ops ops_init(void)
+t_ops ops_compose(t_ops lhs, t_ops rhs)
{
- const t_ops res = {
- .ops = {
- ops_sa(),
- ops_sb(),
- ops_ss(),
- ops_pa(),
- ops_pb(),
- ops_ra(),
- ops_rb(),
- ops_rr(),
- ops_rra(),
- ops_rrb(),
- ops_rrr(),
- }
- };
+ t_ops res;
+ t_op op;
+ op = OP_SA;
+ while (op <= OP_RRR)
+ {
+ res.ops[op] = op_compose(lhs.ops[op], rhs.ops[op]);
+ op++;
+ }
return (res);
}
-void ops_add_output(t_ops *ops)
+t_ops ops_init(t_closure (*gen)(t_op))
{
+ t_ops res;
t_op op;
op = OP_SA;
while (op <= OP_RRR)
{
- ops->ops[op] = ops_compose(ops->ops[op], ops_output(op));
+ res.ops[op] = gen(op);
op++;
}
+ return (res);
}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ops_groups.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: agilliar <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2025/12/08 17:02:23 by agilliar #+# #+# */
+/* Updated: 2025/12/08 17:56:36 by agilliar ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "pushswap.h"
+
+t_ops ops_stackops(void)
+{
+ const t_ops ops = {
+ .ops = {
+ op_sa(),
+ op_sb(),
+ op_ss(),
+ op_pa(),
+ op_pb(),
+ op_ra(),
+ op_rb(),
+ op_rr(),
+ op_rra(),
+ op_rrb(),
+ op_rrr(),
+ },
+ };
+
+ return (ops);
+}
+
+t_ops ops_output(void)
+{
+ return (ops_init(op_output));
+}
/* By: agilliar <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/12/03 11:13:51 by agilliar #+# #+# */
-/* Updated: 2025/12/03 11:14:05 by agilliar ### ########.fr */
+/* Updated: 2025/12/08 17:48:52 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef OPS_INNER_H
# define OPS_INNER_H
-typedef struct s_ops_compose
+typedef struct s_op_compose
{
t_closure first;
t_closure second;
-} t_ops_compose;
+} t_op_compose;
#endif
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ops_optimizer.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: agilliar <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2025/12/08 17:54:20 by agilliar #+# #+# */
+/* Updated: 2025/12/08 20:20:59 by agilliar ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "pushswap.h"
+#include "ops_optimizer_inner.h"
+
+#include <stdio.h>
+
+static void op_optimizer_inner(t_op_optimizer *data, t_stacks *stacks)
+{
+ t_closure cb;
+
+ if (data->op == OP_RA || data->op == OP_RR)
+ data->opt->a++;
+ if (data->op == OP_RB || data->op == OP_RR)
+ data->opt->b++;
+ if (data->op == OP_RRA || data->op == OP_RRR)
+ data->opt->a--;
+ if (data->op == OP_RRB || data->op == OP_RRR)
+ data->opt->b--;
+ if (data->op == OP_SA || data->op == OP_SB || data->op == OP_SS
+ || data->op == OP_PA || data->op == OP_PB)
+ {
+ ops_optimizer_commit(data->opt, stacks);
+ cb = data->opt->commit.ops[data->op];
+ (cb.func)(cb.data, stacks);
+ }
+}
+
+static t_closure op_optimizer(t_optimizer *opt, t_op op)
+{
+ t_closure res;
+ t_op_optimizer *data;
+
+ data = cheatalloc(sizeof(t_op_optimizer));
+ data->op = op;
+ data->opt = opt;
+ res.data = data;
+ res.func = &op_optimizer_inner;
+ return (res);
+}
+
+t_ops ops_optimizer(t_ops commit, t_optimizer *data)
+{
+ t_ops res;
+ t_op op;
+
+ data->a = 0;
+ data->b = 0;
+ data->commit = commit;
+ op = OP_SA;
+ while (op <= OP_RRR)
+ {
+ res.ops[op] = op_optimizer(data, op);
+ op++;
+ }
+ return (res);
+}
+
+static void ops_optimizer_commit_end(t_optimizer *data, t_stacks *stacks)
+{
+ t_closure cb;
+ int64_t *counter;
+
+ cb = data->commit.ops[OP_RA];
+ if (data->b > 0)
+ cb = data->commit.ops[OP_RB];
+ if (data->a < 0)
+ cb = data->commit.ops[OP_RRA];
+ if (data->b < 0)
+ cb = data->commit.ops[OP_RRB];
+ counter = &data->a;
+ if (data->b != 0)
+ counter = &data->b;
+ if (*counter > 0)
+ *counter *= -1;
+ while (*counter != 0)
+ {
+ (cb.func)(cb.data, stacks);
+ (*counter)++;
+ }
+}
+
+void ops_optimizer_commit(t_optimizer *data, t_stacks *stacks)
+{
+ t_closure cb;
+
+ cb = data->commit.ops[OP_RR];
+ while (data->a > 0 && data->b > 0)
+ {
+ data->a--;
+ data->b--;
+ (cb.func)(cb.data, stacks);
+ }
+ cb = data->commit.ops[OP_RRR];
+ while (data->a < 0 && data->b < 0)
+ {
+ data->a++;
+ data->b++;
+ (cb.func)(cb.data, stacks);
+ }
+ ops_optimizer_commit_end(data, stacks);
+}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ops_optimizer_inner.h :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: agilliar <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2025/12/08 18:26:54 by agilliar #+# #+# */
+/* Updated: 2025/12/08 18:28:58 by agilliar ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#ifndef OPS_OPTIMIZER_INNER_H
+# define OPS_OPTIMIZER_INNER_H
+
+#include "pushswap.h"
+
+typedef struct s_op_optimizer
+{
+ t_optimizer *opt;
+ t_op op;
+} t_op_optimizer;
+
+#endif
/* By: agilliar <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/12/02 11:02:44 by agilliar #+# #+# */
-/* Updated: 2025/12/08 12:03:24 by agilliar ### ########.fr */
+/* Updated: 2025/12/08 20:14:33 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
# include <stdbool.h>
# include <stddef.h>
+# include <stdint.h>
typedef int t_psval;
t_psval *ptr;
} t_list;
+typedef struct s_optimizer
+{
+ int64_t a;
+ int64_t b;
+ t_ops commit;
+} t_optimizer;
+
void cheatexit(int errcode);
void *cheatalloc(size_t len);
t_psval psval_parse(const char *s);
void psval_output(t_psval val);
-t_closure ops_pa(void);
-t_closure ops_pb(void);
-t_closure ops_ra(void);
-t_closure ops_rb(void);
-t_closure ops_rr(void);
-t_closure ops_rra(void);
-t_closure ops_rrb(void);
-t_closure ops_rrr(void);
-t_closure ops_sa(void);
-t_closure ops_sb(void);
-t_closure ops_ss(void);
-
-t_closure ops_output(t_op op);
-
-t_closure ops_compose(t_closure first, t_closure second);
-t_ops ops_init(void);
-void ops_add_output(t_ops *ops);
+t_closure op_pa(void);
+t_closure op_pb(void);
+t_closure op_ra(void);
+t_closure op_rb(void);
+t_closure op_rr(void);
+t_closure op_rra(void);
+t_closure op_rrb(void);
+t_closure op_rrr(void);
+t_closure op_sa(void);
+t_closure op_sb(void);
+t_closure op_ss(void);
+
+t_closure op_output(t_op op);
+
+t_closure op_compose(t_closure first, t_closure second);
+t_ops ops_compose(t_ops lhs, t_ops rhs);
+t_ops ops_init(t_closure (*gen)(t_op));
+
+t_ops ops_stackops(void);
+t_ops ops_output(void);
+
+t_ops ops_optimizer(t_ops commit, t_optimizer *data);
+void ops_optimizer_commit(t_optimizer *data, t_stacks *stacks);
t_list list_new(t_stack stack);
t_list list_sub(t_list self, size_t start, size_t end);