Machineboy空

Excercism - Saddle Points 2차원 배열, 최대최소 본문

Computer/Coding Test

Excercism - Saddle Points 2차원 배열, 최대최소

안녕도라 2025. 1. 15. 18:23

문제요약

조건에 만족하는 나무를 찾아 좌표를 반환

  • 동-서 축에서 가장 클 것
  • 북-남 축에서 가장 작을 것

https://exercism.org/tracks/csharp/exercises/saddle-points/mentor_request/new

 

Exercism

Learn, practice and get world-class mentoring in over 50 languages. 100% free.

exercism.org

 

난이도

medium


풀이 포인트

  • 2차원 배열 요소 접근

https://machineboy0.tistory.com/305

 

C# 다차원 배열 - rank, getLength

배열(Array)참조형식https://machineboy0.tistory.com/76 Value vs Reference typeCall by Reference Call by Value 원본 복사 복사본 복사 사물함에 넣어두고 사물함 번호를 알려주는 방법 ref, out을 활용 매개변수에서의 ga

machineboy0.tistory.com

  • (추가) LINQ 사용법 익혀보기..

REVIEW

 

2차원 배열 요소 접근하는 법을 좀 헤맸다.

더불어 2차원 배열을 선언하는 방법 등 C# 기본 문법이 약해 난관을 겪었다.

 

arr[0][0]이 아닌, arr[0,0]으로 접근해야 한다.

그래도 덕분에  int[][]로 선언하는 가변 배열과 int[,]로 선언하는 고정 2차원 배열의 차이를 명확히 짚고 넘어간다.

 

그리고 문제를 잘못읽었다.. 동서축에서 최대, 남북축에서 최소라는 조건을 파악하지 못했다..

최대 최소 체크도 해야하는 문제였다.

 

꽤 기본이면서 좋은 문제인 것 같다.


CODE

using System;
using System.Collections.Generic;
using System.Linq;

public static class SaddlePoints
{
    public static (int, int)[] Calculate(int[,] matrix)
    {
        var answer = new List<(int, int)>();
        int rows = matrix.GetLength(0);
        int cols = matrix.GetLength(1);

        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                int current = matrix[i, j];

                // 조건 1: 행에서 가장 큰 값인지 확인
                bool isLargestInRow = true;
                for (int col = 0; col < cols; col++)
                {
                    if (matrix[i, col] > current)
                    {
                        isLargestInRow = false;
                        break;
                    }
                }

                // 조건 2: 열에서 가장 작은 값인지 확인
                bool isSmallestInColumn = true;
                for (int row = 0; row < rows; row++)
                {
                    if (matrix[row, j] < current)
                    {
                        isSmallestInColumn = false;
                        break;
                    }
                }

                // 두 조건을 모두 만족하면 결과에 추가
                if (isLargestInRow && isSmallestInColumn)
                {
                    answer.Add((i + 1, j + 1)); // 1-based 인덱스 반환
                }
            }
        }

        return answer.ToArray();
    }
}

 

// 내 코드

using System;
using System.Collections.Generic;
using System.Linq;

// rows : largest
// cols : smallest

public static class SaddlePoints
{
    public static (int, int)[] Calculate(int[,] matrix)
    {
       // 만족하는 좌표 담을 List 생성
        List<(int, int)> answer = new List<(int, int)>();
        int rows = matrix.GetLength(0);
        int cols = matrix.GetLength(1);  

        // for문으로 좌표 검사
        for(int i = 0; i < rows; i++){
            for(int j = 0; j < cols; j++){

                // row: largest, cols: smallest 체크
                bool isLargestInRows = true;
                bool isSmallestInCols = true;
                
                // 현재 값
                int currentH = matrix[i,j];

                for(int a = 0; a < rows; a++){
                    if(a == i) continue;		// 이 코드 필요 없네
                    if (currentH > matrix[a,j]){
                        isSmallestInCols = false;
                        
                        break;
                    }
                }

                for(int b = 0; b < cols; b++){
                    if(b == j) continue;		// 이 코드 필요 없네
                    
                    if(currentH < matrix[i,b]){
                        isLargestInRows = false;
                        break;
                    }
                }

                if(isLargestInRows && isSmallestInCols){
                    answer.Add((i+1,j+1));
                }
            }
        }

        return answer.ToArray();
    }
}

 

// 모범 코드

using System.Linq;
using System.Collections.Generic;

public static class SaddlePoints
{
    public static IEnumerable<(int, int)> Calculate(int[,] m)
    {
        var ri = Enumerable.Range(0, m.GetLength(0));
        var ci = Enumerable.Range(0, m.GetLength(1));

        var r = from i in ri select from j in ci select m[i, j];
        var c = from i in ci select from j in ri select m[j, i];

        return from i in ri from j in ci
        where r.ElementAt(i).All(x => m[i, j] >= x) 
        where c.ElementAt(j).All(x => m[i, j] <= x)
        select (i + 1, j + 1);
    }
}
public static IEnumerable<(int, int)> Calculate(int[,] matrix)
{
    int rows = matrix.GetLength(0);
    int cols = matrix.GetLength(1);

    int[] rowMaxs = Enumerable.Range(0, rows).Select(row => Enumerable.Range(0, cols).Max(col => matrix[row, col])).ToArray();
    int[] colMins = Enumerable.Range(0, cols).Select(col => Enumerable.Range(0, rows).Min(row => matrix[row, col])).ToArray();
    
    for (int row = 0; row < rows; row++)
    {
        for (int col = 0; col < cols; col++)
        {
            if (rowMaxs[row] == colMins[col])
            {
                yield return (row + 1, col + 1);
            }
        }
    }
}