#include <vector>
int solution(int n)
{
switch(n)
{
case 0 : return 0;
case 1 : return 1;
}
int answer = solution(n-2) + solution(n-1);
return answer % 1234567;
}
처음엔 굉장히 심플하게 생각해서 재귀로 간단하게 작성하고 돌려봤다.
당연히 되지 않았다.
최대 백만까지 값이 들어 올 수 있기 때문인데 이 떄문에 제대로 오버플로우 문제도 발생한다.
요구 사항은 결국 F(n-2) + F(n-1)
#include <vector>
int solution(int n)
{
std::vector<int> v(2);
v[0] = 0;
v[1] = 1;
for(int i=2;i<=n;++i)
{
int a = v[i-1] % 1234567;
int b = v[i] % 1234567;
v.push_back((a+b)%1234567)
}
return v.back();
}
누적하는 결과를 얻기위해 이런식으로 구성해 봤는데 동작이 안되었다.
벡터로 누적하는 것도 마음에 들지 않았었는데 되지도 않았다. 왜 되지 않는가 고민하면서
정답코드도 넣어봤다. 그래도 되지않았다.
#include <string>
#include <vector>
using namespace std;
int solution(int n) {
int answer = 1; // == f(n-1) % 1234567
int before = 0; // == f(n-2) % 1234567
int tmp;
for (int i = 2; i <= n; i++)
{
tmp = answer;
answer = (answer% 1234567 + before% 1234567) % 1234567; // == f(n) % 1234567
before = tmp;
}
return answer;
}
위는 정답 코드인데 그래도 되지않았다.
문제는 반례를 검색해서 넣은 테스트케이스가 문제였는데
누가 잘못 올려놓은걸 테스트케이스에 넣어둔 것이었다.
필사적으로 머리를 굴리는게 맞지 믿을건 없다..
std::lower_bound 지정값 이상이 들어있는 인덱스를 얻어온다.
std::upper_bound 지정값 이하의 인덱스를 얻어온다.
vector<int> v = {1,2,3,4,5,6,7,8,9,9};
int start = lower_bound(v.begin(), v.end(), 4);
int end = upper_bound(v.begin(), v.end(), 6);
// 4이상 6이하의 인덱스를 가지고 오므로
// 그것들을 계산해주면 개수를 구할 수 있다.
int count = end-start;
[조호영 튜터님]
1. 특별한 커리어가 필요하지 않다.
2. 튜터님 공부법
[김하연 튜터님]
게임 개발자의 가치
[박경호 튜터님]
기술블로그가 중요하다.
나는 어떤 절차를 밟아야할지에 대해서 생각해봤는데 우선 클라 개발자가 되고, 엔진 엔지니어 쪽으로 가보고 싶다는 생각을 하게 되었다. 보았던 경지가 있으니 거기를 목표로 두고서 가고 싶다.
끝내 맨땅에서 컴퓨터 하나만 가지고 무언가 뚝딱 만들 수 있는 레벨까지 올라가고 싶다.
언리얼에서 GEngine->GetWorld()는 쓰지 않는게 좋다. Level에서 배치된 Actor의 GetWorld를 쓰는것을 권장한다. 다른 문제가 있는 줄 알고 한참 찾았는데 이게 원인이였다.
FString.Contains("")를 사용하자 물론 ==도 제공을 해주지만 다국적언어를 지원하는 언리얼에서는
어떤 문제가 발생할 지 모르니 아직 맨땅에 부딛혀 얻은 결론은 아니지만 굳이 헤딩하지말자.
타이머의 델리게이트를 추가할 수 있게 해준다.
FTimerDelegate.bind(
[해당 객체의 포인터],
[함수 이름],
[파라메터]);
GetWorldTimerManager().SetTimer(
[헨들],
[FTimerDelegate],
[지속시간],
[반복여부]
);
델리게이트를 빼고 람다를 넣어도 된다.
타임매니저의 기능이다. 감소된 시간을 가지고 올 수 있다.
GetWorldTimeManager.GetTimerRemining(
TimerHandle
);
이렇게 하면 가지고 올 수 있다.
언리얼 이넘은 좀 까다롭다
UENUM(BlueprintType)
enum class EUIType : uint8
{
HUD UMETA(DisplayName = "HUD"),
MENU UMETA(DisplayName = "MENU"),
Max UMETA(Hidden)
};
ENUM_RANGE_BY_FIRST_AND_LAST(EUIType, EUIType::HUD, EUIType::MENU);
for(EUIType Type : TEnumRange<EUIType>())
{
}
이렇게 지정을 해주는 이유는 결국에는 for문에서 모든 타입을 순회할 때 편하게 쓰기 위해서다.
ENUM_RANGE_BY_FIRST_AND_LAST(EUIType, EUIType::HUD, EUIType::MENU)해당 매크로는 Range를 설정해준다.
위의 Enum처럼 Hidden이 들어가 있다면 오류가 나기 떄문이다.
USTRUCT(BlueprintType)
struct FSpartaWidget
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadOnly)
TSubclassOf<UUserWidget> CustomWidget;
UPROPERTY()
UUserWidget* Instance = nullptr;
};
무언가를 상속받아서 사용하는 건줄 알았는데 이렇게만 해도 쓸 수 있다.
TMap<EUIType,FSpartaWidget> Widgets;
맵으로 타입과 위젯을 관리할 수 있게 되었다 사용 해보니까 편하다.
역시 자료구조는 잘 써야 좋다.
깊게 들어가서 공부를 하기엔 시간이 짧다 구현 방법이나 노하우만 빠르게 익히고
이력서나 포폴에 대한 구성을 준비하는게 좋을거 같다는 결론이 나왔다.
그렇다고 코드를 너무 막가져다가 쓰면 결국 남는게 없다.
적절히 조율해서 내가 생각해서 코드를 짜 낸 결과가 비슷할 수 있도록
부수고 다시 조립해보는게 최고일 거라는 생각이 든다.