2019년 11월 29일 금요일

알고리즘(algorithm) - 직사각형 나머지 한 점 구하기

문제 설명


직사각형을 만드는 데 필요한 4개의 점 중 3개의 좌표가 주어질 때, 나머지 한 점의 좌표를 구하려고 합니다. 점 3개의 좌표가 들어있는 배열 v가 매개변수로 주어질 때, 직사각형을 만드는 데 필요한 나머지 한 점의 좌표를 return 하도록 solution 함수를 완성해주세요. 단, 직사각형의 각 변은 x축, y축에 평행하며, 반드시 직사각형을 만들 수 있는 경우만 입력으로 주어집니다.
제한사항
  • v는 세 점의 좌표가 들어있는 2차원 배열입니다.
  • v의 각 원소는 점의 좌표를 나타내며, 좌표는 [x축 좌표, y축 좌표] 순으로 주어집니다.
  • 좌표값은 1 이상 10억 이하의 자연수입니다.
  • 직사각형을 만드는 데 필요한 나머지 한 점의 좌표를 [x축 좌표, y축 좌표] 순으로 담아 return 해주세요.

입출력 예
vresult
[[1, 4], [3, 4], [3, 10]][1, 10]
[[1, 1], [2, 2], [1, 2]][2, 1]
입출력 예 설명
입출력 예 #1
세 점이 [1, 4], [3, 4], [3, 10] 위치에 있을 때, [1, 10]에 점이 위치하면 직사각형이 됩니다.
입출력 예 #2
세 점이 [1, 1], [2, 2], [1, 2] 위치에 있을 때, [2, 1]에 점이 위치하면 직사각형이 됩니다.

문제 풀이 ) 
난 너무 복잡하게 풀어서 정석 풀이로..

x, y 좌표가 각가 2개씩 같은 수가 있어야 하므로
간단하게 X1 xor X1 xor X2 = X2를 사용하여 다른 값 1개를 구할 수 있다.

예제 코드)

vector<int> solution(vector<vector<int> > v) {
    vector<int> ans = {0,0};

    for (int i = 0; i < 3; ++i)
    {
        ans[0] ^= v[i][0];
        ans[1] ^= v[i][1];
    }

    return ans;

}

2019년 11월 21일 목요일

알고리즘(algorithm) - 순열 검사

문제 설명


길이가 n인 배열에 1부터 n까지 숫자가 중복 없이 한 번씩 들어 있는지를 확인하려고 합니다.
1부터 n까지 숫자가 중복 없이 한 번씩 들어 있는 경우 true를, 아닌 경우 false를 반환하도록 함수 solution을 완성해주세요.
제한사항
  • 배열의 길이는 10만 이하입니다.
  • 배열의 원소는 0 이상 10만 이하인 정수입니다.

입출력 예
arrresult
[4, 1, 3, 2]true
[4, 1, 3]false
입출력 예 설명
입출력 예 #1
입력이 [4, 1, 3, 2]가 주어진 경우, 배열의 길이가 4이므로 배열에는 1부터 4까지 숫자가 모두 들어 있어야 합니다. [4, 1, 3, 2]에는 1부터 4까지의 숫자가 모두 들어 있으므로 true를 반환하면 됩니다.
입출력 예 #2
[4, 1, 3]이 주어진 경우, 배열의 길이가 3이므로 배열에는 1부터 3까지 숫자가 모두 들어 있어야 합니다. [4, 1, 3]에는 2가 없고 4가 있으므로 false를 반환하면 됩니다.



나의 풀이 )
배열을 정렬한 뒤 차례대로 값을 비교.


코드 )

#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

bool solution(vector<int> arr)
{
   sort(arr.begin(), arr.end());
    
    for(int i = 0; i < arr.size(); ++i)
    {
        if(arr[i] != i + 1 )
            return false;
    }
    return true;
}




또 다른 풀이 1 )
범위를 벗어나지 않는 값이 몇번 나오는지 체크.


코드)

#include <iostream>
#include <vector>

using namespace std;


int check[100001] = { 0 };

bool solution(vector<int> arr)
{
int n = arr.size();

for (int i = 0; i < n; ++i)

{
if (arr[i] < i || arr[i] > n)
return false;
check[arr[i]]++;
}

for(int i = 1; i <= n; ++i)

if(check[i] != i)
return false;

return true;

}




또 다른 풀이 2 )
배열안에 있는 값을 모두 더한 값을 1부터 배열크기까지의 정수를 더한값을 비교.


코드)

#include <vector>
#include <iostream>
using namespace std;

bool solution(vector<int> arr)

{
    bool answer = true;

    long a = 0;

    long b = 0;

    for( int i = 0 ; i < arr.size(); ++i )

    {
        a += ( i + 1 );
        b += arr[i];
    }

    if( a!= b )

        answer = false;


    return answer;

}

문제 출처 : https://programmers.co.kr/learn/courses/18/lessons/1877 (프로그래머스 예제)

알고리즘(algorithm) - 자릿수 더하기

문제 설명

자연수 N이 주어지면, N의 각 자릿수의 합을 구해서 return 하는 solution 함수를 만들어 주세요.
예를들어 N = 123이면 1 + 2 + 3 = 6을 return 하면 됩니다.
제한사항
  • N의 범위 : 100,000,000 이하의 자연수

입출력 예
Nanswer
1236
98724
입출력 예 설명
입출력 예 #1
문제의 예시와 같습니다.
입출력 예 #2
9 + 8 + 7 = 24이므로 24를 return 하면 됩니다.


나의 생각 )
나머지 구하기와 나누기를 이용하여 한자리씩 더하면 결과값과 일치하게 나올것입니다.


예제 코드 )

#include <iostream>

using namespace std;
int solution(int n)
{
    int answer = 0;
        
    for(int i = 0 ; i < 10 ; ++i)
    {
        if(n == 0
            break;
        
        answer += n % 10;
        n /= 10;
    }

    return answer;
}

문제 출처 : https://programmers.co.kr/learn/courses/18/lessons/1876 (프로그래머스 예제)

2019년 11월 20일 수요일

Git이란?

▶ 1. Git이란? (참고 : https://git-scm.com/book/ko/v2 (공식 Site 한글 매뉴얼))



 - SVN과 마찬가지로 소스코드의 효율적인 관리를 위한 형상 관리 도구(Configuration Management Tool) 중 하나.
즉, 소프트웨어를 개발하는 기업의 핵심 자산인 소스코드를 효과적으로 관리할 수 있게 해주는 무료이자 공개소프트웨어이다.
최근 오픈소스 커뮤니티의 발전과 함께 널리 사용되고 있으며, SVN을 사용하던 개발 조직들도 하나둘씩 Git으로 갈아타고 있는 추세.

 - Git이 SVN과 다른 점은 분산형 관리 시스템이라는 것이다.
중앙 서버에 소스코드와 히스토리를 저장하는 SVN과 달리 Git은 소스코드를 여러 개발 PC와 저장소에 분산해서 저장하기 때문에 중앙 서버에 장애가 발생해도 로컬 저장소에 커밋을 할 수 있으며, 로컬 저장소들을 이용하여 중앙 저장소의 복원도 가능하다.
또한, 분산형으로 코드를 관리하기 때문에 다양한 Workflow를 가능하게 한다는 점이 SVN과 비교하여 Git이 갖는 장점이라 할 수 있다.

 - 초창기 Git은 리눅스를 만든 리눅스 토발즈가 리눅스 커널 개발에 이용하려고 만들었다. 
기존 리눅스 커널 관리를 위해 BitKeeper라는 툴을 쓰다가 유료로 전환되는 바람에 만든 분산형 버전 관리 시스템이다.
이후 GitHub 등에서 오픈소스 개발을 위해 사용하면서 소프트웨어 업계에 널리 사용되게 되었다.

 - 참고 URL
SourceTree (클릭으로 Git을 관리할 수 있는 툴) : https://www.sourcetreeapp.com/



▶ 2. Git의 장점

- 소스코드를 주고 받을 필요 없이, 같은 파일을 여러 명이 동시에 작업하는 병렬 개발이 가능하다.

- 즉 브랜치를 통해 개발한 뒤, 본 프로그램에 합치는 방식(Merge)으로 개발을 진행할 수 있다. 

- 분산 버전관리이기 때문에 인터넷이 연결되지 않은 곳에서도 개발을 진행할 수 있으며, 중앙 저장소가 날라가버려도 다시 원상복구할 수 있습니다.

- 팀 프로젝트가 아닌, 개인 프로젝트일지라도 GIT을 통해 버전 관리를 하면 체계적인 개발이 가능해지고, 프로그램이나 패치를 배포하는 과정도 간단해집니다. (pull을 통한 업데이트, patch 파일 배포) 


  (그림 출처: http://pismute.github.io/whygitisbetter/images/local-remote.png)



▶ 3. 공식 사이트에 나온 Git의 특징

 - 3.1 Distributed development
전체 개발 이력을 각 개발자의 로컬로 복사본을 제공하고 변경된 이력을 다시 하나의 저장소로 복사한다.
이러한 변경은 추가개발지점을 가져와, 로컬개발 지점과 동일하게 병합(merge)할 수 있다.저장소는 Git protocol 및 HTTP로 쉽고 효율적(특별한 웹서버 구성없이)으로 접근할 수 있다.

 - 3.2 Strong support for non-linear development
신속하고 편리항 branch 및 merge 지원, 비선형(여러갈래) 개발 이력을 시각화하고 탐색 할 수 있는 강력한 도구를 제공한다.

 - 3.3 Efficient handling of large projects
Git은 매우 빠르고, 대형프로젝트나 이력이 많은 작업에 매우 합리적이다. Git은 대부분의 다른 버전관리시스템보다 빠르게 요청한다. 그리고 일부 작업에서는 더 빠르게 진행한다.
또한, 최근의 정상급 오픈소스 버전관리 시스템보다 장기간의 수정내역을 매우 효율적인 압축방법을 사용한다.

 - 3.4 Cryptographic authentication of history
GIt의 이력은  성공한 개발이력의 commit에 의해 개정명으로 저장된다. 일단 그것이 배포되면, 그것을 모르고 예전버전으로 변경하는것은 불가능하다. 또한, 그것들을 암호화 할수 있다.

 - 3.5 Toolkit design
UNIX의 전통에 따라, GIT은 C로 작성된 많은 소규모 도구모음이다, 그리고 많은 스크립트들이 기능 보강을 제공한다. Git은 새로운 기발한 작업을 위한 손쉬운 사용과 쉬운 스크립팅을 위한 도구를 제공한다.



▶ 4. Github. Gitlab?

- Git 이랑 Github은 무슨 차이일까????

Git의 기능 데이터를 원격 저장소에 저장하는 기능이 있다. 이때 원격 저장소 역할을 하는 것이 Github이다.
하지만 비공개(Private) 프로젝트의 경우 월 비용을 지불해야 하기 때문에 비공개 프로젝트도 무료로 지원하는 gitlab도 많이 사용되고 있다.



▶ 5. 관련 용어들
 - Repository : 저장소를 의미하며, 저장소는 히스토리, 태그, 소스의 가지치기 혹은 branch에 따라 버전을 저장한다. 저장소를 통해 작업자가 변경한 모든 히스토리를 확인 할 수 있다.

 - Working Tree : 저장소를 어느 한 시점을 바라보는 작업자의 현재 시점.

 - Staging Area : 저장소에 커밋하기 전에 커밋을 준비하는 위치.

 - Commit : 현재 변경된 작업 상태를 점검을 마치면 확정하고 저장소에 저장하는 작업.

 - Head : 현재 작업중인 Branch를 가리킨다.

 - Branch : 가지 또는 분기점을 의미하며, 작업을 할때에 현재 상태를 복사하여 Branch에서 작업을 한 후에 완전하다 싶을때 Merge를 하여 작업을 한다.

 - Merge : 다른 Branch의 내용을 현재 Branch로 가져와 합치는 작업을 의미한다.



▶ 6. Git 사용하기 기초 용어

git init : 버전관리 하고싶은 폴더에서 초기화를 하는 준비

git branch
- 독립적인 공간을 만든다. 
- 새로 만든 branch lab1은 master와 완전히 동일한 상태를 가진 공간.
- 브랜치에서 수정을 한 후 커밋하면 lab1에만 기록되며 master 브랜치에는 어떤 영향도 주지 않는다.
- 원하는 만큼 빠르게 branch를 만들 수 있다.

- 실험 중 다른 브랜치로 돌아가야 할 때 : checkout master 로 head를 옮겨야 한다.
(cf > 작업 중인 위치를 가르키는 가상의 커서가 존재하는데 이를 git에서는 HEAD라 한다.)

- 실험 성공 : lab1 브랜치의 내용을 마스터 브랜치와 병합(Merge) 한다.
- 실험 실패 : lab1 브랜치를 삭제한다.

checkout
- 독립된 작업 공간인 브랜치를 자유롭게 이동할 수 있다.

git commit 
 - 의미있는 수정 작업이 끝났을 때 마침을 알리는 작업

pull
- 리모트 저장소의 변경된 내용을 로컬(내 컴퓨터) 저장소에 적용하는 작업을 pull이라 한다.


master
- git init을 했을 때, default로 만들어지는 가지가 'master'이다.


동료와 함께 작업하려면? -> github! or bitbucket
- git은 'remote 저장소'를 지원한다.
- github이 바로 remote저장소이다.
- bitbucket은 5명까지 공동작업 가능하다. (그 이상은 유료)
- github은 private가 유료이다.


( add, commit, push, pull, fetch, checkout 용어에 따른 프로세스)
( 그림 출처: http://osteele.com)


출처: https://goddaehee.tistory.com/91 [갓대희의 작은공간]

2019년 11월 16일 토요일

unity - coroutine( 코루틴 )

[Unity] 유니티 코루틴 이해하기 (LUA coroutine 참고)


@유니티 코루틴 이해하기

Update() 함수에 제어문을 통해 함수를 호출하는 식으로 코딩할 경우,이미 사용됐거나 굳이 필요치 않은 기능들도 작업을 계속 수행해 연산이 낭비된다.
몇 초 후에 작업이 필요할 때 또는 특정 상황의 종료 후에 작업하려할 때Update() 함수를 통해 매 프레임마다 작업이 끝났는지 계속 확인해야 하기 때문이다.


*코루틴이란?

진입 지점이 여러개인 함수.  단일 쓰레드로 동작하는 유니티는 코루틴을 사용하므로써 멀티쓰레드를 흉내낼 수 있다.  일반적으로 함수가 호출되서 끝나는 서브루틴의 개념과 달리  yield return을 사용해 그 위치를 기억한 후 다음 호출 때 그곳부터 다시 실행할 수 있다.  그래서 여러개의 코루틴을 동작시키고 각기 다른 시점에 yield가 반환되도록 할 경우 마치 여러 개의 쓰레드가 동시에 동작하는 것과 같은 효과를 낸다.


*코루틴의 특징

문자열로 호출 가능while문을 이용해 무한 유지 가능yield 키워드를 통해 대기와 호출 조정 가능해당 게임 오브젝트가 비활성화되면 자동 소멸


*코루틴 시작 함수
StartCoroutine("문자열");StartCoroutine(함수이름);


*기본 구조
IEnumerator 함수이름(매개변수) { ... }


*yield
yield 키워드를 통해 코루틴이 해당 조건이 될 때까지 실행을 일시정지시키는 기능을 사용할 수 있다.
yield return null : 다음 프레임까지 대기
yield return new WaitForSeconds(float) : 지정된 초만큼 대기
yield return new WaitForFixedUpdate() : 다음 물리 프레임까지 대기
yield return new WaitForEndOfFrame() : 모든 렌더링 작업이 끝날 때까지 대기
yield return StartCoroutine(string) : 다른 코루틴이 끝날 때까지 대기
yield return new WWW(string) : 웹 통신 작업이 끝날 때까지 대기
yield return new AsyncOperation : 비동기 작업이 끝날 때까지 대기(씬로딩)


출처 : http://kukanuc.blogspot.com/2019/01/unity.html

c# - 가비지컬렉터(GarbageCollector)사용시 주의해야 할 점

C# __6.0 가비지컬렉터(GarbageCollector)사용시 주의해야 할 점


이전 내용에서 가비지 컬렉션에 대해 알아보았으니, 이번에는 비지 컬렉터의 성능을 저하시키지 않기 위해 객체를 생성함에 있어서 조심해야할 부분 살펴보겠습니다.

첫번째로 객체를 너무 많이 할당하지 말아야 합니다. 
가장 기본적인 지침인데요, CLR 객체 할당 속도가 빠르긴 하지만 너무 많은 수의 객체는 관리되는 힙의  세대에 메모리 포화를 초래할  있고이는 빈번한 가비지 컬렉션을 부르는 결과를 낳습니다객체 할당 코드를 작성할   필요한 객체인지와 필요 이상으로 많은 객체를 생성하는 코드가 아닌지의 여부를 고려해야합니다.


두번째는 너무  객체 할당을 피해야 합니다. 
CLR 보통 크기의 객체를 할당하는 힙과는 별도로 85KB 이상의  객체를 할당하기 위한 '대형 객체 (LOH:Large Object Heap)' 따로 유지합니다. 우리가 평소에 사용하는 힙은 대형 객체 힙에 대비되는 개념으로 소형 객체 이라고 부르기도 합니다.

커다란 객체를 소형 객체 힙에 할당한다면 0세대가 빠르게 차오르게 되므로 가비지 컬렉션을  자주 촉발하게 되고이는 어플리케이션의 성능 저하를 불러오게 됩니다그래서 대형 객체 힙을 별도로 유지함으로  성능 향상의 효과를 내고 있습니다만단점도 있겠지요.

우선 대형 객체 힙은 동작 방식이 소형 객체 힙과 다릅니다대형 객체 힙은 객체의 크기를 계산한  그만한 여유 공간이 있는지 힙을 탐색하여 할당합니다. GC 수행한  소형 객체 힙은 해제된 메모리 공간에 인접 객체들을 끌어당겨 차곡차곡 정리하지만대형 객체 힙은 해제된 공간을 그대로 둔답니다매우  메모리를 복사하는 비용이 너무 비싸기 때문이지요.
 공간은 나중에 다른 객체들에게 할당 되겠지만메모리를 0바이트의 낭비도 없이 사용하는 소형객체 힙과는 달리  공간을 군데군데 낭비하게 됩니다.

그리고 또하나 CLR 대형 객체 힙을 2세대 힙으로 간주하기 때문에 대형 객체 힙에 있는 쓰레기 객체가 수거되려면 2세대에 대한 가비지 컬렉션이 수행되어야 합니다2세대 가비지 컬렉션은  세대에 대한 가비지 컬렉션을 유발하기 때문에 수거되는 메모리의 양이  수록 어플리케이션이 정지되는 경우가 발생하게 됩니다그래서 너무  객체를 할당하는 코드는 조심스럽게 고려해보아야 한답니다.


세번째는 너무 복잡한 참조 관계는 자제해야 합니다
이러한 지침은 성능 뿐아니라 가독성을 위해서라도 주의하셔야합니다참조 관계가 많은 객체는 가비지 컬렉션 후에 살아남았을 때가 문제입니다가비지 컬렉션에서 살아남았을 경우 다음 세대로 옮기기 위해 메모리 복사를 수행하는데  참조관계가 복잡한 객체의 경우에는 단순히 메모리를 복사하는데서 끝나지 않습니다객체를 구성하고 있는  필드 객체 간의 참조 관계를 일일이 조사해서 참조하고 있는 메모리 주소를 전부 수정한답니다 클래스 구조가 간단했다면 메모리 복사만으로도 끝났을 일을 탐색과 수정까지 거치게 되는것이죠.


네번째는 루트를 너무 많이 만들지 말아야 합니다. 
가비지 컬렉터는 루트 목록을 순회하면서 쓰레기를 찾아냅니다루트 목록이 작아진다면 그만큼 가비지 컬렉터가 검사를 수행하는 횟수가 줄어들므로  빨리 가비지 컬렉션을 끝낼  있습니다따라서 루트를 가급적 많이 많들지 않는 것이 성능에 유리하겠지요 내용은 필요 이상으로 객체를 만들지 말라는 기본적인 지침입니다.