Swift 프로그래머스 lv1 12

프로그래머스 Lv. 1 Swift 알고리즘 - 숫자 짝꿍

머릿속으로는 알고리즘이 뻔히 보이는데... 막상 구현하려니 코드가 점점 복잡해져서 고생한 문제이다. 심지어 시간 제한을 맞추는 것도 꽤나 빡셌다... 문제 자체는 간단하다. 두 배열 간 공통으로 쓰이는 원소들을 다시 재조합하여 가장 큰 숫자를 만드는 문제이다. 이 문제를 풀면서 생각한 논리적 흐름 X에 있는 원소와 Y에 있는 원소들 중 어떤 원소들이 겹치는지 확인한다. 겹친 원소들이 X와 Y에 각각 몇개씩 있는지 확인한다. 이렇게 dictX, dictY에 각 숫자를 Key로, 숫자의 빈도를 value로 둔다. 결국 가장 큰 수를 만들기 위해서는 1~9 사이의 숫자 중 가장 큰 숫자인 9부터 앞자리에 위치하면 된다. dictX, dictY에서 9가 두세번씩 공통으로 등장하는 경우도 있을 수 있기 때문에 "..

프로그래머스 Lv. 1 Swift 알고리즘 - 삼총사

각 배열에 있는 3가지 숫자의 합이 0이 되는 경우를 찾아주면 되는 문제이다. 입력받은 number의 원소들을 하나씩 차례대로 골라 전부 더해줬을 때 0이 되면 count를 1 추가해주면 되는 간단한 문제이다. 이 문제를 풀면서 생각한 논리적 흐름 number array에 있는 값들을 1번째 원소 + 2번째 원소 + 3번째 원소로 나누어서 더해준다. 각 더한 값들이 0이 될 경우 count를 1 추가해준다. i, j, k와 같은 인덱스들의 범위가 초과하지 않도록 신경써준다. * 코드 import Foundation func solution(_ number:[Int]) -> Int { var tempValue = 0 var count = 0 for i in 0...number.count-3 { for j ..

프로그래머스 Lv. 1 Swift 알고리즘 - 콜라 문제

콜라 문제는 몫과 나머지만 잘 활용하면 간단하게 풀 수 있는 문제였다. 빈병과 새병을 구분하여 빈병을 바꿔서 만들어진 새병 + 바꾸지 못한 기존 빈병 개수를 누적하고 이를 바탕으로 빈병 -> 새병 -> 빈병 과정을 반복하여 값을 세준다. 이 문제를 풀면서 생각한 논리적 흐름 처음 시작할 때 병은 emptyBottle에 저장한다. 새로 생기는 병(emptyBottle / a * b)을 newBottle에 저장해준다. emptyBottle을 새로 생긴 병 + 제출하지 못해 기존에 남아있던 빈병으로 정의해준다. 답은 내가 몇개의 새병을 받았는지 확인해야하므로 count에는 새로 받은 병들만 값을 누적한다. * 코드 import Foundation func solution(_ a:Int, _ b:Int, _ n..

프로그래머스 Lv. 1 Swift 알고리즘 - 옹알이(2)

이 문제는 특정 단어들을 찾아내고 그 값을 조합할 수 있느냐를 물어보는 문제이다. 문제를 보자마자 replacingOccurences가 생각났지만... 아무래도 해당 함수가 소요시간이 꽤 걸리는 함수이다 보니, 이번에는 최대한 이거말고 다른 방향으로 풀어보고자했다. 그런데 답이 안나와서... 결국 relacingOccurences를 사용했다..ㅎㅎ 이 문제를 풀면서 생각한 논리적 흐름 알고리즘을 풀면서 굉장히 중요하게 느낀 것은 예외사항을 빠르게 쳐내주는 것이었다. 그래야 데이터 수가 줄어들고 알고리즘에 필요한 비용이 기하급수적으로 줄어든다. 그래서 먼저 예외사항부터 제거해주었다. ayaaya, yeye처럼 같은 단어가 연속으로 나올 수 없기 때문에 해당 단어들이 들어가 있는 String에는 @를 치환하..

프로그래머스 Lv. 1 Swift 알고리즘 - 햄버거 만들기

2시간은 넘게 풀었는데 도저히 시간 오류 문제를 해결못한 문제다. 문제 자체는 간단하다. 1-2-3-1의 순서대로 원소를 찾아내면 된다. 찾은 원소는 날려버리고 다시 순서대로 1-2-3-1의 원소가 존재하는지 찾으면 된다. 근데 가장 큰 문제는 효율성이다. replacing을 이용했는데 계속 시간 오류가 났다. 그래서 extension도 만들고 별거 다 해봤지만 그래도 오류가 해결되지 않아 결국 replacing을 버려야겠다는 생각을 하고 구글링을 했다... 이 문제를 풀면서 생각한 논리적 흐름 타입이 String인 array에 ingredient를 묶어서 String으로 만들고 array에 1231이 포함되어 있으면 count를 올리고 1231은 ""으로 대체한다. 다만, 여기서 그냥 replacing..

프로그래머스 Lv. 1 Swift 알고리즘 - 푸드 파이트 대회

비교적 간단한 문제였다. 왼쪽과 오른쪽 값이 좌우대칭이 되게 만들면 된다. 이 문제를 풀면서 생각한 논리적 흐름 가져온 음식의 개수를 2로 나눈 값만큼 반복해서 사용하면 된다. 그 값들을 하나의 String으로 만들어서 이어준 다음 String + "0" + String.reversed() 개념을 적용하면 끝. * 코드 import Foundation func solution(_ food:[Int]) -> String { var foodSetting: String = "" for i in 1...food.count-1 { let count = food[i] / 2 if count != 0 { for _ in 1...count { foodSetting.append(String(i)) } } } let re..

프로그래머스 Lv. 1 Swift 알고리즘 - 과일 장수

시간초과 오류가 났을 때 마음이 정말 아픈데... 그럼에도 불구하고 코드를 다시 짰을때 꽤나 간결해진 코드를 보고 있자면 마음에 평안이 온다. 이게 개발자들에게만 허락된 유일한 마약일까? 문제는 쉬웠다! 이 문제를 풀면서 생각한 논리적 흐름 score의 개수가 한 박스당 들어가는 개수인 m으로 나누어 떨어지면 1 box로 볼 수 있다. 1번 테스트케이스의 경우 score가 7개고 한 박스당 4개가 들어가야하니 남은 3개는 자동으로 버려야한다. 그러므로 score.count 개수를 m으로 나눈 몫들만 남기면 된다.(= boxCount) 각 박스마다 최저 값을 구해야하는데 최대한 이익을 내기 위해서는 큰 값은 큰 값끼리, 작은 값은 작은 값끼리 들어가 있어야 유리하다. 그래서 score를 오름차순 정리해준다..

프로그래머스 Lv. 1 Swift 알고리즘 - 기사단원의 무기

알고리즘 풀면서 가장 어려운 문제가 효율성이다. 답을 찾아내는 알고리즘을 만들었지만 결국 오래 걸려서 시간 초과가 뜨면 어떤 부분을 효율화시켜야할지 고민이 깊어진다. 여러가지 방면으로 생각하다 약수의 개념에 대해서 조금 더 깊게 파보자는 생각이 들었다. 그렇게 찾게된 것이 약수의 대칭성..! 인수분해를 통해 약수를 하나하나 찾는 과정이 너무 비효율적으로 비용이 많이 들기에 값의 제곱근을 기준으로 under value의 약수가 존재한다면 대칭적인 약수 값이 존재한다는 뜻이다. 이러한 특성을 이용하여 3번째 만에 효율성 테스트를 통과했다. 이 문제를 풀면서 생각한 논리적 흐름 간단하게 생각해서 number의 약수를 인수분해를 통해 직접 하나씩 다 찾아주고 그 값을 array에 저장한다. 저장된 값들과 lim..

프로그래머스 Lv. 1 Swift 알고리즘 - 명예의 전당(1)

이번 문제는 간단했다. 글이 너무 어렵게 쓰여있어 솔직히 몇번 더 읽고 문제를 풀었는데, 역시 테스트 케이스를 보면 이해가 금방 간다. 결국 k번째까지 나오는 값들은 전부 배열에 저장해두고 k+1번째 나오는 값들을 k번까지 나왔던 값들과 비교하여 최소값은 날리고 새로운 값을 추가하면 되는 문제였다. 그리고 추가가 끝난 뒤 새롭게 최솟값을 찾아 배열에 저장하면 답을 구할 수 있었다. 이 문제를 풀면서 생각한 논리적 흐름 k번째 값까지는 전부 Array에 쌓는다. k+1번째 값부터 누적된 Array 내에 있는 원소들과 값을 비교한다. k+1번째 값이 Array를 sort해서 나온 가장 작은 숫자보다 크다면, sorteaArray 내부의 원소중 가장 작은 값을 지워준다.(sortedArray.removeLas..

프로그래머스 Lv. 1 Swift 알고리즘 - 문자열 나누기

진짜 오래 걸렸다... 풀다가 도중에 밥 먹으러 일어나니까 풀이가 생각난 케이스 아르키메데스가 목욕을 괜히 한 것이 아니다... 역시 뭐가 안될땐 가벼운 전환이 필요한가보다. 처음 문제를 풀때 잘못 시작한 부분은 그냥 맨 앞 char(=x)가 바로 뒤 char과 다를 경우 2unit을 나누어서 끊어줬던 것이다. 이러한 경우를 먼저 나누고 시작하기보다는, 앞 char과 뒤 char이 다른 경우 어떻게 해결할지에 대해서 동시에 고민하고 이 두가지 케이스르 전부 커버할 수 있는 알고리즘을 생각해야하는 것이 맞았다. 그래서 처음 테스트 케이스 1, 2번은 금방 나왔는데 3번 테스트케이스를 만족시키는 알고리즘을 찾느라 시간을 엄청 쓴거 같다. 결국 다시 원론으로 돌아와 1, 2, 3번 케이스를 모두 포함할 수 있..