본문 바로가기
일반 학습/코딩 테스트

[프로그래머스] 조이스틱

by StelthPark 2022. 3. 18.

처리순서

풀이

알파벳 위아래로 움직여 최소 움직임을 찾는값과 name으로 들어온 값에서 왼쪽, 오른쪽으로 이동하는 최솟값을 찾아야한다. 먼저 calc함수를 만들어 name에 들어온 각 알파벳마다 A를 기준으로 위로 또는 아래로 움직여 해당하는 알파벳이 만들어질 때 움직인 거리를 계산하기 위해 아스키코드를 사용하였다.

function calc(i) {
  let start = 90 - i.charCodeAt(0) + 1;
  let end = i.charCodeAt(0) - 65;
  let minValue = Math.min(start, end);
  return minValue;
}

i로 알파벳이 하나들어오면 해당 알파벳은A를 기준으로 얼마나 움직이여할지 위로 움직일때와 아래로 움직일때의 최소값을 반환하게 된다. 알파벳마다 거리가 반환된 값은 upDownCount에 저장시킨다.

 

이제 좌 우로 움직이는 최소거리를 구해야하는데 한방향으로 쭉 갔을때 거리는 최소 이 name길이의 -1이다.

이 거리와 아래 거리처럼 최소거리가 또 존재하게 된다.

여기서 1번을의 최소거리를 구하기위해 0번부터 for문을 돌리는데 기준인덱스보다 1이큰 자리가 A로 쭉이어디지는지 이어진다면 NAME길이보다 적게될때까지 INDEX+1를 한 값을 계속올려 준다.

기준인덱스와 NAME길이에서 최종 INDEX+1한 값을 빼준 값이 시작과 뒷시작 수가 된다. 여기서 시작인덱스는 startOfA, 뒤에서 바꿀 갯수는 length - endOfA이다. 각각 leftRightCountList에 담아주기전 위 메모장에서 보면 ABAB가 갔다가 돌아오기때문에 *2 를 해주고 뒤에 BA는 한번이니 그냥 더해주어 담아주면된다.

 

 

난이도2치고 어려웠고 알파벳을 위아래 구하는건 생각이 잘났고 처음에는 그냥 앞으로 쭉 진행하고 뒤로 쭉 진행하게 하는 순서를 계산했지만 중간에 갔다가 다시 돌아와 뒤로 가는경우가 더 적은 순서횟수를 가질 수 있다는 생각이 안났고..고민을 많이했던거 같다.

 

function calc(i) {
  let start = 90 - i.charCodeAt(0) + 1;
  let end = i.charCodeAt(0) - 65;
  let minValue = Math.min(start, end);
  return minValue;
}

function solution(name) {
  var answer = 0;
  const length = name.length;
  let upDownCount = 0;
  let leftRightCountList = [length - 1]; //한 방향으로 쭉 갔을 때
  for (let i = 0; i < length; i++) upDownCount += calc(name[i]);
  for (let startOfA = 0; startOfA < name.length; startOfA++) {
    let endOfA = startOfA + 1;
    while (endOfA < length && name[endOfA] === "A") endOfA++;
    const [moveToStartOfA, moveToEndOfA] = [startOfA, length - endOfA];
    leftRightCountList.push(moveToStartOfA * 2 + moveToEndOfA); // 0 -> A.., 0 <- A.., ..A <- -1
    leftRightCountList.push(moveToEndOfA * 2 + moveToStartOfA); //시작부터 뒤로 가는 경우 ..A <- -1, ..A -> -1, 0 -> A..
  }
  answer = upDownCount + Math.min(...leftRightCountList);
  return answer;
}​

댓글