source: CIVL/examples/verifyThisProblems/DancingLinks.c@ c245979

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

formating DancingLinks.c

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

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