Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

67-9kyo-hwang #228

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

67-9kyo-hwang #228

wants to merge 5 commits into from

Conversation

9kyo-hwang
Copy link
Collaborator

@9kyo-hwang 9kyo-hwang commented Sep 22, 2024

πŸ”— 문제 링크

퍼즐 쑰각 μ±„μš°κΈ°

image
ν…Œμ΄λΈ”μ— 놓인 블둝을 κ²Œμž„ λ³΄λ“œμ˜ 빈 곡간에 μ˜¬λ €λ†“μ•„μ•Ό ν•œλ‹€. 이 λ•Œ, λ‹€μŒ κ·œμΉ™μ„ 따라야 ν•œλ‹€.

  • 쑰각은 ν•œ λ²ˆμ— ν•˜λ‚˜μ”© μ±„μ›Œ λ„£λŠ”λ‹€
  • 쑰각을 νšŒμ „μ‹œν‚¬ 수 μžˆλ‹€
  • 쑰각을 뒀집을 수 μ—†λ‹€
  • κ²Œμž„ λ³΄λ“œμ— μƒˆλ‘œ μ±„μ›Œ 넣은 λΈ”λŸ­κ³Ό μΈμ ‘ν•œ 칸이 λΉ„μ–΄μžˆμœΌλ©΄ μ•ˆλœλ‹€.

image
μœ„μ™€ 같이 3, 4, 5번 λΈ”λŸ­μ„ 격자 칸에 λ†“μœΌλ©΄ κ·œμΉ™μ— μ–΄κΈ‹λ‚˜ λΆˆκ°€λŠ₯ν•˜λ‹€.

image
κ·œμΉ™μ— 맞게 μ΅œλŒ€ν•œ λ§Žμ€ λΈ”λŸ­μ„ μ±„μ›Œ λ„£μœΌλ©΄ μœ„μ™€ κ°™μœΌλ©°, 총 14칸을 μ±„μšΈ 수 μžˆλ‹€.

κ·œμΉ™μ— 맞게 μ΅œλŒ€ν•œ λ§Žμ€ 퍼즐 쑰각을 μ±„μ›Œ 넣을 경우, 총 λͺ‡ 칸을 μ±„μšΈ 수 μžˆλŠ”μ§€ return ν•˜λ„λ‘ ν•¨μˆ˜λ₯Ό μ™„μ„±ν•˜λΌ.

βœ”οΈ μ†Œμš”λœ μ‹œκ°„

λͺ¨λ¦„. 맀우 였래 κ±Έλ¦Ό

✨ μˆ˜λ„ μ½”λ“œ

λ¬Έμ œμ—μ„œ 퍼즐 쑰각은 μ΅œλŒ€ 6κ°œκΉŒμ§€λ§Œ 주어진닀고 ν–ˆμœΌλ―€λ‘œ, λ³΄λ“œμ™€ ν…Œμ΄λΈ”μ—μ„œ 퍼즐 쑰각 정보λ₯Ό μ €μž₯ν•œ λ’€ μ „μˆ˜ κ²€μ‚¬ν•˜λŠ” 방식을 μ‚¬μš©ν•œλ‹€.

μš°μ„  퍼즐 쑰각 정보λ₯Ό μ–»μ–΄λ‚΄λŠ” 것은 DFS/BFS λ°©μ‹μœΌλ‘œ κ°€λŠ₯ν•˜λ‹€. 2차원 λ°°μ—΄μ—μ„œ κ·Έλž˜ν”„ μ—°κ²° μš”μ†Œ μ•Œμ•„λ‚΄λŠ” κ²ƒμ²˜λŸΌ ꡬ해낼 수 μžˆλ‹€.

using FPoint = pair<int, int>;

vector<vector<FPoint>> GetBlocksFrom(vector<vector<int>>& Board, bool IsBoard = true)
{
    const vector<FPoint> Offset{{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    auto OutOfBound = [&](int x, int y)
    {
        return x < 0 || x >= Board.size() || y < 0 || y >= Board.size();
    };
    
    vector<vector<FPoint>> Blocks;
    
    function<void(int, int)> DFS = [&](int x, int y)  // λΈ”λŸ­μ€ DFS λ°©μ‹μœΌλ‘œ 인접 칸을 κ²€μ‚¬ν•˜λ©° μ’Œν‘œλ₯Ό μ–»μ–΄μ˜¨λ‹€.
    {
        Blocks.back().emplace_back(x, y);
        Board[x][y] = (IsBoard ? 1 : 0);

        for(const auto& [dx, dy] : Offset)
        {
            int nx = x + dx, ny = y + dy;
            if(!OutOfBound(nx, ny) && Board[nx][ny] == (IsBoard ? 0 : 1))
            {
                DFS(nx, ny);
            }
        }
    };
    
    for(int i = 0; i < Board.size(); ++i)
    {
        for(int j = 0; j < Board.size(); ++j)
        {
            if(IsBoard && Board[i][j] == 0  // game_board의 경우 빈 칸
              || !IsBoard && Board[i][j] == 1)  // table의 경우 μ±„μ›Œμ§„ μΉΈ
            {
                Blocks.push_back({});
                DFS(i, j);
            }
        }
    }
    
    return Blocks;
}

λ‹€λ§Œ game_board와 tableμ—μ„œ λͺ¨λ‘ μΆ”μΆœν•΄λ‚΄μ•Ό ν•˜λŠ”λ°, κ²Œμž„ λ³΄λ“œλŠ” 빈 μΉΈ / ν…Œμ΄λΈ”μ€ μ±„μ›Œμ§„ μΉΈμ΄λ―€λ‘œ 이λ₯Ό κ΅¬λΆ„ν•΄μ£ΌλŠ” ν”Œλž˜κ·Έ IsBoardλ₯Ό 톡해 κ΅¬λΆ„ν•œλ‹€.

이 ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄ λ‹€μŒκ³Ό 같이 game_board에 λŒ€ν•œ λΈ”λŸ­λ“€κ³Ό table에 λŒ€ν•œ λΈ”λŸ­λ“€ 정보λ₯Ό μ–»λŠ”λ‹€.

vector<vector<FPoint>> BoardBlocks = GetBlocksFrom(InGameBoard, true);
vector<vector<FPoint>> TableBlocks = GetBlocksFrom(InTable, false);

이제 μ΄λ ‡κ²Œ 얻은 쑰각듀을 가지고 μ „μˆ˜ 쑰사λ₯Ό μ‹œμž‘ν•œλ‹€. λͺ¨λ“  λ³΄λ“œ λΈ”λŸ­λ“€μ— λŒ€ν•΄, ν…Œμ΄λΈ” λΈ”λŸ­μ„ ν•˜λ‚˜μ”© νšŒμ „μ‹œν‚€λ©° ν™•μΈν•œλ‹€.

for(const vector<FPoint>& BoardBlock : BoardBlocks)  // λͺ¨λ“  λ³΄λ“œ λΈ”λŸ­μ— λŒ€ν•΄
{
    ....
    
    for(const vector<FPoint>& TableBlock : TableBlocks)  // ν…Œμ΄λΈ” λΈ”λŸ­μ„ ν•˜λ‚˜μ”© 비ꡐ해본닀.
    {
        ....  // 이 λ•Œ νšŒμ „λ„ 같이 ν•  것
    }
}

μ΄λŸ¬ν•œ 둜직으둜 μ§„ν–‰λ˜λŠ”λ°, λ¬Έμ œλŠ” "λΈ”λŸ­λΌλ¦¬ μ–΄λ–»κ²Œ 비ꡐ할 것인가"이닀. λ‚˜λŠ” μ—¬κΈ°μ„œ μ–»μ–΄λ‚Έ λΈ”λŸ­λ“€μ„ 2차원 λ°°μ—΄λ‘œ 가곡 μ²˜λ¦¬ν–ˆλ‹€.

예λ₯Ό λ“€μ–΄ μ˜ˆμ‹œ κ·Έλ¦Όμ—μ„œ 주어진 2번 λΈ”λŸ­μ˜ 경우 이런 μ‹μœΌλ‘œ λ³€ν™˜ν•œλ‹€.
제λͺ©μ„ μž…λ ₯ν•΄μ£Όμ„Έμš”_-001 (1)

vector<vector<int>> GetGridFrom(const vector<FPoint>& Block)
{
    auto [MinX, MinY] = Block[0];
    auto [MaxX, MaxY] = Block[0];

    for(const auto& [x, y] : Block)
    {
        if(x < MinX) MinX = x;
        else if(x > MaxX) MaxX = x;

        if(y < MinY) MinY = y;
        else if(y > MaxY) MaxY = y;
    }

    vector<vector<int>> Grid(MaxX - MinX + 1, vector<int>(MaxY - MinY + 1, 0));
    for(const auto& [x, y] : Block)
    {
        Grid[x - MinX][y - MinY] = 1;
    }
    
    return Grid;
}

이 과정은 λ“€κ³  μžˆλŠ” μ’Œν‘œλ“€μ˜ μ΅œλŒ€, μ΅œμ†Œ x/y μ’Œν‘œκ°’μ„ μ΄μš©ν•΄ κ΅¬ν˜„ν•  수 μžˆλ‹€.

λ§ˆμ§€λ§‰μœΌλ‘œ 남은 건 λΈ”λŸ­μ˜ "νšŒμ „" κΈ°λŠ₯이닀.
제λͺ©μ„ μž…λ ₯ν•΄μ£Όμ„Έμš”_-002

μ΄λŠ” λ‹€μŒκ³Ό 같은 μ’Œν‘œ λ³€ν™˜μœΌλ‘œ κ°€λŠ₯ν•˜λ‹€: [x, y] -> [y, N - 1 - x](N: 2차원 ν–‰λ ¬μ˜ ν–‰ 크기)

  • (0, 0) -> (0, 2), (0, 1) -> (1, 2), (0, 2) -> (2, 2)
  • (1, 0) -> (0, 1), (1, 1) -> (1, 1), (1, 2) -> (2, 1)
  • (2, 0) -> (0, 0), (2, 1) -> (1, 0), (2, 2) -> (2, 0)
int Rotate(vector<vector<int>>& Grid)
{
    vector<vector<int>> Rotated(Grid[0].size(), vector<int>(Grid.size(), 0));
    int NumCell = 0;
    
    for(int i = 0; i < Grid.size(); ++i)
    {
        for(int j = 0; j < Grid[0].size(); ++j)
        {
            if(Grid[i][j] == 1) NumCell++;
            Rotated[j][Grid.size() - 1 - i] = Grid[i][j];
        }
    }
    
    Grid = Rotated;  // 90도 νšŒμ „ν•œ λΈ”λŸ­μ€ 기쑴에 λ„˜κ²¨λ°›μ€ λΈ”λŸ­μ„ λŒ€μ²΄ν•¨
    return NumCell;  // ν˜„μž¬ λΈ”λŸ­μ€ λͺ‡ 칸짜리인 지 λ°˜ν™˜
}

μ€€λΉ„κ°€ μ™„λ£Œλ˜μ—ˆμœΌλ‹ˆ, λͺ¨λ“  λΈ”λŸ­λΌλ¦¬ νšŒμ „μ„ ν•˜λ©΄μ„œ λΉ„κ΅ν•œλ‹€.

set<vector<FPoint>> UsedTableBlocks;  // μ‚¬μš©λœ ν…Œμ΄λΈ” λΈ”λŸ­μ„ κ΅¬λΆ„ν•˜κΈ° μœ„ν•œ Set
int Answer = 0;

for(const vector<FPoint>& BoardBlock : BoardBlocks)  // λ³΄λ“œμ˜ λΈ”λŸ­μ„ μˆœνšŒν•¨
{
    bool IsFilled = false;
    vector<vector<int>> BoardBlockGrid = GetGridFrom(BoardBlock);  // 2차원 λ°°μ—΄ ν˜•νƒœλ‘œ λ³€ν™˜
    
    for(const vector<FPoint>& TableBlock : TableBlocks)
    {
        if(IsFilled) break;  // 이전 ν…Œμ΄λΈ” λΈ”λŸ­μ— μ˜ν•΄ μ±„μ›Œμ‘Œλ‹€λ©΄ 더 이상 ν™•μΈν•˜μ§€ μ•ŠμŒ
        if(UsedTableBlocks.count(TableBlock)) continue;  // μ•žμ„  λΉ„κ΅μ—μ„œ 이미 μ‚¬μš©λœ ν…Œμ΄λΈ” λΈ”λŸ­μ΄λΌλ©΄ Skip
        
        vector<vector<int>> TableBlockGrid = GetGridFrom(TableBlock);  // 2차원 λ°°μ—΄ ν˜•νƒœλ‘œ λ³€ν™˜
        for(int i = 0; i < 4; ++i)  // 4번 νšŒμ „
        {
            int NumCell = Rotate(TableBlockGrid);
            if(BoardBlockGrid == TableBlockGrid)  // νšŒμ „ν•œ 결과와 μΌμΉ˜ν•˜λ‹€λ©΄
            {
                Answer += NumCell;
                UsedTableBlocks.emplace(TableBlock);
                IsFilled = true;
                break;
            }
        }
    }
}

return Answer;
전체 μ½”λ“œ

#include <string>
#include <vector>
#include <functional>
#include <set>

using namespace std;
using FPoint = pair<int, int>;

vector<vector<FPoint>> GetBlocksFrom(vector<vector<int>>& Board, bool IsBoard = true)
{
    const vector<FPoint> Offset{{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    auto OutOfBound = [&](int x, int y)
    {
        return x < 0 || x >= Board.size() || y < 0 || y >= Board.size();
    };
    
    vector<vector<FPoint>> Blocks;
    
    function<void(int, int)> DFS = [&](int x, int y)
    {
        Blocks.back().emplace_back(x, y);
        Board[x][y] = (IsBoard ? 1 : 0);

        for(const auto& [dx, dy] : Offset)
        {
            int nx = x + dx, ny = y + dy;
            if(!OutOfBound(nx, ny) && Board[nx][ny] == (IsBoard ? 0 : 1))
            {
                DFS(nx, ny);
            }
        }
    };
    
    for(int i = 0; i < Board.size(); ++i)
    {
        for(int j = 0; j < Board.size(); ++j)
        {
            if(IsBoard && Board[i][j] == 0
              || !IsBoard && Board[i][j] == 1)
            {
                Blocks.push_back({});
                DFS(i, j);
            }
        }
    }
    
    return Blocks;
}

vector<vector<int>> GetGridFrom(const vector<FPoint>& Block)
{
    auto [MinX, MinY] = Block[0];
    auto [MaxX, MaxY] = Block[0];

    for(const auto& [x, y] : Block)
    {
        if(x < MinX) MinX = x;
        else if(x > MaxX) MaxX = x;

        if(y < MinY) MinY = y;
        else if(y > MaxY) MaxY = y;
    }

    vector<vector<int>> Grid(MaxX - MinX + 1, vector<int>(MaxY - MinY + 1, 0));
    for(const auto& [x, y] : Block)
    {
        Grid[x - MinX][y - MinY] = 1;
    }
    
    return Grid;
}

int Rotate(vector<vector<int>>& Grid)
{
    vector<vector<int>> Rotated(Grid[0].size(), vector<int>(Grid.size(), 0));
    int NumCell = 0;
    
    for(int i = 0; i < Grid.size(); ++i)
    {
        for(int j = 0; j < Grid[0].size(); ++j)
        {
            if(Grid[i][j] == 1) NumCell++;
            Rotated[j][Grid.size() - 1 - i] = Grid[i][j];
        }
    }
    
    Grid = Rotated;
    return NumCell;
}

int solution(vector<vector<int>> InGameBoard, vector<vector<int>> InTable) 
{
    vector<vector<FPoint>> BoardBlocks = GetBlocksFrom(InGameBoard, true);
    vector<vector<FPoint>> TableBlocks = GetBlocksFrom(InTable, false);
    
    set<vector<FPoint>> UsedTableBlocks;
    int Answer = 0;
    
    for(const vector<FPoint>& BoardBlock : BoardBlocks)
    {
        bool IsFilled = false;
        vector<vector<int>> BoardBlockGrid = GetGridFrom(BoardBlock);
        
        for(const vector<FPoint>& TableBlock : TableBlocks)
        {
            if(IsFilled) break;
            if(UsedTableBlocks.count(TableBlock)) continue;
            
            vector<vector<int>> TableBlockGrid = GetGridFrom(TableBlock);
            for(int i = 0; i < 4; ++i)
            {
                int NumCell = Rotate(TableBlockGrid);
                if(BoardBlockGrid == TableBlockGrid)
                {
                    Answer += NumCell;
                    UsedTableBlocks.emplace(TableBlock);
                    IsFilled = true;
                    break;
                }
            }
        }
    }
    
    return Answer;
}

πŸ“š μƒˆλ‘­κ²Œ μ•Œκ²Œλœ λ‚΄μš©

ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€ κ·Έλž˜ν”„ 순회 μΉ΄ν…Œκ³ λ¦¬μ— μžˆλŠ” 건데 ν•œ 번쯀 풀어봐야지... ν•˜κ³  λƒ…λ’€λ‹€κ°€ ν’€μ–΄λ³΄κ²Œ λλŠ”λ°
ν›„... λ„ˆλ¬΄ ν™”λ‚œλ‹€. 쀑간에 λΈ”λ‘œκ·Έ μ°Έκ³ λ₯Ό λͺ‡ λ²ˆμ΄λ‚˜ ν–ˆλŠ”μ§€ λͺ¨λ₯΄κ² λ‹€. μ‹œκ°„λ„ μ™•μ°½ λ‚ λ €λ¨Ήμ—ˆλ‹€.

Copy link
Collaborator

@mjj111 mjj111 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

첫 번째 트라이

import java.util.*;
class Solution {

    private static int N;
    private static int[] dx = {0, 0, -1, 1};
    private static int[] dy = {1, -1, 0, 0};
    private static Map<Integer, Integer> blocks;
    private static boolean[][] visited;
    private static int answer;
    private static int[][] table;
    private static int[][] game_board;

    public int solution(int[][] game_board, int[][] table) {
        this.table = table;
        this.game_board = game_board;
        N = table.length;
        answer = 0;
        blocks = new HashMap<>();
        visited = new boolean[N][N];
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (!visited[i][j] && table[i][j] == 1) {
                    count(i, j);
                }
            }
        }
        visited = new boolean[N][N];
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (!visited[i][j] && game_board[i][j] == 0) { 
                    bfs(i, j);
                }
            }
        }
        return answer;
    }
    private static void bfs(int gx, int gy) {
        visited[gx][gy] = true;
        Deque<int[]> dq = new LinkedList<>();
        dq.addLast(new int[]{gx, gy});
        int count = 0; 
        while (!dq.isEmpty()) {
            count++;
            int[] now = dq.removeFirst();
            int x = now[0];
            int y = now[1];

            for (int i = 0; i < 4; i++) {
                int nx = x + dx[i];
                int ny = y + dy[i];
                if (isOut(nx, ny)) continue;
                if (visited[nx][ny]) continue;
                if (game_board[nx][ny] != 0) continue;
                visited[nx][ny] = true;
                dq.addLast(new int[]{nx, ny});
            }
        }

        if (blocks.containsKey(count) && blocks.get(count) > 0) {
            answer += count; 
            blocks.put(count, blocks.get(count) - 1);
        }
    }
    private static void count(int gx, int gy) {
        visited[gx][gy] = true;
        Deque<int[]> dq = new LinkedList<>();
        dq.addLast(new int[]{gx, gy});
        int count = 0; 
        while (!dq.isEmpty()) {
            count++; 
            int[] now = dq.removeFirst();
            int x = now[0];
            int y = now[1];
            for (int i = 0; i < 4; i++) {
                int nx = x + dx[i];
                int ny = y + dy[i];
                if (isOut(nx, ny)) continue;
                if (visited[nx][ny]) continue;
                if (table[nx][ny] != 1) continue;
                visited[nx][ny] = true;
                dq.addLast(new int[]{nx, ny});
            }
        }
        blocks.put(count, blocks.getOrDefault(count, 0) + 1);
    }
    private static boolean isOut(int x, int y) {
        return x < 0 || x >= N || y < 0 || y >= N;
    }
}

μ•„.. 문제λ₯Ό 잘λͺ» μ½μ–΄μ„œ 20λΆ„ 날리고 λ‹€μ‹œ ν’€μ—ˆλ„€μš”..γ… γ… 
ν‘œμ€€ν™”ν•˜λŠ”λ° 흰머리 λ‚˜κ³ ,, 이게 또 λ§žλŠ”μ§€ μƒκ°ν•˜λŠ”λ° 흰머리 또 λ‚¬μŠ΅λ‹ˆλ‹€..
board 크기가 50으둜 μž‘μ•„μ„œ Set μƒμ„±ν•˜κ³  ν™œμš©ν•΄μ„œ ν’€μ—ˆμŠ΅λ‹ˆλ‹Ή
++이게 μ™œ level3μ£ ...

두 번째 트라이

import java.util.*;

class Solution {
    private static final int[] dx = {-1, 1, 0, 0};
    private static final int[] dy = {0, 0, -1, 1};
    private static int N;
    
    public int solution(int[][] game_board, int[][] table) {
        N = game_board.length;
        List<List<int[]>> emptySpaces = findBlocks(game_board, 0);
        List<List<int[]>> puzzlePieces = findBlocks(table, 1);
        
        boolean[] used = new boolean[puzzlePieces.size()];
        int answer = 0;

        for (List<int[]> space : emptySpaces) {
            for (int i = 0; i < puzzlePieces.size(); i++) {
                if (used[i]) continue;
                List<int[]> piece = puzzlePieces.get(i);
                if (canFit(space, piece)) {
                    used[i] = true;
                    answer += piece.size();
                    break;
                }
            }
        }

        return answer;
    }

    private List<List<int[]>> findBlocks(int[][] board, int target) {
        boolean[][] visited = new boolean[N][N];
        List<List<int[]>> blocks = new ArrayList<>();

        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if(board[i][j] != target) continue;
                if(visited[i][j]) continue;
                
                List<int[]> block = new ArrayList<>();
                dfs(board, i, j, visited, block, target);
                normalize(block);
                blocks.add(block);
            }
        }

        return blocks;
    }

    private void dfs(int[][] board, int x, int y, boolean[][] visited, List<int[]> block, int target) {
        if (x < 0 || x >= N || y < 0 || y >= N ||
            visited[x][y] || board[x][y] != target) {
            return;
        }

        visited[x][y] = true;
        block.add(new int[]{x, y});

        for (int i = 0; i < 4; i++) {
            dfs(board, x + dx[i], y + dy[i], visited, block, target);
        }
    }

    private void normalize(List<int[]> block) {
        int minX = Integer.MAX_VALUE;
        int minY = Integer.MAX_VALUE;
        
        for (int[] point : block) {
            minX = Math.min(minX, point[0]);
            minY = Math.min(minY, point[1]);
        }
        for (int[] point : block) {
            point[0] -= minX;
            point[1] -= minY;
        }
    }

    private boolean canFit(List<int[]> space, List<int[]> piece) {
        if (space.size() != piece.size()) return false;

        for (int rot = 0; rot < 4; rot++) {
            if (isSameShape(space, piece)) return true;
            rotate(piece);
        }

        return false;
    }

    private boolean isSameShape(List<int[]> shape1, List<int[]> shape2) {
        Set<String> set1 = new HashSet<>();
        Set<String> set2 = new HashSet<>();

        for (int[] point : shape1) set1.add(point[0] + "," + point[1]);
        for (int[] point : shape2) set2.add(point[0] + "," + point[1]);

        return set1.equals(set2);
    }

    private void rotate(List<int[]> piece) {
        for (int[] point : piece) {
            int temp = point[0];
            point[0] = point[1];
            point[1] = -temp;
        }
        normalize(piece);
    }
}

Copy link
Member

@gjsk132 gjsk132 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

문제보자마자 머리 μ•„νŒŒμ˜€λŠ” 문제... table에 μžˆλŠ” block만 뽑아내고, board에 λ„£λŠ”κ±΄... ν¬κΈ°ν–ˆμŠ΅λ‹ˆλ‹€πŸ₯² κ·Έλƒ₯ λƒ…λ‹€ λ‹€ 돌리면 λ˜λŠ”κ±°μ˜€κ΅°μš”...

PR μ°Έκ³ ν•΄μ„œ 슀슀μŠ₯ ν•΄κ²°ν•˜κ³  κ°‘λ‹ˆλ‹€!
μ €λŠ” κ·Έλƒ₯ set μ•ˆ μ“°κ³  μŠ₯μ‚­ ν–‡μŠ΅λ‹ˆλ‹€

와μž₯μ°½
def solution(game_board, table):
    
    puzzles, emptys = [], []

    offset = [(-1, 0), (0, 1), (1, 0), (0, -1)]

    tx, ty = len(table), len(table[0])
    gx, gy = len(game_board), len(game_board[0])

    def dfs_table(x, y):
        
        puzzle = [(x, y)]

        for dx, dy in offset:
            nx, ny = x + dx, y + dy
            
            if not 0 <= nx < tx or not 0 <= ny < ty:
                continue

            if table[nx][ny] == 0 or table[nx][ny] == 2:
                continue

            table[nx][ny] = 2

            puzzle += dfs_table(nx, ny)

        return puzzle
    
    def dfs_board(x, y):
        
        empty = [(x, y)]

        for dx, dy in offset:
            nx, ny = x + dx, y + dy
            
            if not 0 <= nx < gx or not 0 <= ny < gy:
                continue

            if game_board[nx][ny] == 1 or game_board[nx][ny] == 2:
                continue

            game_board[nx][ny] = 2

            empty += dfs_board(nx, ny)

        return empty

    def stadnard(space):
        dx = min([i[0] for i in space])
        dy = min([i[1] for i in space])
        h = max([i[0] for i in space]) - dx + 1
        w = max([i[1] for i in space]) - dy + 1

        grid = [[0]*w for _ in range(h)]

        for x, y in space:
            grid[x-dx][y-dy] = 1

        return grid

        grid = [list(e) for e in zip(*grid[::-1])]

    num = 0
    for i in range(tx):
        for j in range(ty):
            if table[i][j] == 1:
                table[i][j] = 2 
                num += 1
                puzzles.append(stadnard(dfs_table(i, j)))

    for i in range(gx):
        for j in range(gy):
            if game_board[i][j] == 0:
                game_board[i][j] = 2 
                emptys.append(stadnard(dfs_board(i, j)))
                
    result = 0
    is_use = [False]*len(puzzles)
    
    for e in emptys:
        is_empty = True

        for idx, p in enumerate(puzzles):
            if is_use[idx]:
                continue

            cnt = 4
            while cnt:
                if e == p:
                    result += sum([sum(i) for i in e])
                    is_use[idx] = True
                    is_empty = False
                    break
                else:
                    p = [list(e) for e in zip(*p[::-1])]
                    cnt -= 1

            if not is_empty:
                break

    return result

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants