문제 설명
- 숫자를 한명씩 돌아가면서 말하는구조, 여기서 특이한점은 11 이라면 이걸 2명이서 나눠서 말하는 구조
- 꼭 10진수만있는게 아니라 주어진 진수에 맞게 수행하면됨
- t번 말할때까지 그 숫자 하나씩 다 뭉쳐서 이제 길이가t가 됐을때 끝 ! 그걸 출력하면 정답
예를들어
전체 숫자: 0, 1, 10, 11, 100, 101, 110, 111
한 자리씩 나눔: 0, 1, 1, 0, 1, 1, 1, 0, ...
사람별 순서: [튜브(1번), 다른 사람(2번)]
튜브가 말해야 하는 숫자: 0, 1, 1, 1 (1번친구 추적하면 0 , 1 , 1 ,1 말했음 )
결과 : "0111"
문제 접근
- 10진법으로 반복문을 시작하면서 하나씩 올려주면서 해당 진수 처리해주면 될 것 같기도 ?
- 번갈아가는거만 카운팅잘해주기
문제풀이
처음에는 enumerated()를 통해서 idx도 같이 추출을 하면서, 거기서 m을 한 것으로 순서를 체킹해줬는데, 이게 길이가 1인 경우에는 계속 한사람만 말하게 되더라! 그래서 counting_num이라는 거를 만들어줘서 while문밖의 전역변수로 관리해줬다.
while tube_arr.count < t { // 길이가 t완성되면 끝 !
let saying_num = String(current_num, radix: n) // 현재 불러야하는 것
for (idx, value) in saying_num.enumerated() {
// print(counting % m)
if counting % m == p - 1 {
// print(saying_num)
tube_arr.append(String(value))
}
counting += 1
}
current_num += 1
}
다음 제출코드
여기에서 문제는
0111
나와야하는데,01110
이 나오는 문제가 있었다. 분명히
while tube_arr.count < t
로 제한조건을 걸어줬는데 왜 이렇게 됐지? 해서 디버깅한 결과, 이게 for문 안에서 남은게 있으면 더 체킹을 하고 있더라! 그래서 안에서 조건에따라 t길이가 충족되면 바로 break해주도록 수정을 해줬다.
func solution(_ n: Int, _ t: Int, _ m: Int, _ p: Int) -> String {
var current_num = 0
var tube_arr = [String]()
var counting = 0
while tube_arr.count < t { // 길이가 t완성되면 끝 !
let saying_num = String(current_num, radix: n) // 현재 불러야하는 것
for (idx, value) in saying_num.enumerated() {
// print(counting % m)
if counting % m == p - 1 {
// print(saying_num)
tube_arr.append(String(value))
}
counting += 1
}
current_num += 1
}
return tube_arr.reduce("") { $0 + $1 }.uppercased() // t길이를 string으로 바꿔주기 !
}
최종 제출 코드
func solution(_ n: Int, _ t: Int, _ m: Int, _ p: Int) -> String {
var current_num = 0
var tube_arr = [String]()
var counting = 0
while tube_arr.count < t { // 길이가 t완성되면 끝 !
let saying_num = String(current_num, radix: n) // 현재 불러야하는 것
for (value) in saying_num {
if tube_arr.count == t {
break
}
// print(counting % m)
if counting % m == p - 1 {
// print(saying_num)
tube_arr.append(String(value))
}
counting += 1
}
current_num += 1
}
return tube_arr.reduce("") { $0 + $1 }.uppercased() // t길이를 string으로 바꿔주기 !
}
채점 결과
정확성: 100.0
합계: 100.0 / 100.0
생각보다 쉽게 풀렸던 것 같다. String(num,radix:바꾸고싶은 진수)사용하면 숫자를 쉽게 바꿀 수 있어서 무리없이 풀 수 있었던 것 같다.
타인의 코드
func solution(_ n: Int, _ t: Int, _ m: Int, _ p: Int) -> String {
let count = t*m
var values: [String] = []
var number = 0
while values.count < count {
values += String(number, radix: n).compactMap({ String($0).uppercased() })
number += 1
}
return stride(from: p - 1, to: count, by: m).reduce("", { $0 + values[$1] })
}
values 배열의 길이를 직관적인 t로 하지않고, m으로해서 사람수까지 거른다음에 stride활용해주는게 새로운 접근이라 신기했다.
특히 이부분stride(from: p - 1, to: count, by: m)
좀 더 알아보자면 ...
범위안에서 반복처리를 해주는 함수라고 생각하시면 될 것 같다.
역순서 배열을 만들 때 사용했던 것인데, p-1 순서부터 시작해서, 카운트까지 m주기로 깡총뛰면서 체킹하는거니까 m순번 도는게 깔끔하게 가능하다. 항상 %로 인덱스 계산하는게 왜인지모르게 나한텐 어려운데, 이런방식으로 트라이 해보는것도 좋을 듯 !