반응형

https://www.hackerrank.com/challenges/frequency-queries/problem?h_l=interview&playlist_slugs%5B%5D=interview-preparation-kit&playlist_slugs%5B%5D=dictionaries-hashmaps

 

Frequency Queries | HackerRank

Process the insert/delete queries and report if any integer is there with a particular frequency.

www.hackerrank.com

 

[ 문제 ] 주어지는 query들을 정해진 규칙에 따라 수행하고 최종 출력을 return한다.

 

query 형태 = [a,b]

 

a에 따라 수행 작업이 달라지며, b는 수행의 대상이다.

arr, output = []

 

1) a = 1 : b를 arr에 넣는다.

2) a = 2 : b를 arr에서 뺀다.(존재할 경우)

3) a = 3 : list에서 frequency가 b인 것이 존재할 경우 1을, 존재하지 않을 경우 0을 output에 넣는다.

 

[ 예시 ]

 

[ 방법 ] : 리스트를 만들지 않고 dictionary로 처리한다.

dict = {}

output = []

1. query를 읽는다.

 

query[0] = a

query[1] = b

 

   1) a == 1일 경우 : dict[b]에 1을 추가한다. 

   2) a == 2일 경우 : dict[b]에서 1을 뺀다.

   * 이 때, dict[b]가 음수가 되어서는 안된다.

   3) a == 3일 경우 : dict.values()에 b가 있다면 1을, 없다면 0을 output에 추가한다.

 

간단한 문제이지만 Time out으로 해결되지 않는 case도 있어서 몇가지 Trick을 추가해줘야 합니다-!

반응형

'Computer Science > 알고리즘' 카테고리의 다른 글

백준 - 탑(2493) Python  (0) 2020.12.21
백준 - 괄호(9012)  (1) 2020.12.20
HackerRank - Count Triplets  (0) 2020.04.02
HackerRank - Array Manipulation  (0) 2020.03.31
Hackerrank - Minimum Swaps2  (0) 2020.03.31
반응형

https://www.hackerrank.com/challenges/count-triplets-1/problem?h_l=interview&playlist_slugs%5B%5D=interview-preparation-kit&playlist_slugs%5B%5D=dictionaries-hashmaps

 

Count Triplets | HackerRank

Return the count of triplets that form a geometric progression.

www.hackerrank.com

간단해 보이지만 어김없이 시간 제약에 걸리는 문제입니다.

 

문제 : 숫자 리스트 arr과 공비 r이 주어졌을 때,

arr[i] = 임의의 숫자 k

arr[j] = k * r

arr[k] = k * r * r

를 만족하는 (i,j,k)의 총 갯수를 구하는 문제입니다. 이 때 i < j < k를 만족해야 합니다.

 

예를 들어,

 

arr = [1, 2, 2, 4] , r = 2라고 할 때

arr[0] = 1, arr[1] = 2, arr[3] = 4 (i = 0, j = 1, k = 3)

arr[0] = 1, arr[2] = 2, arr[3] = 4 (i = 0, j = 2, k = 3)

 

라는 두개의 해를 찾을 수 있습니다. 

 

방법 : 저는 찾아야 하는 3개의 숫자 중 가운데 숫자(arr[j])를 기준으로 i,j,k의 조합을 찾아내기로 했습니다.

* arr[j]의 특성은 r로 나눴을 때 나머지가 0이라는 점입니다.(arr[k]도 마찬가지긴 합니다.)

 

1) Counter 라이브러리를 활용하여 arr의 구성 요소에 대한 dict를 생성한다.

2) 빈 라이브러리 dict2를 생성한다.

3) 리스트에 대해 for loop을 돌리면서 나오는 숫자(num)가 r로 나눴을 때 나머지가 0인지 확인한다.

  3.1) 나머지가 0이 아닌 경우 : dict2[num]에 1을 더하고, dict[num]에 1을 빼준다.

  3.2) 나머지가 0인 경우 :

          1) dict2[num//r]이 존재하고, dict[num*r]이 존재할 경우, 정답에 dict2[num//r] * dict[num*r]을 더한다.

          2) 위의 둘 중 하나가 없는 경우 dict2[num]에 1을 더하고, dict[num]에 1을 빼준다.

 

위의 작업을 리스트의 처음부터 끝까지 반복하면 정답을 구할 수 있습니다 -!

반응형

'Computer Science > 알고리즘' 카테고리의 다른 글

백준 - 괄호(9012)  (1) 2020.12.20
HackerRank - Frequency Queries  (0) 2020.04.02
HackerRank - Array Manipulation  (0) 2020.03.31
Hackerrank - Minimum Swaps2  (0) 2020.03.31
Hackerrank - New Year Chaos  (0) 2020.03.16
반응형

이번 시간에는 리눅스 환경에서 프로세스들이 어떻게 작동하는지 알아봅니다.

 

프로세스는 구조는 아래와 같습니다. 아래의 구조를 PCB라고 부르며, 프로세스가 생성되면 고유의 pid(Process ID) 및 PCB가 주어집니다. 이 공간에 프로세스 이미지가 업로드되고, 실행하면 프로세스의 작업이 시작됩니다.

이 때 생성되는 pid는 파일에서의 inode와 같이, 프로세스와 1:1로 관리가 됩니다.(이 때 커널 메모리는 모든 프로세스가 공유합니다.)

 

1) STACK : 함수 실행 간 생성되는 데이터를 정적으로 할당

2) HEAP : 함수 실행 간 생성되는 데이터를 동적으로 할당

3) BSS : 초기화되지 않은 변수 값들을 저장

4) DATA : 초기화된 변수 값들을 저장

5) TEXT : 실행프로그램의 코드를 저장

운영체제가 Load되면 최초의 프로세스인 init이 생성되고, 이 프로세스에 pid = 1이 주어집니다. 리눅스에서는 일반적으로 init을 제외한 다른 프로세스를 생성할 때 fork() 시스템 콜을 사용하여 생성하게 됩니다. 

프로세스의 생성 과정은 아래와 같습니다.

 

[프로세스 생성]

1) 부모 프로세스에서 fork()를 수행한다.

2) fork()를 하면 자식 프로세스의 경우 성공적으로 수행되면 새로운 가상메모리(4GB) 공간을 생성한 뒤 return 값으로 0을 주게 되는데(실패하면 -1), return 값이 0으로 확인되면 exec(실행파일)을 수행한다.

3) exec(실행파일)에 의해서 새 프로세스 공간에 실행파일을 덮어씌우고, 이를 처음부터 실행한다.

4) 자식 프로세스 마지막에 exit(종료 상태값)을 사용하여 자식 프로세스를 종료함과 동시에 종료 상태값을 전달한다.

5) 부모 프로세스에서 wait(종료 상태값)을 사용하여 자식 프로세스의 종료 상태값을 확인하고, 남은 부모 프로세스를 수행한다.

 

* copy-on-write : 부모 프로세스에서 자식 프로세스를 fork()할 때 새로운 가상메모리공간 4GB를 복사하여 만들게 되는데, 4GB를 복사하는데 시간이 매우 오래 걸린다. 이를 개선하기 위해 자식 프로세스에서는 처음에 생성된 뒤 부모의 메모리 공간(물리적)을 참조한다. 읽기 과정에서는 해당 참조값이 없지만, 자식 프로세스의 수행 과정에서 메모리에 write할 일이 생기면, 부모 프로세스의 메모리 공간(물리적)에 그대로 쓰는 것이 아니라 변화가 필요한 내용의 페이지만 새로운 공간에 복사하여 write를 진행한다.

 

[ 프로세스 관련 시스템 콜 ]

 

* fork() : 시스템 콜. 해당 시스템 콜이 실행되면, 운영체제는 새로운 프로세스 공간(PCB)를 만들고, fork() 시스템콜을 호출한 프로세스(부모 프로세스) 공간을 모두 복사해서 새로운 프로세스 공간에 붙여넣습니다. 이렇게 새로 만들어진 프로세스에는 새로운 pid가 부여됩니다. 이 때 부포 프로세스의 id를 ppid라고 하고, 해당 변수도 새롭게 만들어진 프로세스에 저장됩니다.

 


ex)

#include <sys/types.h>
#include 
#include 
int main()
{
        pid_t pid;
        printf("Before fork() call\n");
        pid = fork();

        if(pid == 0)
                printf("This is Child process. PID is %d\n", pid);
        else if (pid > 0)
                printf("This is Parent process. PID is %d\n", pid);
        else
                printf("fork() is failed\n");
        return 0;
}


* exec() : 시스템 콜. 해당 시스템 콜을 호출한 프로세스 공간의 [TEXT, DATA, BSS] 영역을 새로운 프로세스(인자로 전달)의 이미지로 덮어씌웁니다. 따라서 인자로 실행파일을 전달해줘야 합니다.

 

exec()는 fork()와 다르게 여러 버전의 함수가 있습니다. 해당 함수들은 인자를 전달하는 방식이 다릅니다.

 

1) execl() 

2) execlp()

3) execle()

4) execv()

5) execvp()

6) execve()

 

* getpid() : pid(Process ID)를 가져옵니다.

* getppid() :ppid(부모의 Process ID)를 가져옵니다.

 

* wait() : 시스템 콜, 부모 프로세스가 자식 프로세스보다 먼저 종료되는 일이 없도록, 자식 프로세스가 종료될 때까지 기다리게 하는 함수입니다. 자식 프로세스가 종료할 때 종료 상태값(정상 종료 : 0)을 저장하면, 해당 상태값을 참조하여 나머지 부모 프로세스를 수행합니다.

 

* exit() : 시스템 콜, 프로세스를 강제로 즉시 종료시킵니다. 인자로 프로세스 종료 상태 번호를 전달합니다.

# 동작 과정

1) atexit()이라는 함수에 등록된 함수를 역순으로 순차적으로 실행한다.

2) 열려있는 모든 입출력 스트림 버퍼를 삭제한다.

3) 프로세스가 오픈한 파일을 모두 닫는다.

4) tmpfile() 함수를 통해 생성한 임시 파일을 삭제한다. 

 

[ Process 관련 명령어 ]

 

* ps -ef : 현재 실행중인 프로세스의 모든 정보를 출력합니다.

반응형
반응형

https://www.hackerrank.com/challenges/crush/problem?h_l=interview&playlist_slugs%5B%5D=interview-preparation-kit&playlist_slugs%5B%5D=arrays

 

Array Manipulation | HackerRank

Perform m operations on an array and print the maximum of the values.

www.hackerrank.com

매우 골치를 썩였던 문제입니다.

단순히 풀리나 싶더니 어김없이 Time Limit을 걸어놓았더군요 ㅎㅎ

discussion을 조금 보고서야 풀 수 있었습니다.

 

문제 : 길이가 n이며 원소가 모두 0인 배열 arr이 주어질 때, 주어지는 query에 따라서 arr[a:b]에 k만큼 더한다. query들이 끝나면, 배열 내에서 가장 큰 수를 찾는다.

 

input : n, m, a, b, k

n : array의 길이

m : query의 수

a : 시작 index

b : 끝 index

k : 더하는 수

 

Ex) n = 5, m = 3 a,b,k = [[0, 1, 100], [1, 2, 100], [2, 3, 100]]

 

n= 5이므로 처음 배열의 시작은 

 

[0,0,0,0,0]

1) a = 1, b = 2, k = 100

arr 배열의 1번째 원소부터 2번째 원소까지 k만큼 더합니다.

→ [100, 100, 0, 0, 0]

 

이와 같이 문제를 풀어나가시면 됩니다. 다만 단순히 구현만 해서는 Timeout에 걸릴 수 있으니 주의하세요.

직접 풀어보시길 추천합니다. 저는 방법에 대한 힌트를 얻어서 이미 불가능했습니다..

 

방법 :

0) arr = [0] * (n+1) 

* n+1개를 만드는 이유는 1)번 과정을 보시면 이해할 수 있습니다.

 

1) query가 주어질 때([a,b,k]), a-1번째 원소에 +k를, b번째 원소에 -k를 해줍니다.

 * a와 b의 index는 1부터 시작하기 때문에, a,b가 주어졌을 때 arr[a-1: b] += k를 해줘야 합니다.

 * 여기서 (1)번을 수행하는 이유는, a-1번째 원소부터 b-1번째 원소들의 최대값을 표시한 것입니다. 모두 동일한 값을 더했기 때문에 우리가 구하길 원하는 최댓값을 구하는 방법을 간단히 구현하였습니다.

(arr의 최댓값을 구하는 3번 과정을 보시면 더 잘 이해할 수 있습니다.)

 

2) 1)번이 완료되면, arr에 for loop을 돌리면서 값들을 더해줍니다. 더해주는 과정에서 max가 될 때의 값을 찾아냅니다.

 

max, x = 0

for i in arr:

    x += i

    if(max<x):

        max = x

 

반응형

'Computer Science > 알고리즘' 카테고리의 다른 글

HackerRank - Frequency Queries  (0) 2020.04.02
HackerRank - Count Triplets  (0) 2020.04.02
Hackerrank - Minimum Swaps2  (0) 2020.03.31
Hackerrank - New Year Chaos  (0) 2020.03.16
HackerRank - Statistics 1  (0) 2020.03.10
반응형

https://www.hackerrank.com/challenges/minimum-swaps-2/submissions/code/149223858?h_l=interview&playlist_slugs%5B%5D=interview-preparation-kit&playlist_slugs%5B%5D=arrays

불러오는 중입니다...

 

이번 문제는 주어진 배열을 정렬하기 위해 필요한 최소의 swap 수를 구하는 것입니다.

[4, 3, 2, 1]이란 배열이 주어진다면, 이 배열을 [1,  2 3, 4]로 정렬하기 위해 필요한 swap의 수를 구하면 됩니다.

이 때, swap은 아무 위치에 있는 숫자끼리도 바꿀 수 있습니다.

위의 예를 보면,

 

[4,1] swap → [1, 3, 2, 4]

[3,2] swap → [1, 2, 3, 4]

 

따라서 위의 배열을 정렬하는데 필요한 최소의 swap 수는 2입니다.

 

1. 방법

  1) for loop에 enumerate 함수를 사용하여 idx, 숫자를 순차적으로 뽑아냅니다.

  2) 만약 idx와 숫자(x)가 일치하지 않는다면(정렬되어있지 않다는 뜻), 해당 숫자(x)의 고유 idx 위치에 숫자(x)를 입력합니다.(일치하면 for loop 지속)

  3) swap 횟수를 1을 더해줍니다.

  4) x의 고유idx에 존재하던 숫자(y)와 y의 고유 idx에 있는 숫자 z를 비교하고, 다르다면 swap한 뒤 swap 횟수에 1을 더합니다.(같아질 때까지 반복하고, 같다면 swap 횟수에 1을 빼고 for loop로 복귀합니다.) 

  5) for loop이 완료될 때까지 (2) - (4)를 반복한다.

 

* 이 때 for loop 복귀 전에 swap 횟수를 1을 빼주는 이유는, 위에서 주어진 예시[4,3,2,1]에서의 [1,4], [3,2]와 같이 한번 swap을 통하여 두 숫자가 제자리를 찾아가는 경우가 있습니다. 하지만 이 알고리즘에서는 해당 경우를 즉각적으로 검출해내지 못하므로, 1을 빼주는 것입니다.

 

Ex) Input : [4, 3, 2, 1] (이 때 보기 쉽게 idx는 1, 2, 3, 4로 지정하겠습니다. 실제로는 0, 1, 2, 3)

 

for idx, num in enumerate(Input):

→ idx = 1, num = 4

→ idx != num이므로 4가 있어야 할 원래 위치(idx : 4)에 4를 입력하고, num을 1로 바꿔줍니다. [swap 횟수 = 1]

→ [4, 3, 2, 4], num = 1

→ num(=1)이 있어야할 원래 위치(idx : 1)의 숫자(=4)와 num(=1)을 비교합니다.

num(=1)이 있어야할 원래 위치(idx : 1)에 num을 입력하고, num을 4로 바꿔줍니다. [swap 횟수 = 2]

→ num(=4)이 있어야할 위치에 해당 숫자(4)가 위치해 있으므로 for loop을 벗어납니다.

 

이상 끝-!

반응형

'Computer Science > 알고리즘' 카테고리의 다른 글

HackerRank - Count Triplets  (0) 2020.04.02
HackerRank - Array Manipulation  (0) 2020.03.31
Hackerrank - New Year Chaos  (0) 2020.03.16
HackerRank - Statistics 1  (0) 2020.03.10
Hackerrank - Nested Logic  (0) 2020.02.24
반응형

이어서 패스트캠퍼스의 [컴퓨터공학 - 운영체제] 수강 내용을 작성해보겠습니다.

 

운영체제는 자세히 그려보면 아래와 같은 구조를 하고 있습니다.

 

컴퓨터 아키텍쳐에서 배운 CPU, Memory, Storage, Network로 이루어진 Hardware 위에 운영체제(OS)가 탑재되어 있고, 이 운영체제는 시스템 콜을 바탕으로 작동합니다. 이 위에는 각 프로그래밍 언어를 컴파일하는 컴파일러와 라이브러리/API가 있으며, 그 위에 사용자와 컴퓨터의 Interaction을 담당하는 Shell 및 Editor가 있습니다. 

 

즉, 사용자가 Shell이나 Editor를 통해 작성한 응용프로그램은, 컴파일러를 통해 번역되어 필요한 작업을 시스템 콜을 통하여 OS에 요청하게 됩니다. 

 

그럼 구성요소 각각에 대해서 조금 더 알아보겠습니다.

 

1. Shell : 사용자가 운영체제 기능과 서비스를 조작할 수 있도록 하는 인터페이스

*CLI / GUI 두가지 방식이 있다.

2. API : 라이브러리 혹은 함수의 모음집

3. 컴파일러 : 사용자가 작성한 코드를 컴퓨터가 이해할 수 있는 언어로 번역하는 시스템

4. 시스템 콜(시스템 호출 인터페이스): 사용자가 원하는 작업을 OS에 요청하는 방식

5. 운영체제 : 리눅스, 윈도우 같은 컴퓨터 자원 관리 및 사용자 요청 작업을 수행하는 프로그램

 

이제 본격적으로 운영체제에 대하여 알아보겠습니다.

 

사용자가 작성한 응용 프로그램은 CPU에서 원하는 작업을 수행하게 되는데, 이 때 직접 수행 가능한 것이 있고 반드시 시스템 콜을 거쳐서 작업을 수행해야만 하는 것이 있습니다. 시스템 콜을 통해서만 수행할 수 있는 영역은 커널 영역(모드)라고 하고, 그렇지 않은 영역을 사용자 영역(모드)라고 합니다. 이러한 영역은 CPU Protection Ring으로 아래와 같이 구체화되어 있습니다. 사용자 모드/커널 모드로 구분하여 권한을 부여함으로써, 컴퓨터는 임의의 사용자가 함부로 컴퓨터의 운영체제를 손상하는 것을 막을 수 있습니다.

다음 글에서는 컴퓨터 구조의 구성요소들을 컴퓨터가 어떻게 활용하고 분배하는지, 프로세스와 스케쥴링에 대해 알아보도록 하겠습니다 -!

 

반응형
반응형

삼각형의 세 변의 길이 A, B, C가 기록되어있는 테이블 TRIANGLE이 주어졌을 때, 각 삼각형의 종류를 4가지로 분류하는 문제입니다.(정삼각형/이등변삼각형/그냥 삼각형/삼각형이 아니다)

 

https://www.hackerrank.com/challenges/what-type-of-triangle/problem

 

Type of Triangle | HackerRank

Query a triangle's type based on its side lengths.

www.hackerrank.com

MySQL의 CASE문을 배웠습니다. 풀이를 보면 쉽게 이해가 되실 겁니다.

(CASE - WHEN - THEN - ELSE - END 로 구성됩니다.)


SELECT 
CASE 
WHEN A = B AND B = C THEN 'Equilateral' 
WHEN A >=B+C OR B>=A+C OR C>=A+B THEN 'Not A Triangle'
WHEN A = B OR A = C OR B = C THEN 'Isosceles' 
ELSE 'Scalene' END
FROM TRIANGLES;


 

반응형

'DB > SQL' 카테고리의 다른 글

Hackerrank - SQL  (0) 2020.03.17
Hackerrank[SQL] - Weather Observation Station 6  (0) 2020.03.10
Hackerrank[SQL] - Weather Observation Station 5  (1) 2020.03.06
Hackerrank[SQL] - Weather Observation Station 4  (0) 2020.03.06
반응형

STUDENT라는 테이블의 Name의 오른쪽 세자리를 기준으로 정렬하는 문제입니다. 엑셀같군요.

 

SELECT NAME

FROM STUDENTS S

WHERE S.Marks > 75 

ORDER BY RIGHT(S.NAME, 3), ID;

반응형

+ Recent posts