/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* solution.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: tischmid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/04 21:46:57 by tischmid #+# #+# */ /* Updated: 2023/04/05 11:18:21 by tischmid ### ########.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 = get_cell(map, idx, 0, 0) == map->meta.obstacle; map->data[idx] = is_obstacle + \ get_cell(map, idx, 0, -1) + \ get_cell(map, idx, -1, 0) - \ get_cell(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_cell(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_cell(map, idx, -1, -1) - \ get_cell(map, idx, -1, sq_size - 1) + \ get_cell(map, idx, sq_size - 1, sq_size - 1) - \ get_cell(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; else map->data[idx] = map->copy[idx]; 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); }