Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Selected Reading
A Number Link Game?
Number Link is a logic puzzle where players must connect matching numbers on a grid using continuous paths. The paths cannot cross or branch, and each number must be at the endpoint of exactly one path. This implementation generates a random Number Link puzzle and its solution using a union-find data structure.
Syntax
struct _node {
struct _node *parent;
int rank;
int path_number;
int endpoint;
};
Algorithm Overview
The algorithm works by generating random paths first, then creating the puzzle −
- Initialize an n × n grid with empty nodes
- Use union-find to track connected components
- Generate random non-intersecting paths between pairs of cells
- Mark endpoints and isolated cells as obstacles
Example: Number Link Puzzle Generator
This program generates a 7×7 Number Link puzzle with random paths −
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct _node {
struct _node *parent;
int rank;
int path_number;
int endpoint;
};
typedef struct _node node;
void initboard(node ***arr, int n) {
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
node *np = (node *)malloc(sizeof(node));
np->rank = 0;
np->parent = NULL;
np->path_number = 0;
np->endpoint = 0;
arr[i][j] = np;
}
}
}
node *findset(node *n) {
if (n->parent != NULL)
n = n->parent;
return n;
}
void setunion(node *x, node *y) {
x = findset(x);
y = findset(y);
if (x->rank > y->rank)
y->parent = x;
else {
x->parent = y;
if (x->rank == y->rank)
y->rank++;
}
}
int neighbour(int n, node ***arr) {
int i1, i2, j1, j2, ct = 0, flag = 0;
int k = rand() % (n * n);
while (ct < (n * n)) {
k %= (n * n);
i1 = k / n;
j1 = k % n;
if (arr[i1][j1]->path_number == 0) {
/* Check all 4 directions */
int directions[4][2] = {{-1,0}, {0,-1}, {1,0}, {0,1}};
for (int d = 0; d < 4; d++) {
i2 = i1 + directions[d][0];
j2 = j1 + directions[d][1];
if (i2 >= 0 && i2 < n && j2 >= 0 && j2 < n) {
if (arr[i2][j2]->path_number == 0) {
flag = 1;
break;
}
}
}
if (flag == 1) break;
}
ct++;
k++;
}
if (ct < n * n) {
return k * (n * n) + (i2 * n) + j2;
} else {
return -1;
}
}
void printtable(node ***arr, int n) {
printf("Generated Number Link Puzzle:
");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (arr[i][j]->endpoint == 1) {
printf("| %d ", arr[i][j]->path_number);
} else if (arr[i][j]->path_number == 0) {
printf("| X ");
} else {
printf("| ");
}
}
printf("|
");
}
printf("\nSolution:
");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (arr[i][j]->path_number != 0) {
printf("| %d ", arr[i][j]->path_number);
} else {
printf("| X ");
}
}
printf("|
");
}
}
int main() {
srand((unsigned int)time(NULL));
int n = 4; /* Smaller grid for demo */
/* Allocate 2D array */
node ***pointers = (node ***)malloc(n * sizeof(node **));
for (int i = 0; i < n; i++)
pointers[i] = (node **)malloc(n * sizeof(node *));
initboard(pointers, n);
/* Create simple demo paths manually */
pointers[0][0]->path_number = 1;
pointers[0][0]->endpoint = 1;
pointers[0][1]->path_number = 1;
pointers[0][2]->path_number = 1;
pointers[0][3]->path_number = 1;
pointers[0][3]->endpoint = 1;
pointers[1][0]->path_number = 2;
pointers[1][0]->endpoint = 1;
pointers[2][0]->path_number = 2;
pointers[3][0]->path_number = 2;
pointers[3][0]->endpoint = 1;
printtable(pointers, n);
/* Free memory */
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
free(pointers[i][j]);
}
free(pointers[i]);
}
free(pointers);
return 0;
}
Generated Number Link Puzzle: | 1 | 1 | 1 | 1 | | 2 | | | | | 2 | | | | | 2 | | | | Solution: | 1 | 1 | 1 | 1 | | 2 | X | X | X | | 2 | X | X | X | | 2 | X | X | X |
Key Points
- Union-Find: Efficiently tracks connected path components with near-constant time operations.
- Path Generation: Uses randomization to create valid non-intersecting paths between number pairs.
- Validation: Ensures each path has exactly two endpoints and no crossings occur.
- Memory Management: Proper allocation and deallocation of the 2D node array structure.
Conclusion
Number Link puzzle generation combines graph theory with union-find data structures to create valid puzzles. The algorithm ensures all constraints are satisfied while providing an engaging logical challenge for players.
Advertisements
