source: CIVL/examples/verifyThisProblems/dancingLinks.c@ 0e12c94

1.23 2.0 acw/focus-triggers main test-branch
Last change on this file since 0e12c94 was f7e5282, checked in by Yihao Yan <yihaoyan1@…>, 10 years ago

minor changes

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@3142 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 3.7 KB
Line 
1/*
2author Yihao
3
4Link(chanllege 3): http://etaps2015.verifythis.org/challenges
5
6problem description:
7Dancing links is a technique introduced in 1979 by Hitotumatu and
8Noshita and later popularized by Knuth. The technique can be used to
9efficiently implement a search for all solutions of the exact cover
10problem, which in its turn can be used to solve Tiling, Sudoku,
11N-Queens, and other problems.
12
13Suppose x points to a node of a doubly linked list; let L[x] and R[x]
14point to the predecessor and successor of that node. Then the operations
15
16L[R[x]] := L[x];
17R[L[x]] := R[x];
18
19remove x from the list. The subsequent operations
20
21L[R[x]] := x;
22R[L[x]] := x;
23
24will put x back into the list again.
25
26command: civl verify DancingLinks.c
27
28result: the problem is solved
29
30*/
31
32#include <stdlib.h>
33#include <stdbool.h>
34#include <assert.h>
35#include <time.h>
36
37#ifdef _CIVL
38#include <civlc.cvh>
39$input int N=10;
40$assume (N >= 3);
41#else
42int N=10;
43#endif
44
45struct Node {
46 struct Node *left;
47 struct Node *right;
48};
49
50void insert(struct Node *x) {
51 x->right->left = x;
52 x->left->right = x;
53}
54
55void delete(struct Node *x) {
56 x->right->left = x->left;
57 x->left->right = x->right;
58}
59
60//initilize a linkedlist
61struct Node* init(int n) {
62 struct Node *head = (struct Node *)malloc(sizeof(struct Node));
63 struct Node *temp = head;
64
65 temp->left = NULL;
66 while(n > 1) {
67 struct Node *new = (struct Node *)malloc(sizeof(struct Node));
68
69 temp->right = new;
70 new->left = temp;
71 temp = temp->right;
72 n--;
73 }
74 temp->right = NULL;
75 return head;
76}
77
78struct Node* getNode(struct Node* list, int index) {
79 struct Node *result = list;
80
81 while(index >1) {
82 result = result->right;
83 index--;
84 }
85 return result;
86}
87
88void initNodeArray(struct Node** array, struct Node* list, int n) {
89 struct Node *cur = list;
90 int index=0;
91
92 while(n > 0) {
93 array[index++] = cur;
94 cur = cur->right;
95 n--;
96 }
97}
98
99void verifyDelete(struct Node *list, struct Node **nodeArray, int index, int n) {
100 struct Node *temp1 = list;
101
102 for(int i=0; i<index-1; i++) {
103 assert(temp1 == nodeArray[i]);
104 assert(temp1->left == (nodeArray[i])->left);
105 if(i != index-2) {
106 assert(temp1->right == (nodeArray[i])->right);
107 } else {
108 if(index == n) {
109 assert(temp1->right == NULL);
110 } else {
111 assert(temp1->right == nodeArray[index]);
112 }
113 }
114 temp1 = temp1->right;
115 }
116
117 for(int j=index; j<=n-1; j++) {
118 assert(temp1 == nodeArray[j]);
119 assert(temp1->right == (nodeArray[j])->right);
120 if(j == index) {
121 if(index == 1) {
122 assert(temp1->left == NULL);
123 } else {
124 assert(temp1->left == nodeArray[index-2]);
125 }
126 } else {
127 assert(temp1->left == (nodeArray[j])->left);
128 }
129 temp1 = temp1->right;
130 }
131}
132
133void verifyInsert(struct Node *list, struct Node **nodeArray, int index, int n) {
134 struct Node *temp1 = list;
135
136 for(int k=0;k < n; k++) {
137 assert(temp1 == nodeArray[k]);
138 assert(temp1->left == (nodeArray[k])->left);
139 assert(temp1->right == (nodeArray[k])->right);
140 temp1 = temp1->right;
141 }
142}
143
144int main() {
145 // size of the linked list
146#ifdef _CIVL
147 int n = $choose_int(N-2)+3;
148#else
149 srand(time(NULL));
150 int n = rand()%(N-2)+3;
151#endif
152
153 struct Node *list = init(n);
154 // the index of the node who get deleted
155#ifdef _CIVL
156 int index = $choose_int(n-2)+2;
157#else
158 int index = rand()%(N-2)+2;
159#endif
160
161 struct Node *x = getNode(list, index);
162 struct Node *nodeArray[n];
163
164 initNodeArray(nodeArray, list, n);
165 delete(x);
166 verifyDelete(list, nodeArray, index, n);
167 insert(x);
168 verifyInsert(list, nodeArray, index, n);
169
170 int t = n;
171 struct Node *temp1 = list;
172
173 while(t >0) {
174 struct Node *temp2 = temp1;
175
176 temp1 = temp1->right;
177 free(temp2);
178 t--;
179 }
180 return 0;
181}
Note: See TracBrowser for help on using the repository browser.