42 Piscine/Rush01

# Overview

This program is designed to solve the Skyscrapers puzzle, a logic-based grid puzzle involving the placement of skyscrapers with different heights. The `init_grid` function initializes the puzzle grid based on input constraints, utilizing the `asign`, `asign_one`, and `inc_asign` functions to assign values according to specific conditions. Helper functions like `row_leftright`, `col_updown`, `rightleft`, and `downup` check the visibility conditions in rows and columns, ensuring compliance with puzzle rules. The main `solve` function orchestrates the recursive solving process, exploring different possibilities until a valid solution is found or an error is detected. Input processing functions (`initialize`, `input_to_arr`) handle the conversion of input strings to the array format required for puzzle initialization. The program, initiated by the `main` function, takes command line input, processes it, and outputs either the solved puzzle or an error message. Overall, the program systematically solves the Skyscrapers puzzle through a logical combination of initialization, assignment, visibility checking, and recursive exploration. The recursive backtracking algorithm systematically explores different configurations, making educated guesses and backtracking when necessary. The code is designed to efficiently search through the solution space, ensuring that it arrives at a valid solution for the Skyscrapers puzzle.
## Further Breakdown

### Initialization (`init_grid`)

* The puzzle grid (`grid`) is initialized based on the input constraints provided in the array `arr`.
* The `asign` function is used to assign values to specific cells based on the given clues in the `arr` array.

### Assigning Values (`asign`, `asign_one`, `inc_asign`)

* `asign`: Decides how to assign values based on the position (`i` and `j`) and the clues provided in `arr`. It calls either `asign_one` for specific cases or `inc_asign` for incremental assignments.
* `asign_one`: Sets a specific value (4) based on the position and input conditions.
* `inc_asign`: Assigns values incrementally or decrementally based on parameters like the constant value, row or column indication, and the direction of assignment.

### Visibility Check (`row_leftright`, `col_updown`, `rightleft`, `downup`)

* These functions check the visibility conditions in rows and columns to ensure that the skyscrapers are correctly placed according to the puzzle rules.
* They help in validating whether a certain assignment adheres to the visibility constraints in the Skyscrapers puzzle.

### Recursive Backtracking (`recursion`)

* The `recursion` function is the core of the solving process. It explores different possibilities for each cell while considering visibility conditions and backtracks when necessary.
* It recursively moves through the grid, trying different values for each cell until a valid solution is found or an error is detected.

### Validity Check (`is_valid`, `condition`, `condition_loop`)

* The `is_valid` function checks if a given assignment in the grid adheres to visibility conditions. If not, it backtracks and tries a different value.
* Conditions specific to the puzzle (e.g., clues indicating the number of visible skyscrapers) are checked to ensure the validity of the solution.

### Final Output (`print_criteria`)

* If a valid solution is found, the `print_criteria` function prints the solved grid.
* If no solution is found, an error message is output.

# Files

For this project, we initially worked with two files. The first file, `solve.c`, housed the program responsible for solving the puzzle. The second file, `map_parse.c`, included the main function to execute the project, print error messages, and manage all other functions. Unfortunately, due to a five function limit, we had to redistribute the functions originally in `map_parse.c` into two additional files.

## Asign.c

The functions in this file work together to set up and change a 4x4 grid. The main function, `init_grid`, starts everything off. It uses the other functions to decide what values to put in the grid cells, depending on certain conditions in the code. The `asign` function is like a decision-maker. It figures out whether to use `asign_one` or `inc_asign` based on what's in the `arr` array and the current positions in the grid. The `inc_asign` function adjusts values in a specific row or column of the grid, either making them bigger or smaller. The `asign_one` function has a specific job: it puts the value 4 into a grid cell based on the values of `i` and `j`.

```
void    asign_one(int grid[4][4], int i, int j);
void    init_grid(int arr[4][4], int grid[4][4]);
void    asign(int grid[4][4], int *i, int *j, int arr[4][4]);
void    inc_asign(int grid[4][4], int constant, int roworcol, int inc_or_dec);

void    inc_asign(int grid[4][4], int constant, int roworcol, int inc_or_dec)
{
        int     z;

        if (inc_or_dec == 0)
        {
                z = -1;
                while (++z < 4)
                {
                        if (roworcol == 0)
                                grid[constant][z] = z + 1;
                        else
                                grid[z][constant] = z + 1;
                }
        }
        else
        {
                z = 4;
                while (--z > -1)
                {
                        if (roworcol == 0)
                                grid[constant][z] = 4 - z;
                        else
                                grid[z][constant] = 4 - z;
                }
        }
}

void    asign_one(int grid[4][4], int i, int j)
{
        if (i == 0)
                grid[0][j] = 4;
        else if (i == 1)
                grid[3][j] = 4;
        else if (i == 2)
                grid[j][0] = 4;
        else
                grid[j][3] = 4;
}

void    asign(int grid[4][4], int *i, int *j, int arr[4][4])
{
        int     z;

        z = -1;
        if (arr[*i][*j] == 1)
                asign_one(grid, *i, *j);
        else if (*i == 0)
                inc_asign(grid, *j, 1, 0);
        else if (*i == 1)
                inc_asign(grid, *j, 1, 1);
        else if (*i == 2)
                inc_asign(grid, *j, 0, 0);
        else
                inc_asign(grid, *j, 0, 1);
}

void    init_grid(int arr[4][4], int grid[4][4])
{
        int     i;
        int     j;

        i = -1;
        while (++i < 4)
        {
                j = -1;
                while (++j < 4)
                {
                        if (arr[i][j] == 4 || arr[i][j] == 1)
                        {
                                asign(grid, &i, &j, arr);
                        }
                }
        }
}

```

### Function Declarations

In the first section, the code declares four functions, asign\_one, init\_grid, asign, and inc\_asign. These functions are responsible for initializing and manipulating a 4x4 grid based on certain conditions. The functions need to be declared at the top of a file to let the compiler know about them before they are used. This helps the compiler understand the function's signature (return type, name, and parameter types) and ensures that the functions are used correctly in the code. It's like introducing characters in a story before they play a role, making the code easier for the compiler to interpret.

```
void asign_one(int grid[4][4], int i, int j);
void init_grid(int arr[4][4], int grid[4][4]);
void asign(int grid[4][4], int *i, int *j, int arr[4][4]);
void inc_asign(int grid[4][4], int constant, int roworcol, int inc_or_dec);

```

### inc\_asign

The inc\_asign function changes numbers in a row or column of a 4x4 grid. You tell it which row or column to change with the "constant" number, say whether it's a row or column with "roworcol", and decide if you want to add or subtract numbers with "inc\_or\_dec". If adding, it starts with 1 and goes up; if subtracting, it starts with 4 and goes down. This function helps adjust the grid based on what you need.

```
void inc_asign(int grid[4][4], int constant, int roworcol, int inc_or_dec)
{
        int     z;

        if (inc_or_dec == 0)
        {
                z = -1;
                while (++z < 4)
                {
                        if (roworcol == 0)
                                grid[constant][z] = z + 1;
                        else
                                grid[z][constant] = z + 1;
                }
        }
        else
        {
                z = 4;
                while (--z > -1)
                {
                        if (roworcol == 0)
                                grid[constant][z] = 4 - z;
                        else
                                grid[z][constant] = 4 - z;
                }
        }
}

```

* **Parameters**
	+ `grid[4][4]` The 4x4 grid to be modified.
	+ `constant` The index of the row or column to be modified.
	+ `roworcol` Indicates whether to modify a row (`roworcol = 0`) or a column (`roworcol = 1`).
	+ `inc_or_dec` Determines whether to increment (`inc_or_dec = 0`) or decrement (`inc_or_dec = 1`) the values.

**Function Behavior**
* `if (inc_or_dec == 0)` (increment)
	+ `if (roworcol == 0)`, this adds 1 to each number in a row and puts the result in the same position in the row.
	+ `grid[constant][z] = z + 1;`
		- This means you are working with a specific row (constant is the row index).
		- For each column (z), you are assigning a value to the corresponding cell in that row. The value is one more than the column index.
	+ `else grid[z][constant] = z + 1;` If `roworcol` is `1`, it increments the values in the specified column (`constant`), assigning each cell the value of its row index plus 1.
* If `inc_or_dec` is not `0` (decrement) *view code below*.

```
        else
        {
                z = 4;
                while (--z > -1)
                {
                        if (roworcol == 0)
                                grid[constant][z] = 4 - z;
                        else
                                grid[z][constant] = 4 - z;
                }
        }

```

* + `if (roworcol == 0)`, decreases the values in the specified row (`constant`), assigning each cell the value of 4 minus its column index.
	+ `else` If `roworcol` is `1`, it decrements the values in the specified column (`constant`), assigning each cell the value of 4 minus its row index.

### asign\_one

The function `asign_one` that takes a 4x4 grid (represented as a 2D array) and two indices `i` and `j` as parameters. The purpose of this function is to assign the value 4 to a specific element in the grid based on the values of `i` and `j`. The specific location is determined by the conditions in the `if-else` statements.

```
void asign_one(int grid[4][4], int i, int j)
{
	if (i == 0)
		grid[0][j] = 4;
	else if (i == 1)
		grid[3][j] = 4;
	else if (i == 2)
		grid[j][0] = 4;
	else
		grid[j][3] = 4;
}

```

* If `i` is 0, it sets the value 4 in the first row at column `j` (`grid[0][j] = 4`).
* If `i` is 1, it sets the value 4 in the last row at column `j` (`grid[3][j] = 4`).
* If `i` is 2, it sets the value 4 in the first column at row `j` (`grid[j][0] = 4`).
* If none of the above conditions are met (i.e., `i` is not 0, 1, or 2), it sets the value 4 in the last column at row `j` (`grid[j][3] = 4`).

### asign

This is a function called `asign` that works with a 4x4 grid, two pointers to numbers (`i` and `j`), and another 4x4 array called `arr`. Its job is to change the values in the grid using information from the `arr` array and the indices given by `i` and `j`. Depending on the conditions related to the values at those specific indices in `arr` and the value of `i`, it makes adjustments to the grid. The actual changes happen in other functions called `asign_one` and `inc_asign`, and how exactly they happen depends on how those functions are set up.

```
void asign(int grid[4][4], int *i, int *j, int arr[4][4])
{
	int	z;

	z = -1;
	if (arr[*i][*j] == 1)
		asign_one(grid, *i, *j);
	else if (*i == 0)
		inc_asign(grid, *j, 1, 0);
	else if (*i == 1)
		inc_asign(grid, *j, 1, 1);
	else if (*i == 2)
		inc_asign(grid, *j, 0, 0);
	else
		inc_asign(grid, *j, 0, 1);
}

```

* It sets up a variable called `z` and gives it the value -1.
* It checks if the value at a specific spot (`arr[*i][*j]`) is 1. If it is, the function `asign_one` is called with the current grid and the indices `*i` and `*j`. This function seems to place the value 4 at a particular spot in the grid based on these indices.
* If the value at `arr[*i][*j]` is not 1, it looks at the value of `*i`:
	+ If `*i` is 0, it calls the function `inc_asign` with the current grid, the value of `*j`, and the parameters 1 and 0.
	+ If `*i` is 1, it calls `inc_asign` again with the current grid, the value of `*j`, and the parameters 1 and 1.
	+ If `*i` is 2, it calls `inc_asign` with the current grid, the value of `*j`, and the parameters 0 and 0.
	+ If `*i` is none of the above (i.e., not 0, 1, or 2), it calls `inc_asign` with the current grid, the value of `*j`, and the parameters 0 and 1.This function makes decisions on how to assign values to the grid based on the values in the `arr` array and the current indices `i` and `j`. It calls `asign_one` or `inc_asign` accordingly.

### init\_grid

The `init_grid` function does something simple: it sets up a 4x4 grid using values from a given 4x4 array called `arr`. It also needs another 4x4 grid called `grid` to do this. The trick is, it decides how to fill in the new `grid` based on certain rules found in the `arr` array. These rules are determined by another function called `asign`. So, `init_grid` is like a manager that uses the rules from `asign` to organize and fill in the cells of the `grid`.

```
void init_grid(int arr[4][4], int grid[4][4])
{
	int	i;
	int	j;

	i = -1;
	while (++i < 4)
	{
		j = -1;
		while (++j < 4)
		{
			if (arr[i][j] == 4 || arr[i][j] == 1)
			{
				asign(grid, &i, &j, arr);
			}
		}
	}
}

```

* The function uses two nested loops to iterate through each cell in the `arr` array.
* If the value in the current cell of `arr` is either 4 or 1, it calls the `asign` function. This function seems to modify the `grid` based on certain conditions.
* The use of `&i` and `&j` as arguments in the `asign` function suggests that the function might work with pointers, potentially altering the values of `i` and `j`.

## check.c

This piece of code has four functions, `row_leftright`, `col_updown`, `rightleft`, and `downup`. Each function checks certain things in a 4x4 grid. For example, they look at rows or columns to see if all the numbers are different or count how many are bigger than a specific number. They also check if there's a placeholder value in the grid. These functions are likely used in a bigger program, maybe for solving puzzles or organizing the grid in a certain way. The exact details depend on how these functions work together with the rest of the code.

```
int		row_leftright(int check, int *attr, int grid[4][4], int arr[4][4]);
int		col_updown(int check, int *attr, int grid[4][4], int arr[4][4]);
int		rightleft(int check, int *attr, int grid[4][4], int arr[4][4]);
int		downup(int check, int *attr, int grid[4][4], int arr[4][4]);

int	row_leftright(int check, int *attr, int grid[4][4], int arr[4][4])
{
	int	i;
	int	highest;
	int	count;

	i = -1;
	highest = 0;
	count = 0;
	while (++i < 4)
	{
		if (attr[2] == grid[attr[0]][i] && i != attr[1])
			return (1);
		if (grid[attr[0]][i] > highest)
		{
			highest = grid[attr[0]][i];
			count++;
		}
		if (grid[attr[0]][i] == -1)
			check = 1;
	}
	if (count > arr[2][attr[0]] && check == 0)
		return (1);
	if (check == 0 && count != arr[2][attr[0]])
		return (1);
	return (0);
}

int	col_updown(int check, int *attr, int grid[4][4], int arr[4][4])
{
	int	i;
	int	highest;
	int	count;

	count = 0;
	i = -1;
	highest = 0;
	while (++i < 4)
	{
		if (attr[2] == grid[i][attr[1]] && i != attr[0])
			return (1);
		if (grid[i][attr[1]] > highest)
		{
			highest = grid[i][attr[1]];
			count++;
		}
		if (grid[i][attr[1]] == -1)
			check = 1;
	}
	if (count > arr[0][attr[1]] && check == 0)
		return (1);
	if (check == 0 && count != arr[0][attr[1]])
		return (1);
	return (0);
}

int	rightleft(int check, int *attr, int grid[4][4], int arr[4][4])
{
	int	count;
	int	highest;
	int	i;

	count = 0;
	highest = 0;
	i = 4;
	while (--i > -1)
	{
		if (grid[attr[0]][i] > highest)
		{
			highest = grid[attr[0]][i];
			count++;
		}
		if (grid[attr[0]][i] == -1)
			check = 1;
	}
	if (count > arr[3][attr[0]] && check == 0)
		return (1);
	if (check == 0 && count != arr[3][attr[0]])
		return (1);
	return (0);
}

int	downup(int check, int *attr, int grid[4][4], int arr[4][4])
{
	int	count;
	int	highest;
	int	i;

	count = 0;
	highest = 0;
	i = 4;
	while (--i > -1)
	{
		if (grid[i][attr[1]] > highest)
		{
			highest = grid[i][attr[1]];
			count++;
		}
		if (grid[i][attr[1]] == -1)
			check = 1;
	}
	if (count > arr[1][attr[1]] && check == 0)
		return (1);
	if (check == 0 && count != arr[1][attr[1]])
		return (1);
	return (0);
}

```

#### Function Declarations

* `row_leftright`
* `col_updown`
* `rightleft`
* `downup`

#### Function Parameters

* Each function takes four parameters:
	+ `check`: an integer used for checking conditions.
	+ `attr`: an array of integers used for various attributes.
	+ `grid[4][4]`: a 4x4 grid manipulated by the functions.
	+ `arr[4][4]`: another 4x4 array likely holding conditions/rules.

#### Function Operations

* The functions (`row_leftright`, `col_updown`, `rightleft`, and `downup`) check conditions related to grid values and rules in `arr`.
* Each function uses a loop to iterate through row or column elements in the grid, checking conditions like:
	+ Whether a certain value (`attr[2]`) appears in a specific row or column.
	+ Counting elements greater than a specified value (`highest`) in a row or column.
	+ Checking for the presence of a placeholder value (`-1`) in the row or column.

#### Return Values

* Based on these conditions, the functions return either 1 (indicating conditions are not met) or 0 (indicating conditions are met).

#### Program Context

* The conditions being checked likely play a role in a larger program, possibly for solving puzzles or organizing the grid according to specific rules.

## map\_parse.c

`map_parse.c` checks if it receives the right amount of information and if the input is the correct length. If everything looks good, the program processes the input, converts it into a special grid, and then tries to solve the puzzle using a function called `solve` (shown in solve.c). If there are any issues with the input, like if it's too short or has invalid characters, the program prints an error message. Finally, it displays the solution or an error message based on the input provided.

```
﻿﻿﻿#include <unistd.h>

void	print_criteria(int arr[4][4]);
void	solve(int arr[4][4]);
void	initialize(char *str, int *attr, int arr[4][4]);
int		input_to_arr(char *str, int *attr, int arr[4][4]);

int	ft_strlen(char *c)
{
	int	i;

	i = 0;
	while (c[i])
		i++;
	return (i);
}

int	main(int argc, char **argv)
{
	int	i;
	int	arr[4][4];
	int	attr[3];

	if (argc == 2)
	{
		if (ft_strlen(argv[1]) != 31)
		{
			write(1, "Error\n", 6);
			return (1);
		}
		i = -1;
		while (i++ < 3)
			(attr[i] = 0);
		arr[3][3] = -1;
		if (input_to_arr(argv[1], attr, arr) == 1)
			return (0);
		if (arr[3][3] == -1)
			return (1);
		solve(arr);
	}
	else
		write(1, "Error\n", 6);
	return (0);
}

void	initialize(char *str, int *attr, int arr[4][4])
{
	if (attr[1] == 4)
	{
		attr[1] = 0;
		attr[2] += 1;
	}
	arr[attr[2]][attr[1]] = str[attr[0]] - 48;
	attr[1]++;
	attr[0]++;
}

int	input_to_arr(char *str, int *attr, int arr[4][4])
{
	while (str[attr[0]] != '\0')
	{
		if (str[attr[0]] >= '1' && str[attr[0]] <= '4')
			initialize(str, attr, arr);
		else if (str[attr[0]] == ' ')
			++attr[0];
		else
		{
			write(1, "Error\n", 6);
			return (1);
		}
	}
	if (attr[0] >= 32)
	{
		write(1, "Error\n", 6);
		return (1);
	}
	return (0);
}

void	print_criteria(int arr[4][4])
{
	int		i;
	int		j;
	char	ans;

	i = -1;
	while (++i < 4)
	{
		j = -1;
		while (++j < 3)
		{
			ans = arr[i][j] + 48;
			write(1, &ans, 1);
			write(1, " ", 1);
		}
		ans = arr[i][j] + 48;
		write(1, &ans, 1);
		write(1, "\n", 1);
	}
}

```

### Function Declarations

```
void print_criteria(int arr[4][4]);
void solve(int arr[4][4]);
void initialize(char *str, int *attr, int arr[4][4]);
int input_to_arr(char *str, int *attr, int arr[4][4]);
int ft_strlen(char *c);

```

The code starts with declarations of several functions: `print_criteria`, `solve`, `initialize`, `input_to_arr`, and a custom string length function `ft_strlen`. These functions likely perform specific tasks in the puzzle-solving program.

#### ft\_strlen

```
int ft_strlen(char *c)
{
    int i = 0;
    while (c[i])
        i++;
    return i;
}

```

This function calculates and returns the length of the input string `c`.

#### main

The `main` function is the entry point of the program. It checks if the program is provided with the correct number of command-line arguments (1 argument), and if the length of the input string is valid (31 characters). If not, it prints an error message. If the conditions are met, it initializes variables, processes the input string with the `input_to_arr` function, checks for errors, and then proceeds to solve the puzzle using the `solve` function.

```
int	main(int argc, char **argv)
{
	int	i;
	int	arr[4][4];
	int	attr[3];

	if (argc == 2)
	{
		if (ft_strlen(argv[1]) != 31)
		{
			write(1, "Error\n", 6);
			return (1);
		}
		i = -1;
		while (i++ < 3)
			(attr[i] = 0);
		arr[3][3] = -1;
		if (input_to_arr(argv[1], attr, arr) == 1)
			return (0);
		if (arr[3][3] == -1)
			return (1);
		solve(arr);
	}
	else
		write(1, "Error\n", 6);
	return (0);
}

```

#### initialize

This function is part of the process of converting the input string into a 4x4 array (`arr`). It assigns values to the array based on the input string, updating attributes in the process.

```
void initialize(char *str, int *attr, int arr[4][4])
{
    if (attr[1] == 4)
    {
        attr[1] = 0;
        attr[2] += 1;
    }
    arr[attr[2]][attr[1]] = str[attr[0]] - 48;
    attr[1]++;
    attr[0]++;
}

```

#### input\_to\_arr

This function processes the input string, calling the `initialize` function to convert the string into a 4x4 array. It checks for errors, such as invalid characters or an incorrect string length.

```
int input_to_arr(char *str, int *attr, int arr[4][4])
{
    while (str[attr[0]] != '\0')
    {
        if (str[attr[0]] >= '1' && str[attr[0]] <= '4')
            initialize(str, attr, arr);
        else if (str[attr[0]] == ' ')
            ++attr[0];
        else
        {
            write(1, "Error\n", 6);
            return 1;
        }
    }
    if (attr[0] >= 32)
    {
        write(1, "Error\n", 6);
        return 1;
    }
    return 0;
}

```

* `if (str[attr[0]] >= '1' && str[attr[0]] <= '4')` The given line of code checks if the character at the current position (`attr[0]`) in the string `str` is a digit between '1' and '4' (inclusive). The condition `str[attr[0]] >= '1' && str[attr[0]] <= '4'` evaluates to true if the character represents a number between 1 and 4 in the ASCII character set. In other words, it verifies whether the character at the specified position is a valid digit for the Skyscrapers puzzle, where the numbers represent the height of skyscrapers in a particular row or column. If the condition is true, it suggests that the character is within the valid range, and the associated code block will be executed.

#### print\_criteria

This function prints the criteria stored in the 4x4 array to the standard output. The code sets up the main logic of the program, checks input conditions, processes the input string, and then solves and prints the puzzle's criteria. The actual puzzle-solving logic is implemented in the `solve` function, which we placed in `solve.c`

```
void print_criteria(int arr[4][4])
{
    int i = -1;
    while (++i < 4)
    {
        int j = -1;
        while (++j < 3)
        {
            char ans = arr[i][j] + 48;
            write(1, &ans, 1);
            write(1, " ", 1);
        }
        char ans = arr[i][j] + 48;
        write(1, &ans, 1);
        write(1, "\n", 1);
    }
}

```

## solve.c

The code looks at each box, tries different numbers, and checks if they fit the rules. If a number works, it keeps it. If it gets stuck and can't find a good number, it says, "Oops, can't solve it!" But if it figures out all the numbers, it happily shows you the solved puzzle. It's like a clever friend who tries different things until the puzzle makes sense.
### Function Declarations

```
void print_criteria(int arr[4][4]);
void init_grid(int arr[4][4], int grid[4][4]);
int recursion(int grid[4][4], int arr[4][4], int r, int c);
int row_leftright(int check, int *attr, int grid[4][4], int arr[4][4]);
int col_updown(int check, int *attr, int grid[4][4], int arr[4][4]);
int rightleft(int check, int *attr, int grid[4][4], int arr[4][4]);
int downup(int check, int *attr, int grid[4][4], int arr[4][4]);

```

### is\_valid

This function sets a value in the grid, checks if it satisfies certain conditions using helper functions (row\_leftright), and returns whether the value is valid or not.

```
int is_valid(int grid[4][4], int arr[4][4], int *attr)
{
    grid[attr[0]][attr[1]] = attr[2];
    if (row_leftright(0, attr, grid, arr) == 1)
    {
        grid[attr[0]][attr[1]] = -1;
        return 1;
    }
    return 0;
}

```

### condition

This function checks specific conditions for a given cell position in the Skyscrapers puzzle, returning whether the conditions are met.

```
int condition(int arr[4][4], int r, int c)
{
    if ((r == 0) && (arr[0][c] == 2 || arr[0][c] == 3))
        return 1;
    if ((r == 3) && (arr[1][c] == 2 || arr[1][c] == 3))
        return 1;
    if ((c == 0) && (arr[2][r] == 2 || arr[2][r] == 3))
        return 1;
    if ((c == 3) && (arr[3][r] == 2 || arr[3][r] == 3))
        return 1;
    return 0;
}

```

### condition\_loop

This function loops through possible values for a cell in the Skyscrapers puzzle, checks conditions, and calls the `is_valid` function to determine if a value is valid.

```
int condition_loop(int *i, int *attr, int arr[4][4], int grid[4][4])
{
    int r = attr[0];
    int c = attr[1];
    while (++*i < 5)
    {
        {
            if (condition(arr, r, c) == 1)
                continue;
        }
        attr[2] = *i;
        if (is_valid(grid, arr, attr) == 0)
        {
            if (recursion(grid, arr, r, c + 1) == 0)
                return 0;
            grid[r][c] = -1;
        }
        else
            grid[r][c] = -1;
    }
    return 1;
}

```

### recursion

This recursive function attempts to solve the Skyscrapers puzzle by trying different values for each cell. It uses the `condition_loop` function to handle the possible values and checks if the conditions are met.

```
int recursion(int grid[4][4], int arr[4][4], int r, int c)
{
    int i = 0;
    int attr[3] = {r, c, 0};
    if (r == 4)
        return 0;
    else if (c == 4)
        return recursion(grid, arr, r + 1, 0);
    else if (grid[r][c] != -1)
        return recursion(grid, arr, r, c + 1);
    else
    {
        if (condition_loop(&i, attr, arr, grid) == 0)
            return 0;
        else
            return 1;
    }
}

```

### solve

This function initializes a grid, calls the `recursion` function to solve the puzzle, and prints the solved grid or an error message if no solution is found.

```
void solve(int arr[4][4])
{
    int grid[4][4];
    int i = -1;
    int j;
    int ans;
    while (++i < 4)
    {
        j = -1;
        while (++j < 4)
            grid[i][j] = -1;
    }
    init_grid(arr, grid);
    ans = recursion(grid, arr, 0, 0);
    if (ans == 0)
        print_criteria(grid);
    else
        write(1, "Error\n", 6);
}

```