카드 뉴스 쉽게 보는 법: 첫 이미지 클릭하고 방향키로 스크롤해서 넘기기

 

자바스크립트도 갓 입문한 입장이지만 동시에 배우기 시작한 타입스크립트 입문편!

지금 시작합니다!


타입스크립트란 예전부터 지금까지 받아들여지는 정의가 다양하게 변화해왔지만,

가장 입문자가 이해하기 쉽게 정의한 것은 다음과 같다.

'타입스크립트는 자바스크립트에 타입을 추가한 것이다.'

타입스크립트 = 자바스크립트 + 타입

 

타입스크립트는 자바스크립트의 상위 개념(슈퍼셋; Super Set)이다.

자바스크립트가 인터프리터형 언어라면 타입스크립트는 컴파일형 언어로

컴파일 이후 자동으로 자바스크립트 코드로 변환된다. 

 

그렇다면 굳이 자바스크립트 대신 타입스크립트를 사용해야 하는 이유가 있는가?

이는 기존의 자바스크립트가 가진 특징인 높은 자유도와 유연성을 보완하기 위함이라 할 수 있다.

자바스크립트는 동적 타입 언어로 비교적 타입의 변환이 유연하게 이뤄진다.

예를 들어 정수형 1과 문자형 '3'은 원래 연산이 이뤄지면 안 되지만

자바스크립트에서는 형변환이 임의로 유연하게 이뤄지며 연산을 가능하게 한다. 

이는 사용자 입장에서 간편하게 느껴질 수 있지만,

큰 규모의 프로젝트를 진행할 때는 보다 엄격한 형식이 필요할 것이다.

반면 타입스크립트는 정적 타입 언어로 이러한 높은 자유도와 유연성을 가진

자바스크립트가 갖추지 못한 안정성을 제공한다.

 

따라서 자바스크립트가 보다 높은 자유도와 유연성을 가지고 있다면,

타입스크립트는 높은 안정성과 일관성을 추구한다.

 

이는 복잡하고 큰 프로젝트를 진행함에 있어 안정성을 제공한다는 측면에서

자바스크립트보다 더욱 적합하다고 할 수 있다. 

이 외에도 자바스크립트보다 에러에 대하여 더욱 자세하게 설명해주는 것과 같은 디버깅에 용이한

특징을 많이 가지고 있는 것이 타입스크립트이다.  

 

나 나름 해석을 해보자면, 자바스크립트는 자유로운 글쓰기에 가깝다.

편하게 매일 매일 작성하는 일기는 형식을 갖추지 않는데,

자유로운 형식이 글쓰기를 편하고 효율적으로 만들 것이다. 

한편, 타입스크립트를 사용하는 것은 각 잡고 책 만들기라 생각하면 편할 것 같다.

목차를 구성하고, 각 챕터 별 어떤 내용이 들어갈지 구상을 하면서, 작성과 퇴고를 거친다.

 

그럼 간단한 타입스크립트 사용법을 알아보자.

어려울 것 없다.

변수 선언할 때, 콜론과 함께 타입을 선언하면 된다.

 

클래스 선언 시에도 마찬가지이다. 생성자 괄호 안에 각 변수의 타입을 선언하면 된다.

더 간단하게 표기하는 방법이 존재하는데 이는 다음에 알아보도록 하겠다. 

제로

📄 문제

문제

나코더 기장 재민이는 동아리 회식을 준비하기 위해서 장부를 관리하는 중이다.
재현이는 재민이를 도와서 돈을 관리하는 중인데,
애석하게도 항상 정신없는 재현이는 돈을 실수로 잘못 부르는 사고를 치기 일쑤였다.
재현이는 잘못된 수를 부를 때마다 0을 외쳐서, 가장 최근에 재민이가 쓴 수를 지우게 시킨다.
재민이는 이렇게 모든 수를 받아 적은 후 그 수의 합을 알고 싶어 한다. 재민이를 도와주자!

입력

첫 번째 줄에 정수 K가 주어진다. (1 ≤ K ≤ 100,000)
이후 K개의 줄에 정수가 1개씩 주어진다.
정수는 0에서 1,000,000 사이의 값을 가지며,
정수가 "0" 일 경우에는 가장 최근에 쓴 수를 지우고, 아닐 경우 해당 수를 쓴다.
정수가 "0"일 경우에 지울 수 있는 수가 있음을 보장할 수 있다.

출력

재민이가 최종적으로 적어 낸 수의 합을 출력한다.
최종적으로 적어낸 수의 합은 231-1보다 작거나 같은 정수이다.

🧞 풀이

더보기

풀이

import sys

n = int(sys.stdin.readline())               # 정수 n 입력 및 할당

stack = []                                  # 빈 스택 할당

for _ in range(n):                          # n번 반복
    integer = int(sys.stdin.readline())     # 정수 입력 및 할당

    if integer == 0:                        # 정수가 0이면
        stack.pop()                         # 스택에서 가장 위에 있는 수 pop()
    else:                                   # 정수가 0이 아니면
        stack.append(integer)               # 스택에 해당 정수 추가

print(sum(stack))                           # 스택 안에 있는 정수의 합 출력

스택

📄 문제

문제

정수를 저장하는 스택을 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.

명령은 총 다섯 가지이다.

  • push X: 정수 X를 스택에 넣는 연산이다.
  • pop: 스택에서 가장 위에 있는 정수를 빼고, 그 수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.
  • size: 스택에 들어있는 정수의 개수를 출력한다.
  • empty: 스택이 비어있으면 1, 아니면 0을 출력한다.
  • top: 스택의 가장 위에 있는 정수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.

입력

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 
둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다.
주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다.
문제에 나와있지 않은 명령이 주어지는 경우는 없다.

출력

출력해야하는 명령이 주어질 때마다, 한 줄에 하나씩 출력한다.

🧞 풀이

더보기

풀이

'''
input()을 사용하면 시간 초과가 난다.
따라서 sys를 불러와, stdin.readline()을 활용한다.
'''

import sys

n = int(sys.stdin.readline())                   # 정수 n 입력 및 할당
stack = []                                      # 빈 스택 할당

for _ in range(n):                              # n번 반복
    w = list(sys.stdin.readline().split())      # w로 명령 불러오기
    command = w[0]                              # 명령어 할당
    if len(w) == 2:                             # 명령어 뒤에 정수가 있을 경우
        num = int(w[1])                         # 정수는 num에 할당

    if command == 'push':                       # 명령어가 push일 경우,
        stack.append(num)                       # stack에 해당 num 추가

    elif command == 'pop':                      # 명령어가 pop일 경우,
        if len(stack) != 0:
            print(stack.pop())                  # stack에 맨 뒤의 정수 pop() 하고 출력
        else:
            print(-1)

    elif command == 'size':                     # 명령어가 size일 경우,
        print(len(stack))                       # stack의 길이 출력

    elif command == 'empty':                    # 명령어가 empty일 경우,
        if len(stack) == 0:
            print(1)                            # 스택이 비어 있다면 1, 아니면 0 출력
        else:
            print(0)

    elif command == 'top':                      # 명령어가 top일 경우,
        if len(stack) != 0:
            print(stack[-1])                    # 스택에서 가장 높이 있는 정수 출력
        else:
            print(-1)

재귀함수 (Recursive Function)


통곡의 벽

 

어느 한 컴퓨터공학과 학생이 유명한 교수님을 찾아가 물었다.
"재귀함수가 뭔가요?"
"잘 들어보게. 옛날옛날 한 산 꼭대기에 이세상 모든 지식을 통달한 선인이 있었어.
마을 사람들은 모두 그 선인에게 수많은 질문을 했고, 모두 지혜롭게 대답해 주었지.
그의 답은 대부분 옳았다고 하네. 그런데 어느 날, 그 선인에게 한 선비가 찾아와서 물었어."
____"재귀함수가 뭔가요?"
____"잘 들어보게. 옛날옛날 한 산 꼭대기에 이세상 모든 지식을 통달한 선인이 있었어.
____마을 사람들은 모두 그 선인에게 수많은 질문을 했고, 모두 지혜롭게 대답해 주었지.
____그의 답은 대부분 옳았다고 하네. 그런데 어느 날, 그 선인에게 한 선비가 찾아와서 물었어."
________"재귀함수가 뭔가요?"
________"재귀함수는 자기 자신을 호출하는 함수라네"
________라고 답변하였지.
____라고 답변하였지.
라고 답변하였지.

재귀(Recursion):

  • 함수 스스로 자신을 참조해 호출하면서 동일한 코드가 계속적으로 수행되는 함수 호출 방법
  • 재귀 함수는 특정 조건이 됐을 때, 자신을 그만 호출되도록 제한하는 exit code가 필요
  • 재귀함수: 함수 내부에서 한 번 이상 자신의 함수를 호출
  • 재귀알고리즘: 알고리즘 내부에서 한 번 이상 자신의 알고리즘을 호출

재귀함수를 쓰는 이유:

  • 변수를 여럿 만들 필요가 없다.
  • 코드가 간결해지고 직관적이기 때문에 가독성이 높아진다.
  • DFS(깊이 우선 탐색)을 함에 있어 자주 활용된다. 

예시 1)

// 3 + 2 + 1 + 0
function recursive(num) {
	if (num == 0) return;
	recursive(num - 1);
}

// 3 + (2 + (1 + 0)) -> 6
console.log(recursive(3));

예시 2)

function factorial(num) {
	if (num == 0) return 0;
    return num * factorial(num - 1);
}

// 3 * 2 * 1 * 0 -> 6
console.log(factorial(3));

랜선 자르기(결정알고리즘)

📄 문제

엘리트 학원은 자체적으로 K개의 랜선을 가지고 있다.
그러나 K개의 랜선은 길이가 제각각이다.
선생님은 랜선을 모두 N개의 같은 길이의 랜선으로 만들고 싶었기 때문에K개의 랜선을 잘라서 만들어야 한다.
예를 들어 300cm 짜리 랜선에서 140cm 짜리 랜선을 두 개 잘라내면 20cm 은 버려야 한다.
(이미 자른 랜선은 붙일 수 없다.)
편의를 위해 랜선을 자를때 손실되는 길이는 없다고 가정하며,
기존의 K개의 랜선으로 N개의 랜선을 만들 수 없는 경우는 없다고 가정하자.
그리고 자를 때는 항상 센티미터 단위로 정수 길이만큼 자른다고 가정하자.
N개보다 많이 만드는 것도 N개를 만드는 것에 포함된다.
이때 만들 수 있는 최대 랜선의 길이를 구하는 프로그램을 작성하시오.

▣ 입력설명
첫째 줄에는 엘리트학원이 이미 가지고 있는 랜선의 개수 K,
그리고 필요한 랜선의 개수 N이 입력된다.
K는 1이상 10,000이하의 정수이고, N은 1이상 1,000,000이하의 정수이다.
그리고 항상 K ≦ N 이다.
그 후 K줄에 걸쳐 이미 가지고 있는 각 랜선의 길이가 센티미터 단위의 2^31 - 1이하의 자연수로 주어진다.

▣ 출력설명
첫째 줄에 N개를 만들 수 있는 랜선의 최대 길이를 센티미터 단위의 정수로 출력한다.

▣ 입력예제
4 11
802
743
457
539

▣ 출력예제
200

🧞 풀이

더보기

풀이 (실패)

# 실패
k, n = map(int, input().split())
k_list = []
c_list = []
c = 0
a_list = []

for i in range(k):
    a = int(input())
    k_list.append(a)

k_list = sorted(k_list, reverse = True)

for i in range(k):
    c += 1
    a = n // k
    if c <= n % k:
        a += 1
    c_list.append(a)

# print(k, n, k_list, c_list)

for j in range(k):
    a_list.append(k_list[j] // c_list[j])

# print(a_list)
print(min(a_list))

 

풀이 (성공)

k, n = map(int, input().split())
k_list = []
answer = 0

for i in range(k):
    a = int(input())
    k_list.append(a)

lt = 1
rt = max(k_list)

while lt <= rt:
    mid = (lt + rt) // 2
    a = 0
    for i in k_list:
        a += i // mid
    if a >= n:
        if mid >= answer:
            answer = mid
        lt = mid + 1
    else:
        rt = mid - 1

print(answer)

 

다른 사람 풀이

def count(len):
    cnt = 0
    for x in line:
        cnt += (x//len)
    return cnt


k, n = map(int, input().split())
line = []
res = 0 # 최대값 찾기
largest = 0
for i in range(k):
    tmp = int(input())
    line.append(tmp)
    largest = max(largest, tmp)

lt = 1
rt = largest

while lt <= rt:
    mid = (lt + rt) // 2
    if count(mid) >= n:
        res=mid
        lt = mid + 1
    else:
        rt = mid - 1

print(res)

이분 검색

📄 문제

임의의 N개의 숫자가 입력으로 주어집니다.
N개의 수를 오름차순으로 정렬한 다음
N개의 수 중 한 개의 수인 M이 주어지면
이분검색으로 M이 정렬된 상태에서 몇 번째에 있는지 구하는 프로그램을 작성하세요.
단 중복값은 존재하지 않습니다.

▣ 입력설명
첫 줄에 한 줄에 자연수 N(3<=N<=1,000,000)과 M이 주어집니다.
두 번째 줄에 N개의 수가 공백을 사이에 두고 주어집니다.

▣ 출력설명
첫 줄에 정렬 후 M의 값의 위치 번호를 출력한다.

▣ 입력예제
8 32
23 87 65 12 57 32 99 81

▣ 출력예제
3

🧞 풀이

더보기

풀이

# 입력: 첫 줄에 자연수 n, m, 두 번째 줄에 n개의 수가 공백을 사이에 두고 주어짐
# 출력: 첫 줄에 정렬 후 m의 값의 위치 번호를 출력

n, m = map(int, input().split())                                    # n, m 입력 및 할당
n_list = list(map(int, input().split()))                            # 숫자 리스트 입력 및 할당

n_list = sorted(n_list)                                             # n_list 오름차순 정렬

c = 0                                                               # 순서 담을 c 할당

for i in n_list:                                                    # n_list 요소 반복
    c += 1                                                          # c 1씩 증가
    if i == m:                                                      # 만약 i가 m이면
        print(c)                                                    # c 출력
        break                                                       # 반복문 종료

 

다른 사람 풀이

# 이분검색

'''
lt, rt
0 1 2 3 4 5 6 7
12 23 32 57 65 81 87 99

mid = (lt + rt) // 2

3 = mid

a[mid] == m

rt = mid - 1
lt = mid + 1

절반씩 좁혀 나감

1 = mid

lt, rt = 2

만약 1024개의 데이터가 있다면
512개로 줄어듦
256으로 절반으로 줄어듦
128씩 작아지면

이분검색 log n번만에 된다.
'''

n, m = map(int, input().split())
a = list(map(int, input().split()))
a.sort()
lt = 0
rt = n-1
while lt <= rt:
    mid = (lt + rt) // 2
    if a[mid] == m:
        print(mid + 1)
        break
    elif a[mid]>m:
        rt = mid - 1
    else:
        lt = mid + 1

격자판 회문수

📄 문제

1부터 9까지의 자연수로 채워진 7*7 격자판이 주어지면 격자판 위에서 가로방향 또는 세로방향으로 길이 5자리 회문수가 몇 개 있는지 구하는 프로그램을 작성하세요. 회문수란 121과 같이 앞에서부터 읽으나 뒤에서부터 읽으나 같은 수를 말합니다.


빨간색처럼 구부러진 경우(87178)는 회문수로 간주하지 않습니다.

▣ 입력설명
1부터 9까지의 자연수로 채워진 7*7격자판이 주어집니다.

▣ 출력설명
5자리 회문수의 개수를 출력합니다.

▣ 입력예제
2 4 1 5 3 2 6
3 5 1 8 7 1 7
8 3 2 7 1 3 8
6 1 2 3 2 1 1
1 3 1 3 5 3 2
1 1 2 5 6 5 2
1 2 2 2 2 1 5

▣ 출력예제
3

🧞 풀이

더보기

풀이

'''
가로로 검사해야 하는 수: 3 * 7 = 21
세로로 검사해야 하는 수: 3 * 7 = 21
42개 검사할 수 있는 함수를 만들면 됨

[0:5]
'''

cnt = 0                                                         # 갯수 세기 위한 cnt 할당

a = [list(map(int, input().split())) for _ in range(7)]         # 배열 값들 입력하여 할당

tmp = []                                                        # 행 슬라이싱해서 담을 빈 리스트 할당
for i in range(7):                                              # 7번 반복
    for j in range(3):                                          # 3번 반복 (이중반복)
        tmp = a[i][0+j:5+j]                                     # 5개의 요소만 슬라이싱

        if tmp[0] == tmp[4] and tmp[1] == tmp[3]:               # 회문일 때,
            cnt += 1                                            # cnt 1 증가

        if a[0+j][i] == a[4+j][i] and a[1+j][i] == a[3+j][i]:   # 세로로 회문일 때,
            cnt += 1                                            # cnt 1 증가

print(cnt)                                                      # cnt 출력

 

다른 사람 풀이

board = [list(map(int, input().split())) for _ in range(7)]

cnt = 0

for i in range(3):
    for j in range(7):
        tmp = board[j][i:i+5]
        if tmp == tmp[::-1]:
            cnt += 1
        for k in range(2):
            if board[i+k][j] != board[i+5-k-1][j]:
                break
        else:
            cnt += 1
print(cnt)

+ Recent posts