diff --git a/include/app/best_move.h b/include/app/best_move.h index 4ac62e9..d0e075b 100644 --- a/include/app/best_move.h +++ b/include/app/best_move.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/29 20:10:21 by maiboyer #+# #+# */ -/* Updated: 2024/01/29 20:28:35 by maiboyer ### ########.fr */ +/* Updated: 2024/01/31 14:10:08 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,28 +15,32 @@ #include "app/state.h" -enum e_stack_selector { +enum e_stack_selector +{ STACK_A, STACK_B, }; -enum e_zero_position { +enum e_zero_position +{ MIN_ZERO_POS, MAX_ZERO_POS, }; -struct s_functions { +struct s_functions +{ void (*forward)(void *); void (*reverse)(void *); }; -typedef struct s_best_move_args { +typedef struct s_best_move_args +{ enum e_stack_selector main_stack; enum e_zero_position zero_pos; - void *function_arguments; - struct s_functions main; - struct s_functions other; - struct s_functions both; + void *args; + struct s_functions main; + struct s_functions other; + struct s_functions both; } t_best_move_args; void run_func_with_best_rotate_for_item(t_state *state, t_usize index, diff --git a/include/app/best_move_inner.h b/include/app/best_move_inner.h index 4913278..3c419dc 100644 --- a/include/app/best_move_inner.h +++ b/include/app/best_move_inner.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/29 21:31:42 by maiboyer #+# #+# */ -/* Updated: 2024/01/29 21:50:15 by maiboyer ### ########.fr */ +/* Updated: 2024/01/31 14:12:25 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -38,31 +38,13 @@ typedef struct s_best_move_args_but_better } t_best_move_args_but_better; -static inline t_banana_func choose_rot(enum e_best_move_stack_selector ty, - t_best_move_args_but_better *data, - t_rotation *rot) +static inline t_banana_func choose_func(struct s_functions *funcs, + t_rotation rotate) { - if (ty == MAIN) - { - if (rot->direction == FORWARD) - return (data->data.main.forward); - else - return (data->data.main.reverse); - } - else if (ty == OTHER) - { - if (rot->direction == FORWARD) - return (data->data.other.forward); - else - return (data->data.other.reverse); - } - else if (ty == BOTH) - { - if (rot->direction == FORWARD) - return (data->data.both.forward); - else - return (data->data.both.reverse); - } + if (rotate.direction == FORWARD) + return (funcs->forward); + else if (rotate.direction == REVERSE) + return (funcs->reverse); return (NULL); } diff --git a/include/app/find_iter.h b/include/app/find_iter.h new file mode 100644 index 0000000..0f445c6 --- /dev/null +++ b/include/app/find_iter.h @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* find_iter.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/31 14:24:10 by maiboyer #+# #+# */ +/* Updated: 2024/01/31 14:24:47 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FIND_ITER_H +#define FIND_ITER_H + +#include "me/types.h" +#include "me/vec/vec_i64.h" + +t_usize min_iter_zero_pos(t_vec_i64 *vec); +t_usize max_iter_zero_pos(t_vec_i64 *vec); + +#endif /* FIND_ITER_H */ diff --git a/include/app/iter_state.h b/include/app/iter_state.h new file mode 100644 index 0000000..8eb554d --- /dev/null +++ b/include/app/iter_state.h @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* iter_state.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/31 14:19:06 by maiboyer #+# #+# */ +/* Updated: 2024/01/31 14:19:50 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef ITER_STATE_H +#define ITER_STATE_H + +#include "me/types.h" + +typedef struct s_iter_state +{ + t_usize pos; + t_i64 elem; +} t_iter_state; + +#endif /* ITER_STATE_H */ diff --git a/include/app/state.h b/include/app/state.h index 60c10eb..63c630a 100644 --- a/include/app/state.h +++ b/include/app/state.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/11 14:27:25 by maiboyer #+# #+# */ -/* Updated: 2024/01/29 22:15:52 by maiboyer ### ########.fr */ +/* Updated: 2024/01/31 15:09:44 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -27,4 +27,43 @@ typedef struct s_state t_state parses_arguments(t_usize count, t_str nums[]); void free_state(t_state state); +static inline void make_sorted_true_for_elem(t_state *s, t_i64 elem) +{ + t_usize i; + + i = 0; + while (i < s->sorted.len) + { + if (s->sorted.buffer[i].value == elem) + { + s->sorted.buffer[i].active = true; + return; + } + i++; + } +} + +static inline void make_sorted_true_from_stack(t_state *s, t_vec_i64 *stack) +{ + t_usize i; + + i = 0; + while (i < stack->len) + { + make_sorted_true_for_elem(s, stack->buffer[i++]); + } +} + +static inline void make_sorted_all_false(t_state *s) +{ + t_usize i; + + i = 0; + while (i < s->sorted.len) + { + s->sorted.buffer[i].active = false; + i++; + } +} + #endif /* STATE_H */ diff --git a/src.list b/src.list index 2572cb1..e6591e3 100644 --- a/src.list +++ b/src.list @@ -1,5 +1,7 @@ app/best_move -app/find_best_move_for +app/do_move +app/find_place +app/iter_find app/moves app/moves/push app/moves/rev_rotate diff --git a/src/app/best_move.c b/src/app/best_move.c index 4fce44a..c23fabc 100644 --- a/src/app/best_move.c +++ b/src/app/best_move.c @@ -6,12 +6,13 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/29 20:04:33 by maiboyer #+# #+# */ -/* Updated: 2024/01/29 22:41:28 by maiboyer ### ########.fr */ +/* Updated: 2024/01/31 14:25:00 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "app/best_move.h" #include "app/best_move_inner.h" +#include "app/find_iter.h" #include "app/find_place.h" #include "app/rotate.h" #include "app/state.h" @@ -19,9 +20,6 @@ #include "me/types.h" #include "me/vec/vec_i64.h" -t_usize min_iter_zero_pos(t_vec_i64 *vec); -t_usize max_iter_zero_pos(t_vec_i64 *vec); - static inline t_usize abs_diff(t_usize lhs, t_usize rhs) { if (lhs > rhs) @@ -65,8 +63,9 @@ static void run_func_with_best_rotate_for_item_inner( { t_usize other_size_len_min_1; t_usize target_index; - t_rotation rotate_main; - t_rotation rotate_other; + t_rotation main; + t_rotation other; + t_usize i; other_size_len_min_1 = data.other_stack->len; if (other_size_len_min_1 == 0) @@ -75,14 +74,35 @@ static void run_func_with_best_rotate_for_item_inner( (find_place(data.main_stack->buffer[index], state) + (data.other_stack->len - data.iter_func(data.other_stack))) % other_size_len_min_1; - rotate_main = target(0, index, data.main_stack->len); - rotate_other = target(target_index, 0, data.other_stack->len); + main = target(0, index, data.main_stack->len); + other = target(target_index, 0, data.other_stack->len); + find_least_move(&main, &other); + if (main.direction == other.direction) + { + i = 0; + while (i++ < min(main.value, other.value)) + choose_func(&data.data.both, main)(data.data.args); + i = 0; + if (main.value > other.value) + while (i++ < main.value - other.value) + choose_func(&data.data.main, main)(data.data.args); + else + while (i++ < other.value - main.value) + choose_func(&data.data.other, other)(data.data.args); + } + else + { + i = 0; + while (i++ < main.value) + choose_func(&data.data.main, main)(data.data.args); + i = 0; + while (i++ < other.value) + choose_func(&data.data.other, other)(data.data.args); + } } void run_func_with_best_rotate_for_item(t_state *state, t_usize index, t_best_move_args data) { - t_vec_i64 *main_stack; - t_vec_i64 *other_stack; t_best_move_args_but_better better_args; if (data.zero_pos == MIN_ZERO_POS) diff --git a/src/app/do_move.c b/src/app/do_move.c new file mode 100644 index 0000000..756123a --- /dev/null +++ b/src/app/do_move.c @@ -0,0 +1,70 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* do_move.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/31 14:25:57 by maiboyer #+# #+# */ +/* Updated: 2024/01/31 15:11:24 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/best_move.h" +#include "app/moves.h" +#include "app/state.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" + +void push_a(void *s); +void push_b(void *s); +void swap_a(void *s); +void swap_b(void *s); +void swap_both(void *s); +void rotate_a(void *s); +void rotate_b(void *s); +void rotate_both(void *s); +void rev_rotate_a(void *s); +void rev_rotate_b(void *s); +void rev_rotate_both(void *s); + +void do_sort_insert(t_state *state, t_usize index, + enum e_stack_selector move_from, + enum e_zero_position zero_pos) +{ + void (*pop_move)(void *); + t_vec_i64 *pushed_stack; + struct s_functions main; + struct s_functions other; + + if (move_from == STACK_A) + { + pushed_stack = &state->stack_b; + pop_move = push_b; + main.forward = rev_rotate_a; + main.reverse = rotate_a; + other.forward = rev_rotate_b; + other.reverse = rotate_b; + } + else + { + pushed_stack = &state->stack_a; + pop_move = push_a; + main.forward = rev_rotate_b; + main.reverse = rotate_b; + other.forward = rev_rotate_a; + other.reverse = rotate_a; + } + run_func_with_best_rotate_for_item( + state, index, + (t_best_move_args){ + .zero_pos = zero_pos, + .main_stack = move_from, + .args = state, + .both = {.forward = rev_rotate_both, .reverse = rotate_both}, + .main = main, + .other = other, + }); + (pop_move)(state); + make_sorted_true_for_elem(state, pushed_stack->buffer[0]); +} diff --git a/src/app/find_place.c b/src/app/find_place.c index 8df0be9..7636ac4 100644 --- a/src/app/find_place.c +++ b/src/app/find_place.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/29 22:01:12 by maiboyer #+# #+# */ -/* Updated: 2024/01/29 22:17:33 by maiboyer ### ########.fr */ +/* Updated: 2024/01/31 14:13:34 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,6 +17,7 @@ static void find_place_iter(t_usize index, t_i64_bool *elem, t_find_place_iter_state *state) { + (void)(index); if (!elem->active) return; if (elem->value == state->to_find_elem) diff --git a/src/app/iter_find.c b/src/app/iter_find.c new file mode 100644 index 0000000..474e9cc --- /dev/null +++ b/src/app/iter_find.c @@ -0,0 +1,57 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* iter_find.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/31 14:17:53 by maiboyer #+# #+# */ +/* Updated: 2024/01/31 14:23:26 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/iter_state.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" + +static void iter_min(t_usize index, t_i64 *elem, t_iter_state *state) +{ + if (*elem < state->elem) + { + state->elem = *elem; + state->pos = index; + } +} + +static void iter_max(t_usize index, t_i64 *elem, t_iter_state *state) +{ + if (*elem > state->elem) + { + state->elem = *elem; + state->pos = index; + } +} + +t_usize min_iter_zero_pos(t_vec_i64 *vec) +{ + t_iter_state state; + + if (vec->len == 0) + return (0); + state.pos = 0; + state.elem = vec->buffer[0]; + vec_i64_iter(vec, (void (*)())iter_min, &state); + return (state.pos); +} + +t_usize max_iter_zero_pos(t_vec_i64 *vec) +{ + t_iter_state state; + + if (vec->len == 0) + return (0); + state.pos = 0; + state.elem = vec->buffer[0]; + vec_i64_iter(vec, (void (*)())iter_max, &state); + return (state.pos); +} diff --git a/src/app/moves/rev_rotate.c b/src/app/moves/rev_rotate.c index e83cba7..29ae711 100644 --- a/src/app/moves/rev_rotate.c +++ b/src/app/moves/rev_rotate.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/11 16:26:04 by maiboyer #+# #+# */ -/* Updated: 2024/01/29 18:56:05 by maiboyer ### ########.fr */ +/* Updated: 2024/01/31 14:57:21 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -33,3 +33,9 @@ void rev_rotate_b(t_state *s) { rev_rotate_inner(&s->stack_b, "RevRotate B"); } + +void rev_rotate_both(t_state *s) +{ + rev_rotate_inner(&s->stack_a, "RevRotate Both"); + rev_rotate_inner(&s->stack_b, "RevRotate Both"); +} diff --git a/src/app/moves/rotate.c b/src/app/moves/rotate.c index 83a569b..23cb016 100644 --- a/src/app/moves/rotate.c +++ b/src/app/moves/rotate.c @@ -6,30 +6,35 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/11 16:26:04 by maiboyer #+# #+# */ -/* Updated: 2024/01/11 17:31:20 by maiboyer ### ########.fr */ +/* Updated: 2024/01/31 14:58:10 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ - #include "app/state.h" -static inline void rotate_inner(t_vec_i64 *stack, t_const_str tag) +static inline void rotate_inner(t_vec_i64 *stack, t_const_str tag) { - t_i64 e; + t_i64 e; (void)(tag); if (stack->len <= 1) - return ; + return; vec_i64_pop(stack, &e); vec_i64_push_front(stack, e); } -void rotate_a(t_state *s) +void rotate_a(t_state *s) { rotate_inner(&s->stack_a, "Rotate A"); } -void rotate_b(t_state *s) +void rotate_b(t_state *s) { rotate_inner(&s->stack_b, "Rotate B"); } + +void rotate_both(t_state *s) +{ + rotate_inner(&s->stack_a, "Rotate Both"); + rotate_inner(&s->stack_b, "Rotate Both"); +} diff --git a/src/app/moves/swap.c b/src/app/moves/swap.c index f9029c1..416abd7 100644 --- a/src/app/moves/swap.c +++ b/src/app/moves/swap.c @@ -6,34 +6,39 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/11 16:26:04 by maiboyer #+# #+# */ -/* Updated: 2024/01/11 17:56:12 by maiboyer ### ########.fr */ +/* Updated: 2024/01/31 14:58:32 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ - #include "app/state.h" #include "me/vec/vec_i64.h" -static inline void swap_inner(t_vec_i64 *stack, t_const_str tag) +static inline void swap_inner(t_vec_i64 *stack, t_const_str tag) { - t_i64 first; - t_i64 second; + t_i64 first; + t_i64 second; (void)(tag); if (stack->len <= 1) - return ; + return; vec_i64_pop(stack, &first); vec_i64_pop(stack, &second); vec_i64_push(stack, first); vec_i64_push(stack, second); } -void swap_a(t_state *s) +void swap_a(t_state *s) { swap_inner(&s->stack_a, "Swap A"); } -void swap_b(t_state *s) +void swap_b(t_state *s) { swap_inner(&s->stack_b, "Swap B"); } + +void swap_both(t_state *s) +{ + swap_inner(&s->stack_a, "Swap Both"); + swap_inner(&s->stack_b, "Swap Both"); +} diff --git a/src/app/run_with_items.c b/src/app/run_with_items.c new file mode 100644 index 0000000..aff138b --- /dev/null +++ b/src/app/run_with_items.c @@ -0,0 +1,116 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* run_with_items.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/31 15:12:47 by maiboyer #+# #+# */ +/* Updated: 2024/01/31 15:41:41 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/best_move.h" +#include "app/state.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" + +void push_a(void *s); +void push_b(void *s); +void swap_a(void *s); +void swap_b(void *s); +void swap_both(void *s); +void rotate_a(void *s); +void rotate_b(void *s); +void rotate_both(void *s); +void rev_rotate_a(void *s); +void rev_rotate_b(void *s); +void rev_rotate_both(void *s); + +void do_sort_insert(t_state *state, t_usize index, + enum e_stack_selector move_from, + enum e_zero_position zero_pos); + +void inc(void *s) +{ + t_usize *p; + + p = (t_usize *)s; + *p += 1; +} + +t_usize best_index_to_move(t_state *state, enum e_stack_selector move_from, + enum e_zero_position zero_pos) +{ + t_vec_i64 *stack; + t_usize min_pos; + t_usize min_val; + t_usize i; + t_usize tmp; + + if (move_from == STACK_A) + stack = &state->stack_a; + else + stack = &state->stack_b; + if (stack->len == 0) + return (0); + i = 1; + min_pos = 0; + run_func_with_best_rotate_for_item(state, 0, + (t_best_move_args){ + .args = &tmp, + .zero_pos = zero_pos, + .main_stack = move_from, + .other = {inc, inc}, + .main = {inc, inc}, + .both = {inc, inc}, + }); + min_val = tmp; + while (i < stack->len) + { + run_func_with_best_rotate_for_item(state, i, + (t_best_move_args){ + .args = &tmp, + .zero_pos = zero_pos, + .main_stack = move_from, + .other = {inc, inc}, + .main = {inc, inc}, + .both = {inc, inc}, + }); + if (tmp < min_val) + { + min_val = tmp; + min_pos = i; + } + i++; + } + return (min_val); +} + +bool is_sorted(t_vec_i64 *v) +{ + t_usize i; + i = 1; + while (i < v->len) + { + if (v->buffer[i - 1] > v->buffer[i]) + return (false); + i++; + } + return (true); +} + +void run_with_items(t_state *state) +{ + if (is_sorted(&state->stack_a)) + return; + while (state->stack_a.len > state->stack_b.len) + { + do_sort_insert(state, best_index_to_move(state, STACK_A, MAX_ZERO_POS), + STACK_A, MAX_ZERO_POS); + } + while (state->stack_a.len != 0) + { + push_b(state); + } +}