20231101_기록_두 정수 사이의 합(프로그래머스)

2023. 11. 1. 20:41IT/TIL

오늘 한 것들

 

알고리즘 코드카타 풀이

카드 뒤집기 basic version 코드 분석

TIL 작성 특강 참가

Github merge 시도하기

Github merge에서 conflict 해결법 찾기 -> 튜터님께 문의

endTxt 게임 오브젝트 구현하기

TMI란 자료 만들기

 

https://school.programmers.co.kr/learn/courses/30/lessons/12912

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

오전 9시부터 1시간 동안 알고리즘 코드카타를 풀이했다.

오늘 코드카타에서 알고 가고 싶은 점은 2개인데

하나는 12번 문제인 '두 정수 사이의 합'이다.

두 정수 사이에 속한 모든 정수의 합을 구하는 문제로

using System;

public class Solution {
    public long solution(int a, int b) {
        long answer = 0;
        
        if (a > b)
        {
            for (int i = b; i <= a; i++)
                answer += i;
        }
        else if (a < b)
        {
            for (int i = a; i <= b; i++)
                answer += i;
        }
        else
            answer = a;
           
        return answer;
    }
}

 

코드를 구현하는건 어렵지 않았으나 두 정수의 차가 크면 for 문이 많이 돌아갈 수 밖에 없는 구조로

특정 테스트에서 시간이 오래 소모되는 것을 발견하였다.

따라서 for 문을 없애고 수학을 사용하여 답을 변경했다. 

using System;

public class Solution {
    public long solution(int a, int b) {
        long answer = 0;
        
        answer = ((long)(Math.Abs(a - b) + 1) * (a + b)) / 2;
        
        return answer;
    }
}

 

(등차가 1인 등차수열에서 첫째항이 a이고 마지막항이 b인 경우에 이 등차수열의 합은 n(a + b) / 2로 

 n 값을 구하면 되는데 a<= x <= b에서 x에 속하는 갯수를 구하면 되는 문제로 이는 b - a + 1인데

 a와 b 중에 어느 수가 큰 지 알 수 없다는 조건이 있기에 절대값을 사용하여 (a - b) + 1로 풀이했다.

 

 

 

다른 하나는 13번 문제인 '콜라스 추측'으로

수학과 관련한 유튜브 등에서 자주 나오는 문제였다.

public class Solution {
    public int solution(int num) {
        int answer = 0;
        long x = num;
        int cnt = 0;
        
        for (cnt = 0; cnt <= 500; cnt ++)
        {
            if (x % 2 == 0)
            {
                x = x / 2;
            }
            else if (x == 1)
            {
                return cnt;
            }
            else
            {
                x = x * 3 + 1;
            }  
        }
        
        if (num == 1)
        {
            answer = 0;
        }
        else if (cnt <= 500)
        {
            answer = cnt;
        }
        else
        {
            answer = -1;            
        }
        
        return answer;
    }
}

 

해결 자체는 for 문으로 cnt를 올리며 짝수인지 홀수인지 아니면 1인지 판단하게 시켜서 그 cnt를 반환한 후에

조건에 따라(입력된 수가 1이면 답은 0, cnt가 500회 이하면 답은 cnt, 500 초과면 답은 -1) if문을 작성했다.

그런데 계속해서 3번 문제(입력된 수가 626331인 경우)가 풀리지 않아 해결법을 찾는데 시간이 소모됬는데

이는 주어진 코드에서 입력된 수가 int num으로 주어져서

이를 계산하기 위해 가져오면서 int x를 선언했을때 발생한 문제로,

int로 지정된 수는 저장 공간의 한계로 수가 너무 커지면 숫자가 짤려서 생긴 문제였다.

따라서 int x가 아닌 long x로 선언하여 문제를 해결하였다.

 

알고리즘 문제를 풀거나 코딩을 하는 경우에 큰 숫자 데이터를 포함해야되는 경우에는

int 가 아닌 long 으로 변수를 선언하는 것을 일깨워주는 문제였다.

 

 

 

이후에 어제는 내가 기존에 만들었던 카드 뒤집기 게임을 기반으로 구현하고 있었는데

이를 basic version에서 코딩하려고 했을 때 느꼈던 점으로

내가 구현한 코드랑 많이 달라서 해당 코드들을 읽어보면서 어떤 방식으로 코딩했는지 리뷰하는 시간을 가졌다.

특히 PlayerPrefs을 사용한 점과 yield return을 사용한 점이 인상깊었는데,

 

PlayerPrefs는 선언한 특정 데이터를 컴퓨터 내부(레지스트리)에 저장하는 방법으로

게임의 종료해도 데이터가 남아있어 최고 점수를 저장하는데 좋은 기능이다.

 

yield return은 return과 다르게 여러번 return할 수 있다는 점이 특징인데,

for, if, while 문 등에서 return을 하는 경우 해당 함수를 종료하고 돌아가면서 값을 반환하는데,

yield return을 하면 반환하는 값이 1개가 아닌 여러개를 사용할 수 있고,

1개를 반환하더라도 해당 함수를 지연된 사용이 가능하다는 특징이 있다.

 

 

endTxt 게임 오브젝트 구현하기

TMI란 자료 만들기

 

이후에 어제 구현했던

endTxt 게임 오브젝트 및 출력 텍스트 변경, 최고 점수 표시 등의 코드를 추가한 버전을 merge(병합) 시도하였는데

코드 뿐만 아니라 MainScene의 여러 오브젝트의 값들을 변경한 것이 있어서

다른 팀원들과 conflict(충돌)하는 상황이 발생하였다.

 

이를 해결하기 위해 여러 방법을 찾아봤는데

얻은 결과는

1. 코딩 시에 순차적으로 코딩하여 충돌을 피하기

2. 충돌 시에 코드를 분석하여 수정된 코드로 병합시키기

의 두 가지 방법이였다.

 

이러한 정보를 가지고 좀 더 좋은 해결법이 있을까 오정호 튜터님께 문의드렸는데

확실히 C# 등의 언어에서 발생한 코드들은 분석하여 수정한 후에 병합시키는 방법으로 해결할 수 있어서 문제가 적으나

유니티의 오브젝트에서 발생한 오류는 사람이 분석하여 수정하기 어려운 것으로 말씀해 주신 것 같다.

(혹시라도 잘못 이해 했을 수 있으니 잘못된 정보는 제가 착각한 내용입니다)

따라서 해결책으로 상의한 것은

각각의 팀원들이 담당한 작업을 순차적으로 진행하기

-> 한 팀원이 담당한 작업을 마친 후에 push하고

그 데이터를 pull한 뒤에 다음 팀원이 작업 진행하는 것으로 충돌을 피할 수 있을 것이다.

 

이쪽 공부를 더 하면서 이러한 충돌을 최소화시킬 수 있는 방법을 찾고 싶다.

 

 

이후에 추가로 구현하고 싶었던 endTxt 쪽 기능들을 생각해보며

버그로 생각했던

빠르게 카드를 없애면 게임이 종료되지 않는 현상

게임을 클리어하는 경우 cardsLeft라는 변수를 이용하여

이를 체크하여 클리어 판정을 하는데 이 판정하는 시점이 강제로 넘어가지는 것으로 판단하여

cardsLeft == 2 에서 cardsLeft <= 2로 수정하여 해결하였다.

 

남아있는 버그로 생각되는

게임이 종료된 후에 카드를 뒤집을 수 있는 현상이 남아있는데

게임이 종료로 판정되면 카드 오브젝트가 안보이게하거나(SetActive 사용)

오브젝트가 보이지만 상호작용이 되지 않는 상태로 변경(버튼의 OnClick을 조절하는 방식)하거나

종료 시에 나타나는 오브젝트들(점수 텍스트, 게임 종료 텍스트, 리트라이 버튼(or 다음 단계로 넘어가는 버튼))로

카드를 클릭하지 못하게 변경(button의 판정 범위를 늘려서)하는 방식으로 해결할 예정이다.

'IT > TIL' 카테고리의 다른 글

20231103_기록_카드 뒤집기 게임  (1) 2023.11.03
20231102_기록_카드 뒤집기 게임 버그 수정  (0) 2023.11.02
20231031_기록_isActive,setActive  (0) 2023.10.31
20231030_기록  (0) 2023.10.30
20231027_기록_프로그래머스  (0) 2023.10.27