https://www.acmicpc.net/problem/9093

 

9093번: 단어 뒤집기

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있으며, 문장이 하나 주어진다. 단어의 길이는 최대 20, 문장의 길이는 최대 1000이다. 단어와 단어 사이에는

www.acmicpc.net

 

풀이: 문장을 띄어쓰기를 기준으로 자르고, 단어를 뒤집고 join으로 합칩니다.

 

T = int(input())


for _ in range(T):

    l = list(input().split())
    answer = [i[::-1] for i in l]
    print(' '.join(answer))

현재, 자바스크립트에는 함수를 선하는 방법이 2가지 있습니다.

  1. Arrow function () => {}
  2. function

오늘은 이 두 가지의 다른 부분에 대해서 알아보고자 합니다.

 

 

1. this

일반 function에서는 this가 함수가 불려지는 방법에 따라 바뀝니다.

  • simple invocation (단순 호출): this는 전역 오브젝트와 같거나, 1strict1 모드를 사용한다면 정의되지 않을 수 있습니다.
  • method invocation(메서드 호출): method this를 소유한 오브젝트와 같습니다.
  • indirect invocation(간접 호출): this는 첫 번째 인자와 같습니다.
  • constructor invocation(생성자 호출): `this1는 새롭게 생성된 instance와 같습니다.
// Simple Invocation
function simpleInvocation() {
  console.log(this);
}
simpleInvocatoin(); // logs global object
--------------------------------------------------------------------
// Method Invocation
const methodInvocation= {
  method() {
    console.log(this);
  }
};
methodInvocation.method(); // logs methodInvocation object
--------------------------------------------------------------------
// Indirect Invocation
const context = { value1: 'A', value2: 'B' };
function indirectInvocation() {
  console.log(this);
}
indirectInvocation.call(context);  // logs { value1: 'A' }
indirectInvocation.apply(context); // logs { value1: 'A' }
--------------------------------------------------------------------
// Constructor Invocation
function constructorInvocation() {
  console.log(this);
}

new constructorInvocation(); // logs an instance of constructorInvocation

 

 

Arrow function에서는, this의 행동이 완전히 바뀝니다.

Arrow functionthis 자체가 없으며, 함수 내에서 this를 재정의하지 않습니다.

 

Arrow function의 이런 점은, 메소드 안에 callback을 사용할 때 매우 유용합니다.

const selft = this 또는 Arrow function과 함께 callback.bind(this)와 같이 사용하지 않아도 됩니다.

그리고, callback안에 this로 사용하여 발생하는 실수를 방지할 수 있습니다.

 

 

 

2. Argument object

일반 javascript 함수에서 arguments 키워드는 함수가 호출될 때 전달된 인수를 access하는 데 사용합니다.

예를 들어, 3개의 인자로 함수를 부른다면 다음과 같이할 수 있습니다.

 

하지만, Arrow function은 그 자체의 인자를 가질 수 없고, 외부 함수를 통해 인자를 사용할 수 있습니다.

 

하지만, Arrow function에서 인수를 직접 access하려면, ...args 기능을 사용할 수 있습니다.

 

 

 

3. Constructors(생성자) / new keyword

new 키워드로 함수를 호출하기만 하면, 일반 function으로 쉽게 객체를 생성할 수 있습니다.

function Article(topic) {
  this.topic= topic;
}

const article= new Article('JavaScript');

 

 

 

 

4. Implicit return (암시적 반환)

 

일반 function에서는, return을 사용하여 함수로부터 반환값을 받을 수 있습니다.

return 을 주지 않는다면, function은 암시적으로 undefined를 반환할 것입니다.

function exampleFunction() {
 return 10;
}
exampleFunction(); // output -> 10
--------------------------------------------------------------------
function exampleFunction() {
 var number  = 10;
}
exampleFunction(); // output -> undefined
--------------------------------------------------------------------
function exampleFunction() {
 var number  = 10;
  return;
}
exampleFunction(); // output -> undefined

Arrow function은 같은 방식으로 반환 값을 돌려주지만, 장점이 하나 있습니다.

만얀 Arrow function이 하나의 표현식을 가지고 있다면, curly braces {} 를 생랼할 수 있습니다ㅏ. 그리고 암시적으로 해당 표현식이 반환됩니다.

+ 추가

Promise, Dynamic context 가 있는 callback 함수, Object method를 다루는 상황에서는 에서는 Arrow function을 사용하는 것을 피해야합니다.

 

 

 

 

이 글은 다음의 블로그를 해석했습니다.

https://blog.bitsrc.io/arrow-functions-vs-regular-functions-in-javascript-458ccd863bc1

 

Arrow Functions vs. Regular Functions in JavaScript

Learn when and when not to use the arrow function

blog.bitsrc.io

 

https://www.acmicpc.net/problem/1100

 

1100번: 하얀 칸

체스판은 8×8크기이고, 검정 칸과 하얀 칸이 번갈아가면서 색칠되어 있다. 가장 왼쪽 위칸 (0,0)은 하얀색이다. 체스판의 상태가 주어졌을 때, 하얀 칸 위에 말이 몇 개 있는지 출력하는 프로그램

www.acmicpc.net

 

문제 : 체스판의 상태가 주어지면, 하얀 칸 위에 말이 있는 개수를 세는 것입니다.

풀이 : 체스판의 크기는 8x8로 고정되어 있고, 체스판의 검정색과 하얀색이 번갈아 가면서 칠해져 있습니다.

 

체스판

 

리스트의 index시작은 0부터 시작하므로

1차원 list index가 0,2,4,6,8인 배열은, 2차원 index가 짝수인 것이 하얀색 칸이고,

1차원 list index가 1,3,5,7인 배열은, 2차원 index가 홀수인 것이 하얀색 칸입니다.

 

그래서 반복문을 통해 하얀 칸 위에 말이 몇 개 있는지 세어 줍니다.

 

chess_board = []
count = 0

for _ in range(8):
    chess_board.append(list(input()))


for i in range(0,8):
    if(i%2 == 0):
        for j in range(0,8,2):
            if(chess_board[i][j] == 'F'):
                count += 1
    else:
        for j in range(1,8,2):
            if(chess_board[i][j] == 'F'):
                count += 1
print(count)

https://www.acmicpc.net/problem/2004

 

2004번: 조합 0의 개수

첫째 줄에 정수 $n$, $m$ ($0 \le m \le n \le 2,000,000,000$, $n \ne 0$)이 들어온다.

www.acmicpc.net

 

조합의 수에서 뒷자리 0의 개수를 구하는 문제입니다.

뒤에 0의 개수는, 소인수 분해했을 때 2와 5의 최소 개수입니다.

 

n, m =map(int,input().split())

def count_num(n,k):
    count=0
    while n:
        n //=k
        count += n
    return count

five_num =count_num(n,5) - count_num(m,5) - count_num(n-m,5)
two_num =count_num(n,2) - count_num(m,2) - count_num(n-m,2)
print(min(five_num, two_num))

https://www.acmicpc.net/problem/2522

 

2522번: 별 찍기 - 12

첫째 줄부터 2×N-1번째 줄까지 차례대로 별을 출력한다.

www.acmicpc.net

 

문제 : 예제를 보고 규칙을 유추한 뒤에 별을 찍어보세요!

 

예제에는 3이 나와있고,

예제 출력은 다음과 같습니다.

  *
 **
***
 **
  *

 

 

절반을 나눠서 그 위에는 반복할 수록 별이 늘어나고, 그 아래에는 반복할 수록 별이 줄어는 것을 볼 수 있습니다.

N = int(input())
for i in range(1, N+1):
    print(' '*(N-i) + '*'*i)
for i in range(1, N):
    print(' '*(i) + '*'*(N-i))

https://www.acmicpc.net/problem/1009

 

1009번: 분산처리

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트 케이스에 대해 정수 a와 b가 주어진다. (1 ≤ a < 100, 1 ≤ b < 1,000,000)

www.acmicpc.net

a, b가 주어졌을 때, 총 데이터의 개수는 a를 b번만큼 곱한 값입니다.

그러므로 일의 자리수는 반복되는 규칙이 생기게 됩니다.

3을 예로 들면,

3^1 = 3 => 3

3^2 = 9 => 9

3^3 = 27 => 7

3^4 = 81 => 1

3^5 = 243 => 3

와 같이 순환이 생기게 됩니다.

그래서, b만큼의 반복문으로 숫자가 언제 반복되는지 확인하고, 순환되는 리스트를 만듭니다.

그리고 리스트의 첫 index는 시작이 0이므로, 구한 값에서 1을 빼주어 처리될 컴퓨터의 번호를 구합니다.

t = int(input())

for _ in range(t):
    a,b = map(int,input().split())

    #숫자가 언제 반복되는지 확인합니다.
    l = [a%10]
    x = a
    for _ in range(b):
        x = (x*a) % 10
        if (l[0] == x):
            break
        else:
            l.append(x)
    y = b%len(l) -1 
    if(l[y]==0):
        print(10)

    else:
        print(l[y])

https://www.acmicpc.net/problem/4195

 

4195번: 친구 네트워크

첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스의 첫째 줄에는 친구 관계의 수 F가 주어지며, 이 값은 100,000을 넘지 않는다. 다음 F개의 줄에는 친구 관계가 생긴 순서대로 주어진

www.acmicpc.net

친구 관계수 F가 주어졌을 때, 친구 관계가 생길 때마다 두 사람의 친구 네트워크에 몇 명이 있는지 구하는 프로그램을 작성하는 문제입니다.

친구 네트워크를 구축하기 위해서, Union-find 알고리즘을 사용했습니다.

일단 Union-find를 알고리즘을 설명하기 전에, Disjoint Set이라는 자료구조를 함께 이야기해야 할 것 같습니다.


Disjoint Set 이란?
: 서로소 집합 자료구조로, 서로 중복되지 않는 부분 집합들로 나눠진 원소들에 대한 정보를 저장하고 조작하는 자료구조입니다.

 

Union-find란?

: Disjoint Set을 표현할 때 사용하는 알고리즘으로, 효율적인 트리 구조로 이를 구현합니다.

 

 

Union-find 알고리즘을 위해서는 크게 2가지 연산이 필요합니다.

  1. union(x, y)
    : x 가 속한 집합과, y 가 속한 집합을 합칩니다.
  2. find(x)
    : x가 속한 집합의 Root node 값을 찾고, x가 어떤 집합에 속한지 찾습니다.

위키백과 - 유니온 파인드 연산 데모

https://ko.wikipedia.org/wiki/%EC%84%9C%EB%A1%9C%EC%86%8C_%EC%A7%91%ED%95%A9_%EC%9E%90%EB%A3%8C_%EA%B5%AC%EC%A1%B0

 

서로소 집합 자료 구조 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 메이크셋은 8개의 개체를 생성한다. 유니온 연산을 여러 번 수행하면 여러 집합들이 합쳐진다. 컴퓨터 과학 분야에서 서로소 집합(disjoint-set) 자료 구조, 또는

ko.wikipedia.org

위키 백과에서 예시가 잘 나와있어서 함께 보면 좋을 것 같습니다.

 


 

import sys

input = sys.stdin.readline

#Root node 찾기
def find(x):
    if x== parent[x]:
        return x
    else:
        root_x = find(parent[x])
        parent[x] = root_x
        return parent[x]

def union(x,y):
    root_x = find(x)
    root_y = find(y)

    if root_x != root_y:
        parent[root_y] = root_x
        number[root_x] += number[root_y]


T=int(input())

for _ in range(T):
    parent = dict()
    number = dict()

    r = int(input())

    for _ in range(r):
        x,y = input().split()
        if x not in parent:
            parent[x]=x
            number[x]=1
        if y not in parent:
            parent[y]=y
            number[y]=1
        union(x,y)
        print(number[find(x)])

이 글은 아래의 링크의 글을 해석한 글입니다.

setInterval() 함수는 주기적으로 인자를 실행하는 함수입니다.

clearInterval() 함수 현재 진행되고 있는 함수의 진행을 멈추는 것에 쓰입니다.

 

 

React의 useEffect() 내부에서 clearInterval()을 사용하는 방법과, 중요한 이유

- setInterval을 지우지 않으면 어떻게 될까요?

const Blinker = ({ text }) => {
  const [visible, setVisible] = useState(true);
  useEffect(() => {
    setInterval(() => {
      console.log(`Current blinking text: ${text}`);
      setVisible((visible) => !visible);
    }, 1000);
  }, [text]);
  return visible ? <h1>{text}</h1> : null;
};

처음 렌더링 될때는, useEffect()이 불리므로 Current blinking text가 1초마다 실행 될 것입니다.

Blinkertext prop 변경하면 어떻게 될까요?

1. useEffecttext에 영향을 받으므로, 다시 렌더링되고, 기능을 다시 실행합니다.

2. 이제는 Current blinking text : a 가 1초간격마다 로그에 찍힐 것입니다.

이 시나리오에서 콘솔 로그는 다음과 같습니다.

처음 렌더링 될 때 setIntervaltext가 변한 후의 setInterval이 함께 존재해서 그렇습니다.

이렇게 되는 것은 원하지 않으므로, 새 interval를 만들기 전에 이전 interval을 삭제해야합니다.

 

 

해결책

const Blinker = ({ text }) => {
  const [visible, setVisible] = useState(true);
  useEffect(() => {
    const intervalId = setInterval(() => {
      console.log(`Current blinking text: ${text}`);
      setVisible((visible) => !visible);
    }, 1000);
    // 정리하는 곳
    return () => {
      clearInterval(intervalId);
    };
  }, [text]);
  return visible ? <h1>{text}</h1> : null;
};

이렇게 되면

1. Blinker prop이 변경되었기 때문에 이전과 동일하게 다시 렌더링 됩니다.

2. React의 useEffect의 종속성을 확인하고, 변경되었기 때문에 기능을 다시 실행합니다.

3. 하지만, 이전과 다르게 먼저 반환된 함수를 실행하여, 이전 효과(interval)를 정리합니다.

4. 이를 통해 Current blinking text : a 만 콘솔 로그에 찍힐 것입니다.

React는 효과를 다시 실행하기 전과, 구성 요소를 마운트 해제할 때 이 정리 기능을 실행합니다.

즉, 기본적으로 변경 사항이 반응하기 전에, 더 이상 구성 요소가 필요하지 않을 때 정리합니다.

 

 

 

https://www.codementor.io/@damianpereira/how-to-use-clearinterval-inside-react-s-useeffect-and-why-it-is-important-1si7mztjlk\

 

How to use clearInterval() inside React's useEffect(), and why it is important. | Codementor

Learn how to properly clear your intervals inside useEffect's cleanup function.

www.codementor.io

 

 

https://developer.mozilla.org/en-US/docs/Web/API/setInterval

 

setInterval() - Web APIs | MDN

The setInterval() method, offered on the Window and Worker interfaces, repeatedly calls a function or executes a code snippet, with a fixed time delay between each call.

developer.mozilla.org

 

https://developer.mozilla.org/en-US/docs/Web/API/clearInterval

 

clearInterval() - Web APIs | MDN

The global clearInterval() method cancels a timed, repeating action which was previously established by a call to setInterval(). If the parameter provided does not identify a previously established action, this method does nothing.

developer.mozilla.org

 

https://www.acmicpc.net/problem/1244

 

1244번: 스위치 켜고 끄기

첫째 줄에는 스위치 개수가 주어진다. 스위치 개수는 100 이하인 양의 정수이다. 둘째 줄에는 각 스위치의 상태가 주어진다. 켜져 있으면 1, 꺼져있으면 0이라고 표시하고 사이에 빈칸이 하나씩

www.acmicpc.net

 

문제에서 생각해봐야할 것은 '스위치를 중심으로 좌우가 대칭이면서 가장 많은 스위치를 포함하는 구간을 찾아서, 그 구간에 속한 스위치의 상태를 모두 바꾼다.' 는 것이다.

 

스위치의 길이를 반으로 나눈 후, 그 길이만큼 다 비교하는 방법을 택했다.

N=int(input())
btn=[-1] + list(map(int,input().split()))
student_num = int(input())

def switch(num):
    if(btn[num]==0):
        btn[num]=1
    else:
        btn[num]=0
    return

for _ in range(student_num):
    sex, num = map(int,input().split())

    if(sex==1):
        for i in range(num, N+1, num):
            switch(i)
    else:
        switch(num)
        for j in range(N//2):
            if num+j > N or num-j < 1: break
            if btn[num+j] == btn[num-j]:
                switch(num+j)
                switch(num-j)
            else:
                break


for i in range(1,N+1):
    print(btn[i], end=' ')
    if i%20 == 0: print()

 

https://www.acmicpc.net/problem/1924

 

1924번: 2007년

첫째 줄에 빈 칸을 사이에 두고 x(1 ≤ x ≤ 12)와 y(1 ≤ y ≤ 31)이 주어진다. 참고로 2007년에는 1, 3, 5, 7, 8, 10, 12월은 31일까지, 4, 6, 9, 11월은 30일까지, 2월은 28일까지 있다.

www.acmicpc.net

 

1월 1일이 월요일이므로, 일주일 뒤인 1월 8일도 월요일일 것입니다.

 

12월 25일의 요일을 구하고 싶다면, 1월부터 11월까지의 날을 모두 더하고, 25일을 더한 후에 7로 나눈 나머지를 확인하면 됩니다.

 

DAY = ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT']
MONTH_DATE = [0,31,28,31,30,31,30,31,31,30,31,30,31]

month, date = map(int,input().split())

all_day = sum(MONTH_DATE[0:month]) + date

print(DAY[all_day%7])

https://www.acmicpc.net/problem/2108

 

2108번: 통계학

첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.

www.acmicpc.net

 

 

Pyhthon3로 하면, 시간초과가 떠서 pypy로 했다...

 

from collections import Counter

n=int(input())
l = []
for _ in range(n):
    l.append(int(input()))
l.sort()
l_count = Counter(l).most_common()



print(round(sum(l)/n))
print(l[n//2])
if len(l_count) > 1:
    if l_count[0][1] == l_count[1][1]:
        print(l_count[1][0])
    else:
        print(l_count[0][0])
else:
    print(l_count[0][0])

print(l[-1] - l[0])

https://www.acmicpc.net/problem/4375

 

4375번: 1

2와 5로 나누어 떨어지지 않는 정수 n(1 ≤ n ≤ 10000)가 주어졌을 때, 1로만 이루어진 n의 배수를 찾는 프로그램을 작성하시오.

www.acmicpc.net

 

문제: 정수 n이 주어졌을 때, 그 n으로 나누어 떨어지는 1로만 이루어진 가장 작은 자리 숫자를 찾는 문제입니다.

풀이: 브루트포스로 처음부터 모든 경우를 확인합니다.

 

while True:
    try:
        n = int(input())
    except EOFError:
        break
    i=1
    num=0
    while True:
        num = num*10 + 1
        if num %n==0:
            print(i)
            break
        i+=1

백준에서 계속 런타임 에러(EOFError)가 나서, EOFError가 무엇인지 찾아보았습니다.

EOF = End Of File

이런 에러가 뜨는 이유는 입력 도중에 파일의 끝을 만나면 발생하는 에러입니다.

 

다음 코드를 사용하면 파이썬 입력이 끝날 때까지 받아올 수 있습니다.

while True:
    try:
        n = int(input())
    except EOFError:
        break

+ Recent posts