struct media_entity * media_entity_graph_walk_next(struct media_entity_graph *graph) { if (stack_top(graph) == NULL) return NULL; while (link_top(graph) < stack_top(graph)->num_links) { struct media_entity *entity = stack_top(graph); struct media_link *link = &entity->links[link_top(graph)]; struct media_entity *next; if (!(link->flags & MEDIA_LNK_FL_ENABLED)) { link_top(graph)++; continue; } next = media_entity_other(entity, link); if (next == stack_peek(graph)) { link_top(graph)++; continue; } link_top(graph)++; stack_push(graph, next); } return stack_pop(graph); }
void set_row_node(unsigned long grid_origin, piece_t *piece, unsigned long column, node_t *left) { row_node->row_node->grid_origin = grid_origin; row_node->row_node->piece = piece; row_node->row_node->column = &nodes[column]; link_left(row_node, left); link_top(row_node, tops[column]); tops[column] = row_node++; nodes[column].rows++; }
/** * media_entity_graph_walk_next - Get the next entity in the graph * @graph: Media graph structure * * Perform a depth-first traversal of the given media entities graph. * * The graph structure must have been previously initialized with a call to * media_entity_graph_walk_start(). * * Return the next entity in the graph or NULL if the whole graph have been * traversed. */ struct media_entity * media_entity_graph_walk_next(struct media_entity_graph *graph) { if (stack_top(graph) == NULL) return NULL; /* * Depth first search. Push entity to stack and continue from * top of the stack until no more entities on the level can be * found. */ while (link_top(graph) < stack_top(graph)->num_links) { struct media_entity *entity = stack_top(graph); struct media_link *link = &entity->links[link_top(graph)]; struct media_entity *next; /* The link is not enabled so we do not follow. */ if (!(link->flags & MEDIA_LNK_FL_ENABLED)) { link_top(graph)++; continue; } /* Get the entity in the other end of the link . */ next = media_entity_other(entity, link); if (WARN_ON(next->id >= MEDIA_ENTITY_ENUM_MAX_ID)) return NULL; /* Has the entity already been visited? */ if (__test_and_set_bit(next->id, graph->entities)) { link_top(graph)++; continue; } /* Push the new entity to stack and start over. */ link_top(graph)++; stack_push(graph, next); } return stack_pop(graph); }
/** * media_entity_graph_walk_next - Get the next entity in the graph * @graph: Media graph structure * * Perform a depth-first traversal of the given media entities graph. * * The graph structure must have been previously initialized with a call to * media_entity_graph_walk_start(). * * Return the next entity in the graph or NULL if the whole graph have been * traversed. */ struct media_entity * media_entity_graph_walk_next(struct media_entity_graph *graph) { if (stack_top(graph) == NULL) return NULL; /* * Depth first search. Push entity to stack and continue from * top of the stack until no more entities on the level can be * found. */ while (link_top(graph) < stack_top(graph)->num_links) { struct media_entity *entity = stack_top(graph); struct media_link *link = &entity->links[link_top(graph)]; struct media_entity *next; /* The link is not enabled so we do not follow. */ if (!(link->flags & MEDIA_LNK_FL_ENABLED)) { link_top(graph)++; continue; } /* Get the entity in the other end of the link . */ next = media_entity_other(entity, link); /* Was it the entity we came here from? */ if (next == stack_peek(graph)) { link_top(graph)++; continue; } /* Push the new entity to stack and start over. */ link_top(graph)++; stack_push(graph, next); } return stack_pop(graph); }
int main(void) { int r; unsigned long grid_cells_n2, pieces_n, pieces_max, column_nodes_n1, column_nodes_n2, row_nodes_n, pieces_r, piece_f, piece_l, nodes_n, i, j, k; scanf("%lu", &grid_rows); if (!grid_rows) { return EXIT_FAILURE; } scanf("%lu", &grid_columns1); if (!grid_columns1) { return EXIT_FAILURE; } grid_cells_n1 = grid_rows*grid_columns1; grid_columns2 = grid_columns1+1; grid_cells_n2 = grid_rows*grid_columns2; grid_cells = malloc(grid_cells_n2+1); if (!grid_cells) { free_data(0UL); return EXIT_FAILURE; } for (i = grid_columns1; i < grid_cells_n2; i += grid_columns2) { grid_cells[i] = '\n'; } grid_cells[grid_cells_n2] = 0; scanf("%lu", &pieces_n); if (!pieces_n) { return EXIT_FAILURE; } pieces_max = pieces_n*8; pieces = malloc(sizeof(piece_t)*pieces_max); if (!pieces) { return EXIT_FAILURE; } column_nodes_n1 = grid_cells_n1+pieces_n; column_nodes_n2 = column_nodes_n1+1; row_nodes_n = 0; pieces_r = 0; for (i = 0; i < pieces_n; i++) { if (!read_piece(&pieces[pieces_r], i)) { free_data(pieces_r); return EXIT_FAILURE; } piece_f = pieces_r; row_nodes_n += pieces[pieces_r].row_nodes_n; pieces_r++; j = 1; do { if (!rotate_piece(&pieces[pieces_r-1], &pieces[pieces_r])) { free_data(pieces_r); return EXIT_FAILURE; } r = compare_pieces(&pieces[piece_f], &pieces[pieces_r]); for (k = piece_f+1; k < pieces_r && !r; k++) { r = compare_pieces(&pieces[k], &pieces[pieces_r]); } if (!r) { row_nodes_n += pieces[pieces_r].row_nodes_n; pieces_r++; j++; } else { free_piece(&pieces[pieces_r]); } } while (j < 4 && !r); piece_l = pieces_r; j = piece_f; do { if (!flip_piece(&pieces[j], &pieces[pieces_r])) { free_data(pieces_r); return EXIT_FAILURE; } r = compare_pieces(&pieces[piece_f], &pieces[pieces_r]); for (k = piece_f+1; k < piece_l && !r; k++) { r = compare_pieces(&pieces[k], &pieces[pieces_r]); } if (!r) { row_nodes_n += pieces[pieces_r].row_nodes_n; pieces_r++; j++; } else { free_piece(&pieces[pieces_r]); } } while (j < piece_l && !r); } row_nodes = malloc(sizeof(row_node_t)*row_nodes_n); if (!row_nodes) { free_data(pieces_r); return EXIT_FAILURE; } nodes_n = column_nodes_n2+row_nodes_n; nodes = malloc(sizeof(node_t)*nodes_n); if (!nodes) { free_data(pieces_r); return EXIT_FAILURE; } for (i = column_nodes_n2; i < nodes_n; i++) { nodes[i].row_node = &row_nodes[i-column_nodes_n2]; } tops = malloc(sizeof(node_t *)*column_nodes_n1); if (!tops) { free_data(pieces_r); return EXIT_FAILURE; } header = &nodes[column_nodes_n1]; set_column_node(nodes, header); for (i = 0; i < column_nodes_n1; i++) { set_column_node(&nodes[i+1], &nodes[i]); tops[i] = &nodes[i]; } row_node = header+1; for (i = 0; i < pieces_r; i++) { print_piece(&pieces[i]); set_piece_row_nodes(&pieces[i]); } for (i = 0; i < column_nodes_n1; i++) { link_top(&nodes[i], tops[i]); } dlx_search(); printf("\nCost %lu\nSolutions %lu\n", cost, solutions); free_data(pieces_r); return EXIT_SUCCESS; }