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);
}
예제 #2
0
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++;
}
예제 #3
0
/**
 * 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);
}
예제 #4
0
/**
 * 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);
}
예제 #5
0
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;
}