int solve(){ memset(tick, 0x1f, sizeof(tick)); Pos start = findCh('S'); Pos target = findCh('T'); //start.display("S"); //start.display("T"); queue<Pos> Q; Q.push(start); tick[start.x][start.y][start.color][start.dir] = 0; while (Q.size()){ Pos s = Q.front(); Q.pop(); //s.display("Pop"); for (int i = 0; i < 3; i++){ Pos t = s.action(i); if (!t.isValid()) continue; if (tick[t.x][t.y][t.color][t.dir] != INF) continue; if (grid[t.x][t.y] == '#') continue; tick[t.x][t.y][t.color][t.dir] = tick[s.x][s.y][s.color][s.dir] + 1; Q.push(t); //s.display(" Push"); } } int best = INF; for (int i = 0; i < 4; i++){ target.dir = i; best = min(best, tick[target.x][target.y][target.color][target.dir]); } return best; }
bool ParserCreateQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) { ParserKeyword s_create("CREATE"); ParserKeyword s_temporary("TEMPORARY"); ParserKeyword s_attach("ATTACH"); ParserKeyword s_table("TABLE"); ParserKeyword s_database("DATABASE"); ParserKeyword s_if_not_exists("IF NOT EXISTS"); ParserKeyword s_as("AS"); ParserKeyword s_view("VIEW"); ParserKeyword s_materialized("MATERIALIZED"); ParserKeyword s_populate("POPULATE"); ParserToken s_dot(TokenType::Dot); ParserToken s_lparen(TokenType::OpeningRoundBracket); ParserToken s_rparen(TokenType::ClosingRoundBracket); ParserStorage storage_p; ParserIdentifier name_p; ParserColumnsOrIndicesDeclarationList columns_or_indices_p; ParserSelectWithUnionQuery select_p; ASTPtr database; ASTPtr table; ASTPtr columns_list; ASTPtr to_database; ASTPtr to_table; ASTPtr storage; ASTPtr as_database; ASTPtr as_table; ASTPtr select; String cluster_str; bool attach = false; bool if_not_exists = false; bool is_view = false; bool is_materialized_view = false; bool is_populate = false; bool is_temporary = false; if (!s_create.ignore(pos, expected)) { if (s_attach.ignore(pos, expected)) attach = true; else return false; } if (s_temporary.ignore(pos, expected)) { is_temporary = true; } if (s_table.ignore(pos, expected)) { if (s_if_not_exists.ignore(pos, expected)) if_not_exists = true; if (!name_p.parse(pos, table, expected)) return false; if (s_dot.ignore(pos, expected)) { database = table; if (!name_p.parse(pos, table, expected)) return false; } if (ParserKeyword{"ON"}.ignore(pos, expected)) { if (!ASTQueryWithOnCluster::parse(pos, cluster_str, expected)) return false; } // Shortcut for ATTACH a previously detached table if (attach && (!pos.isValid() || pos.get().type == TokenType::Semicolon)) { auto query = std::make_shared<ASTCreateQuery>(); node = query; query->attach = attach; query->if_not_exists = if_not_exists; query->cluster = cluster_str; getIdentifierName(database, query->database); getIdentifierName(table, query->table); return true; } /// List of columns. if (s_lparen.ignore(pos, expected)) { if (!columns_or_indices_p.parse(pos, columns_list, expected)) return false; if (!s_rparen.ignore(pos, expected)) return false; if (!storage_p.parse(pos, storage, expected) && !is_temporary) return false; } else { storage_p.parse(pos, storage, expected); if (!s_as.ignore(pos, expected)) return false; if (!select_p.parse(pos, select, expected)) /// AS SELECT ... { /// AS [db.]table if (!name_p.parse(pos, as_table, expected)) return false; if (s_dot.ignore(pos, expected)) { as_database = as_table; if (!name_p.parse(pos, as_table, expected)) return false; } /// Optional - ENGINE can be specified. if (!storage) storage_p.parse(pos, storage, expected); } } } else if (is_temporary) return false; else if (s_database.ignore(pos, expected)) { if (s_if_not_exists.ignore(pos, expected)) if_not_exists = true; if (!name_p.parse(pos, database, expected)) return false; if (ParserKeyword{"ON"}.ignore(pos, expected)) { if (!ASTQueryWithOnCluster::parse(pos, cluster_str, expected)) return false; } storage_p.parse(pos, storage, expected); } else { /// VIEW or MATERIALIZED VIEW if (s_materialized.ignore(pos, expected)) { is_materialized_view = true; } else is_view = true; if (!s_view.ignore(pos, expected)) return false; if (s_if_not_exists.ignore(pos, expected)) if_not_exists = true; if (!name_p.parse(pos, table, expected)) return false; if (s_dot.ignore(pos, expected)) { database = table; if (!name_p.parse(pos, table, expected)) return false; } if (ParserKeyword{"ON"}.ignore(pos, expected)) { if (!ASTQueryWithOnCluster::parse(pos, cluster_str, expected)) return false; } // TO [db.]table if (ParserKeyword{"TO"}.ignore(pos, expected)) { if (!name_p.parse(pos, to_table, expected)) return false; if (s_dot.ignore(pos, expected)) { to_database = to_table; if (!name_p.parse(pos, to_table, expected)) return false; } } /// Optional - a list of columns can be specified. It must fully comply with SELECT. if (s_lparen.ignore(pos, expected)) { if (!columns_or_indices_p.parse(pos, columns_list, expected)) return false; if (!s_rparen.ignore(pos, expected)) return false; } if (is_materialized_view && !to_table) { /// Internal ENGINE for MATERIALIZED VIEW must be specified. if (!storage_p.parse(pos, storage, expected)) return false; if (s_populate.ignore(pos, expected)) is_populate = true; } /// AS SELECT ... if (!s_as.ignore(pos, expected)) return false; if (!select_p.parse(pos, select, expected)) return false; } auto query = std::make_shared<ASTCreateQuery>(); node = query; query->attach = attach; query->if_not_exists = if_not_exists; query->is_view = is_view; query->is_materialized_view = is_materialized_view; query->is_populate = is_populate; query->temporary = is_temporary; getIdentifierName(database, query->database); getIdentifierName(table, query->table); query->cluster = cluster_str; getIdentifierName(to_database, query->to_database); getIdentifierName(to_table, query->to_table); query->set(query->columns_list, columns_list); query->set(query->storage, storage); getIdentifierName(as_database, query->as_database); getIdentifierName(as_table, query->as_table); query->set(query->select, select); return true; }