디자인 패턴 : 컴포지트 패턴(Composite Pattern)
단일 객체(Leaf)와 복합 객체(Composite)로 이루어지며, 이 둘을 동일한 컴포넌트로 취급하고 동일한 인터페이스로 묶는다. 그리고 재귀적으로 계속 아래로 내려가며, Leaf에 있는 함수를 호출하는 패턴,
파일(Leaf)와 폴더(Compositie)를 생각하면 편하다. 파일 안에 파일이 있을 수도, 파일 안에 파일과 폴더가 있을 수도 있다.
https://febelo0524.tistory.com/73
디자인 패턴 : 컴포지트 패턴
간단한 패턴이다. leaf와 Composite 모두 같은 인터페이스를 상속받고, 구현은 leaf에서, 하며 composite에서는 재귀적으로 자신의 리스트 안에 있는 leaf에서 구현을 호출하게 한다. using System;using Syste
febelo0524.tistory.com
디자인 패턴 : 퍼사드 패턴(Facade Pattern)
배웠던 패턴 중에 가장 쉬웠던 패턴
결국 '단순화된 진입'과 '정리'가 목적
https://febelo0524.tistory.com/74
디자인 패턴 : 파사드 패턴
Facade Pattern : 사용하기 복잡한 클래스 라이브러리에 대해 사용하기 편한 인터페이스를 구성하기 위한 패턴특정한 기능들을 묶어두거나, 생성에 특정한 로직을 추가하는 것이 아닌 '정리'를 위
febelo0524.tistory.com
각각의 캡슐마다 다른 기능이 있지만, 퍼사드 패턴으로 묶고 그 퍼사드 패턴을 인스턴스화 해서 버튼에서 실행해줌.
코딩테스트 : 이진수 더하기
이진수를 의미하는 두 개의 문자열 bin1과 bin2가 매개변수로 주어질 때, 두 이진수의 합을 return하도록 solution 함수를 완성해주세요.
using System;
using System.Collections.Generic;
public class Solution {
public string solution(string bin1, string bin2)
{
string answer = "";
int num1 = Convert.ToInt32(bin1);
int num2 = Convert.ToInt32(bin2);
int num3 = num1 + num2;
string length = Convert.ToString(num3);
var plusnum = length.ToCharArray();
List<int> numList = new List<int>();
for (int i = 0; i < plusnum.Length; i++)
{
numList[i] = Convert.ToInt32(plusnum[i]);
}
for (int i = numList.Count-1; i >= 0; i--)
{
if (numList[i] == 0 || numList[i] == 1) continue;
if (numList[i] > 1)
{
if (i == 0)
{
numList.Insert(0,1);
}
int nextplus = numList[i] - 1;
numList[i+1] += nextplus;
}
}
answer += Convert.ToString(numList);
return answer;
}
}
이런 식으로 논리구조를 작성했는데 하다보니 오류가 발생했다.
1. 처음에는 var plusnum = lenght.Split(""); 을 사용했는데 이는 불가능하다, C#에는 ""으로 나눌수 없다.
2. 만일 정상 작동한다해도 반례가 있다. 11111111111111 정도의 숫자를 두 번 더한다면, 두 자릿수 숫자가 넘어가게 되어 오류가 발생할 가능성이 크다.
3. 더해주는 숫자를 2로 나눈 뒤 더해줘야 한다.
using System;
public class Solution {
public string solution(string bin1, string bin2)
{
string result = "";
int num1 = Convert.ToInt32(bin1, 2);
int num2 = Convert.ToInt32(bin2, 2);
int num3 = num1 + num2;
result += Convert.ToString(num3, 2);
return result;
}
}
허허..... 바꿔주는...ㄱ.ㅣ능이... 있었네.....
다른 사람의 흥미로운 풀이
이것도 린큐를 쓰셔서 푸시는 분들이 있네, 결국 린큐라는 것이 한 번만 쓰는 함수를 이용해서 하는 것이기 떄문에
다 할수 있긴 하겠네요..
코딩테스트 : 잘라서 배열로 저장하기
문자열 my_str과 n이 매개변수로 주어질 때, my_str을 길이 n씩 잘라서 저장한 배열을 return하도록 solution 함수를 완성해주세요.
using System;
using System.Collections.Generic;
public class Solution
{
public string[] solution(string my_str, int n)
{
//여기서 올림 처리를 해줌 : 그렇지 않으면 n보다 작은 수의 문자열이 남았을 때 사라짐
string[] answer = new string[(int)MathF.Floor(my_str.Length +n -1/n)]; { };
List<string> str = new List<string>();
for (int i = 0; i < my_str.Length; i++)
{
n보다 작은 수의 문자열이 남았을 때
if (my_str.Length < i + n)
{
str.Add(my_str.Substring(i, my_str.Length - i));
}
// 기본적인 추가
else
{
str.Add(my_str.Substring(i, n));
}
// -1을 해주는 것에 주의
i = i + n-1;
}
answer = str.ToArray();
return answer;
}
}
전체적인 논리는 틀리지 않았지만, 숫자 올림을 해주거나, 마지막 배열을 어떻게 저장할 것인지에 대해서는
자동완성이 해 주었다.
구체적인 숫자를 대입해 보면서 어떤 처리를 해주어야 하는지 다시 생각해보자.
다른 사람의 흥미로운 풀이
비슷한 방식이지만
for (int i = 0; i < my_str.Length; i++)
{
if (i > 0 && i % n == 0)
이렇게 처리를 해서 n으로 나눴을 때마다 temp를 초기화 해 주고 리스트에 더해주는 방식도 있었다.
굳이 마지막 처리를 할 필요가 없어 굉장히 마음에 드는 방식이다.
코딩테스트 : 삼각형의 완성조건(2)
선분 세 개로 삼각형을 만들기 위해서는 다음과 같은 조건을 만족해야 합니다.
가장 긴 변의 길이는 다른 두 변의 길이의 합보다 작아야 합니다.
삼각형의 두 변의 길이가 담긴 배열 sides이 매개변수로 주어집니다. 나머지 한 변이 될 수 있는 정수의 개수를 return하도록 solution 함수를 완성해주세요.
using System;
public class Solution
{
public int solution(int[] sides)
{
int answer = 0;
int count = 0;
int MaxVal = int.MinValue;
int minVal = int.MaxValue;
for (int i = 0; i < sides.Length; i++)
{
MaxVal = Math.Max(MaxVal, sides[i]);
minVal = Math.Min(minVal, sides[i]);
}
// 뒤의 숫자, 그러니까 새로 추가하는 선분의 길이가 둘 다 포함되지 않기 때문에 -1을 해준다
// ex a<= b <= c 면 b의 갯수는 c - a +1
answer = (MaxVal + minVal) - (MaxVal - minVal) -1;
return answer;
}
}
공책에 쓰니까 쉬웠던 문제
1. 결국 주어진 두 개의 숫자 중에서 큰 숫자를 찾을 수 있다.
2. 그럼 경우의 수는, 새로 넣는 숫자가 가장 클 경우, 그리고 원래 있던 숫자가 가장 클 경우 2 가지이다.
3. 범위를 구해준다.
다른 사람의 흥미로운 풀이
결국 이 논리에서 크게 벗어나지 않지만 다른 방법도 있다.
for 문 안에서 if문을 추가해 계산하는 방식을 생각하지 못했었다. 조건을
if (max < i + min)
{
answer++;
}
요렇게 달고 답을 1씩 더해주는 방법도 있다.
코딩테스트 : 캐릭터의 좌표
머쓱이는 RPG게임을 하고 있습니다. 게임에는 up, down, left, right 방향키가 있으며 각 키를 누르면 위, 아래, 왼쪽, 오른쪽으로 한 칸씩 이동합니다. 예를 들어 [0,0]에서 up을 누른다면 캐릭터의 좌표는 [0, 1], down을 누른다면 [0, -1], left를 누른다면 [-1, 0], right를 누른다면 [1, 0]입니다. 머쓱이가 입력한 방향키의 배열 keyinput와 맵의 크기 board이 매개변수로 주어집니다. 캐릭터는 항상 [0,0]에서 시작할 때 키 입력이 모두 끝난 뒤에 캐릭터의 좌표 [x, y]를 return하도록 solution 함수를 완성해주세요.
코드 양식입니다.
결국 핵심은, '순서'를 맞춰서 입력의 값을 진행해 주어야 한다는 점이다.
무효가 되는 입력이 있기에, 특정 인풋의 개수를 카운팅해서 더해주는 방식은 오류가 있을 수 있다.
using System;
using UnityEngine.UI;
public class Solution {
public int[] solution(string[] keyinput, int[] board)
{
int[] answer = new int[2]{0,0};
for (int i = 0; i < keyinput.Length; i++)
{
int[]Movement = Move(keyinput[i]);
answer[0]+= Movement[0];
answer[1]+= Movement[1];
}
return answer;
}
int[] Move(string input)
{
int[] Movement = new int[2] { 0, 0 };
if (input == "Right")
{
Movement[0] = 1;
}
if (input == "Left")
{
Movement[0] = -1;
}
if (input == "Up")
{
Movement[1] = 1;
}
if (input == "Down")
{
Movement[1] = -1;
}
return Movement;
}
}
이 방식이 작동을 안하길래 한참 보고 있었다. (약 10분)
입력이 소문자였다.
using System;
public class Solution {
public int[] solution(string[] keyinput, int[] board)
{
int[] answer = new int[2]{0,0};
for (int i = 0; i < keyinput.Length; i++)
{
int[]Movement = Move(keyinput[i]);
answer[0]+= Movement[0];
answer[1]+= Movement[1];
int xLimit = board[0]/2;
int yLimit = board[1]/2;
if (answer[0] > xLimit)
{
answer[0] = xLimit;
}
else if (answer[0] < -xLimit)
{
answer[0] = -xLimit;
}
else if (answer[1] > yLimit)
{
answer[1] = yLimit;
}
else if (answer[1] < -yLimit)
{
answer[1] = -yLimit;
}
}
return answer;
}
int[] Move(string input)
{
int[] Movement = new int[2] { 0, 0 };
if (input == "right")
{
Movement[0] = 1;
}
if (input == "left")
{
Movement[0] = -1;
}
if (input == "up")
{
Movement[1] = 1;
}
if (input == "down")
{
Movement[1] = -1;
}
return Movement;
}
}
다른 사람의 흥미로운 풀이
Move 함수를 만들어서 사용하는 것도 좋지만, 이 문제만을 풀기 위해서라면
x = x == leftEnd ? leftEnd : x - 1;
이런 식으로 x,y를 구한 뒤 배열의 숫자에 대입하는 것도 좋은 방법이 될 수 있을것 같다.
사운드 매니저 구현 이어서 하기
오류 1
슬라이더를 만들어서 볼륨 조절을 했다.
그런데 Mute를 담당하는 버튼을 연타하다보면 슬라이더 값도 자동으로 변경되는 문제였다.
다른 분들의 도움을 받아 해결했다. 이유는 버튼 UI를 다른 UI의 자식 오브젝트로 연결하는 문제였다.
Slider는 자식 오브젝트인 Button의 입력값도 받게 된다. 이해를 위해 동영상을 준비했다.
SFXMute는 SFX의 사운드를 담당하는 슬라이더의 하위 오브젝트로 있기에, 드래그하면 SFX Slider 값이 0이 되고,
BGMMute는 BGM의 슬라이의 자식 오브젝트로 있지 않기에 드래그해도 Slider 값이 변하지 않는다.
이 패널창 자체도, 위의 느낌표 모양의 버튼의 하위 오브젝트로 있기에 클릭하면 클릭이 되는 모션이 보인다.
정렬을 위해서 택한 방식인데, 오류가 발생했다. 이유를 알았으니 그냥 귀찮더라도 새 오브젝트를 만들고 그곳에다 정렬을 해야겠다.