source: CIVL/examples/verifyThisProblems/dancingLinks.c@ 6247c10

1.23 2.0 main test-branch
Last change on this file since 6247c10 was 76f18de, checked in by Yihao Yan <yihaoyan1@…>, 10 years ago

format changes

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

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