https://programmers.co.kr/learn/courses/30/lessons/42840

 

코딩테스트 연습 - 모의고사

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 1번 문제부터 마지막 문제까지 다음과 같이 찍습니다. 1번 수포자가 찍는

programmers.co.kr

문제

exam with pencil

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 1번 문제부터 마지막 문제까지 다음과 같이 찍습니다.

1번 수포자가 찍는 방식: 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, ...
2번 수포자가 찍는 방식: 2, 1, 2, 3, 2, 4, 2, 5, 2, 1, 2, 3, 2, 4, 2, 5, ...
3번 수포자가 찍는 방식: 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, ...

1번 문제부터 마지막 문제까지의 정답이 순서대로 들은 배열 answers가 주어졌을 때, 가장 많은 문제를 맞힌 사람이 누구인지 배열에 담아 return 하도록 solution 함수를 작성해주세요.

 

발상

문제 카테고리가 완전탐색인만큼 모든 경우의 수를 다 검색하면서 조건을 따지는 문제였다.

3명의 수포자가 같은 문제를 가지고 각각의 방식으로 문제를 푼다는 점에서 디자인패턴 전략패턴을 사용하면 확장성이 높고 깔끔한 코드가 나올 것 같았지만, 타임아웃이 걸릴 것 같아서 우선 반복문으로 풀어보고 다음에 리팩토링 해보기로 하였다.

 

의사코드

1. 초기값 세팅(각 수포자의 전략 템플릿)

2. 정답 확인(){

    1. a 정답 확인

    2. b 정답 확인

    3. c 정답 확인
}

3. 최고점 확인(스트림)
4. 최고점을 맞은 수포자 리스트 추출
5. 배열로 변환

 

개선

의사코드를 작성하고, 구현하고 제출하였더니 런타임에러가 발생하였다.

수포자들의 전략템플릿을 구현할 때 따로 메서드를 추출하여서 각각의 전략템플릿의 길이를 넘어가면 초기화하는 식으로 하였는데, 그 부분을 따로 계산하지 않고 나머지값과 전략템플릿 배열인덱스를 매칭하는 방법으로 리팩토링 하니 통과하였다.

 

단순히 전략패턴 업데이트만 함수로 재사용했는데도 런타임에러가 발생한 것을 보면, 추가적으로 리팩토링해서 전략 디자인패턴을 구현하면 더 호출이 복잡해지니 테스트케이스는 통과하지 못할 것 같다.

 

'IT > Algorithm' 카테고리의 다른 글

[Programmers] 가운데 글자 가져오기  (0) 2022.07.04
[Programmers] 2016년  (0) 2022.07.03
[Programmers] 키패드 누르기  (0) 2022.07.02
[LeetCode] 773. Sliding Puzzle  (0) 2022.06.25
Day 22: Binary Search Trees  (0) 2018.06.25

https://programmers.co.kr/learn/courses/30/lessons/67256

 

코딩테스트 연습 - 키패드 누르기

[1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5] "right" "LRLLLRLLRRL" [7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2] "left" "LRLLRRLLLRR" [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] "right" "LLRLLRLLRL"

programmers.co.kr

문제

휴대폰 숫자패드

숫자 배열이 주어집니다. 정해진 규칙에 따라 왼손 혹은 오른속으로 숫자패드를 누르게 되는데, 어떤 손으로 눌렀는지를 출력하세요.

 

발상

우선 왼쪽라인은 왼손, 오른쪽 라인은 오른손으로 정해져있으니, 먼저 고정값들을 반환하고

그 뒤에 현재 왼손,오른손 검지의 위치와 목표숫자의 거리를 계산하는 것이 포인트였다.

 

1. 숫자패드가 정해져있으니 숫자패드를 [1,2,~10,11,12] 숫자배열로 추상화하고

2. 엄지와 목표값의 거리를 3x4 배열의 특성을 이용하여 3으로 나눈 몫을 y거리, 3으로 나눈 몫의 나머지를 x거리로 잡아서

3. x와 y의 값을 더하여 각 손의 거리를 구하고 비교하기로 하였다.

 

 

의사코드

1. 초기값 세팅(숫자패드, 왼손, 오른손 위치)

2. 입력값 테스트(){

    1. 목표가 0일 경우 추상화한 11로 치환

    2. 손가락판별()

    3. 결과배열 더하기
}
3. 결과배열 반환



손가락판별(){

1.3으로 나누었을때 나머지가 1이면 L

2. 3으로 나누었을때 나머지가 0이고 목표가 0이 아니면 R

3. 왼손과 오른손의 목표와의 거리값 비교

4. 결과값 반환

}



거리값 비교(){

1. 목표와 현재위치 절대값 계산

2. 차이값을 3으로 나눈 몫 = y거리

3. 차이값을 3으로 나눈 몫의 나머지 = x거리

4. y+x 반환

}

 

개선

테스트케이스 통과 후, 다른사람들이 작성한 코드를 보니 발상은 비슷한데 세부적으로 최적화한 부분이 있었다.

예를들어 주어지는 값 "left","right"를 "L","R"로 새로 할당하여 비교한다던지

나는 각각의 거리를 매 로직마다 계산하게 하였는데, 패드가 작은 것을 이용하여 미리 구해놓은 값을 바로 쓰는 경우도 있었다.

다음부터는 사용하기 편리한 값들을 설정하는 것도 고려하자.

'IT > Algorithm' 카테고리의 다른 글

[Programmers] 2016년  (0) 2022.07.03
[Programmers] 모의고사  (0) 2022.07.02
[LeetCode] 773. Sliding Puzzle  (0) 2022.06.25
Day 22: Binary Search Trees  (0) 2018.06.25
Day 21: Generics  (0) 2018.06.25

최근에 시스템관리자분에게 로그관련하여 문의를 드리러 간 적이 있었다.

이슈를 확인하기 위해서 여러 곳에 있는 정보들을 하나씩 확인하면서 도와주셨는데, 그때 리눅스 명령어를 자유자재로 쓰시는 모습이 너무 멋있어보였다.

 

같이 일하시는 개발자 선배분들도 배포나 로그 확인 등의 작업을 하실 때 부족함 없이 필요한 만큼 리눅스를 잘 활용하시지만 시스템관리만 전문적으로 하시는 분들의 모습은 확실히 숙련도가 달라보였다.

지금부터라도 정리하고 하나씩 손에 익혀나가자 

 

 

도움말

명령어 기능
which 명령어의 위치를 찾는다
--help 옵션에 붙여서 아무 명령어의 도움말을 표시한다

 

 

파일시스템

명령어 기능 옵션
cd [디렉토리명] 
(change directory)
현재 디렉토리를 변경한다. ~,~/, 빈값 엔터 : 홈 디렉토리로 이동 
cd / 루트 디렉토리로 이동
cd .. 상위 디렉토리로 이동
pwd
(print working directory)
현재 디렉토리를 절대 경로 명으로 출력한다.  
 ls [옵션] [파일명] 
(list)
현재 디렉토리 내의 파일과 디렉토리에 대한 정보를 출력한다. -a 디렉토리 내의 모든파일(.으로 시작되는 파일 포함)을 출력 
-i 파일의 아이노드(inode)번호를 출력 
-h 파일의 크기를 단위로 표시
-l 파일의 다양한 정보를 함께 출력(소유자 정보, 권한 정보, 크기, 날짜) 
-m 파일을 쉼표로 구분하여 가로로 출력 
-s kb 단위의파일크기를 출력 
-t 파일을 최근에 생성된 시간순으로 출력 
-F 파일의 형태와 함께 출력('*' : 실행파일, '@' : 심볼릭링크, '/' : 디렉토리) 
-R 서브 디렉토리의 내용을 포함하여 출력
-S 파일을 크기순으로 출력 
 cp [옵션] [원본파일명] [목적 파일명 / 디렉토리명] 
(copy)
하나 이상의 원본 파일을 목적 파일이나 디렉토리로 복사한다. -i 파일 복사시 동일 파일명이 있을시에 사용자에게 덮어 쓸 것인지를 표시
-f 동일파일명 발생시에도 모두 강제적으로 복사함 
-p 원본 파일의 시간 및 소유 권한 보존 
-r 포함된 자식 디렉토리까지 모두 복사
rm [옵션] [파일명] 
(remove)
파일(디렉토리)을 삭제한다. -f 디렉토리 안의 파일을 삭제할 때 사용자에게 확인을 요구하지 않음 
-r 인수 list 에서 지정한 디렉토리 혹은 그 아래의 subdirectory를 삭제 
-i whrite permission 이 없는 파일의 삭제를 위해 대화식으로 확인 
-p 디렉토리 dir-name과 비어있는 부모 디렉토리를 사용자가 제거할 수 있으며, 전체 경로명이 삭제 되거나 어떤 이유로 인해 경로명의 일부가 남은것과 무관하게 표준출력에 메세지가 출력됨 
-s -p 선택항목 지정시 표준오류에 출력되는 메시지를 삭제
mkdir [옵션] [파일명]
(make directory)
새로운 디렉토리를 만든다. -p 만들고자하는 디렉토리의 상위 디렉토리가 없는 경우 상위 디렉토리까지 같이 만든다.
rmdir [옵션] [파일명] 
(remove directory)
디렉토리를 삭제한다. -p 삭제한 디렉토리에 대한 메시지가 표시됨 
-s 삭제한 디렉토리에 대한 메시지가 표시되지 않음.(Default)
diff 
(difference)
두 파일의 차이를 출력한다.  
mv [옵션] [파일명] 
(move)
파일의 위치를 바꾸거나 이름을 변경한다. -f 대상 파일이 존재할 대 새로운 파일로 대체 
-i 대상파일이 있을 때 확인 후 작업 
-f 파일의 이동 과정을 보여준다.
touch [-amc] [MMDDhhmmYY] [파일명]  파일의 액세스 시간이나 갱신 시간을 수정한다. -a 파일의 액세스 시간을 바꿈 
-m 파일의 갱신 시간을 바꿈 
-c 파일명이 존재하지 않는다면 새로운 파일을 만들지 않음 

 

 

검색

명령어 기능 옵션
locate 패턴과 일치하는 파일을 이름으로 검색한다.  
find [옵션] [파일명]  파일을 이름, 수정날짜, 소유주, 허가 등을 기준으로 하여 검색하게 해준다. -name filename filename과 일치하는 파일을 찾음
-print 현재의 경로 이름을 표시
grep [옵션] [패턴] [파일명] 
(Global Regular Expression Print)
파일 내부에 있는 텍스트의 내용으로 파일을 검색한다. -c 파일 내에서 패턴과 일치하는 줄의 총수를 구한다. 
-h 여러 개의 파일을 검색할 때, 출력에 파일명이 나타나는 것을 방지한다. 
-i 대, 소문자를 구별하지 않는다 
-n 일치하는 줄의 줄 번호도 같이 출력한다 
-v 패턴과 일치하지 않는 줄만 출력한다
head [-카운트] [파일명]  파일의 첫 부분부터 카운트로 정한 숫자만큼의 줄 수를 출력한다  
tail [-카운트] [파일명]  파일의 카운트로 정한 숫자만큼의 끝 부분 줄 수를 출력한다  

 

 
 
 

'IT > Linux' 카테고리의 다른 글

[Linux] grep 명령어  (0) 2022.07.08

 

 

개요

Vue.js

Vue.js는 JavaScript 프레임워크입니다. 

표준 HTML, CSS, JavaScript로 만들어져 있으며, 선언적이고 컴포넌트 기반의 프로그래밍 모델을 제공하여 효율적으로 사용자 인터페이스를 개발할 수 있도록 도와줍니다.

Vue의 가장 큰 특징 두가지는 선언적 렌더링(Declarative Rendering)과 반응성(Reactivity)입니다.

 

 

선언적 렌더링(Declarative Rendering)

Vue는 표준 HTML을 템플릿 문법과 함께 확장하여 Javascript 상태에 기반한 HTML 결과물을 만들어냅니다.

<div id="app">
  {{ message }}
</div>
var app = new Vue({
  el: '#app',
  data: {
    message: '안녕하세요 Vue!'
  }
})

 

반응성(Reactivity)

Vue는 JavaScript의 상태변화를 추적하고, 변화가 발생하였을 때 DOM을 효과적으로 업데이트 할 수 있습니다.

<div id="app-2">
  <span v-bind:title="message">
    내 위에 잠시 마우스를 올리면 동적으로 바인딩 된 title을 볼 수 있습니다!
  </span>
</div>
var app2 = new Vue({
  el: '#app-2',
  data: {
    message: '이 페이지는 ' + new Date() + ' 에 로드 되었습니다'
  }
})

 

 

진보적인 프레임워크

Vue는 프론트엔드 개발에 필요한 공통적인 특징들을 지원하는 프레임워크이며 생태계입니다.

Vue는 유연하고 점진적으로 채택할 수 있도록 설계되었습니다.

사용 사례에 따라 Vue를 다양한 방식으로 사용할 수 있습니다.

  • 빌드 단계 없이 정적 HTML 향상 모든 페이지에 웹 구성 요소로 포함
  • 단일 페이지 애플리케이션(SPA)
  • 풀스택/서버 측 렌더링(SSR)
  • Jamstack/정적 사이트 생성(SSG)
  • 데스크탑, 모바일, WebGL, 터미널까지 타겟팅

 

 

싱글 파일 컴포넌트

Vue 프로젝트에서 단일 파일 구성 요소(*.vue 파일이라고도 함, SFC로 약칭)라는 HTML과 유사한 파일 형식을 사용하여 Vue 구성 요소의 논리(JavaScript), 템플릿(HTML) 및 스타일(CSS)을 하나의 파일로 캡슐화합니다.

 

<script>
export default {
  data() {
    return {
      count: 0
    }
  }
}
</script>

<template>
  <button @click="count++">Count is: {{ count }}</button>
</template>

<style scoped>
button {
  font-weight: bold;
}
</style>

 

 

API 스타일

Vue 구성 요소는 옵션 API와 구성 API의 두 가지 API 스타일로 작성할 수 있습니다.

 

Options API

Options API를 사용하여 데이터, 메소드, 마운트와 같은 옵션의 개체를 사용하여 구성 요소의 논리를 정의합니다. 옵션으로 정의된 속성은 구성 요소 인스턴스를 가리키는 내부 함수에 노출됩니다.

<script>
export default {
  // Properties returned from data() become reactive state
  // and will be exposed on `this`.
  data() {
    return {
      count: 0
    }
  },

  // Methods are functions that mutate state and trigger updates.
  // They can be bound as event listeners in templates.
  methods: {
    increment() {
      this.count++
    }
  },

  // Lifecycle hooks are called at different stages
  // of a component's lifecycle.
  // This function will be called when the component is mounted.
  mounted() {
    console.log(`The initial count is ${this.count}.`)
  }
}
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

 

Composition API

구성 API를 사용하면 가져온 API 기능을 사용하여 구성 요소의 논리를 정의할 수 있습니다. SFC에서는 일반적으로 <script setup>과 함께 Composition API를 사용합니다. setup 속성은 더 적은 상용구로 컴포지션 API를 사용할 수 있도록 하는 컴파일 타임 변환을 수행하도록 Vue에 지시하는 힌트입니다. 예를 들어 <script setup>에서 선언된 import와 최상위 변수/함수는 템플릿에서 직접 사용할 수 있습니다.

다음은 정확히 동일한 템플릿을 사용하지만 대신 Composition API와 <script setup>을 사용하는 동일한 구성 요소입니다.

<script setup>
import { ref, onMounted } from 'vue'

// reactive state
const count = ref(0)

// functions that mutate state and trigger updates
function increment() {
  count.value++
}

// lifecycle hooks
onMounted(() => {
  console.log(`The initial count is ${count.value}.`)
})
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

 

 

참고

Vue.js 레퍼런스 문서https://vuejs.org/guide/introduction.html#the-progressive-framework

 

 
 
 

https://leetcode.com/problems/sliding-puzzle/

 

Sliding Puzzle - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

문제

2 x 3 보드에는 1에서 5까지 레이블이 지정된 5개의 타일과 0으로 표시되는 빈 사각형이 있습니다. 이동은 0과 4방향으로 인접한 숫자를 선택하고 교체하는 것으로 구성됩니다. 보드의 상태는 보드가 [[1,2,3],[4,5,0]]인 경우에만 해결됩니다. 퍼즐 보드 보드가 주어지면 보드의 상태가 해결되도록 필요한 최소 이동 횟수를 반환합니다. 보드의 상태를 해결할 수 없는 경우 -1을 반환합니다.

 

접근

어렸을때 가지고 놀던 슬라이딩퍼즐을 맞추는 가장 적은 횟수를 구하는 문제이다.

 

퍼즐의 풀이방법을 구현하여서 푸는 방법도 있을 것 같고https://namu.wiki/w/%EC%8A%AC%EB%9D%BC%EC%9D%B4%EB%94%A9%20%ED%8D%BC%EC%A6%90

 

슬라이딩 퍼즐 - 나무위키

루빅스 큐브보다는 쉽다. 루빅스 큐브는 한 면을 돌리면 8개의 블럭 위치가 바뀌고 블럭의 방향까지 생각해야 하지만, 슬라이딩 퍼즐은 블럭을 하나씩 움직이고 위치만 맞추면 되기 때문. 우선 1

namu.wiki

빈 공간을 기준으로 이동알고리즘을 작성하는 방법도 있을 것 같았는데, 절차가 잘 떠오르지 않았다.

퍼즐의 배열 상태를 하나의 노드로 보고,

빈공간(0)의 이동 가능 경로의 이동 후 배열상태를 자식노드로 연결하여

전체 경우의 수를 탐색하는 방법을 쓰는 것을 방향으로 잡고 접근하였다.

구현에 사용한 변수는 다음과 같다.

 

목표 퍼즐상태 String = "123450"

현재 상태 String

방문노드 캐시용 HashSet<String>

탐색노드 저장용 Queue

퍼즐의 위치 별 탐색 가능 방향 배열 int[][]

 

의사코드

1. 초기값 세팅

2. 탐색용 배열과 캐시에 현재상태 세팅

3. 노드 탐색(큐가 빌 때까지){

    1. 탈출조건 체크 ( 탐색깊이 반환 )

    2. 현재 0의 위치 확인

    3. 가능한 이동방향 퍼즐상태 저장(0 <-> 목표 스왑)

        1. 캐시확인, 방문노드면 큐에 저장X

        2. 미방문 노드면 큐에 저장

    4. 탐색깊이 ++

}

4. 탐색 실패 시 -1 반환
 

'IT > Algorithm' 카테고리의 다른 글

[Programmers] 모의고사  (0) 2022.07.02
[Programmers] 키패드 누르기  (0) 2022.07.02
Day 22: Binary Search Trees  (0) 2018.06.25
Day 21: Generics  (0) 2018.06.25
Day 20: Sorting  (0) 2018.06.19
 

배경

최근에 일을 하는데 세션과 쿠키 관련해서 개발환경에서 작업을 할 때 로그인쪽에서 이슈가 발생하였다.

결론적으로 여러 프로젝트를 교체하면서 작업을 하는데 브라우저의 세션id 쿠키값이 안지워져서 발생한 문제였는데 이슈를 찾다보니 세션에 관해서 개념이 잘 안잡혀있다는 것을 깨달았다.

그래서 한번 제대로 정리하고 이미지를 잡기 위하여 구글링을 한 결과를 정리하였다.

 

정의

 

session

a formal meeting or series of meetings of an organization such as a parliament or a law court

세션을 캠브릿지 영어사전으로 검색하면 공식적인 미팅 혹은 일련된 미팅들이라는 정의가 나온다.

 

IT에서 사용하는 세션도 처음에 세션이라는 단어를 사용한 이유는 세션의 역할이 서버와 클라이언트 양방향 통신이 컴퓨터들의 미팅이라고 생각해서 사용한게 아닐까 싶다.

 

세션으로 구글링을 하면 많이 나오는 설명들로는

  • HTTP의 Stateless의 단점을 극복하기 위한 서버저장소
  • 일련의 요구를 하나의 상태로 보고 상태를 일정하게 유지시키는 기술
  • 여러페이지에 걸쳐 사용되는 사용자 정보를 저장하는 방법

등이 있다. 모두 맞는 말들이지만, 조금씩 관점이 다르게 느껴져서 이해하는데 개념이 명확히 잡히지 않았다.

 

그러다 위키백과의 세션 설명을 찾아보게 되었는데, 추상적이지면 개념적으로 가장 이해가 잘 되는 것 같았다.

컴퓨터 과학 및 네트워킹에서 세션은 시간으로 구분된 양방향 링크이며 tcp/ip 프로토콜의 실용적인(상대적으로 높은) 계층으로, 둘 이상의 통신 장치 또는 종단 간에 대화식 표현 및 정보 교환을 가능하게 합니다. -위키백과-

세션은 클라이언트와 서버의 `양방향 링크'이며, 이를 시간을 제약으로 구분해놓은 것이다.

그 이유는 대화식 표현과 정보교환을 가능하게 하여 불필요한 중복된 정보전달을 피하고 더 많은 정보를 활용할 수 있게 하는 것이다.

 

구현

그리고 이를 구현하는 방법도 여러가지가 있는데

  • 소프트웨어 구현
    - 자식 프로세스, 멀티스레딩 등으로 구현할 수도 있으며
  • 서버사이드 웹 세션
    - 우리가 흔히 공부하는 HTTP 세션 방식으로 서버측에서 구현할 수도 있으며
  • 클라이언트 사이드 웹 세션
    - 쿠키도 사실 클라이언트 사이드의 웹 세션의 구현방식인 것이다.

지금까지 구글링을 하면서 쿠키와 세션을 대비하면서 바라보았는데, 위키백과의 쿠키와 세션에 대한 설명은 세션의 더 큰 개념인 `양방향 링크'의 각 사이드의 구현체로 보는 것이었다.

 

우리가 웹애플리케이션을 구현할 때 사용하는 세션은, WAS에서 구현하며 세션이 설정되면 어원과 연결하여 비유하자면

미팅(양방향 링크의 세션)이 진행되는 회의실(서버사이드 웹 세션)의 방번호(JSessionID)등을 쿠키로 사용자들에게 전달해주고, 사용자들은 미팅에 참여했다가 집에갔다가 다시 와도, 회의실에 책같은 것을 두고 다녀서 가볍게 다닐 수 있는 것이다. 

 

위에서 언급한 이슈는 A대학에서 미팅이 진행된 회의실의 방번호를 받아서 클라이언트에 저장해놓았는데

A대학이 없어지고 B대학을 세워놓고 A대학의 회의실을 찾고 있어서 발생한 문제였던 것 같다.

 

참고

https://en.wikipedia.org/wiki/Session_(computer_science)

 
 
 

'IT > WEB' 카테고리의 다른 글

[Nginx] Nginx Architecture  (0) 2023.04.11
[Nginx] Nginx 소개  (0) 2023.04.05
[Web] URL Encoding  (0) 2022.07.17

+ Recent posts