-
Notifications
You must be signed in to change notification settings - Fork 0
/
Towers4.1.cpp
366 lines (315 loc) · 10.2 KB
/
Towers4.1.cpp
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
//Tim Fullagar
//Towers of Hanoi
//UH REU summer 2013
//Purpose: To test that the formula provided by Paul K. Stockmeyer will give the minimum number of
// moves to solve a 4 node Towers of Hanoi puzzle with a variable number of disks. As long
// as the formula holds then we will start adding nodes up to 20 and see if a pattern emerges
// for a generalized Towers of Hanoi puzzle with a variable number of nodes above 4.
#include <iostream>
#include <cmath>
#include <fstream>
#include <climits>
using namespace std;
//Function: Towers_3peg
//Precondition: Requires "disks" and "count" to be declared and initialized and arr1[] to be declared
//Postcondition: Takes the amount of disks input by the user and calculates the minimum number of
// moves using the known 2^n-1 formula for 3 pegs
//Returns: NONE
void Towers_3peg(int disks, int arr1[], int count, ofstream &outfile);
//Function: Towers_sm
//Precondition: Requires "disks", "count", and "ppart" to be declared and initialized, "arr1[]"
// and "arr2[]" to be declared and both the "fout" and "outfile" streams declared
//Postcondition: Splits the stack of disks at every value and tests to see which split gives the
// lowest value and then places that value in an array
//Returns: Returns the minimum number of moves to solve the puzzle with n disks for 4
int Towers_sm(int disks, int arr1[], int arr2[], int count, bool &ppart, ofstream &fout, ofstream &outfile);
//Function: Towers_lg
//Precondition: Requires "disks", "count", and "ppart" to be declared and filled, requires "arr2[]"
// and "arr3[]" to be declred and recieves the infile, outfile, and fout streams
//Postcondition: The function determines if the program is on an even iteration and uses that info
// to determine whih array to fill. If the number of disks is less than or equal to
// the number of pegs the function uses 2(n)-1 to fill both arrays, if not the function
// fills arr2[] with the last inforation written by the "fout" stream and uses that
// array to fill arr3[], which is then written to a file for later use
//Returns: Returns the minimum number of moves to solve the puzzle with n disks for more than 4 pegs
int Towers_lg(int disks, int count, int arr2[], int arr3[], bool &ppart, ifstream &infile, ofstream & outfile, ofstream &fout);
int main()
{
int count;
bool ppart = false;
int disks;
int pegs;
int orig;
int m;
int n;
char yesno = 'Y';
ofstream outfile;
ifstream infile;
ofstream fout;
fout.open("array.txt");
infile.open("array.txt");
outfile.open("results.txt");
cout << "Welcome to the Towers of Hanoi caluculation program.\n";
cout << "You will be asked to provide a number of disks and pegs, then the program will then";
cout << " calculate the number of moves required to solve a puzzle with that number of disks";
cout << " for 4 pegs, then 5 pegs and so on up to the number of pegs entered. The program will";
cout << " print the results to the screen and a file.";
cout << endl;
while(yesno == 'Y' || yesno == 'y')
{
//Initializing here so count and disks so far will reset when doing the program again
count = 3;
cout << "Please enter an integer greater than 0 for the disks you wish to use.\n";
cin >> disks;
cout << "Please enter an integer 3 or greater for the nuber of pegs you wish to use .\n";
cin >> pegs;
//Using to check that the input values are indeed integers
n = (10*disks)%10;
m = (10*pegs)%10;
//While the input for "disks" is not greater than 0 and is not an integer, ask the user to
//re-enter the value
while(disks < 0 && n != 0)
{
cout << "Please enter an integer that is greater than 0.\n";
cin >> disks;
}
//Declaring the arrays of size "disks"
int arr1[disks];
int arr2[disks];
int arr3[disks];
//While the input for "pegs" is not greater than 3 and is not an integer, ask the user re-enter
//the value.
while(pegs < 3 && m != 0)
{
cout << "Please enter an integer that is equal to or greater than 3.\n";
cin >> pegs;
}
if(count == 3)
Towers_3peg(disks, arr1, count, outfile);
while(count <= pegs)
{
if(count == 4)
orig = Towers_sm(disks, arr1, arr2, count, ppart, fout, outfile);
else
orig = Towers_lg(disks, count, arr2, arr3, ppart, infile, outfile, fout);
if(!ppart)
{
cout << "The number of moves for " << disks << " disks and " << count << " pegs using";
cout << " \na spliting method is approximately: " << orig << endl << endl;
outfile << "The number of moves for " << disks << " disks and " << count << " pegs using";
outfile << " \na spliting method is approximately: " << orig << endl << endl;
}
else
{
cout << "The number of moves for " << disks << " disks and " << count << " pegs, in which ";
cout << "\nthe number of disks in equal to or less than the number of pegs is: " << orig << endl;
cout << endl;
outfile << "The number of moves for " << disks << " disks and " << count << " pegs, in which ";
outfile << "\nthe number of disks is less than the number of pegs is: " << orig << endl;
outfile << endl;
}
count++;
}
//Asking the user if they would like to use the program again
cout << "Would you like to go again? Please enter 'y' or 'Y' for yes and 'n' or 'N' for \nno." << endl;
cin >> yesno;
while(yesno != 'Y' && yesno != 'y' && yesno != 'N' && yesno != 'n')
{
cout << "Please enter 'y or 'Y' for yes and 'n' or 'N' for no." << endl;
cin >> yesno;
}
}
fout.close();
infile.close();
outfile.close();
return 0;
}
void Towers_3peg(int disks, int arr1[], int count, ofstream &outfile)
{
int diskssofar;
int result;
for(diskssofar = 1; diskssofar < count; diskssofar++)
arr1[diskssofar - 1] = 2*(diskssofar) - 1;
if(diskssofar >= count)
{
for(int h = diskssofar; h <= disks; h++)
arr1[h-1] = pow(2.00, diskssofar) - 1;
}
cout << "The array for 3 pegs and " << disks << " disks is: ";
outfile << "The array for 3 pegs and " << disks << " disks is: ";
for (int t = 0; t < disks; t++)
{
cout << arr1[t] << " ";
outfile << arr1[t] << " ";
}
cout << endl;
cout << endl;
outfile << endl;
outfile << endl;
}
int Towers_sm(int disks, int arr1[], int arr2[], int count, bool &ppart, ofstream &fout, ofstream &outfile)
{
int split;
int split_res;
int remaining;
int remaining_res;
int result;
int diskssofar;
int smallest_so_far;
for(diskssofar = 1; diskssofar < count; diskssofar++)
{
arr2[diskssofar - 1] = 2*(diskssofar) - 1;
ppart = true;
}
if(diskssofar >= count)
{
for(int a = diskssofar; a <= disks; a++)
{
//Resetting "smallest_so_far"
smallest_so_far = INT_MAX;
for(split = 1; split < diskssofar; split++)
{
remaining = diskssofar - split;
split_res = arr2[split - 1];
remaining_res = arr1[remaining - 1];
result = 2*(split_res) + remaining_res;
//Only update "smallest_so_far" if "result" is lower
if(result <= smallest_so_far)
smallest_so_far = result;
}
//Setting the used array to "smallest_so_far"
arr1[a-1] = smallest_so_far;
ppart = false;
}
}
cout << "The array is: ";
outfile << "The array is: ";
for (int g = 0; g < disks; g++)
{
cout << arr2[g] << " ";
fout << arr2[g] << " ";
outfile << arr2[g] << " ";
}
cout << endl;
outfile << endl;
//Setting the writting stream cursor back to the beginning
fout.clear();
fout.seekp(0);
return arr2[disks - 1];
}
int Towers_lg(int disks, int count, int arr2[], int arr3[], bool &ppart, ifstream &infile, ofstream & outfile, ofstream &fout)
{
int even = count%2;
int totres;
int split;
int split_res;
int remaining;
int remaining_res;
int result;
int smallest_so_far;
int disks1;
//Setting in reading stream cursor back to the beginning
infile.clear();
infile.seekg(0);
for(disks1 = 1; disks1 < count; disks1++)
{
arr2[disks1 - 1] = 2*(disks1) - 1;
arr3[disks1 - 1] = 2*(disks1) - 1;
}
//If the number of disks is equal to or less than the number of pegs, then calculate based on 2n-1
if(disks < count)
{
cout << "The array is: ";
outfile << "The array is: ";
if(even == 0)
{
for (int g = 0; g < disks; g++)
{
cout << arr2[g] << " ";
outfile << arr2[g] << " ";
fout << arr2[g] << " ";
}
cout << endl;
outfile << endl;
//Setting the writting stream cursor back to the beginning
fout.clear();
fout.seekp(0);
//Making sure the reading stream is at the beginning of the file
infile.clear();
infile.seekg(0);
ppart = true;
return totres = arr2[disks - 1];
}
else
{
cout << "The array is: ";
outfile << "The array is: ";
for (int r = 0; r < disks; r++)
{
cout << arr3[r] << " ";
outfile << arr3[r] << " ";
fout << arr3[r] << " ";
}
cout << endl;
outfile << endl;
//Setting the writting stream cursor back to the beginning
fout.clear();
fout.seekp(0);
//Making sure the reading stream is at the beginning of the file
infile.clear();
infile.seekg(0);
ppart = true;
return totres = arr3[disks - 1];
}
}
else
{
while(!infile.eof())
{
for(int z = 0; z < disks; z++)
{
infile >> arr2[z];
}
}
//Resetting the reading cursor back to the beginning
infile.clear();
infile.seekg(0);
//Setting the first position in the next array
arr3[0] = 1;
for(int j = 4; j <= count; j++)
{
//Resetting "smallest_so_far"
smallest_so_far = INT_MAX;
for(split = 1; split < disks1; split++)
{
remaining = disks1 - split;
split_res = arr3[split - 1];
remaining_res = arr3[remaining - 1];
result = 2*(split_res) + remaining_res;
//Only update "smallest_so_far" if "result" is lower
if(result <= smallest_so_far)
smallest_so_far = result;
}
//Setting the used array to "smallest_so_far"
arr2[j - 1] = smallest_so_far;
}
cout << "The array is: ";
outfile << "The array is: ";
for (int g = 0; g < disks; g++)
{
cout << arr2[g] << " ";
outfile << arr2[g] << " ";
fout << arr2[g] << " ";
}
cout << endl;
outfile << endl;
//Setting the writting stream cursor back to the beginning
fout.clear();
fout.seekp(0);
//Making sure the reading stream is at the beginning of the file
infile.clear();
infile.seekg(0);
ppart = false;
}
return totres = arr3[disks - 1];
}