tgrekov-push_swap
HIVE push_swap July 2024
Loading...
Searching...
No Matches
sort.c
Go to the documentation of this file.
1/* ************************************************************************** */
2/* */
3/* ::: :::::::: */
4/* sort.c :+: :+: :+: */
5/* +:+ +:+ +:+ */
6/* By: tgrekov <tgrekov@student.hive.fi> +#+ +:+ +#+ */
7/* +#+#+#+#+#+ +#+ */
8/* Created: 2024/07/11 05:49:56 by tgrekov #+# #+# */
9/* Updated: 2024/07/17 08:28:53 by tgrekov ### ########.fr */
10/* */
11/* ************************************************************************** */
12
20#include <stdlib.h>
21#include "utils/utils.h"
22#include "stack/stack.h"
23
32static int pick_i(t_stack *stack, int mode, int n)
33{
34 int minix;
35 int i;
36
37 minix = get_minix(stack[mode].n, stack[mode].len);
38 i = minix;
39 if (mode)
40 i = wrap_ix(minix + 1, stack[mode].len);
41 while ((mode && stack[mode].n[i] > n)
42 || (!mode && stack[mode].n[i] < n))
43 {
44 i = wrap_ix(i + 1, stack[mode].len);
45 if ((mode && i == wrap_ix(minix + 1, stack[mode].len))
46 || (!mode && i == minix))
47 break ;
48 }
49 return (i);
50}
51
60static void rot_i(t_stack *stack, int mode, int i)
61{
62 int dir;
63
64 dir = 0;
65 if (i < (stack[mode].len / 2 + 1))
66 dir = 1;
67 i = stack[mode].n[i];
68 while (stack[mode].n[0] != i)
69 {
70 if (dir)
71 rot(stack, mode);
72 else
73 r_rot(stack, mode);
74 }
75}
76
87static int rot_cost(t_stack stack, int o_i, int o_len, int i)
88{
89 if (i < (stack.len / 2 + 1))
90 {
91 if (o_i < (o_len / 2 + 1))
92 {
93 if (i >= o_i)
94 return (i);
95 return (o_i);
96 }
97 return (i + (o_len - o_i));
98 }
99 if (o_i < (o_len / 2 + 1))
100 return (stack.len - i + o_i);
101 if ((stack.len - i) >= (o_len - o_i))
102 return (stack.len - i);
103 return (o_len - o_i);
104}
105
114static void pick(t_stack *stack, int mode, int *costs)
115{
116 int i;
117 int minix;
118
119 if (!stack[1 - mode].len)
120 return ;
121 i = -1;
122 while (++i < stack[mode].len)
123 costs[i] = rot_cost(stack[1 - mode], i, stack[mode].len,
124 pick_i(stack, 1 - mode, stack[mode].n[i]));
125 minix = get_minix(costs, i);
126 i = minix;
127 if (minix > (stack[mode].len / 2))
128 i = minix - stack[mode].len;
129 while (i)
130 {
131 if (i > 0)
132 rot(stack, fallback((pick_i(stack, 1 - mode, stack[mode].n[minix])
133 < (stack[mode].len / 2 + 1)) * 2, mode));
134 else
135 r_rot(stack, fallback((pick_i(stack, 1 - mode, stack[mode].n[minix])
136 > (stack[mode].len / 2)) * 2, mode));
137 i += 1 + (i > 0) * -2;
138 }
139 rot_i(stack, 1 - mode, pick_i(stack, 1 - mode, stack[mode].n[0]));
140}
141
148int sort(t_stack *stack)
149{
150 int *costs;
151
152 costs = malloc(sizeof(int) * stack[0].len);
153 if (!costs)
154 return (err("Error\n", 1));
155 while (stack[0].len > 3 && !is_sorted(stack, 0))
156 {
157 pick(stack, 0, costs);
158 push(stack, 0);
159 }
160 if (!is_sorted(stack, 0))
161 {
162 swap(stack, 0);
163 rot_i(stack, 0, get_minix(stack[0].n, stack[0].len));
164 }
165 while (stack[1].len)
166 {
167 pick(stack, 1, costs);
168 push(stack, 1);
169 }
170 rot_i(stack, 0, get_minix(stack[0].n, stack[0].len));
171 free(costs);
172 return (0);
173}
int err(char *str, int retval)
Print str to stderr and return retval.
Definition err.c:29
int fallback(int a, int b)
Return a if non-zero, otherwise return b.
Definition fallback.c:27
int get_minix(int *arr, int len)
Get the index of the smallest element.
Definition get_minix.c:27
int is_sorted(t_stack *stack, int mode)
Check if the contents of a stack are in the correct order relative to the smallest element.
Definition is_sorted.c:31
void push(t_stack *stack, int mode)
Push the first element from stack 1 or 2 into the other stack, depending on whether mode is set to 0 ...
Definition push.c:55
void r_rot(t_stack *stack, int mode)
Shift all elements in stack 1, 2, or both up, depending on whether mode is set to 0,...
Definition r_rot.c:51
void rot(t_stack *stack, int mode)
Shift all elements in stack 1, 2, or both down, depending on whether mode is set to 0,...
Definition rot.c:51
static int rot_cost(t_stack stack, int o_i, int o_len, int i)
Determine move cost of rotating to an index, considering whether it is shorter to rotate or reverse r...
Definition sort.c:87
int sort(t_stack *stack)
Output all instructions required to sort stack a.
Definition sort.c:148
static int pick_i(t_stack *stack, int mode, int n)
Find appropriate index for n in stack[mode]
Definition sort.c:32
static void rot_i(t_stack *stack, int mode, int i)
Rotate to an index with rotate or reverse rotate, depending on which is shorter.
Definition sort.c:60
static void pick(t_stack *stack, int mode, int *costs)
Determine which element to push from stack mode to the opposite stack by comparing their movement cos...
Definition sort.c:114
void swap(t_stack *stack, int mode)
Swap the first two elements in stacks 1, 2, or both, depending on whether mode is set to 0,...
Definition swap.c:48