static inline double horner_seq (double x, const double* a, unsigned long n) { double res = a[to_index(n, n)]; return horner_seq_hilo(x, a, n, res, n, 0); }
static void __h_insert(struct hash_table *ht, unsigned bucket, struct entry *e) { e->hash_next = ht->buckets[bucket]; ht->buckets[bucket] = to_index(ht->es, e); }
static unsigned get_index(struct entry_alloc *ea, struct entry *e) { return to_index(ea->es, e) - ea->begin; }
Grid_2D :: Grid_2D(const char filename[]) { ifstream fin; fin.open(filename); fin >> this->width; fin >> this->height; this->displays = new uint8_t[this->width * this->height](); this->connections = new uint8_t[this->width * this->height](); this->weights= new uint8_t[this->width * this->height](); this->path = new uint8_t[this->width * this->height](); uint32_t index; for(uint32_t i = 0; i < this->height; i ++) { for(uint32_t j = 0; j < this->width; j++) { index = to_index(i , j); fin >> this->displays[index]; if(this->displays[index] == BLOCKED) { this->weights[index] = INF; } else { this->weights[index] = 1; } } } fin.close(); uint32_t top; uint32_t top_L; uint32_t top_R; uint32_t left; uint32_t right; uint32_t bot; uint32_t bot_L; uint32_t bot_R; bool not_top_edge; bool not_bot_edge; bool not_left_edge; bool not_right_edge; for(uint32_t i = 0; i < this->height; i ++) { for(uint32_t j = 0; j < this->width; j++) { index = to_index(i, j); top = to_index(i + 1, j); top_L = to_index(i + 1, j - 1); top_R = to_index(i + 1, j + 1); left = to_index(i, j - 1); right = to_index(i, j + 1); bot = to_index(i - 1, j); bot_L = to_index(i - 1, j - 1); bot_R = to_index(i - 1, j + 1); not_top_edge = i ? 1 : 0; not_bot_edge = !(height - (i + 1)) ? 1 : 0; not_left_edge = j ? 1 : 0; not_right_edge = !(width - (j + 1)) ? 1 : 0; this->connections[index] = 0; if(not_top_edge) { // index = 1000 0000 = 128 this->connections[index] + (this->weights[top] != INF) ? 128 : 0; if(not_left_edge) { // index = 0100 0000 = 64 this->connections[index] + (this->weights[top_L] != INF) ? 64 : 0; } if(not_right_edge) { // index = 0010 0000 = 32 this->connections[index] + (this->weights[top_R] != INF) ? 32 : 0; } } if(not_left_edge) { // index = 0001 0000 = 16 this->connections[index] + (this->weights[left] != INF) ? 16 : 0; } if(not_right_edge) { // index = 0000 1000 = 8 this->connections[index] + (this->weights[left] != INF) ? 8 : 0; } if(not_bot_edge) { // index = 0000 0100 = 4 this->connections[index] + (this->weights[bot] != INF) ? 4 : 0; if(not_left_edge) { // index = 0000 0010 = 2 this->connections[index] + (this->weights[bot_L] != INF) ? 2 : 0; } if(not_right_edge) { // index = 0000 0001 = 1 this->connections[index] + (this->weights[bot_R] != INF) ? 1 : 0; } } } } }
int main( int argc, char ** argv ) { /* Vars */ uint i, j, k; node block; /* check to make sure an input file was supplied */ /* get the number of blocks (the first line of input) */ /* I am just assuming that the input will always be */ /* correct since this is for a competition */ if( argc == 2) get_num_blocks(argv[1]); else exit(EXIT_FAILURE); /* Initialize the graph and cycles arrays */ /* The graph array is an incidence matrix */ /* if graph(i,j) is true, then there is a */ /* directed edge from i -> j */ for( i = 0; i < SIZE; ++i ) { for( j = 0; j < SIZE; ++j ) { graph[i][j] = NO_CONN; } } /* Get the input blocks */ for( i = 0; i < num_blocks; ++i ) { /* for each block... */ if( get_block( &block ) > 2 ) { /* if the block has more than 2 '00' terms then just skip it */ /* if the block has 3 or 4 sides with '00' terms then it */ /* cannot connect to anything so it doesn't matter */ continue; } /* else // block has less than 2 zeros */ /* if a block matches itself, then the structure is unbounded */ /* We wouldn't have to do this, but it is a simple enough check */ /* and as n -> 40,000 it can save a lot of time */ for( k = 0; k < 4; ++k ) { for( j = 0; j < 4; ++j ) { if( block[k*2] == block[j*2] && block[k*2+1] != block[j*2+1] ) goto unbounded; } } /* else // block does not match itself */ /* add links to the graph */ for( j = 0; j < 4; ++j ) { /* For each side... */ /* assume correct formatting so only need to test first block for if 0 */ if( block[j*2] == '0' ) { /* no links can be added */ continue; } else { for( k = 0; k < 4; ++k ) { /* for every other side on the block... */ if( j == k ) /* same side we are already on, so continue */ continue; else if( block[k*2] == '0' ) /* side is 00 so continue */ continue; /* else add link */ /* The basic idea for the links is, add a directed edge */ /* between the opposite of that side (i.d. opposite of */ /* P- is P+) to each of the other sides on the block. */ /* This is because if you can connect to the current */ /* side of the block (i.d. block[j*2]) then you will */ /* connect with the opposite of this block, and it will */ /* connect you to any of the other sides of the current */ /* block. */ /* The problem is actually pretty nice since you can */ /* rotate and reflect, the geometry of the block doesnt */ /* actually matter. */ if( block[j*2+1] == '+' ) graph[ NEGATIVE( block[j*2] ) ][ to_index( &block[k*2] ) ] = 1; /* else the block is negative */ else graph[ POSITIVE( block[j*2] ) ][ to_index( &block[k*2] ) ] = 1; } } } /* turn on __DEBUG__ if you want to see the graph */ print_graph(); } /* graph is all set up, just check for cycles */ if( traverse() ) goto unbounded; /* U mad bro? */ /* if we made it here then it is a bounded structure */ printf("bounded\n"); exit(EXIT_SUCCESS); unbounded: printf("unbounded\n"); exit(EXIT_SUCCESS); } /**~ end main ~**/
void add_clause(int a, int b) { a = to_index(a); b = to_index(b); add_edge(not_(a), b); add_edge(not_(b), a); }
void parameters::substitute( value_type *s ) const { value_type replacement; for ( size_type i = 1; i <= 9; ++i ) { value_type::size_type dollar_pos = value_type::npos; bool inside_braces = false; bool replace; for ( value_type::size_type pos = 0; pos < s->size(); ++pos ) { char c = s->at( pos ); // // ordinary (non-substitution) character case // if ( dollar_pos == value_type::npos ) { switch ( c ) { case '$': dollar_pos = pos; replacement.clear(); break; case '\\': // // We can't erase the \ here until the last iteration of the loop // since it has to do its job of escaping characters for all 9 // passes. Until then, simply skip over the next character (in // particular, the $) so it's not treated specially. // if ( i == 9 ) s->erase( pos, 1 ); else ++pos; break; } continue; } // // ${i} case // if ( inside_braces ) { switch ( c ) { case_123456789: if ( to_index( c ) == i ) { value_type const param( lookup_param( i ) ); replace = !param.empty() || replace; replacement += param; } else dollar_pos = value_type::npos; break; case '}': inside_braces = false; goto replace_or_erase; case '\\': if ( pos + 1 < s->size() ) c = s->at( ++pos ); // no break; default: replacement += c; } continue; } // // $i case // switch ( c ) { case '{': inside_braces = true; replace = false; break; case_123456789: if ( to_index( c ) == i ) { value_type const param( lookup_param( i ) ); value_type::size_type pos2 = pos + 1; if ( pos2 < s->size() ) { switch ( s->at( pos2 ) ) { case '?': if ( ++pos2 < s->size() ) { // // $i?<then>:<else> case // pos = pos2; replace = then_else( !param.empty(), *s, &pos, &replacement ); pos2 = pos + 1; if ( pos2 < s->size() ) { switch ( s->at( pos2 ) ) { case ':': pos = pos2 + 1; replace = then_else( param.empty(), *s, &pos, &replacement ) || replace; break; case '\\': s->erase( pos2, 1 ); break; } // switch } // if ( pos2 ... goto replace_or_erase; } // if ( ++pos2 ... break; case '\\': s->erase( pos2, 1 ); break; } // switch } // if ( pos2 ... s->replace( dollar_pos, 2, param ); pos = dollar_pos + param.length(); } // if ( to_index( c ) ... // no break; default: dollar_pos = value_type::npos; } // switch continue; replace_or_erase: value_type::size_type const replace_or_erase_len = pos - dollar_pos + 1; if ( replace ) { s->replace( dollar_pos, replace_or_erase_len, replacement ); pos = dollar_pos + replacement.length() - 1; } else { s->erase( dollar_pos, replace_or_erase_len ); pos = dollar_pos - 1; } dollar_pos = value_type::npos; } // for ( ... pos ... } // for ( ... i ... }
char * PROC findparse(char *src, int *idx, int start) /* driver for ?, /, && : lineranges */ { int addr = start; char c; s_wrapped = 0; switch (*src) { case '/': case '?': /* get a token for find & find it in the buffer */ src = search(src,&addr); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* fabricate a count */ count = 0; while (*src >= '0' && *src <= '9') count = (count*10) + *(src++) - '0'; addr = to_index(count); break; case '$': addr = bufmax-1; src++; break; case '.' : src++; break; case '`': case '\'': addr = getcontext(*(src+1), (*src == '\'')); src += 2; break; } while (addr>=0 && (*src =='+' || *src == '-')) { c = *(src++); /* skip delimiter */ if (*src == '/' || *src == '?') { count = 1; if ((src = search(src,&addr)) == NULL) break; } else { if (*src >= '0' && *src <= '9') { /* fabricate a count */ count = 0; while (*src >= '0' && *src <= '9') count = (count*10) + *(src++) - '0'; } else count = -1; /* for naked + & - */ if (count == 0) /* +0 goes to beginning of line */ addr = bseekeol(addr); else { addr = nextline((c=='+'), addr, count); if (c=='-' && addr > 0) addr = bseekeol(addr); } if (addr >= bufmax) addr = -1; } } *idx = addr; return(src); }