Coding (164)

02
09

선택이 힘든 당신을 위한 완벽한 매뉴를 준비했습니다!

 

1. 목록의 유스케이스

  • 유저는 어떨 때 목록을 사용하려고 할까?
    1. 전반적인 개요
      • 전체적인 페이지의 인상을 한 번에 파악할 수 있다.
    2. 항목 브라우징
      • 어떻게 메뉴를 정렬해서 볼지 결정할 수 있다. 혹은, 뒤로 돌아가는 등의 다른 항목으로의 이동할 때 도 사용할 수 있다.
    3. 특정 항목의 검색
      • 무언가 기능을 찾을 때 사용한다. 유저의 액션을 줄여 최대한 빠르고 정확하게 메뉴를 보여주는 것도 중요하다.
    4. 정렬과 필터링
      • 요소들의 정렬이나 필터로 필요한 항목을 빠르게 찾을 수 있게 만든다.
    5. 항목 재정렬, 추가, 삭제
      • 유저의 저장목록을 보여주거나, 선택과 추가, 혹은 삭제가 필요할 때도 유용하다. 음악 재생앱의 플레이 리스트를 생각하자!

 

2. 정보의 구조 떠올리기

  • 매뉴를 구성하고자 할 때, 생각해야 할 것들에 대해 알아보자
    1. 길이
      • 메뉴의 사이즈가 요소들을 다 넣을 수 있는가? 혹은, 잘리는 부분도 있을까?
      • 그렇다면, 페이지에서 메뉴의 사이즈는 어떤가? 너무 크지는 않을까?
    2. 순서
      • 알파벳순이나 숫자, 수정시간 등 정렬하는 방식이 있나?
      • 정렬되는 규칙은 유저가 필요하고 찾는 기능에 맞게 되어있는가?
    3. 그룹 핑
      • 요소들이 한 번에 알아보기 쉽게 묶여있을까?
      • 계층들이 나눠져서 카테고리를 알아보기도 편할까?
    4. 항목의 종류
      • 유저가 찾는 종류의 카테고리가 다 있는가?
      • 이미지 등으로 카테고리를 한 번에 구분이 가능한가?
      • 너무 복잡하지 않은가?
    5. 인터랙션
      • 항목을 전부 다 보여줄 것인가? 아니면 가려서 대표적인 것만 일단 노출시킬 것인가?
      • 유저의 쓰임에 따라 버튼이 편할까? 링크가 편할까?
    6. 동적 행동
      • 유저는 목록의 변화를 실시간으로 볼 수 있나?

 

3. 패턴

  1. 2 분할(Two-Panel Selector) 또는 분할 화면(Split View)
    • 무엇인가요?
      • 화면을 두 개로 갈라버린다. 가로든 새로든 상관없다.
      • 목록과 선택한 항목을 중요하게 보여줘야 할 때 사용할 수 있다. 예를 들어, 음악 재생 앱의 경우 노래를 클릭하면 그 노래에 앨범 아트와 다른 쪽에는 내가 듣고 있는 플레이 리스트를 함께 보여주는 경우가 이에 해당한다.
      • 관행적인 디자인이다. 그만큼 친숙하다.
      • 유저가 시선을 빠르게 바꾸기 용의 하다.
    • 어떻게 활용할까요?
      • 선택할 수 있는 목록은 상단이나 왼쪽에, 상세 내용은 하단이나 오른쪽에 배치한다. 왼쪽에서 오른쪽으로 언어를 읽고 사용하는 수많은 국적의 유저들이 그것이 친숙하기 때문이다.
      • 시각적으로 보기 편하게 만드는 것이 좋다. 배경색과 너무 반전되는 색을 사용하거나 하면 잘 안 뜨인다.
  2. 단일 화면 상세 진입(One-Window-Drilldown)
    • 무엇인가요?
      • 하나의 화면에서 목록을 보여주고, 목록을 선택하면 큰 화면으로 새부사항을 보여준다.
      • 목록과 상새화면이 나눠져 있지 않다. 예를 들어, E-mail을 생각하면 정확하다.
      •  모바일 화면을 디자인할 때 유용하다. 모바일 디바이스의 작은 화면에서 모든 정보를 한 번에 보기 쉽지 않기 때문이다.
    • 어떻게 활용할까요?
      • 최신의 디자인이 유리하다. 요즘은 섬네일 그리드나 인스타그렘의 피드 같은 형식이 많은 유저들에게 친숙하다.
      • 꼭 뒤로 가기와 취소 버튼을 만들자. 없으면 슬프다.
      • 위계를 유용하게 사용할 수 있다. 내부에 들어가거나 혹은 평행으로 이동하여 계층적인 효과를 활용할 수 있다.
  3. 포괄 목록(List Inlay)
    • 무엇인가요?
      • 한 줄에 모든 요소를 넣는다.
      • 목록 하나에 많은 정보를 담을 수 있다. 예를 들어, 대중교통 예매를 할 때 다양한 정보를 한 번에 담아서 시간별로 펼쳐 목록으로 보여주는 모습을 볼 수 있다.
    • 어떻게 활용할까요?
      • 2 분할 계층과 같이 사용해서 3분할로 사용도 가능하다.
      • 햄버거 버튼 등을 이용해 목록을 펼쳤다가 접었다가 하면 더 깔끔할 수 있다.
      • 이때, 전환 애니메이션으로 유저의 방향 감각을 유지시켜 주자.
  4. 카드(Cards)
    • 무엇인가요?
      • 가장 인기 있는 UI.
      • 사이즈가 반응형으로 조절되고 이미지를 크게 보여줄 수 있는 예를 들어, 우리 휴대폰에 있는 사진첩을 생각하면 된다.
    • 어떻게 활용할까요?
      • 전부 비슷한 동작이 필요한 요소들이 있을 때 유리하다. 사진을 누르면 크게 볼 수 있으며, 전부 비슷한 사이즈의 텍스트가 있고, 세부적으로 조절할 수 있는 편집기능이 있는 것이 모든 사진이 같으므로 유리한 디자인이라고 할 수 있다.
      • 사이즈가 요소별로 다르더라도 조절해서 나열할 수 있다.
      • 사용자의 액션을 생각해서 가장 빠르고 정확히 원하는 일을 할 수 있게 만들어야 한다.
      • 가로나 세로배치 혹은, 텍스트의 길이 등을 고려한 요소의 정렬이 중요하다. 시각적으로 보여주는 부분이 큰 패턴이기 때문이다.
  5. 섬네일 그리드
    • 무엇인가요?
      • 이미지를 특정한 기준에 따라 정렬하고 N X M의 배열로 보여준다.
      • 이것도 카드와 비슷하지만 정렬하는 기준이 조금 다르다. 예를 들어, 사진첩에서 찍은 날짜나 찍은 장소별로 정렬하면 섬네일 그리드로 패턴이 바뀐다.
    • 어떻게 활용할까요?
      • 정렬 기준이 명확할 때 사용하기 좋다.
      • 꽤 많은 항목을 표현하기 유리하다. 정렬되는 이미지의 사이즈가 같기 때문이다.
      • 그렇기 때문에 모바일에서도 누르기 쉽다.
      • 세로, 가로의 크기가 동일할 때 사용하기 좋다. 아니면 이미지가 어색하게 잘리거나 할 수 있다.
  6. 캐러셀(Carousel)
    • 무엇인가요?
      • 시각적으로 표현해야 할 것이 있을 때, 이미지를 앞, 뒤로 당겼다가 밀면서 스와이프 할 수 있는 패턴이다.
      • 목록에 시각적으로 대표적으로 보여줄 수 있는 시각적 표현이 있을 때 사용하기 좋다. 예를 들어, OTT 서비스의 영화나 드라마의 포스터라거나 음악 앱의 앨범 아트 등을 밀면서 선택도 가능한 패턴을 생각하면 좋다.
    • 어떻게 활용할까요?
      • 일단 보기 예쁘다. 요소를 매력적으로 표현하기 좋다.
      • 다음 항목이나 이전 항목을 함께 볼 수 있다.
      • 공간이 좁으면 쓰기 좋다. 밀고 당기면 계속 요소들을 보여줄 수 있다.
      • 세로 비율이 길어야 한다. 가로가 길면 어색해 보인다.
      • 가로 스크롤이 있는 위젯은 섬네일은 가로로 배치한다.
  7. 페이지네이션(Pagination)
    • 무엇인가요?
      • 매우 긴 목록을 보여줄 때 유리하다. 예를 들어, 인터넷 게시판 등의 글 목록을 말한다.
      • 검색 기능이 거의 필수이다. 요소가 많을 때 사용하기 때문이다.
      • 서버 쪽의 통신에도 유리하다. 조금씩만 정보를 가져와서 일단 보여주고 다음 유저의 행동에 의해 다음 정보를 요청하기 때문이다.
    • 어떻게 활용할까요?
      • 일단 몇 개의 요소를 보여줄지 정하는 것이 중요하다.
      • 그러므로, 유저가 사용하는 기기의 사이즈가 또 중요하다. 가독성이 떨어지면 의미가 없다.
      • 어떻게 유저의 액션에 따라 다음 페이지로 넘어갈 수 있을지를 확실히 보여주고 간단한 액션으로 넘길 수 있게 한다.
      • 가장 중요한 것은 '첫 화면'이다. 처음 화면에서 유저가 머무는 시간이 많기 때문이다. 그래서 처음 화면에서 필요한 정보를 찾을 수 있게 하는 것이 유리하다.
  8. 항목으로 즉시 이동하기(Jump to Item)
    • 무엇인가요?
      • 최상단에 input을 만들어 검색을 가능하게 하고 한쪽 목록에서 요소를 누르면 한 번에 이동하게 한다.
      • 예를 들어, 액셀이나 VS code의 파일 탐색기를 생각하면 좋다.
      • 많은 목록들을 보여주고, text나 제목의 중요성이 있을 때 사용하기 좋다.
    • 어떻게 활용할까요?
      • 많은 목록을 보면서 정확한 요소를 찾을 때 즉, 전문가들이 사용하기 좋은 패턴이다.
      • 키보드에서 모든 작업을 가능하게 한다.

'Coding > UX Insight' 카테고리의 다른 글

동작과 명령의 패턴  (0) 2022.02.11
동작과 명령  (0) 2022.02.10
내비게이션 패턴  (0) 2022.01.25
모바일 디자인의 패턴  (0) 2022.01.24
모바일 인터페이스  (0) 2022.01.21
COMMENT
 
02
08

진짜 개발자는 코드보다 작명에 더 오랜시간을 사용합니다.

1. 문제의 발단

항상 생각했던 문제였다. 자연스럽게 알고 있는 명명규칙을 사용하고 있었는데, 매번 헷갈렸다. 따로 공부를 하기보다는 다른 사람들이 짠 코드나 레퍼런스 등을 보고 알게 된 것일 것이다. 그래서 이 기회에 확실히 알고 넘어가려고 한다.

 

2. 작명의 중요성

  • 코드 가독성에 가장 중요한 요소가 된다.
  • 예를들어, 변수명을 'a'라고 해놨다. 아무리 const로 재선언, 재할당을 막아도 분명 겹칠 수 있고, 가장 중요한 건 어떤 변수인지 알 수가 없다.

 

3. 작명 규칙

  1. 변수와 함수는 '카멜 케이스'를 사용한다.
    • 각 네이밍 컨벤션을 알아보자. 
      1. 카멜 케이스(camelCase) : 첫번째 문자를 소문자, 띄어쓰기 대신에 대문자를 사용한다.
      2. 파스칼 케이스(PascalCase) : 각 어절마다 대문자를 사용한다.
      3. 스네이크 케이스(snake_case) : 띄어쓰기 대신 '_' (언더바)를 사용한다.
  2. 약어(ex: HTML 등)는 대문자 '스네이크 케이스'를 사용한다.
  3. 생성자 함수는 대문자의 '카멜 케이스'를 사용한다.
    • 생성자 함수 : new Array 처럼 유사한 객체를 여러 개 만들 때 사용할 수 있는 함수. 실행시킬 때는 'new'와 함께 사용한다.
  4. 상수의 이름에서 어절을 띄울때나 Private 변수는 '_' (언더바)로 시작한다.
  5. 이미 선언, 할당이 되어 있는 '예약어'(ex: if, for, const)등을 선언하지 않는다.
  6. 전역 변수 선언인 'var'을 사용하지 않는다.
  7. 선언된 이름이 뜻하는 바가 없는 암묵적인 변수(ex: foo, good, hi 등)를 사용하지 않는다.
  8. 폴더의 이름은 '-' (하이픈)을 이용해 띄어쓰기를 표현하고, 소문자를 사용한다.

 

4. 덤으로 알아보는 CSS 규칙

  1. SASS나 LESS에서는 변수를 선언할 수 있다. 이때, BEM 페턴을 사용하기 좋다.
    • BEM(Block Element Modifier) : 각 요소들의 class를 
      • B -  Block : 가장 큰 컨테이너를 말한다. class 네이밍 규칙은 소문자인 한 단어로 만든다. 그리고 id는 사용하지 않는다. 마지막으로, 다른 block 요소의 자식이 될 수 없다.
      • E - Element : block 요소안의 요소이다. class 네이밍 규칙은 "__" (언더바 두 개)로 띄어쓰기를 구분하며, 블록 이름을 앞에 적고 block__element처럼 사용한다. 
      • M - Modifier : 블럭이나 엘리먼트 요소의 상태를 변경한다. class 네이밍 규칙은 block의 상태를 변경할 때는 "--" (하이픈 두 개), element의 상태를 변경할 때에는 block--element--modifier처럼 사용한다.
  2. 간단한 프로젝트일 경우, '-'을 이용해서 띄여쓰기만 구분하기도 한다.
COMMENT
 
02
07

1. 문제 설명

 

코딩테스트 연습 - [1차] 다트 게임

 

programmers.co.kr

카카오톡에 뜬 네 번째 별! 심심할 땐? 카카오톡 게임별~

(예쁘니까 뺴지 않겠읍니다)

카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다. 다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다.
갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다. 다트 게임의 점수 계산 로직은 아래와 같다.

  1. 다트 게임은 총 3번의 기회로 구성된다.
  2. 각 기회마다 얻을 수 있는 점수는 0점에서 10점까지이다.
  3. 점수와 함께 Single(S), Double(D), Triple(T) 영역이 존재하고 각 영역 당첨 시 점수에서 1제곱, 2제곱, 3제곱 (점수1 , 점수2 , 점수3 )으로 계산된다.
  4. 옵션으로 스타상(*) , 아차상(#)이 존재하며 스타상(*) 당첨 시 해당 점수와 바로 전에 얻은 점수를 각 2배로 만든다. 아차상(#) 당첨 시 해당 점수는 마이너스된다.
  5. 스타상(*)은 첫 번째 기회에서도 나올 수 있다. 이 경우 첫 번째 스타상(*)의 점수만 2배가 된다. (예제 4번 참고)
  6. 스타상(*)의 효과는 다른 스타상(*)의 효과와 중첩될 수 있다. 이 경우 중첩된 스타상(*) 점수는 4배가 된다. (예제 4번 참고)
  7. 스타상(*)의 효과는 아차상(#)의 효과와 중첩될 수 있다. 이 경우 중첩된 아차상(#)의 점수는 -2배가 된다. (예제 5번 참고)
  8. Single(S), Double(D), Triple(T)은 점수마다 하나씩 존재한다.
  9. 스타상(*), 아차상(#)은 점수마다 둘 중 하나만 존재할 수 있으며, 존재하지 않을 수도 있다.

0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.

 

2. 제한 사항

  • 위의 점수 계산 로직 참고

 

3. 입출력 예제

예제 dartResult answer 설명
1 1S2D*3T 37 11 * 2 + 22 * 2 + 33
2 1D2S#10S 9 12 + 21 * (-1) + 101
3 1D2S0T 3 12 + 21 + 03
4 1S*2T*3S 23 11 * 2 * 2 + 23 * 2 + 31
5 1D#2S*3S 5 12 * (-1) * 2 + 21 * 2 + 31
6 1T2D3D# -4 13 + 22 + 32 * (-1)
7 1D2S3T* 59 12 + 21 * 2 + 33 * 2

 

4. 나의 접근 방식

  • 일단, 10을 제외한 모든 점수들은 String이라도 1자리이라는 것을 이용해 숫자로 바꾼 배열을 만들면 되겠다고 생각하였다.
  • splice를 이용해 1과 0이 연달아 나올 때 빼주고, 10을 처리한 새로운 배열을 만들어 주었다.
  • 하지만 '10S10S10S'와 같이 10이 연달아 나오는 경우, index로 처리하려고 하였기 때문에 undefined가 들어간다. 실패!
실패한 코드
function solution(dartResult) {
    // arr에 숫자는 숫자대로 문자는 문자로 나눠 넣어준다.
    let arr = [];
    for(let i = 0; i < dartResult.length; i++) {
        if(dartResult[i] === "0") arr.push(0)
        else if(Number(dartResult[i])) arr.push(Number(dartResult[i]))
        else arr.push(dartResult[i])
    }

    // result에 10을 splice로 1이후 0이 따라 나올때 잘라 합쳐서 넣어준다.
    // 하지만 splice는 첫번째에 1이 나올경우, i - 1을 할 수 가 없으므로 사용할 수 없다.
    let result = [];
    for(let i = 0; i < arr.length; i++) {
        if(arr[i] === 1 && arr[i + 1] === 0) {
            arr.splice(i, 2)
            arr.splice(i - 1, 1, 10)
        }

        if(arr[i] === "S") {
            result.push(arr[i - 1]);
        }

        if(arr[i] === "D") {
            result.push(Math.pow(arr[i - 1], 2));
        }

        if(arr[i] === "T") {
            result.push(Math.pow(arr[i - 1], 3));
        }

        if(arr[i] === "*") {
            result[result.length - 1] *= 2;
            result[result.length - 2] *= 2;
        }

        if(arr[i] === "#") {
            result[result.length - 1] *= -1; 
        }
    }
    return result.reduce((acc, cur) => acc + cur);
}​
  • 그래서, 먼저 10만 모아서 다시 배열에 넣어주고 그 10을 처리한 배열을 따로 문자와 합쳐 계산한 다음에 점수 계산이 끝난 배열을 전부 더해주기로 하였다.

 

5. 결과

function solution(dartResult) {
    // arr를 숫자와 문자를 분리하는 것은 같다.
    let arr = [];
    for(let i = 0; i < dartResult.length; i++) {
        if(dartResult[i] === "0") arr.push(0)
        else if(Number(dartResult[i])) arr.push(Number(dartResult[i]))
        else arr.push(dartResult[i])
    }


    // numArr에 10을 처리한 결과를 넣을 것이다.
    let numArr = [];
    for(let i = 0; i < arr.length; i++) {
        // 만약, 1과 0이 연달아 나온다면,
        if(arr[i] === 1 && arr[i + 1] === 0) {
            // 10을 처리하여 배열에 넣고
            numArr.push(10)
            // 분리해 놓은 배열에 2칸 즉, 1과 0을 제거한다.
            arr.splice(i, 2)
        }
        // 일반적인 한자리 숫자가 나올때는 그냥 넣어준다.
        numArr.push(arr[i])
    }

    // 문자열을 이용해 점수를 계산할 배열을 만든다.
    let resultArr = [];
    for(let i = 0; i < numArr.length; i++) {
        // S가 나오면 S가 나온 한자리 앞의 요소를 더해준다.
        if(numArr[i] === "S") {
            resultArr.push(numArr[i - 1]);
        }
        
        // D가 나오면 D가 나온 한자리 앞의 요소를 제곱하여 더해준다.
        if(numArr[i] === "D") {
            resultArr.push(Math.pow(numArr[i - 1], 2));
        }

        // T가 나오면 T가 나온 한자리 앞의 요소를 3제곱 하여 더해준다.
        if(numArr[i] === "T") {
            resultArr.push(Math.pow(numArr[i - 1], 3));
        }
        
        // *가 나온다면 앞과 앞앞 요소를 제곱하여 준다. 만약, 0이나, 앞앞자리 요소가 없더라도,
        // 0이 들어가기 때문에 상관없다.
        if(numArr[i] === "*") {
            resultArr[resultArr.length - 1] *= 2;
            resultArr[resultArr.length - 2] *= 2;
        }

        // #가 나온다면 한자리 앞의 수를 -1을 곱해 빼준다.
        if(numArr[i] === "#") {
            resultArr[resultArr.length - 1] *= -1; 
        }
    }
    // 문자열과 점수 계산이 끝난 배열을 전부 더해준다.
    return resultArr.reduce((acc, cur) => acc + cur);
}

 

6. 개선점이 있다면?

  • 정규표현식으로 풀 수 도 있다고 한다! 하지만 정규표현식 사용이 서툴다. 조금 더 공부가 필요할 것 같다.
  • 선언된 배열들의 이름이 마음에 안 든다. 확실히 구분이 어렵다.
COMMENT
 
02
06

1. 문제 설명

 

코딩테스트 연습 - 크레인 인형뽑기 게임

[[0,0,0,0,0],[0,0,1,0,3],[0,2,5,0,1],[4,2,4,4,2],[3,5,1,3,1]] [1,5,3,5,1,2,1,4] 4

programmers.co.kr

게임개발자인 "죠르디"는 크레인 인형뽑기 기계를 모바일 게임으로 만들려고 합니다.
"죠르디"는 게임의 재미를 높이기 위해 화면 구성과 규칙을 다음과 같이 게임 로직에 반영하려고 합니다.

게임 화면은 "1 x 1" 크기의 칸들로 이루어진 "N x N" 크기의 정사각 격자이며 위쪽에는 크레인이 있고 오른쪽에는 바구니가 있습니다. (위 그림은 "5 x 5" 크기의 예시입니다). 각 격자 칸에는 다양한 인형이 들어 있으며 인형이 없는 칸은 빈칸입니다. 모든 인형은 "1 x 1" 크기의 격자 한 칸을 차지하며 격자의 가장 아래 칸부터 차곡차곡 쌓여 있습니다. 게임 사용자는 크레인을 좌우로 움직여서 멈춘 위치에서 가장 위에 있는 인형을 집어 올릴 수 있습니다. 집어 올린 인형은 바구니에 쌓이게 되는 데, 이때 바구니의 가장 아래 칸부터 인형이 순서대로 쌓이게 됩니다. 다음 그림은 [1번, 5번, 3번] 위치에서 순서대로 인형을 집어 올려 바구니에 담은 모습입니다.

만약 같은 모양의 인형 두 개가 바구니에 연속해서 쌓이게 되면 두 인형은 터뜨려지면서 바구니에서 사라지게 됩니다. 위 상태에서 이어서 [5번] 위치에서 인형을 집어 바구니에 쌓으면 같은 모양 인형 두 개가 없어집니다.

크레인 작동 시 인형이 집어지지 않는 경우는 없으나 만약 인형이 없는 곳에서 크레인을 작동시키는 경우에는 아무런 일도 일어나지 않습니다. 또한 바구니는 모든 인형이 들어갈 수 있을 만큼 충분히 크다고 가정합니다. (그림에서는 화면표시 제약으로 5칸만으로 표현하였음)

게임 화면의 격자의 상태가 담긴 2차원 배열 board와 인형을 집기 위해 크레인을 작동시킨 위치가 담긴 배열 moves가 매개변수로 주어질 때, 크레인을 모두 작동시킨 후 터트려져 사라진 인형의 개수를 return 하도록 solution 함수를 완성해주세요.

 

2. 제한 사항

  • board 배열은 2차원 배열로 크기는 "5 x 5" 이상 "30 x 30" 이하입니다.
  • board의 각 칸에는 0 이상 100 이하인 정수가 담겨있습니다.
    • 0은 빈 칸을 나타냅니다.
    • 1 ~ 100의 각 숫자는 각기 다른 인형의 모양을 의미하며 같은 숫자는 같은 모양의 인형을 나타냅니다.
  • moves 배열의 크기는 1 이상 1,000 이하입니다.
  • moves 배열 각 원소들의 값은 1 이상이며 board 배열의 가로 크기 이하인 자연수입니다.

 

3. 입출력 예제

borard movees result
[[0,0,0,0,0],[0,0,1,0,3],[0,2,5,0,1],[4,2,4,4,2],[3,5,1,3,1]] [1,5,3,5,1,2,1,4] 4

 

4.  나의 접근 방식

  • 정말 게임을 하듯이 하나의 배열에 크레인이 뽑은 요소를 따로 넣어 둬야 겠다고 생각했다.
  • 한번에 처리하기 복잡하므로, 크레인이 요소를 뽑는 과정을 하나 만들고, 연속되면 지워 질 수 있는 과정을 다른 문제로 보았다.
  • 그렇게 문제를 분리하기 위해 함수를 두개 사용할 수 있다.

 

5. 결과

function solution(board, moves) {
    let arr = [];
    let result = 0;
    // moves의 각 요소들을
    moves.map(el => {
        // board에 맞게 크레인으로 뽑는 함수를 만든다.
        let temp = pickup(board, el - 1);
        // 민약 뽑아낸 요소가 있다면,
        if(temp){
            // 뽑아낸 요소를 확인하여 연속으로 똑같은 요소가 들어간 것 인지를 확인하고
            // 연속해서 들어 갔다면
            if(arr[arr.length - 1] === temp){
                // 제거하면서 result를 지운만큼 올려 준다.
                arr.pop();
                result += 2;
            } else {
                // 겹치지 않는다면 그대로 넣어둔다.
                arr.push(temp);
            }
        }
    });
    return result;
}

function pickup(board, el){
    // board를 돌면서
    for(let i = 0; i < board.length ; i++){
        // moves의 요소를 하나씩 뽑아 1씩 뺀 숫자를 el로 받아서 0이 아니라면
        if(board[i][el] !== 0){
            // 크레인이 뽑았다는 의미가 된다.
            let temp = board[i][el];
            board[i][el]= 0;
            return temp;
        }
    }
}

 

COMMENT