int solve(){ /* need factorial to calculate size of tables */ int* fact = factorial(SIZE); /* maximum size of a hash of size SIZE*/ int max_index = fact[SIZE] - 1; /* tables to store hashes of permutations */ char* table_now = calloc(max_index, sizeof(char)); char* table_next = calloc(max_index, sizeof(char)); /* table pointer for swapping */ char* table_temp = NULL; /* table index */ unsigned int ti; /* how deep we are */ int depth; /* set the initial configuration, an ascending sort of consecutive integers 1 .. SIZE */ table_now[0] = 1; /* perform all possible swaps from positions in "table_now" */ /* record these swapped positions in table_next */ for(depth = 0 ; depth < DEPTH; depth++){ /* iterate over generation, build next generation */ for(ti = 0; ti < max_index; ti++){ /* if the position was reached last time */ if(table_now[ti] == 1){ /* rebuild the sequence from the hash */ int* sequence = inv_lex_rank(ti); int swaps; for(swaps = 0; swaps < SIZE - 1; swaps++){ /* swap it */ swap(sequence, swaps); /* set the resulting sequence in the next generation */ table_next[lex_rank(sequence)] = 1; /* swap it back */ swap(sequence, swaps); }/* end for (swaps) */ /* we're done with this sequence */ free(sequence); }/* end if */ }/* end for (ti) */ /* swap tables */ table_temp = table_next; table_next = table_now; table_now = table_temp; /* clear out next */ memset(table_next, 0, fact[SIZE] - 1); }/* end for (depth) */ /* now count the set bits */ int answer = 0; for(ti = 0; ti < max_index; ti++){ if(table_now[ti] > 0){ answer++; } } printf("%d\n", answer); free(table_now); free(table_next); return answer; }
/*test the inverse functions on each other */ void test_lex_rank(){ int x; for(x = 0; x < 5040; x++){ if(lex_rank(inv_lex_rank(x)) != x){ printf("%d doesn't work\n", x); prar(inv_lex_rank(x)); fflush(stdout); } } }
/* Map any node to its I/O node */ int io_node(const int node){ int i,j,k; /* Get the machine coordinates for the specified node */ lex_coords(io_node_coords, 4, machine_dimensions, node); /* Round the node coordinates down to get the io_node coordinate */ for(i = 0; i < 4; i++) io_node_coords[i] = nodes_per_ionode[i] * (io_node_coords[i]/nodes_per_ionode[i]); /* Return the linearized machine coordinates of the I/O node */ return (int)lex_rank(io_node_coords, 4, machine_dimensions); }
/* Map any node to its I/O node */ int io_node(const int node){ int i; int io_node_coords[4]; /* If we don't have I/O partitions, each node does its own I/O */ if(ionodegeomvals == NULL) return node; /* Get the machine coordinates for the specified node */ lex_coords(io_node_coords, 4, dim_mach, node); /* Round the node coordinates down to get the io_node coordinate */ for(i = 0; i < 4; i++) io_node_coords[i] = nodes_per_ionode[i] * (io_node_coords[i]/nodes_per_ionode[i]); /* Return the linearized machine coordinates of the I/O node */ return (int)lex_rank(io_node_coords, 4, dim_mach); }