96 lines
2.9 KiB
C
96 lines
2.9 KiB
C
/* ************************************************************************** */
|
|
/* */
|
|
/* ::: :::::::: */
|
|
/* solution.c :+: :+: :+: */
|
|
/* +:+ +:+ +:+ */
|
|
/* By: apago <apago@student.42.fr> +#+ +:+ +#+ */
|
|
/* +#+#+#+#+#+ +#+ */
|
|
/* Created: 2023/04/04 21:46:57 by tischmid #+# #+# */
|
|
/* Updated: 2023/04/05 18:24:14 by apago ### ########.fr */
|
|
/* */
|
|
/* ************************************************************************** */
|
|
|
|
#include "solution.h"
|
|
|
|
// Replace each cell by the number of obstacles a rectangle starting
|
|
// from the top left cell, filling the board until the cell in question,
|
|
// covers. Border is inclusive. This will enable us to check if a given
|
|
// square contains obstacles or not in O(1) time, instead of O(n^2),
|
|
// namely by summing up the corner cells alternatingly (+, -, +, -, clockwise).
|
|
void preprocess_map(t_map *map)
|
|
{
|
|
int is_obstacle;
|
|
int idx;
|
|
|
|
idx = 0;
|
|
while (idx < map->meta.width * map->meta.height)
|
|
{
|
|
is_obstacle = map->data[idx] == map->meta.obstacle;
|
|
map->index[idx] = is_obstacle + get_index(map, idx, 0, -1)
|
|
+ get_index(map, idx, -1, 0) - get_index(map, idx, -1, -1);
|
|
idx++;
|
|
}
|
|
}
|
|
|
|
int count_obstacles(t_map *map, int idx, int sq_size)
|
|
{
|
|
int alternat_corner_sum;
|
|
|
|
if (sq_size == 0)
|
|
return (0);
|
|
if (sq_size == 1)
|
|
return (get_index(map, idx, 0, 0));
|
|
if (idx + (sq_size - 1) * (map->meta.width + 1) > map->meta.width
|
|
* map->meta.height)
|
|
return (-1);
|
|
alternat_corner_sum = get_index(map, idx, -1, -1) - get_index(map, idx, -1,
|
|
sq_size - 1) + get_index(map, idx, sq_size - 1, sq_size - 1)
|
|
- get_index(map, idx, sq_size - 1, -1);
|
|
return (alternat_corner_sum);
|
|
}
|
|
|
|
void fill_with_full(t_map *map, int sq_idx, int sq_size)
|
|
{
|
|
int idx;
|
|
int idx_row;
|
|
int idx_col;
|
|
int sq_row;
|
|
int sq_col;
|
|
|
|
sq_row = itor(sq_idx, map->meta.width);
|
|
sq_col = itoc(sq_idx, map->meta.width);
|
|
idx = 0;
|
|
while (idx < map->meta.width * map->meta.height)
|
|
{
|
|
idx_row = itor(idx, map->meta.width);
|
|
idx_col = itoc(idx, map->meta.width);
|
|
if (idx_row >= sq_row && idx_row < sq_row + sq_size && idx_col >= sq_col
|
|
&& idx_col < sq_col + sq_size)
|
|
map->data[idx] = map->meta.full;
|
|
idx++;
|
|
}
|
|
}
|
|
|
|
void solve(t_map *map)
|
|
{
|
|
int idx;
|
|
int sq_idx;
|
|
int sq_size;
|
|
|
|
preprocess_map(map);
|
|
idx = 0;
|
|
sq_size = 0;
|
|
sq_idx = 0;
|
|
while (idx < map->meta.width * map->meta.height)
|
|
{
|
|
while (count_obstacles(map, idx, sq_size) == 0)
|
|
{
|
|
sq_idx = idx;
|
|
sq_size++;
|
|
}
|
|
idx++;
|
|
}
|
|
sq_size--;
|
|
fill_with_full(map, sq_idx, sq_size);
|
|
}
|