숏코딩 분석

프로그래머스> [Level1] 두정수 사이의 합 문제를 작성 후

다른 사람은 어떻게 풀었는지 궁금해져서 다른 사람들의 풀이를 확인 하는 곳으로 이동하여, 가장 처음의 풀이의 조건처리 하는 부분을 보았더니 단 2줄.. 처음엔 이게 뭔가..

  1. 뚫어지게 보고,
  2. 비트연산 해보고,
  3. 팀장 아저씨한테 물어보고,
  4. 숏코딩 코드를 분리해 본 후.

숏코딩이 뭔지 찾아보니.. 가독성과 효율은 다 필요없고, 그냥 짧은 타이핑(…)을 목적으로 하고 있었네요. 덕분에 흥미가 자극되어져서 재밋게 문제를 풀어 보았습니다.

  • 문제 설명
    • 두 정수 a, b가 주어졌을 때 a와 b 사이에 속한 모든 정수의 합을 리턴하는 함수, solution을 완성하세요. 예를 들어 a = 3, b = 5인 경우, 3 + 4 + 5 = 12이므로 12를 리턴합니다.
  • 제한 조건
    • a와 b가 같은 경우는 둘 중 아무 수나 리턴하세요.
    • a와 b는 -10,000,000 이상 10,000,000 이하인 정수입니다.
    • a와 b의 대소관계는 정해져있지 않습니다.
#include vector

using namespace std;

long long solution(int a, int b)
{
    long long answer = 0;
    if (a > b) a ^= b ^= a ^= b;
    answer = (long long)b * -~b / 2 - (long long)a * ~-a / 2;
    return answer;
}

계속 읽기 “숏코딩 분석”

[Level1] 연속된 같은 숫자 제거

프로그래머스> [Level1] 같은 숫자는 싫어

#include vector

using namespace std;

vector solution(vector arr)
{
    vector answer;

    int prev = arr[0];
    answer.push_back(arr[0]);

    for (int i = 1; i  제네릭 unique 알고리즘을 이용 중복값 제거"]
#include vector
#include algorithm
#include iostream
#include iterator

using namespace std;

vector solution(vector arr)
{
    vector answer = arr;

    // 문제가 쏘팅 안해도 되는거네.
    //sort(answer.begin(), answer.end());

    // 중복 제거.
    vector::iterator newIntVector;
    newIntVector = unique(answer.begin(), answer.end());

    // 끝부분을 제거.
    answer.erase(newIntVector, answer.end());

    return answer;
}

[Level1] 2016년 a월 b일에 해당하는 요일 구하기

실제 문제를 풀어보고, 다른사람과 비교하는 재미가 꽤 있다. 시간날때 하나씩 풀어보면 좋을듯 함.

프로그래머스> [Level1] 2016년

#include vector
#include string

using namespace std;

string solution(int a, int b)
{
    string answer = "";

    int year = 2016;
    int month = a;
    int day = b;

    // 날짜의 시작은 월요일이고, 가정된상황이 2016년 1월 1일은 금요일
    // 이기 때문에, 추가적으로 금요일(월[0]부터시작 화[1],수[2],목[3],금[4])
    // 만큼의 Day를 더해 주어야 함.
    int additionalDay = 4;

    // 전제 조건이 윤년이므로, 윤년을 체크하는 로직은 필요 없고,
    // 바로 윤년일때의 데이타를 사용하면 됨.
    int DayArr[13] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    int MonthTotalDay = 0;
    for (int i = 0; i < month; i++)
    {
        MonthTotalDay += DayArr[i];
    }

    // 1월1일에서 설정된 월, 일에 맞추어 합산된 Day에 따른
    // VIP(DayOfTheWeek의 약어)를 설정해서 보내준다.
    int DayOfTheWeek = (MonthTotalDay + day + additionalDay) % 7;

    switch (DayOfTheWeek)
    {
        case 0: answer = "SUN"; break;
        case 1: answer = "MON"; break;
        case 2: answer = "TUE"; break;
        case 3: answer = "WED"; break;
        case 4: answer = "THU"; break;
        case 5: answer = "FRI"; break;
        case 6: answer = "SAT"; break;
    }

    return answer;
}

 

  • 윤년 계산법
    • 윤년(4년에 한번)일때는 1일을 더해준다.
    • 윤년 계산에 대한 오차를 보정하기 위해 100년마다 하루를 뺀다.
    • 두번의 오차 수정에도 불구 하고 오류가 정확히 보정되지 않기 때문에 400년 마다 하루를 더해준다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Level01_2016 : MonoBehaviour
{
	void Start ()
    {
        // 01. 1년 부터 (Y-1)년 까지 윤년(LeapingYear)의 수를 구한다.
        int Y = 2016;
        int L = ((Y - 1) / 4) - ((Y - 1) / 100) + ((Y - 1) / 400);
        Debug.Log("1 To 2016 Year LeapingYearCount : " + L);

        Debug.Log("[Func] 1 To 2016 Year LeapingYearCount : " + GetLeapingYear(2016));

        // -- 여기서부터 실제 계산.
        // 2016년 1월 1일은 금요일 이기때문에 추가적으로 금요일(월[0]부터시작 화[1],수[2],목[3],금[4]) 만큼의 Day를 더해 주어야 함.

        int year  = 2016;
        int month = 6;
        int day   = 21;

        Debug.Log(year + ". " + month + ". " + day + " What the VIP");

        Debug.Log("[Func] " + year + " is LeapingYear : " + GetIsLeapingYear(year));

        int TotalMonthDay = GetTotalDayByMonth(month, GetIsLeapingYear(year)) + day + 4;
        string VIP = GetDayOfWeekToString(TotalMonthDay % 7);

        Debug.Log("[Func] VIP : " + VIP);
    }

	// Update is called once per frame
	void Update () {

	}

    string GetDayOfWeekToString(int DayOfTheWeek)
    {
        string DayOfTheWeek_Str = string.Empty;

        switch(DayOfTheWeek)
        {
            case 0: DayOfTheWeek_Str = "SUN"; break;
            case 1: DayOfTheWeek_Str = "MON"; break;
            case 2: DayOfTheWeek_Str = "TUE"; break;
            case 3: DayOfTheWeek_Str = "WED"; break;
            case 4: DayOfTheWeek_Str = "THU"; break;
            case 5: DayOfTheWeek_Str = "FRI"; break;
            case 6: DayOfTheWeek_Str = "SAT"; break;
        }

        return DayOfTheWeek_Str;
    }

    // 01. 1년 부터 TargetYear년 까지의 윤년의 수를 구한다.
    int GetLeapingYear(int TargetYear, int FromYear = 1)
    {
        int LeapingYear = 0;

        /**
         * 태양력에 대한 날짜보정(윤년 계산).
         * 1차. 4년마다 하루를 더해준다.
         * 2차. 1차에서의 계산에 오차가 있어, 100년 마다 하루 뺌.
         * 3차. 2차에서의 보정에 대해서도 오차가 있어 400년 마다 하루를 더함.
         */
        LeapingYear = ((TargetYear - FromYear) / 4) - ((TargetYear - FromYear) / 100) + ((TargetYear - FromYear) / 400);

        return LeapingYear;
    }

    bool GetIsLeapingYear(int TargetYear)
    {
        bool IsLeapingYear = false;

        if ((TargetYear % 4)  " + TotalYearPerDay);
        return TotalYearPerDay;
    }

}

[C#] IEnumerable, Linq 사용 예제

유니티에서 Foreach 를 실행시 Garbage를 생성시키는것을 피하기위해서 주로 사용 했었는데, 근래에는 Foreach를 사용해도 Garbage를 생성 하지 않는다 한다.

다음목표

  1. IEnumerable 를 어떤 케이스에서 쓰는게 효율적일지 생각해보자.
  2. Linq 는 어떤 상황일때 쓰는게 좋을지 생각해보자.
using UnityEngine;
using System.Collections;
using System.Collections.Generic; // IEnumerable 쓰려고.
using System.Linq;

public class Bong9_Enumerable : MonoBehaviour {

	// Use this for initialization
	void Start () {

        ///
        /// string 객체에는 IEnumerable 인터페이스가 구현 되어있다.
        /// 

        string[] strList = { "bong9", "bong8", "bong7", "b09", "b08", "b07" };

        // 구현.
        Debug.Log("------IEnumerable() Start ------");
        IEnumerable(strList);
        Debug.Log("------IEnumerable() End ------");

        // Linq 사용.
        Debug.Log("------IEnumerable_Linq() Start ------");
        IEnumerable_Linq(strList);
        Debug.Log("------IEnumerable_Linq() End ------");
	}

    void IEnumerable_Linq(string[] strList)
    {
        // 조건 : 글자수가 3개 이하.
        IEnumerable enumerable = from str in strList where str.Length <= 3 select str;

        IEnumerator e = enumerable.GetEnumerator();

        while (e.MoveNext())
        {
            Debug.Log(e.Current);
        }
    }

    void IEnumerable(string[] strList)
    {
        IEnumerator e = strList.GetEnumerator();

        while (e.MoveNext())
        {
            Debug.Log(e.Current);
        }
        // Debug.Log(e.Current); // 이미 열거가 완료되어 에러.

        e.Reset(); // 열거 초기화.
        e.MoveNext();
        Debug.Log(e.Current + "열거 초기화 후 다시 출력.");
    }

	// Update is called once per frame
	void Update () {

	}
}

[C#] Action 과 Delegate, 람다식, Action, Func, Event

  •  Delegate ( 위임자 )
    • 일종의 함수 포인터
    • 내부적으로 Count 만큼 List를 순회하는 연결리스트 구조를 생성
  • Action의 정의
    • Action은 반환값과 인자값이 없는 함수 포인터 ( 델리게이트 )
    • 반환 형식이 없음
    • 어떤 결과를 반환하는것을 목적으로 하지 않으며, 일련의 작업 수행을 목적
/* Action 델리게이트 예제 */
    void Start()
    {
        Action act1 = () => Debug.Log("Action()");
        act1();

        int re = 0;
        Action act2 = (x) => re = x * x; // 람다식 밖에서 선언한 re에 결과값 저장.
        act2(3);

        Debug.Log("re : " + re);

        Action act3 = (x, y) =>
        {
            double pi = x / y;
            Debug.Log("Action(" + x + ", " + y + ") : " + pi);
        };

        act3(22.0, 7.0);
    }
using System.Runtime.CompilerServices;

namespace System
{
      public delegate void Action();
}
  • Func ( 델리게이트 )
    • 일종의 함수 포인터
    • 내부적으로 Count 만큼 List를 순회하는 연결리스트 구조를 생성
    • 익명메소드, 무명함수를 만들기위해서는 항상 델리게이트를 선언 해야 하지만 Func를 사용하면 끝

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

public class Tester : MonoBehaviour {

    public Action myAction;

    public void SetAction(Action func)
    {
        myAction += func;
    }

    public static void Func1() { Debug.Log("Func1 실행"); }
    public static void Func2() { Debug.Log("Func2 실행"); }

    // SetAction으로 함수를 등록한후,
    void Start()
    {
        Tester ActionTest = new Tester();
        ActionTest.SetAction(Func1);
        ActionTest.SetAction(Func2);
        ActionTest.myAction();
    }
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text;

public class Tester : MonoBehaviour {

    public delegate int Print (string msg );

    public static int SpeakA(string msg)
    {
        Debug.Log("A : " + msg);
        return 0;
    }
    public static int SpeakB(string msg)
    {
        Debug.Log("B : " + msg);
        return 1;
    }

    void Start()
    {
        Print A = new Print(SpeakA);
        //Print B = new Print(SpeakB);

        A("Hello");
        //B("Hello");
    }
}
void Start()
    {
        Func func1 = () => 10;             // 바로 10을 리턴.
        Func func2 = (x) => x * 2;         // 넣어준 인수의 2를 곱한값 리턴.
        Action act = (x) =>                // 리턴없는 Action 함수.
        {
            Debug.Log(x);                  // Debug.Log로 직접 출력.
        };

        Debug.Log(func1());
        Debug.Log(func2(3));
        act(10);
    }
/* 람다식 (Lambda expression) 선언 예제 */
    delegate int Calculate(int a, int b);
    delegate void DoSomething();

    void Start()
    {
        Calculate cal = (a, b) => a + b;
        Debug.Log(cal(1, 3));

        DoSomething Doit = () =>
        {
            Debug.Log("두잇.");
        };

        Doit();
    }

/* 익명메소드를 이용한 델리게이트 사용 */
    delegate string Fire(string location);

    void Start()
    {
        Fire fire;
        fire = delegate(string location)
        {
            return location;
        };

        Debug.Log(fire("here"));
    }

/* 델리게이트 체인 */
    delegate void MyFire(string location);

    public static void call119(string location)
    {
        Debug.Log("불난곳: " + location);
    }

    public static void shout(string location)
    {
        Debug.Log("소리친곳: " + location);
    }

    public static void escape(string location)
    {
        Debug.Log("도망가는곳: " + location);
    }

    void Start()
    {
        MyFire fire = new MyFire(call119);

        fire += new MyFire(call119);    // 첫번째 델리게이트 체인 등록.
        fire += new MyFire(shout);      // 두번째 델리게이트 체인 등록.
        fire += new MyFire(escape);     // 세번째 델리게이트 체인 등록.

        fire("우리집에서");              // 함수포인터(델리게이트)에 등록이된 함수들을 실행.
    }
/* 문형식의 람다식 */

    string[] args = { "hi", "hello", "good" };

    delegate string Co(string[] args);

    void Start()
    {
        Co c = (arr) =>
        {
            string re = "";
            foreach (string s in arr)
            {
                re += s;
                Debug.Log("Add string is " + s);
            }
            return re;
        };
        Debug.Log(c(args));
    }
  • Event
    • 이벤트는 델리게이트에 event 한정자를 수식해서 선언한것에 불과하다
    • 이벤트와 델리게이트의 차이점은 이벤트는 public으로 선언되어 있어도 외부에서 사용할 수 가 없다.
    • 델리게이트는 public, internal로 수식되어 있으면 클래스 외부에서도 얼마든지 호출이 가능하다
    /* 이벤트, 델리게이트 예제 01 */
    delegate void EventCaller(string m);

    class CallEvent
    {
        public event EventCaller ec;
    }

    void Start()
    {
        CallEvent callEvent = new CallEvent();
        //callEvent.ec("test"); // 에러, 이벤트는 객체 외부에서 직접 호출 할 수 없다.
    }
/* 이벤트, 델리게이트 예제 02 */
    delegate void EventHandler(string m);

    class Notification
    {
        public event EventHandler eventHandler;

        public void EvenOdd(int number)
        {
            int temp = number % 10;

            if (temp != 0 && temp % 3 == 0)
            {
                eventHandler(string.Format("{0} : Even", number));
            }
        }
    }

    public static void MEventHandler(string m)
    {
        Debug.Log(m);
    }

    public static void SEventHandler(string m)
    {
        Debug.Log(m + "SEvebtHandler");
    }

    public static void XEventHandler(string m)
    {
        Debug.Log(m + "XEvebtHandler");
    }

    void Start()
    {
        Notification noti = new Notification();
        noti.eventHandler += new EventHandler(MEventHandler);
        noti.eventHandler += new EventHandler(SEventHandler);
        noti.eventHandler += new EventHandler(XEventHandler);

        for (int i = 1; i < 30; i++)
        {
            noti.EvenOdd(i);
        }
    }

[C#] Delegate And Func

Delegate and Func

  • .NET Framework에는 총 17 가지의 Func 델리게이트가 준비 되어있다.
  • 매개 변수가 없는 메소드부터 매개 변수가 16개인 메소드까지 총 17개의 메소드를 참조 가능.
  • 무명 메소드 뿐만 아니라 일반 메소드도 참조 가능.
  • Func 델리게이트로 메소드를 참조하면 전처럼 델리게이트 타입을 선언하는 과정이 불필요 해지므로 아주 간결하게 코드를 작성할 수 있다.

/**
 * @file    ExamFuncDelegate01.cs
 * @brief   델리게이트와 Func.
 * @details 델리게이트와 Func 사용 예제.
 * @version  0.0.1
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StudyCSharp_Bong9
{
    namespace ExamFuncDelegate01
    {
        /**
         * @brief    델리게이트와 Func 예제 클래스.
         * @details  Func와 Action은 미리 선언된 델리게이트 변수로써 별도의 선언없이 사용이 가능. Func는 반환값이 있는 메소드를 참조하는 델리게이트 변수, Action은 반환값이 없는 메소드를 참조하는 델리게이트 변수.
         * @author   김봉재.
         * @date     2014-08-07
         */
        class ExamFuncDelegate
        {
            static float temp (int a, int b, int c)
            {
                return (a + b + c) * 0.1f;
            }

            static void Main(string[] args)
            {
                Func float             func0 = () =&gt; 0.1f;
                Func int, float        func1 = (a) =&gt; a * 0.1f;
                Func int, int, float&gt;   func2 = (a, b) =&gt; (a+b) * 0.1f;

                Func<span id="mce_SELREST_start" style="overflow:hidden;line-height:0;">&#65279;</span>&lt;int, int, int, float func3;
                func3 = new Func int, int, int, float(temp);

                Console.WriteLine(&quot;func0 반환값: {0}&quot;, func0());
                Console.WriteLine(&quot;func1 반환값: {0}&quot;, func1(10));
                Console.WriteLine(&quot;func2 반환값: {0}&quot;, func2(10,10));
                Console.WriteLine(&quot;func3 반환값: {0}&quot;, func3(10,10,10));
            }
        }
    }
}