Til 15

김정환·2025년 2월 19일
post-thumbnail

1️⃣ 코테

체육복

  • 풀이 코드
  • 풀이 과정
    • 학생들을 한 번만 순회하기 위해서 체육복은 인접한 숫자에게만 빌려줄 수 있다는 부분을 적극적으로 이용해보려고 했다.
    • 스택에다가 학생들에 대한 번호 - 도난 여부를 순차적으로 쌓아둔다.
    • 번호가 올때마다 도난됐는지, 여분이 있는지에 따라 처리를 달리한다.
      • 여분이 있는 사람
        • 수업 참가가 가능하므로 answer++
        • 스택 top에 도난자가 있는지 확인한다.
          • top의 도난자에게 여분 제공이 가능하다면 answer++,
            도난자는 pop 한다
          • 불가능하다면 스택에 넣는다.
        • 도난자가 없어도 뒷사람에게 제공할 수도 있으므로 스택에 넣는다.
      • 도난 당한 사람
        • 스택 top에 여분 제공자가 있는지 확인한다.
          • top에 여분 제공자에게 여분을 받을 수 있다면 answer++,
            여분 제공자는 스택에서 pop한다.
        • 여분 제공자가 없다면 스택에 넣는다.
      • 추가적으로 도난자가 여분을 보유하고 있을 때는 자기가 여분을 사용하도록 처리했다.
  • 다른 풀이
    • 상당히 깔끔한 풀이가 있어서 놀랐다.
using System;

public class Solution {
    public int solution(int n, int[] lost, int[] reserve) {

            int[] Person = new int[n];
            for(int i = 0; i < n; i++)
            {
                Person[i] = 1;
            }


            for(int i = 0; i < lost.Length; i++)
            {
                Person[lost[i] - 1]--;
            }


            for(int i = 0; i < reserve.Length; i++)
            {
                Person[reserve[i] - 1]++;
            }


            for(int i = 0; i < Person.Length - 1; i++)
            {
                if(Math.Abs(Person[i] - Person[i+1]) == 2)
                {
                    Person[i] = 1;
                    Person[i + 1] = 1;
                }
            }


            int count = 0;
            for(int i = 0; i < Person.Length; i++)
            {
                if(Person[i] == 0)
                {
                    count++;
                }
            }

            return Person.Length - count;
    }
}

큰 수 만들기

  • 풀이 코드
  • 풀이 과정
    • number의 최대 길이가 10610^6이므로 O(n2)O(n^2) 이상의 방식은 사용할 수 없다.
    • 생각해낸 풀이 아이디어는 빈칸을 만들고 칸을 채워나가는 방식이다.
      • 칸에 번호를 넣을 때 이전 번호가 현재번호보다 작다면 교체한다.
      • 채워나가야 하는 수가 남은 수보다 클 때까지 전체적으로 수를 비교하는 과정을 계속한다.
    • 이전 번호를 체크하는 과정이 필요해서 어쩔 수 없이 이중 반복문이 사용되었다.
  • 다른 풀이
    • 대체로 문제를 푸는 아이디어가 비슷했고, 세부적인 구현에서 문자열에 담을지 다른 자료구조에 담을지 정도의 차이였다.

회고

  • 문제 풀이에 대한 접근이 아직 좀 어렵게 시도하고 있다.

2️⃣ 개인작업

  • 아이템 및 인벤토리 작업
    • 아이템의 기반을 만들고 인벤토리에 담는 작업에 들어갔다.
    • 마찬가지로 MVP 구조를 시도해볼 것이다.

아이템

아이템 구조 : 데이터 모델의 구조도

  • 아이템은 크게 장비, 소모품으로 정리할 수 있다.
    그래서 공통된 옵션은 부모 클래스를 만들어서 상속해두었다.

데이터 양산 및 처리

  • 게임 데이터는 엑셀 형태로 저장했고 커스텀 기능으로 DatabaseSO에 자동으로 저장된다.

  • DatabaseSO를 따로 만든 이유
    • Json vs SO의 비교
      • 가장 범용적인 것은 JSON이 맞다.
        Unity에서 제공하는 JsonUtility를 사용할 경우 속도도 매우 빠르다.
      • SO의 경우 유니티에서만 제공하지만 JSON처럼 읽어와서 처리하는 과정이 필요없고 바로 사용할 수 있다는 장점이 있다. 즉, 범용성은 떨어지는데 유니티 한정으로 속도가 가장 빠프다.
    • SO의 경우 엑셀을 읽어오는 커스텀 기능을 만들어 두었기 때문에 바로 반영이 가능하다.
    • 이렇게 처리한 두 파일을 클래스로 처리하는 과정
      • Json : Resource.Load<>() => JsonUtility 처리 => 클래스 데이터 저장
      • SO : Resource.Load<>() => 바로 사용 가능
      • 아무래도 Json이 텍스트를 읽어오고 JsonUtility로 변환하는 과정에서 상대적으로 속도가 더 느릴 수 밖에 없다.
    • 게임 데이터의 경우 대체로 변할 일이 적다고 생각하고 DatabaseSO를 만들어두고 데이터를 저장해두었다.

인벤토리 구현

  • 아이템 데이터를 만들었으니 인벤토리(모델)를 구현했다.
  • 그리고 이 모델을 사용할 컨트롤러 겸 프레젠터를 만들었다.
    • 현재는 관심의 분리라는 개념에만 충실하도록 구조를 다듬고 차차 추상화가 필요한 기능들을 붙여나갈 것이다.

기타

인벤토리를 구현하면서 썸네일을 반영하는 작업을 하다가 궁금증이 생겼다.
Resources.Load 시, 하나의 리소스를 2번 이상 호출할 때 메모리 관리가 어떻게 될 것인가?
이 부분은 예전에 지나가면서 들었던 내용이지만 한번 프로파일러를 통해서 직접 확인하는 것도 좋겠다는 생각이 들었다.

프로파일링 결과

  • 여러 차례 리소스 로드 시, 메모리 사용 현황 파악. 참고 디스커션
  • 메모리 프로파일러 : Unity Object
  • 20회 로드
  • 40회 로드

정리

  • 리소스 로드 시, 같은 리소스에 대해서 새로운 메모리 공간에 중복해서 로드를 하기 보다는
    기존에 불러온 리소스를 참조시키는 것으로 확인했다.
  • 이 점은 유니티 메모리 프로파일러를 통해서 확인이 되었다.
  • 다만, 20회와 40회 호출했을때 약간 메모리 사용량의 차이가 있었다.
    • 여기는 리소스 로드와는 별개로 다른 메모리를 사용했다고 보여지는데, 자세한 사용 차이는 다 확인할 순 없었다.
    • 항목이 워낙 많다보니 일일히 보기가 어렵다.
    • 대신 추정해보기로는 Image 컴포넌트에 Sprite 값이 null 이었다가 참조한 Sprite 값을 넣어주면서 스택 영역의 주소값이 더 추가된 것은 아닐까 생각했다.
    • 이 부분은 추후 다시 정리할 필요가 있을 것 같다.
profile
만성피로 개발자

0개의 댓글