void hanoi( rod ** head, rod ** tail)
{
time_start( ) ;
rod * temp, * temp2, * head_t = * head;
int flag = 0 , div = 0 ;
for ( int i = 0 ; i < rods - 2 ; i++ )
{
while ( ( * tail) - > disks[ n - 1 ] ! = n)
{
temp = * head, flag = 0 ;
if ( div % 2 == 0 ) // move smallest disk to the right if odd, or left if even
{
while ( temp ! = ( * tail) - > next)
{
if ( flag == 1 )
{
unshift( 1 , & temp- > disks) ;
break ;
}
if ( temp- > disks[ 0 ] == 1 )
{
pop( & temp- > disks) ;
flag = 1 ;
}
if ( n % 2 == 0 )
{
temp = ( temp- > next == ( * tail) - > next) ? * head : temp- > next;
}
else
{
temp = ( temp- > prev == ( * head) - > prev) ? * tail : temp- > prev;
}
}
}
else // make first possible move
{
while ( temp ! = ( * tail) - > next && flag == 0 )
{
temp2 = * head;
while ( temp2 ! = ( * tail) - > next)
{
if ( ( temp- > disks[ 0 ] < temp2- > disks[ 0 ] || temp2- > disks[ 0 ] == 0 ) && temp- > disks[ 0 ] ! = 1 && temp- > disks[ 0 ] ! = 0 && temp- > num ! = temp2- > num)
{
int t = temp- > disks[ 0 ] ;
pop( & temp- > disks) ;
unshift( t, & temp2- > disks) ;
flag = 1 ;
break ;
}
temp2 = temp2- > next;
}
temp = temp- > next;
}
}
div ++ , moves++ ;
}
// divide and conquer
if ( i < rods - 3 )
{
if ( ( * head) - > num <= i + 1 )
* head = ( * head) - > next;
if ( ( * tail) - > num <= i + 3 )
* tail = ( * tail) - > next;
}
}
* head = head_t;
time_stop( ) ;
}
/**
* Input: {1, 2, 3, 4, 0}, el = 5
* Output: {5, 1, 2, 3, 4}
*
* Input array ALWAYS contains 0's at the end
*/
void unshift( int el, int ** arr)
{
for ( int i = ( int ) n - 1 ; i > 0 ; i-- )
{
( * arr) [ i] = ( * arr) [ i - 1 ] ;
}
( * arr) [ 0 ] = el;
}
/**
* Input: {1, 2, 3, 4}
* Output: {2, 3, 4, 0}
*/
void pop( int ** arr)
{
for ( int i = 0 ; i < ( int ) n - 1 ; i++ )
{
( * arr) [ i] = ( * arr) [ i + 1 ] ;
}
( * arr) [ n - 1 ] = 0 ;
}
dm9pZCBoYW5vaShyb2QgKipoZWFkLCByb2QgKip0YWlsKQp7Cgl0aW1lX3N0YXJ0KCk7CgoJcm9kICp0ZW1wLCAqdGVtcDIsICpoZWFkX3QgPSAqaGVhZDsKCWludCBmbGFnID0gMCwgZGl2ID0gMDsKCglmb3IoaW50IGkgPSAwOyBpIDwgcm9kcyAtIDI7IGkrKykKCXsKCQl3aGlsZSgoKnRhaWwpLT5kaXNrc1tuIC0gMV0gIT0gbikKCQl7CgkJCXRlbXAgPSAqaGVhZCwgZmxhZyA9IDA7CgoJCQlpZihkaXYgJSAyID09IDApIC8vIG1vdmUgc21hbGxlc3QgZGlzayB0byB0aGUgcmlnaHQgaWYgb2RkLCBvciBsZWZ0IGlmIGV2ZW4KCQkJewoJCQkJd2hpbGUodGVtcCAhPSAoKnRhaWwpLT5uZXh0KQoJCQkJewoJCQkJCWlmKGZsYWcgPT0gMSkKCQkJCQl7CgkJCQkJCXVuc2hpZnQoMSwgJnRlbXAtPmRpc2tzKTsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJCWlmKHRlbXAtPmRpc2tzWzBdID09IDEpCgkJCQkJewoJCQkJCQlwb3AoJnRlbXAtPmRpc2tzKTsKCQkJCQkJZmxhZyA9IDE7CgkJCQkJfQoKCQkJCQlpZihuICUgMiA9PSAwKQoJCQkJCXsKCQkJCQkJdGVtcCA9ICh0ZW1wLT5uZXh0ID09ICgqdGFpbCktPm5leHQpID8gKmhlYWQgOiB0ZW1wLT5uZXh0OwoJCQkJCX0KCQkJCQllbHNlCgkJCQkJewoJCQkJCQl0ZW1wID0gKHRlbXAtPnByZXYgPT0gKCpoZWFkKS0+cHJldikgPyAqdGFpbCA6IHRlbXAtPnByZXY7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWVsc2UgLy8gbWFrZSBmaXJzdCBwb3NzaWJsZSBtb3ZlCgkJCXsKCQkJCXdoaWxlKHRlbXAgIT0gKCp0YWlsKS0+bmV4dCAmJiBmbGFnID09IDApCgkJCQl7CgkJCQkJdGVtcDIgPSAqaGVhZDsKCQkJCQl3aGlsZSh0ZW1wMiAhPSAoKnRhaWwpLT5uZXh0KQoJCQkJCXsKCQkJCQkJaWYoKHRlbXAtPmRpc2tzWzBdIDwgdGVtcDItPmRpc2tzWzBdIHx8IHRlbXAyLT5kaXNrc1swXSA9PSAwKSAmJiB0ZW1wLT5kaXNrc1swXSAhPSAxICYmIHRlbXAtPmRpc2tzWzBdICE9IDAgJiYgdGVtcC0+bnVtICE9IHRlbXAyLT5udW0pCgkJCQkJCXsKCQkJCQkJCWludCB0ID0gdGVtcC0+ZGlza3NbMF07CgkJCQkJCQlwb3AoJnRlbXAtPmRpc2tzKTsKCQkJCQkJCXVuc2hpZnQodCwgJnRlbXAyLT5kaXNrcyk7CgkJCQkJCQlmbGFnID0gMTsKCQkJCQkJCWJyZWFrOwoJCQkJCQl9CgkJCQkKCQkJCQkJdGVtcDIgPSB0ZW1wMi0+bmV4dDsKCQkJCQl9CgkJCQoJCQkJCXRlbXAgPSB0ZW1wLT5uZXh0OwoJCQkJfQoJCQl9CgoJCQlkaXYrKywgbW92ZXMrKzsKCQl9CgoJCS8vIGRpdmlkZSBhbmQgY29ucXVlcgoJCWlmKGkgPCByb2RzIC0gMykKCQl7CgkJCWlmKCgqaGVhZCktPm51bSA8PSBpICsgMSkKCQkJCSpoZWFkID0gKCpoZWFkKS0+bmV4dDsKCQkJaWYoKCp0YWlsKS0+bnVtIDw9IGkgKyAzKQoJCQkJKnRhaWwgPSAoKnRhaWwpLT5uZXh0OwoJCX0KCX0KCQoJKmhlYWQgPSBoZWFkX3Q7CgoJdGltZV9zdG9wKCk7Cn0KCi8qKgogKiBJbnB1dDogezEsIDIsIDMsIDQsIDB9LCBlbCA9IDUKICogT3V0cHV0OiB7NSwgMSwgMiwgMywgNH0KICogCiAqIElucHV0IGFycmF5IEFMV0FZUyBjb250YWlucyAwJ3MgYXQgdGhlIGVuZAogKi8Kdm9pZCB1bnNoaWZ0KGludCBlbCwgaW50ICoqYXJyKQp7Cglmb3IoaW50IGkgPSAoaW50KW4gLSAxOyBpID4gMDsgaS0tKQoJewoJCSgqYXJyKVtpXSA9ICgqYXJyKVtpIC0gMV07Cgl9CiAgICAoKmFycilbMF0gPSBlbDsKfQoKLyoqCiAqIElucHV0OiB7MSwgMiwgMywgNH0KICogT3V0cHV0OiB7MiwgMywgNCwgMH0KICovCnZvaWQgcG9wKGludCAqKmFycikKewoJZm9yKGludCBpID0gMDsgaSA8IChpbnQpbiAtIDE7IGkrKykKCXsKCQkoKmFycilbaV0gPSAoKmFycilbaSArIDFdOwoJfQkKCSgqYXJyKVtuIC0gMV0gPSAwOwp9