| /* |
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the following conditions are met: |
| |
| * Redistributions of source code must retain the above copyright |
| notice, this list of conditions and the following disclaimer. |
| |
| * Redistributions in binary form must reproduce the above copyright |
| notice, this list of conditions and the following disclaimer in the |
| documentation and/or other materials provided with the distribution. |
| |
| * Neither the name of "The Computer Language Benchmarks Game" nor the |
| name of "The Computer Language Shootout Benchmarks" nor the names of |
| its contributors may be used to endorse or promote products derived |
| from this software without specific prior written permission. |
| |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
| LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| /* |
| * The Computer Language Shootout |
| * http://shootout.alioth.debian.org/ |
| * Contributed by Heiner Marxen |
| * |
| * "fannkuch" for C gcc |
| * |
| * $Id: fannkuch.1.gcc.code,v 1.15 2009-04-28 15:39:31 igouy-guest Exp $ |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| |
| #define Int int |
| #define Aint int |
| |
| static long |
| fannkuch( int n ) |
| { |
| Aint* perm; |
| Aint* perm1; |
| Aint* count; |
| long flips; |
| long flipsMax; |
| Int r; |
| Int i; |
| Int k; |
| Int didpr; |
| const Int n1 = n - 1; |
| |
| if( n < 1 ) return 0; |
| |
| perm = calloc(n, sizeof(*perm )); |
| perm1 = calloc(n, sizeof(*perm1)); |
| count = calloc(n, sizeof(*count)); |
| |
| for( i=0 ; i<n ; ++i ) perm1[i] = i; /* initial (trivial) permu */ |
| |
| r = n; didpr = 0; flipsMax = 0; |
| for(;;) { |
| if( didpr < 30 ) { |
| for( i=0 ; i<n ; ++i ) printf("%d", (int)(1+perm1[i])); |
| printf("\n"); |
| ++didpr; |
| } |
| for( ; r!=1 ; --r ) { |
| count[r-1] = r; |
| } |
| |
| #define XCH(x,y) { Aint t_mp; t_mp=(x); (x)=(y); (y)=t_mp; } |
| |
| if( ! (perm1[0]==0 || perm1[n1]==n1) ) { |
| flips = 0; |
| for( i=1 ; i<n ; ++i ) { /* perm = perm1 */ |
| perm[i] = perm1[i]; |
| } |
| k = perm1[0]; /* cache perm[0] in k */ |
| do { /* k!=0 ==> k>0 */ |
| Int j; |
| for( i=1, j=k-1 ; i<j ; ++i, --j ) { |
| XCH(perm[i], perm[j]) |
| } |
| ++flips; |
| /* |
| * Now exchange k (caching perm[0]) and perm[k]... with care! |
| * XCH(k, perm[k]) does NOT work! |
| */ |
| j=perm[k]; perm[k]=k ; k=j; |
| }while( k ); |
| if( flipsMax < flips ) { |
| flipsMax = flips; |
| } |
| } |
| |
| for(;;) { |
| if( r == n ) { |
| return flipsMax; |
| } |
| /* rotate down perm[0..r] by one */ |
| { |
| Int perm0 = perm1[0]; |
| i = 0; |
| while( i < r ) { |
| k = i+1; |
| perm1[i] = perm1[k]; |
| i = k; |
| } |
| perm1[r] = perm0; |
| } |
| if( (count[r] -= 1) > 0 ) { |
| break; |
| } |
| ++r; |
| } |
| } |
| } |
| |
| int |
| main( int argc, char* argv[] ) |
| { |
| int n = (argc>1) ? atoi(argv[1]) : 0; |
| |
| printf("Pfannkuchen(%d) = %ld\n", n, fannkuch(n)); |
| return 0; |
| } |