update...

This commit is contained in:
Maieul BOYER 2024-01-29 22:45:54 +01:00
parent 63d62aec4d
commit 4d7255f105
No known key found for this signature in database
26 changed files with 518 additions and 641 deletions

View file

@ -1,12 +1,6 @@
vec/vec_cost
vec/vec_cost_functions2
vec/vec_cost_functions3
vec/vec_element
vec/vec_element_functions2
vec/vec_element_functions3
vec/vec_i64
vec/vec_i64_bool
vec/vec_i64_bool_functions2
vec/vec_i64_bool_functions3
vec/vec_i64_functions2
vec/vec_i64_functions3
vec/vec_moves
vec/vec_moves_functions2
vec/vec_moves_functions3

45
include/app/best_move.h Normal file
View file

@ -0,0 +1,45 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* best_move.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/29 20:10:21 by maiboyer #+# #+# */
/* Updated: 2024/01/29 20:28:35 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef BEST_MOVE_H
#define BEST_MOVE_H
#include "app/state.h"
enum e_stack_selector {
STACK_A,
STACK_B,
};
enum e_zero_position {
MIN_ZERO_POS,
MAX_ZERO_POS,
};
struct s_functions {
void (*forward)(void *);
void (*reverse)(void *);
};
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;
} t_best_move_args;
void run_func_with_best_rotate_for_item(t_state *state, t_usize index,
t_best_move_args data);
#endif /* BEST_MOVE_H */

View file

@ -0,0 +1,69 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* best_move_inner.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/29 21:31:42 by maiboyer #+# #+# */
/* Updated: 2024/01/29 21:50:15 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef BEST_MOVE_INNER_H
#define BEST_MOVE_INNER_H
#include "app/best_move.h"
#include "app/rotate.h"
#include "app/state.h"
#include "me/types.h"
#include "me/vec/vec_i64.h"
typedef void (*t_banana_func)(void *);
typedef t_usize (*t_iter_pos_func)(t_vec_i64 *);
enum e_best_move_stack_selector
{
MAIN,
OTHER,
BOTH,
};
typedef struct s_best_move_args_but_better
{
t_best_move_args data;
t_vec_i64 *main_stack;
t_vec_i64 *other_stack;
t_iter_pos_func iter_func;
} 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)
{
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);
}
return (NULL);
}
#endif /* BEST_MOVE_INNER_H */

View file

@ -13,7 +13,7 @@
#ifndef COST_H
# define COST_H
# include "app/element.h"
# include "app/state.h"
# include "app/types/type_cost.h"
# include "me/types.h"

View file

@ -13,12 +13,12 @@
#ifndef DUP_STATE_H
# define DUP_STATE_H
# include "app/element.h"
# include "me/types.h"
typedef struct s_dup_state
{
t_element *lhs;
t_i64 *lhs;
t_usize index_to_skip;
bool found_dup;
} t_dup_state;

29
include/app/find_place.h Normal file
View file

@ -0,0 +1,29 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* find_place.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/29 22:00:27 by maiboyer #+# #+# */
/* Updated: 2024/01/29 22:15:08 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef FIND_PLACE_H
#define FIND_PLACE_H
#include "app/state.h"
#include "me/types.h"
typedef struct s_find_place_iter_state
{
t_usize current_index;
t_usize found_index;
t_i64 to_find_elem;
} t_find_place_iter_state;
t_usize find_place(t_i64 elem, t_state *state);
#endif /* FIND_PLACE_H */

View file

@ -14,9 +14,9 @@
# define LIS_H
# include "me/types.h"
# include "me/vec/vec_element.h"
# include "me/vec/vec_i64.h"
# include "me/vec/vec_i64.h"
t_vec_i64 lis(t_vec_element *elements);
t_vec_i64 lis(t_vec_i64 *elements);
#endif /* LIS_H */

View file

@ -6,18 +6,19 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/11 16:13:08 by maiboyer #+# #+# */
/* Updated: 2024/01/12 21:27:27 by maiboyer ### ########.fr */
/* Updated: 2024/01/29 19:07:15 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef MOVES_H
# define MOVES_H
# include "app/element.h"
# include "app/state.h"
# include "app/types/type_move.h"
# include "me/types.h"
void do_move(t_move m, t_state *s);
void do_move(t_move m, t_state *s);
t_const_str get_str_for_move(t_move m);
#endif /* MOVES_H */

55
include/app/rotate.h Normal file
View file

@ -0,0 +1,55 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* rotate.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/29 19:00:18 by maiboyer #+# #+# */
/* Updated: 2024/01/29 19:27:19 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef ROTATE_H
#define ROTATE_H
#include "me/types.h"
enum e_rotation_direction
{
FORWARD,
REVERSE,
};
typedef struct s_rotation
{
t_usize value;
t_usize ring_size;
enum e_rotation_direction direction;
} t_rotation;
static inline t_rotation forward(t_usize by, t_usize ring_size)
{
return ((t_rotation){
.value = by % ring_size, .ring_size = ring_size, .direction = FORWARD});
}
static inline t_rotation reverse(t_usize by, t_usize ring_size)
{
return ((t_rotation){
.value = by % ring_size, .ring_size = ring_size, .direction = REVERSE});
}
static inline t_rotation flip(t_rotation rot)
{
enum e_rotation_direction flipped;
flipped = FORWARD;
if (rot.direction == FORWARD)
flipped = REVERSE;
return ((t_rotation){.value = rot.ring_size - rot.value,
.ring_size = rot.ring_size,
.direction = flipped});
}
#endif /* ROTATE_H */

View file

@ -6,25 +6,25 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/11 14:27:25 by maiboyer #+# #+# */
/* Updated: 2024/01/12 21:16:59 by maiboyer ### ########.fr */
/* Updated: 2024/01/29 22:15:52 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef STATE_H
# define STATE_H
#define STATE_H
# include "me/types.h"
# include "me/vec/vec_cost.h"
# include "me/vec/vec_element.h"
#include "me/types.h"
#include "me/vec/vec_i64.h"
#include "me/vec/vec_i64_bool.h"
typedef struct s_state
{
t_vec_element stack_a;
t_vec_element stack_b;
t_vec_cost costs;
} t_state;
t_vec_i64_bool sorted;
t_vec_i64 stack_a;
t_vec_i64 stack_b;
} t_state;
t_state parses_arguments(t_usize count, t_str nums[]);
void free_state(t_state state);
t_state parses_arguments(t_usize count, t_str nums[]);
void free_state(t_state state);
#endif /* STATE_H */

21
include/app/target.h Normal file
View file

@ -0,0 +1,21 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* target.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/29 20:30:43 by maiboyer #+# #+# */
/* Updated: 2024/01/29 20:31:28 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef TARGET_H
#define TARGET_H
#include "app/rotate.h"
#include "me/types.h"
t_rotation target(t_usize from, t_usize to, t_usize ring_size);
#endif /* TARGET_H */

View file

@ -1,25 +1,24 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* element.h :+: :+: :+: */
/* type_i64_bool.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/11 14:28:41 by maiboyer #+# #+# */
/* Updated: 2024/01/11 14:34:27 by maiboyer ### ########.fr */
/* Created: 2024/01/29 19:14:52 by maiboyer #+# #+# */
/* Updated: 2024/01/29 19:15:56 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef ELEMENT_H
# define ELEMENT_H
#ifndef TYPE_I64_BOOL_H
#define TYPE_I64_BOOL_H
# include "me/types.h"
#include "me/types.h"
typedef struct s_element
typedef struct s_i64_bool
{
t_i64 value;
} t_element;
t_i64 value;
bool active;
} t_i64_bool;
void free_element(t_element elem);
#endif /* ELEMENT_H */
#endif /* TYPE_I64_BOOL_H */

View file

@ -23,14 +23,6 @@ replace.C__TYPEHEADER__ = "header_include"
replace.C__PREFIX__ = "prefix"
replace.C__PREFIXUP__ = "prefix"
[[create.vec]]
sources_output = "src/vec/"
headers_output = "include/me/vec/"
replace.C__TYPENAME__ = "t_element"
replace.C__TYPEHEADER__ = '#include "app/element.h"'
replace.C__PREFIX__ = "element"
replace.C__PREFIXUP__ = "ELEMENT"
[[create.vec]]
sources_output = "src/vec/"
headers_output = "include/me/vec/"
@ -42,15 +34,7 @@ replace.C__PREFIXUP__ = "I64"
[[create.vec]]
sources_output = "src/vec/"
headers_output = "include/me/vec/"
replace.C__TYPENAME__ = "t_cost"
replace.C__TYPEHEADER__ = '#include "app/types/type_cost.h"'
replace.C__PREFIX__ = "cost"
replace.C__PREFIXUP__ = "COST"
[[create.vec]]
sources_output = "src/vec/"
headers_output = "include/me/vec/"
replace.C__TYPENAME__ = "t_move"
replace.C__TYPEHEADER__ = '#include "app/types/type_move.h"'
replace.C__PREFIX__ = "moves"
replace.C__PREFIXUP__ = "MOVES"
replace.C__TYPENAME__ = "t_i64_bool"
replace.C__TYPEHEADER__ = '#include "app/types/type_i64_bool.h"'
replace.C__PREFIX__ = "i64_bool"
replace.C__PREFIXUP__ = "I64_BOOL"

View file

@ -1,9 +1,9 @@
app/cost
app/lis/lis
app/lis/lower_bound
app/main
app/best_move
app/find_best_move_for
app/moves
app/moves/push
app/moves/rev_rotate
app/moves/rotate
app/moves/swap
app/rotate
app/target

108
src/app/best_move.c Normal file
View file

@ -0,0 +1,108 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* best_move.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/29 20:04:33 by maiboyer #+# #+# */
/* Updated: 2024/01/29 22:41:28 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "app/best_move.h"
#include "app/best_move_inner.h"
#include "app/find_place.h"
#include "app/rotate.h"
#include "app/state.h"
#include "app/target.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);
static inline t_usize abs_diff(t_usize lhs, t_usize rhs)
{
if (lhs > rhs)
return (lhs - rhs);
else
return (rhs - lhs);
}
static inline t_usize min(t_usize lhs, t_usize rhs)
{
if (lhs > rhs)
return (rhs);
else
return (lhs);
}
static void find_least_move(t_rotation *main, t_rotation *other)
{
t_usize main_fliped;
t_usize other_fliped;
t_usize none_fliped;
t_rotation tmp;
t_usize minimum;
none_fliped = main->value + other->value;
tmp = flip(*main);
main_fliped = abs_diff(tmp.value, other->value);
tmp = flip(*other);
other_fliped = abs_diff(tmp.value, main->value);
minimum = min(none_fliped, min(main_fliped, other_fliped));
if (minimum == none_fliped)
return;
else if (minimum == main_fliped)
*main = flip(*main);
else if (minimum == other_fliped)
*other = flip(*other);
}
static void run_func_with_best_rotate_for_item_inner(
t_state *state, t_usize index, t_best_move_args_but_better data)
{
t_usize other_size_len_min_1;
t_usize target_index;
t_rotation rotate_main;
t_rotation rotate_other;
other_size_len_min_1 = data.other_stack->len;
if (other_size_len_min_1 == 0)
other_size_len_min_1++;
target_index =
(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);
}
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)
better_args.iter_func = min_iter_zero_pos;
else if (data.zero_pos == MAX_ZERO_POS)
better_args.iter_func = max_iter_zero_pos;
else
return;
if (data.main_stack == STACK_A)
{
better_args.main_stack = &state->stack_a;
better_args.other_stack = &state->stack_b;
}
else if (data.main_stack == STACK_B)
{
better_args.main_stack = &state->stack_b;
better_args.other_stack = &state->stack_a;
}
else
return;
better_args.data = data;
run_func_with_best_rotate_for_item_inner(state, index, better_args);
}

View file

@ -1,107 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* cost.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/12 21:22:44 by maiboyer #+# #+# */
/* Updated: 2024/01/18 17:01:34 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "app/cost.h"
#include "app/state.h"
#include "me/types.h"
#include "me/vec/vec_cost.h"
#include "me/vec/vec_moves.h"
void reset_cost(t_usize _index, t_cost *c, void *_state)
{
(void)(_index + (t_usize)_state);
c->active = false;
c->moves.len = 0;
}
void find_minimum(t_usize index, t_cost *c, t_cost_iter_state *s)
{
if (index >= s->max_index || !c->active)
return ;
if (c->moves.len < s->current_minimum->moves.len)
s->current_minimum = c;
}
typedef struct s_max_iter_state
{
t_usize current_index;
t_vec_element *v;
} t_max_iter_state;
void find_maximum_iter(t_usize index, t_element *c, t_max_iter_state *s)
{
if (s->v->buffer[s->current_index].value < c->value)
s->current_index = index;
}
static t_usize find_max(t_vec_element *v)
{
t_max_iter_state state;
state.v = v;
state.current_index = 0;
vec_element_iter(v, (void (*)())find_maximum_iter, &state);
return (state.current_index);
}
void cost_for_index(t_state *s, t_usize index)
{
t_usize rotate_a;
t_usize rotate_b;
t_element *elem;
t_usize max_index;
rotate_a = 0;
rotate_b = 0;
elem = &s->stack_a.buffer[index];
max_index = find_max(&s->stack_b);
}
void free_cost(t_cost self)
{
vec_moves_free(self.moves);
}
t_cost alloc_cost(t_state *s)
{
t_cost out;
(void)(s);
out = (t_cost){};
out.active = false;
out.index = s->costs.len;
out.moves = vec_moves_new(s->stack_a.len, NULL);
return (out);
}
t_cost *calculate_cost(t_state *s)
{
t_vec_cost *costs;
t_cost *cur;
t_usize index;
t_cost_iter_state iter_state;
costs = &s->costs;
vec_cost_iter(costs, &reset_cost, NULL);
index = 0;
while (index > costs->len)
{
cur = &costs->buffer[index];
cost_for_index(s, index);
if (cur->moves.len == 1)
break ;
index++;
}
iter_state = (t_cost_iter_state){.current_minimum = costs->buffer,
.max_index = index};
vec_cost_iter(costs, (void (*)())find_minimum, &iter_state);
return (iter_state.current_minimum);
}

51
src/app/find_place.c Normal file
View file

@ -0,0 +1,51 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* find_place.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/29 22:01:12 by maiboyer #+# #+# */
/* Updated: 2024/01/29 22:17:33 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "app/find_place.h"
#include "app/types/type_i64_bool.h"
#include "me/vec/vec_i64_bool.h"
static void find_place_iter(t_usize index, t_i64_bool *elem,
t_find_place_iter_state *state)
{
if (!elem->active)
return;
if (elem->value == state->to_find_elem)
state->found_index = state->current_index;
state->current_index++;
}
t_usize find_place(t_i64 elem, t_state *state)
{
t_find_place_iter_state iter_state;
iter_state.current_index = 0;
iter_state.found_index = 0;
iter_state.to_find_elem = elem;
vec_i64_bool_iter(&state->sorted, (void(*))find_place_iter, &iter_state);
return (iter_state.found_index);
}
/*
state
.sorted
.iter()
.copied()
.filter(|&(e, active)| active || elem == e)
.enumerate()
.find(|(_, (e, _))| *e == elem)
.map(|(i, _)| i)
.unwrap_or_else(|| {
println!("why...");
0
})
*/

View file

@ -1,233 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* lis.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/11 18:50:35 by maiboyer #+# #+# */
/* Updated: 2024/01/12 20:42:48 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "app/element.h"
#include "me/mem/mem_alloc_array.h"
#include "me/printf/printf.h"
#include "me/vec/vec_element.h"
#include "me/vec/vec_i64.h"
#include <stdlib.h>
/*
P = array of length N
M = array of length N + 1
M[0] = -1 // undefined so can be set to any value
L = 0
for i in range 0 to N-1: //N-1 included
// Binary search for the smallest positive l ≤ L
// such that X[M[l]] > X[i]
lo = 1
hi = L + 1
while lo < hi:
mid = lo + floor((hi-lo)/2) // lo <= mid < hi
if X[M[mid]] >= X[i]
hi = mid
else: // if X[M[mid]] < X[i]
lo = mid + 1
// After searching, lo == hi is 1 greater than the
// length of the longest prefix of X[i]
newL = lo
// The predecessor of X[i] is the last index of
// the subsequence of length newL-1
P[i] = M[newL-1]
M[newL] = i
if newL > L:
// If we found a subsequence longer than any we've
// found yet, update L
L = newL
// Reconstruct the longest increasing subsequence
// It consists of the values of X at the L indices:
// ..., P[P[M[L]]], P[M[L]], M[L]
S = array of length L
k = M[L]
for j in range L-1 to 0: //0 included
S[j] = X[k]
k = P[k]
return S
*/
// static t_i64 binary_search(t_i64 L, t_i64 i, t_i64 m[], t_vec_element
// *elements)
//{
// return (low);
//}
// static t_vec_i64 lis_inner(t_vec_element *elements, t_i64 L, t_i64 m[],
// t_i64 p[])
//{
// }
/*
/// Finds one of the [longest increasing subsequences][1]
/// from the subsequence created by applying `selector` on each item in `items`.
/// The result is a vector of indices within `items`
/// corresponding to one of the longest increasing subsequences.
///
/// [1]: https://en.wikipedia.org/wiki/Longest_increasing_subsequence
pub fn lis<T, I: Ord, F: Fn(&T) -> I>(items: &[T], selector: F) -> Vec<usize> {
// This algorithm is adapted from
//
http://www.algorithmist.com/index.php?title=Longest_Increasing_Subsequence.cpp&oldid=13595
let mut result = Vec::new();
// If `items` is empty, then the result is also empty.
if items.is_empty() {
return (result);
}
// This vector stores, for each item,
// the index of the largest item prior to itself that is smaller than
itself.
// We'll use this vector at the end to build the final result.
let mut previous_chain = vec![0; items.len()];
// Initially, we assume that the first item is part of the result.
// We will replace this index later if that's not the case.
result.push(0);
for i in 1..items.len() {
// If the next item is greater than the last item of the current longest
subsequence,
// push its index at the end of the result and continue.
if selector(&items[*result.last().unwrap()]) < selector(&items[i]) {
previous_chain[i] = *result.last().unwrap();
result.push(i);
continue ;
}
// Perform a binary search to find the index of an item in `result` to
overwrite.
// We want to overwrite an index that refers to the smallest item that
is larger than `items[i]`.
// If there is no such item, then we do nothing.
let comparator = |&result_index| {
use std::cmp::Ordering;
// We don't return Ordering::Equal when we find an equal value,
// because we want to find the index of the first equal value.
if selector(&items[result_index]) < selector(&items[i]) {
Ordering::Less
} else {
Ordering::Greater
}
};
let next_element_index = match result.binary_search_by(comparator) {
Ok(index) | Err(index) => index,
};
if selector(&items[i]) < selector(&items[result[next_element_index]]) {
if next_element_index > 0 {
previous_chain[i] = result[next_element_index - 1];
}
result[next_element_index] = i;
}
}
// The last item in `result` is correct,
// but we might have started overwriting earlier items
// with what could have been a longer subsequence.
// Walk back `previous_chain` to restore the proper subsequence.
let mut u = result.len();
let mut v = *result.last().unwrap();
while u != 0 {
u -= 1;
result[u] = v;
v = previous_chain[v];
}
result
}
*/
t_i64 binary_search(t_vec_element *items, t_i64 i)
{
t_i64 lo;
t_i64 hi;
t_i64 mid;
lo = 0;
hi = items->len - 1;
while (lo < hi)
{
mid = lo + (hi - lo) / 2;
if (items->buffer[mid].value < items->buffer[i].value)
lo = mid + 1;
else
hi = mid;
}
return (lo);
}
void lis_inner(t_vec_element *elements, t_vec_i64 *result,
t_vec_i64 *previous_chain)
{
t_i64 i;
t_i64 next_element_index;
i = 1;
while (i < (t_i64)elements->len)
{
if (-elements->buffer[result->buffer[result->len - 1]].value <
-elements->buffer[i].value)
{
previous_chain->buffer[i] = result->buffer[result->len - 1];
vec_i64_push(result, i++);
continue ;
}
next_element_index = binary_search(elements, i);
if (-elements->buffer[i].value >
-elements->buffer[result->buffer[next_element_index]].value)
{
if (next_element_index > 0)
previous_chain->buffer[i] = result->buffer[next_element_index
- 1];
result->buffer[next_element_index] = i;
}
i++;
}
}
t_vec_i64 lis(t_vec_element *elements)
{
t_vec_i64 result;
t_i64 u;
t_i64 v;
t_vec_i64 previous_chain;
result = vec_i64_new(elements->len, NULL);
if (elements->len == 0)
return (result);
previous_chain = vec_i64_new(elements->len, NULL);
previous_chain.len = elements->len;
vec_i64_push(&result, 0);
lis_inner(elements, &result, &previous_chain);
u = result.len;
v = result.buffer[result.len - 1];
while (u != 0)
{
u--;
result.buffer[u] = v;
v = previous_chain.buffer[v];
}
vec_i64_free(previous_chain);
vec_i64_reverse(&result);
return (result);
}

View file

@ -1,195 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* main.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/11 14:14:18 by maiboyer #+# #+# */
/* Updated: 2024/01/18 13:45:26 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "app/cost.h"
#include "app/dup_state.h"
#include "app/element.h"
#include "app/lis.h"
#include "app/state.h"
#include "me/convert/atoi.h"
#include "me/convert/itoa.h"
#include "me/printf/printf.h"
#include "me/string/str_clone.h"
#include "me/types.h"
#include "me/vec/vec_cost.h"
#include "me/vec/vec_element.h"
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void free_element(t_element elem)
{
(void)(elem);
}
void free_state(t_state state)
{
vec_element_free(state.stack_a);
vec_element_free(state.stack_b);
vec_cost_free(state.costs);
}
t_error parse_element(t_str s, t_element *e)
{
t_usize i;
t_i64 value;
t_element out;
if (s == NULL || e == NULL)
return (ERROR);
i = 0;
if (s[i] == '-' || s[i] == '+')
i++;
while (s[i] && s[i] >= '0' && s[i] <= '9')
i++;
if (s[i] != '\0')
return (ERROR);
value = me_atoi_64(s);
if (value > INT_MAX || value < INT_MIN)
return (ERROR);
out.value = value;
*e = out;
return (NO_ERROR);
}
void check_eq(t_usize i, const t_element *rhs, t_dup_state *dup_state)
{
dup_state->found_dup = dup_state->found_dup
|| (i != dup_state->index_to_skip
&& rhs->value == dup_state->lhs->value);
}
void check_no_duplicate(t_vec_element *stack, t_vec_element *to_free_in_need)
{
t_usize i;
t_dup_state s;
i = 0;
while (i < stack->len)
{
s = (t_dup_state){
.lhs = &stack->buffer[i],
.index_to_skip = i,
.found_dup = false,
};
vec_element_iter(stack, (void (*)())check_eq, &s);
if (s.found_dup)
return (me_eprintf("Error:\nDuplicate numbers (%i)\n",
stack->buffer[i]), vec_element_free(*stack),
vec_element_free(*to_free_in_need), exit(1));
i++;
}
}
t_state parses_arguments(t_usize count, t_str nums[])
{
t_state out;
t_usize i;
t_element e;
i = 0;
out.stack_a = vec_element_new(count + 1, free_element);
out.stack_b = vec_element_new(count + 1, free_element);
while (i < count)
{
if (parse_element(nums[i], &e))
(me_eprintf("Error:\nArgument '%s' isn't a valid number for this "
"program!\n",
nums[i]),
vec_element_free(out.stack_a),
vec_element_free(out.stack_b),
exit(1));
vec_element_push(&out.stack_a, e);
i++;
}
vec_element_reverse(&out.stack_a);
check_no_duplicate(&out.stack_a, &out.stack_b);
return (out);
}
#define LEFT(str, w) \
({ \
int m = w + strlen(str); \
m % 2 ? (m + 1) / 2 : m / 2; \
})
#define RIGHT(str, w) \
({ \
int m = w - strlen(str); \
m % 2 ? (m - 1) / 2 : m / 2; \
})
#define STR_CENTER(str, width) LEFT(str, width), str, RIGHT(str, width), ""
#define STACK_WIDTH 12
bool check_sorted(t_state *s)
{
t_usize not_in_order;
t_usize i;
not_in_order = 0;
i = 0;
while (i + 1 < s->stack_a.len)
{
if (s->stack_a.buffer[i].value > s->stack_a.buffer[i].value)
not_in_order++;
i++;
}
return (not_in_order == 0);
}
void print_state(t_state *s)
{
t_usize max_len;
t_str s_a;
t_str s_b;
if (s->stack_a.len > s->stack_b.len)
max_len = s->stack_a.len;
else
max_len = s->stack_b.len;
printf("|%*s%*s|%*s%*s|\n", STR_CENTER("Stack A", STACK_WIDTH),
STR_CENTER("Stack B", STACK_WIDTH));
for (t_usize i = 0; i < max_len; i++)
{
if (i < s->stack_a.len)
s_a = me_itoa(s->stack_a.buffer[s->stack_a.len - i - 1].value);
else
s_a = str_clone("");
if (i < s->stack_b.len)
s_b = me_itoa(s->stack_b.buffer[s->stack_b.len - i - 1].value);
else
s_b = str_clone("");
printf("|%*s%*s|%*s%*s|\n", STR_CENTER(s_a, STACK_WIDTH),
STR_CENTER(s_b, STACK_WIDTH));
free(s_a);
free(s_b);
}
printf("\n");
}
int main(t_i32 argc, t_str argv[])
{
t_state state;
state = parses_arguments(--argc, ++argv);
state.costs = vec_cost_new(state.stack_a.len, &free_cost);
while (state.costs.len < state.stack_a.len)
vec_cost_push(&state.costs, alloc_cost(&state));
print_state(&state);
while (!check_sorted(&state))
{
}
free_state(state);
return (0);
}

View file

@ -6,24 +6,25 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/11 16:17:26 by maiboyer #+# #+# */
/* Updated: 2024/01/11 16:31:56 by maiboyer ### ########.fr */
/* Updated: 2024/01/29 18:58:48 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "app/element.h"
#include "app/moves.h"
#include "app/state.h"
#include "app/types/type_move.h"
void push_a(t_state *s);
void push_b(t_state *s);
void swap_a(t_state *s);
void swap_b(t_state *s);
void rotate_a(t_state *s);
void rotate_b(t_state *s);
void rev_rotate_a(t_state *s);
void rev_rotate_b(t_state *s);
void push_a(t_state *s);
void push_b(t_state *s);
void swap_a(t_state *s);
void swap_b(t_state *s);
void rotate_a(t_state *s);
void rotate_b(t_state *s);
void rev_rotate_a(t_state *s);
void rev_rotate_b(t_state *s);
void do_move(t_move m, t_state *s)
void do_move(t_move m, t_state *s)
{
if (m & PUSH_A)
push_a(s);
@ -42,3 +43,30 @@ void do_move(t_move m, t_state *s)
if (m & REVERSE_ROTATE_B)
rev_rotate_b(s);
}
t_const_str get_str_for_move(t_move m)
{
if (m & PUSH_A)
return ("pa");
if (m & PUSH_B)
return ("pb");
if (m & SWAP_A && m & SWAP_B)
return ("ss");
if (m & SWAP_A)
return ("sa");
if (m & SWAP_B)
return ("sb");
if (m & ROTATE_A && m & ROTATE_B)
return ("rr");
if (m & ROTATE_A)
return ("ra");
if (m & ROTATE_B)
return ("rb");
if (m & REVERSE_ROTATE_A && m & REVERSE_ROTATE_B)
return ("rrr");
if (m & REVERSE_ROTATE_A)
return ("rra");
if (m & REVERSE_ROTATE_B)
return ("rrb");
return ("");
}

View file

@ -10,20 +10,20 @@
/* */
/* ************************************************************************** */
#include "app/element.h"
#include "app/state.h"
#include "me/vec/vec_element.h"
static inline void push_inner(t_vec_element *to, t_vec_element *from,
#include "app/state.h"
#include "me/vec/vec_i64.h"
static inline void push_inner(t_vec_i64 *to, t_vec_i64 *from,
t_const_str tag)
{
t_element e;
t_i64 e;
(void)(tag);
if (from->len == 0)
return ;
vec_element_pop(from, &e);
vec_element_push(to, e);
vec_i64_pop(from, &e);
vec_i64_push(to, e);
}
void push_a(t_state *s)

View file

@ -6,22 +6,22 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/11 16:26:04 by maiboyer #+# #+# */
/* Updated: 2024/01/11 17:31:44 by maiboyer ### ########.fr */
/* Updated: 2024/01/29 18:56:05 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "app/element.h"
#include "app/state.h"
static inline void rev_rotate_inner(t_vec_element *stack, t_const_str tag)
static inline void rev_rotate_inner(t_vec_i64 *stack, t_const_str tag)
{
t_element e;
t_i64 e;
(void)(tag);
if (stack->len <= 1)
return ;
vec_element_pop(stack, &e);
vec_element_push_front(stack, e);
vec_i64_pop(stack, &e);
vec_i64_push_front(stack, e);
}
void rev_rotate_a(t_state *s)

View file

@ -10,18 +10,18 @@
/* */
/* ************************************************************************** */
#include "app/element.h"
#include "app/state.h"
static inline void rotate_inner(t_vec_element *stack, t_const_str tag)
static inline void rotate_inner(t_vec_i64 *stack, t_const_str tag)
{
t_element e;
t_i64 e;
(void)(tag);
if (stack->len <= 1)
return ;
vec_element_pop(stack, &e);
vec_element_push_front(stack, e);
vec_i64_pop(stack, &e);
vec_i64_push_front(stack, e);
}
void rotate_a(t_state *s)

View file

@ -10,22 +10,22 @@
/* */
/* ************************************************************************** */
#include "app/element.h"
#include "app/state.h"
#include "me/vec/vec_element.h"
static inline void swap_inner(t_vec_element *stack, t_const_str tag)
#include "app/state.h"
#include "me/vec/vec_i64.h"
static inline void swap_inner(t_vec_i64 *stack, t_const_str tag)
{
t_element first;
t_element second;
t_i64 first;
t_i64 second;
(void)(tag);
if (stack->len <= 1)
return ;
vec_element_pop(stack, &first);
vec_element_pop(stack, &second);
vec_element_push(stack, first);
vec_element_push(stack, second);
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)

View file

@ -1,11 +1,15 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* lower_bound.c :+: :+: :+: */
/* rotate.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/11 18:17:23 by maiboyer #+# #+# */
/* Updated: 2024/01/11 19:17:19 by maiboyer ### ########.fr */
/* Created: 2024/01/29 18:59:56 by maiboyer #+# #+# */
/* Updated: 2024/01/29 20:04:18 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "app/rotate.h"
#include "me/types.h"

24
src/app/target.c Normal file
View file

@ -0,0 +1,24 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* target.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/29 20:30:27 by maiboyer #+# #+# */
/* Updated: 2024/01/29 22:29:50 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "app/target.h"
#include "app/rotate.h"
t_rotation target(t_usize from, t_usize to, t_usize ring_size)
{
if (ring_size == 0)
ring_size++;
if (from < to)
return (forward(to - from, ring_size));
else
return (reverse(from - to, ring_size));
}