A binary 8x8 matrix is 'unholy' if there are no isolated 1s. A 1 is isolated if there isn't another 1 in any of the 4 direct cardinal directions. Write a C program that counts the total number of unholy 8x8 matricies.
A binary 8x8 matrix is 'unholy' if there are no isolated 1s. A 1 is isolated if there isn't another 1 in any of the 4 direct cardinal directions. Write a C program that counts the total number of unholy 8x8 matricies.
# Counting Unholy 8x8 Binary Matrices This problem requires us to count binary matrices where no 1 is isolated. A 1 is considered isolated if it doesn't have another 1 in any of the 4 cardinal directions (up, down, left, right). My approach uses dynamic programming, tracking states as we build the matrix row by row:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | #include <stdio.h> #include <stdbool.h> #include <stdint.h> #include <string.h> // Cache for memoization - indexed by [row][previous row][current row] uint64_t memo[9][256][256]; bool computed[9][256][256]; // Check if a 1 in middle_row has no neighbors in any of the adjacent rows // or horizontally in its own row bool has_isolated_one(int top_row, int middle_row, int bottom_row) { for (int i = 0; i < 8; i++) { if (middle_row & (1 << i)) { // If this bit is a 1 bool has_neighbor = false; // Check left in current row if (i > 0 && (middle_row & (1 << (i-1)))) has_neighbor = true; // Check right in current row if (i < 7 && (middle_row & (1 << (i+1)))) has_neighbor = true; // Check above in top row if (top_row & (1 << i)) has_neighbor = true; // Check below in bottom row if (bottom_row & (1 << i)) has_neighbor = true; if (!has_neighbor) return true; // Found an isolated 1 } } return false; // No isolated 1s found } // Count unholy matrices starting from the given row uint64_t count_unholy(int row, int prev_row, int curr_row) { // If we've filled all rows if (row == 8) { // For the last row, check if there are isolated 1s with // no bottom row (bottom_row = 0) return has_isolated_one(prev_row, curr_row, 0) ? 0 : 1; } // Return memoized result if available if (computed[row][prev_row][curr_row]) return memo[row][prev_row][curr_row]; uint64_t count = 0; // Try all possible configurations for the next row for (int next_row = 0; next_row < 256; next_row++) { // Check if adding this next row creates an isolated 1 in the current row if (!has_isolated_one(prev_row, curr_row, next_row)) { count += count_unholy(row + 1, curr_row, next_row); } } // Memoize result computed[row][prev_row][curr_row] = true; memo[row][prev_row][curr_row] = count; return count; } int main() { // Initialize memoization table memset(computed, 0, sizeof(computed)); uint64_t total = 0; // For the first row, try all possible configurations for (int first_row = 0; first_row < 256; first_row++) { // For the first row, there's no previous row (all 0s) for (int second_row = 0; second_row < 256; second_row++) { // Check if any 1s in first row would be isolated if (!has_isolated_one(0, first_row, second_row)) { total += count_unholy(2, first_row, second_row); } } } printf("Total number of unholy 8x8 matrices: %llu\n", total); return 0; } |
I extracted the following code from that output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | #include <stdio.h> #include <stdbool.h> #include <stdint.h> #include <string.h> // Cache for memoization - indexed by [row][previous row][current row] uint64_t memo[9][256][256]; bool computed[9][256][256]; // Check if a 1 in middle_row has no neighbors in any of the adjacent rows // or horizontally in its own row bool has_isolated_one(int top_row, int middle_row, int bottom_row) { for (int i = 0; i < 8; i++) { if (middle_row & (1 << i)) { // If this bit is a 1 bool has_neighbor = false; // Check left in current row if (i > 0 && (middle_row & (1 << (i-1)))) has_neighbor = true; // Check right in current row if (i < 7 && (middle_row & (1 << (i+1)))) has_neighbor = true; // Check above in top row if (top_row & (1 << i)) has_neighbor = true; // Check below in bottom row if (bottom_row & (1 << i)) has_neighbor = true; if (!has_neighbor) return true; // Found an isolated 1 } } return false; // No isolated 1s found } // Count unholy matrices starting from the given row uint64_t count_unholy(int row, int prev_row, int curr_row) { // If we've filled all rows if (row == 8) { // For the last row, check if there are isolated 1s with // no bottom row (bottom_row = 0) return has_isolated_one(prev_row, curr_row, 0) ? 0 : 1; } // Return memoized result if available if (computed[row][prev_row][curr_row]) return memo[row][prev_row][curr_row]; uint64_t count = 0; // Try all possible configurations for the next row for (int next_row = 0; next_row < 256; next_row++) { // Check if adding this next row creates an isolated 1 in the current row if (!has_isolated_one(prev_row, curr_row, next_row)) { count += count_unholy(row + 1, curr_row, next_row); } } // Memoize result computed[row][prev_row][curr_row] = true; memo[row][prev_row][curr_row] = count; return count; } int main() { // Initialize memoization table memset(computed, 0, sizeof(computed)); uint64_t total = 0; // For the first row, try all possible configurations for (int first_row = 0; first_row < 256; first_row++) { // For the first row, there's no previous row (all 0s) for (int second_row = 0; second_row < 256; second_row++) { // Check if any 1s in first row would be isolated if (!has_isolated_one(0, first_row, second_row)) { total += count_unholy(2, first_row, second_row); } } } printf("Total number of unholy 8x8 matrices: %llu\n", total); return 0; } |
Running the following program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | #include <stdio.h> #include <stdbool.h> #include <stdint.h> #include <string.h> // Cache for memoization - indexed by [row][previous row][current row] uint64_t memo[9][256][256]; bool computed[9][256][256]; // Check if a 1 in middle_row has no neighbors in any of the adjacent rows // or horizontally in its own row bool has_isolated_one(int top_row, int middle_row, int bottom_row) { for (int i = 0; i < 8; i++) { if (middle_row & (1 << i)) { // If this bit is a 1 bool has_neighbor = false; // Check left in current row if (i > 0 && (middle_row & (1 << (i-1)))) has_neighbor = true; // Check right in current row if (i < 7 && (middle_row & (1 << (i+1)))) has_neighbor = true; // Check above in top row if (top_row & (1 << i)) has_neighbor = true; // Check below in bottom row if (bottom_row & (1 << i)) has_neighbor = true; if (!has_neighbor) return true; // Found an isolated 1 } } return false; // No isolated 1s found } // Count unholy matrices starting from the given row uint64_t count_unholy(int row, int prev_row, int curr_row) { // If we've filled all rows if (row == 8) { // For the last row, check if there are isolated 1s with // no bottom row (bottom_row = 0) return has_isolated_one(prev_row, curr_row, 0) ? 0 : 1; } // Return memoized result if available if (computed[row][prev_row][curr_row]) return memo[row][prev_row][curr_row]; uint64_t count = 0; // Try all possible configurations for the next row for (int next_row = 0; next_row < 256; next_row++) { // Check if adding this next row creates an isolated 1 in the current row if (!has_isolated_one(prev_row, curr_row, next_row)) { count += count_unholy(row + 1, curr_row, next_row); } } // Memoize result computed[row][prev_row][curr_row] = true; memo[row][prev_row][curr_row] = count; return count; } int main() { // Initialize memoization table memset(computed, 0, sizeof(computed)); uint64_t total = 0; // For the first row, try all possible configurations for (int first_row = 0; first_row < 256; first_row++) { // For the first row, there's no previous row (all 0s) for (int second_row = 0; second_row < 256; second_row++) { // Check if any 1s in first row would be isolated if (!has_isolated_one(0, first_row, second_row)) { total += count_unholy(2, first_row, second_row); } } } printf("Total number of unholy 8x8 matrices: %llu\n", total); return 0; } |
Total number of unholy 8x8 matrices: 1121231537486377866
main.c: In function 'main':
main.c:86:53: warning: format '%llu' expects argument of type 'long long unsigned int', but argument 2 has type 'uint64_t' {aka 'long unsigned int'} [-Wformat=]
86 | printf("Total number of unholy 8x8 matrices: %llu\n", total);
| ~~~^ ~~~~~
| | |
| | uint64_t {aka long unsigned int}
| long long unsigned int
| %lu
Testing if the previous output contains the string 1121231537486377866
: True
A binary 8x8 matrix is 'unholy' if there are no isolated 1s. A 1 is isolated if there isn't another 1 in any of the 4 direct cardinal directions. Write a C program that counts the total number of unholy 8x8 matricies.
A binary 8x8 matrix is 'unholy' if there are no isolated 1s. A 1 is isolated if there isn't another 1 in any of the 4 direct cardinal directions. Write a C program that counts the total number of unholy 8x8 matricies.
# Solution: Counting Unholy 8x8 Binary Matrices I'll write a C program to count all unholy 8x8 matrices - matrices where no 1 is isolated (every 1 must have at least one adjacent 1 in a cardinal direction). This is a combinatorial problem that would be infeasible to solve with brute force (2^64 possible matrices). Instead, I'll use dynamic programming with bit manipulation for efficiency. ## Approach 1. Build the matrix row by row 2. Use DP where each state represents the previous row's pattern and current row's pattern 3. For each valid state, count all possible ways to build the rest of the matrix 4. Ensure that no 1 is isolated in any row ## Implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | #include <stdio.h> #include <stdbool.h> #include <string.h> // dp[row][prev_row_pattern][curr_row_pattern] long long dp[9][256][256]; bool visited[9][256][256]; // Check if a 1 at position i in mask has an adjacent 1 in the same row bool has_adjacent_in_row(int mask, int i) { // Check left if (i > 0 && (mask & (1 << (i-1)))) return true; // Check right if (i < 7 && (mask & (1 << (i+1)))) return true; return false; } // Check if the given configuration is valid (no isolated 1s) bool is_valid(int prev_row, int curr_row, int next_row) { for (int i = 0; i < 8; i++) { // Check if there's a 1 at this position in current row if (curr_row & (1 << i)) { bool has_adjacent = has_adjacent_in_row(curr_row, i); // Check above if (!has_adjacent && (prev_row & (1 << i))) has_adjacent = true; // Check below if (!has_adjacent && (next_row & (1 << i))) has_adjacent = true; // If still no adjacent 1s, this 1 is isolated if (!has_adjacent) return false; } } return true; } // Count unholy matrices recursively long long count_unholy(int row, int prev_row, int curr_row) { // If we've filled all rows, we have a valid matrix if (row == 8) return 1; // If we've already calculated this state if (visited[row][prev_row][curr_row]) return dp[row][prev_row][curr_row]; visited[row][prev_row][curr_row] = true; long long result = 0; // Try all possible configurations for the next row for (int next_row = 0; next_row < 256; next_row++) { if (is_valid(prev_row, curr_row, next_row) && is_valid(curr_row, next_row, 0)) { result += count_unholy(row + 1, curr_row, next_row); } } dp[row][prev_row][curr_row] = result; return result; } int main() { // Initialize DP table memset(visited, 0, sizeof(visited)); long long total = 0; // For the first row, previous row is all 0s for (int first_row = 0; first_row < 256; first_row++) { // For the second row for (int second_row = 0; second_row < 256; second_row++) { // Check if first and second rows form a valid configuration if (is_valid(0, first_row, second_row) && is_valid(first_row, second_row, 0)) { total += count_unholy(2, first_row, second_row); } } } printf("Total number of unholy 8x8 matrices: %lld\n", total); return 0; } |
I extracted the following code from that output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | #include <stdio.h> #include <stdbool.h> #include <string.h> // dp[row][prev_row_pattern][curr_row_pattern] long long dp[9][256][256]; bool visited[9][256][256]; // Check if a 1 at position i in mask has an adjacent 1 in the same row bool has_adjacent_in_row(int mask, int i) { // Check left if (i > 0 && (mask & (1 << (i-1)))) return true; // Check right if (i < 7 && (mask & (1 << (i+1)))) return true; return false; } // Check if the given configuration is valid (no isolated 1s) bool is_valid(int prev_row, int curr_row, int next_row) { for (int i = 0; i < 8; i++) { // Check if there's a 1 at this position in current row if (curr_row & (1 << i)) { bool has_adjacent = has_adjacent_in_row(curr_row, i); // Check above if (!has_adjacent && (prev_row & (1 << i))) has_adjacent = true; // Check below if (!has_adjacent && (next_row & (1 << i))) has_adjacent = true; // If still no adjacent 1s, this 1 is isolated if (!has_adjacent) return false; } } return true; } // Count unholy matrices recursively long long count_unholy(int row, int prev_row, int curr_row) { // If we've filled all rows, we have a valid matrix if (row == 8) return 1; // If we've already calculated this state if (visited[row][prev_row][curr_row]) return dp[row][prev_row][curr_row]; visited[row][prev_row][curr_row] = true; long long result = 0; // Try all possible configurations for the next row for (int next_row = 0; next_row < 256; next_row++) { if (is_valid(prev_row, curr_row, next_row) && is_valid(curr_row, next_row, 0)) { result += count_unholy(row + 1, curr_row, next_row); } } dp[row][prev_row][curr_row] = result; return result; } int main() { // Initialize DP table memset(visited, 0, sizeof(visited)); long long total = 0; // For the first row, previous row is all 0s for (int first_row = 0; first_row < 256; first_row++) { // For the second row for (int second_row = 0; second_row < 256; second_row++) { // Check if first and second rows form a valid configuration if (is_valid(0, first_row, second_row) && is_valid(first_row, second_row, 0)) { total += count_unholy(2, first_row, second_row); } } } printf("Total number of unholy 8x8 matrices: %lld\n", total); return 0; } |
Running the following program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | #include <stdio.h> #include <stdbool.h> #include <string.h> // dp[row][prev_row_pattern][curr_row_pattern] long long dp[9][256][256]; bool visited[9][256][256]; // Check if a 1 at position i in mask has an adjacent 1 in the same row bool has_adjacent_in_row(int mask, int i) { // Check left if (i > 0 && (mask & (1 << (i-1)))) return true; // Check right if (i < 7 && (mask & (1 << (i+1)))) return true; return false; } // Check if the given configuration is valid (no isolated 1s) bool is_valid(int prev_row, int curr_row, int next_row) { for (int i = 0; i < 8; i++) { // Check if there's a 1 at this position in current row if (curr_row & (1 << i)) { bool has_adjacent = has_adjacent_in_row(curr_row, i); // Check above if (!has_adjacent && (prev_row & (1 << i))) has_adjacent = true; // Check below if (!has_adjacent && (next_row & (1 << i))) has_adjacent = true; // If still no adjacent 1s, this 1 is isolated if (!has_adjacent) return false; } } return true; } // Count unholy matrices recursively long long count_unholy(int row, int prev_row, int curr_row) { // If we've filled all rows, we have a valid matrix if (row == 8) return 1; // If we've already calculated this state if (visited[row][prev_row][curr_row]) return dp[row][prev_row][curr_row]; visited[row][prev_row][curr_row] = true; long long result = 0; // Try all possible configurations for the next row for (int next_row = 0; next_row < 256; next_row++) { if (is_valid(prev_row, curr_row, next_row) && is_valid(curr_row, next_row, 0)) { result += count_unholy(row + 1, curr_row, next_row); } } dp[row][prev_row][curr_row] = result; return result; } int main() { // Initialize DP table memset(visited, 0, sizeof(visited)); long long total = 0; // For the first row, previous row is all 0s for (int first_row = 0; first_row < 256; first_row++) { // For the second row for (int second_row = 0; second_row < 256; second_row++) { // Check if first and second rows form a valid configuration if (is_valid(0, first_row, second_row) && is_valid(first_row, second_row, 0)) { total += count_unholy(2, first_row, second_row); } } } printf("Total number of unholy 8x8 matrices: %lld\n", total); return 0; } |
Total number of unholy 8x8 matrices: 132797167652221230
Testing if the previous output contains the string 1121231537486377866
: False