드디어 마지막 회차.

남은 문제는 세문제

기초트레이닝 문제가 끝나면 어떤 도전과제가 생길지 기대된다

 

1. 그림 확대

10보다 작은 양의 정수 k만큼 2차원배열을 늘리는 문제

  var newPicture: [String] = []
  for i in 0 ..< picture.count {
    for _ in 0 ..< k {
      newPicture.append(picture[i])
    }
  }
  
  for line in 0 ..< newPicture.count {
    let arr = Array(newPicture[line])
    var newLine: [String.Element] = []
    for i in 0 ..< arr.count {
      for _ in 0 ..< k {
        newLine.append(arr[i])
      }
    }
    newPicture[line] = newLine.map({ String($0) }).joined()
  }
  
  return newPicture

세로로 늘리고 가로로늘리고를 크게 두가지로 나눠서 처리했는데 이걸 한번에 묶어서 처리를 하는게 인기가 좋나보다.... 다른답들 다 그렇게 처리가 되어있다

2. 정수를 나선형으로 배치하기

이중배열을 시계방향으로 돌아가면서 방문하는 문제이다.

class Position {
  var x: Int
  var y: Int
  init(x: Int, y: Int) {
    self.x = x
    self.y = y
  }
  init(_ copy: Position) {
    self.x = copy.x
    self.y = copy.y
  }
}
enum Direction {
  case right, left, down, up
}
func solution(_ n:Int) -> [[Int]] {
  var map: [[Int]] = Array(repeating: Array(repeating: 0, count: n), count: n)
  // 캐릭터 현재 x,y 좌표
  let position: Position = .init(x: 0, y: 0)
  var checkNumber: Int = 1
  
  func isMoveRight() -> Bool {
    let startX = position.x
    let startY = position.y
    let nextX = startX + 1
    // 맵 범위밖
    if nextX >= n {
      return false
    }
    // 이미 탐사한 지역
    if map[startY][nextX] > 0 {
      return false
    }
    return true
  }
  
  func isMoveLeft() -> Bool {
    let startX = position.x
    let startY = position.y
    let nextX = startX - 1
    if nextX < 0 {
      return false
    }
    if map[startY][nextX] > 0 {
      return false
    }
    return true
  }
  
  func isMoveDown() -> Bool {
    let startX = position.x
    let startY = position.y
    let nextY = startY + 1
    if nextY >= n {
      return false
    }
    if map[nextY][startX] > 0 {
      return false
    }
    return true
  }
  
  func isMoveUp() -> Bool {
    let startX = position.x
    let startY = position.y
    let nextY = startY - 1
    if nextY < 0 {
      return false
    }
    if map[nextY][startX] > 0 {
      return false
    }
    return true
  }
  
  func checkMap(position: Position) -> Bool {
    if map[position.y][position.x] > 0 {
      print("ERROR!!!!!")
      return false
    }
    map[position.y][position.x] = checkNumber
    checkNumber += 1
    return true
  }
  
  // 시작 위치
  _ = checkMap(position: position)
  
  // 순서 right down left up
  var direction: Direction = .right
  while true {
    
    let beforPosition: Position = .init(position)
    
    // 이동 가능 체크
    if !(isMoveRight() || isMoveLeft() || isMoveUp() || isMoveDown()) {
      break
    }
    
    // 이동
    switch direction {
    case .right:
      if isMoveRight() {
        position.x += 1
      } else {
        direction = .down
      }
    case .down:
      if isMoveDown() {
        position.y += 1
      } else {
        direction = .left
      }
    case .left:
      if isMoveLeft() {
        position.x -= 1
      } else {
        direction = .up
      }
    case .up:
      if isMoveUp() {
        position.y -= 1
      } else {
        direction = .right
      }
    }
    
    if beforPosition.x == position.x && beforPosition.y == position.y {
      continue
    }
    // 맵 수정
    _ = checkMap(position: position)
  }
  
  return map
}

이동하는걸 각 기능으로 나눠서 방향지정까지 해놨는데 

솔직히 너무 과했다 쓸모없다

이렇게 해두면 그야 탐색 순서가 달라져도 써먹을 부분이 많겠지만 너무 오버했다

게임을 구현한다고 생각하니 뭔가 필받아서 머리가 나빠졌나보다 

중간에 이동가능체크 라고 넣어둔부분은 

추가로 루프 탈출지점을 깜빡해서 나중에 넣은 부분이라 저런다만 저런건 미리 계산해두고 사용하는게 좋을듯하다 

아니 아예 인덱스부분만 골라서 숫자 올리는게 더 코드가 짧을지도 모르겠다

 

 

3. 정사각형으로 만들기

이중배열을 n형태의 배열로 만드는 문제, 줄수든 줄내의 요소수든 가장 큰값을 기준으로 0을 채워야한다

  var maxECount: Int = 0
  for e in arr {
    maxECount = max(maxECount, e.count)
  }
  
  let targetCount: Int = max(arr.count, maxECount)
  
  var resultArr: [[Int]] = Array(repeating: Array(repeating: 0, count: targetCount), count: targetCount)
  for line in 0 ..< resultArr.count {
    if line >= arr.count {
      continue
    }
    for i in 0 ..< resultArr[line].count {
      if i >= arr[line].count {
        continue
      }
      resultArr[line][i] = arr[line][i]
    }
  }
  
  return resultArr

이번에도 그냥 문제 내용대로 

가장 큰수를 구하고 해당 큰수대로 정사각형 배열을 만들어줬다

문제는 기존 배열을 늘리는거지만 새롭게 만들어준거에 복사해주는것으로 대체.

 

 

그렇게 기초 트레이닝 문제가 끝!

마지막일자꺼는 왜 5문제가 아닐까....

24일날 시작하여 대부분은 25일까지 완료를 짖고  흥미가 떨어져 도전과제로 풀리는것만 풀다보니

일자로만 11일이 걸렸다.

하루에 day가 두개씩 열리는거보면 사이트에서 노린 기초 트레이닝 일자는 대략 14일 정도 2주가 아니였을까?

"사이트의 노림수대로 일자가 끝난거야 " 라며 자신을 위로하며 기초트레이닝 문제를 마무리한다.

한 이틀 정도만 꽤나 열심히 진행했고 그후로는 그냥 한두문제씩 풀고있는데 끝이보이는것도 신기하다

1. 전국대회선발고사

모든 사람의 등수와 이 사람들의 참가 가능여부를 담은 배열 두개를 넣어 마지막 계산식을 반환하는문제

  var trueIndex: [Int] = []
  for( i,b) in attendance.enumerated() {
    if !b { continue }
    trueIndex.append(i)
  }
  var playerRanks: [Int] = []
  for i in trueIndex {
    playerRanks.append(rank[i])
  }
  playerRanks.sort()
  let top3PlayerRanks = playerRanks[0..<3]
  var top3PlayerIndex: [Int] = []
  for tRank in top3PlayerRanks {
    let index = rank.firstIndex { rank in
      rank == tRank
    }
    guard index != nil else {
      return -1
    }
    top3PlayerIndex.append(index!)
  }
  guard top3PlayerIndex.count == 3 else { return -2 }
  let a = top3PlayerIndex[0], b = top3PlayerIndex[1], c = top3PlayerIndex[2]
  return 10000 * a + 100 * b + c

문제를 읽으면서 순서대로 코드로 옴겼더니 코드가 엄청 길어졌다.

일단 답은 맞아서 타인의 답을 볼수 있게 되었는데 zip을 이용해 원본인덱스와 등수를 저장한후 정렬,필터할 생각은 못했구나

엄청 짧게 가능한거 보면 대단들하다

 

2. 두 수의 합

대학시절 1학년때 가산기 만들던거를 코드로 만들어봐라 하는 문제이다

  /**
   어떻게 할까.
   그냥 더해버리면 Int최대값을 넘어버린다, uint로 하면되지 않을까 했지만 안되고, longlongint로 하면되지않나? uint64도 넘어버리나보다.
   문자열을 잘라서 일부분씩 더하고 넘어가는 자리만 따로 구해서 더하는 방식으로 가야겠다.
   0. 네자리수의 문자열을 int형으로 변환후 더하고 자리수가 넘어가는 수와 분리해 넘어가는수, 합쳐진 네자리숫자를 반환하는 함수를 만든다.
   1. 문자열의 뒤 네자리씩 자른 배열로만든다
   2. 0에서 만든 함수를 돌려서 계산
   3. 각 자리수 위치에 맞게 정렬해서 반환
   - 한자리로 만들어 테스트해볼까?
   */
//  return "\(UInt64(a)! + UInt64(b)!)"
  // return (오버, 더해진값)
  enum cError: Error {
    case outOverRange
  }
  // 한자리 덧셈
  func add(over: Int, a: Int, b: Int) throws -> (Int, String) {
    if a > 9 || b > 9 || over > 9 {
      throw cError.outOverRange
    }
    
    let total: Int = over + a + b
    if total < 10 {
      return (0, String(total))
    }
    
    let totalArr = Array(String(total))
//    let over: Int = .init(String(totalArr[..<(totalArr.count - 1)]))!
    let befor = String(totalArr[..<(totalArr.count - 1)])
    let over = Int(befor)!
    
    return (over, String(totalArr.last!))
  }
  
  let aArr = Array(a).map({ String($0) }).reversed().map { $0 }
  let bArr = Array(b).map({ String($0) }).reversed().map { $0 }
  let maxIndex = max(aArr.count, bArr.count)
  
  var over: Int = 0
  var result: [String] = []
  for i in 0 ..< maxIndex {
    var aNum: Int = 0, bNum: Int = 0
    if i < aArr.count {
      let str = aArr[i]
      aNum = Int(str)!
    }
    if i < bArr.count {
      let str = bArr[i]
      bNum = Int(str)!
    }
    guard let calc = try? add(over: over, a: aNum, b: bNum) else {
      return "error"
    }
    over = calc.0
    result.append(calc.1)
  }
  if over > 0 {
    result.append("\(over)")
  }
  return result.reversed().joined()

만들다 보니 또 엄청길어졌다..........

또 "나는 4자리씩 끊어서 해야지" 라고 마음먹고 시작했으나 막상 1자리가 성공적으로 되니 귀찮아져서 포기

가산기를 만들다보니 디지털논리회로 강의때가 생각나 또 과거회상에 빠져 현재와의 비교되는 과거에 우울해졌다

그때는 이것저것 해보면서 재밌었는데 안타깝다

 

아무튼 그렇게 day25로 구성된 문제집이  day24,25 밖에 안남아서  내일로 끝이날거다 

처음 시작할때 넉넉잡아 일주일정도면 끝나겠지 했던 기초문제가 2주나 걸려버린거 생각하면 누군가 나에게 프로젝트 일정은 너가 생각한거의 두배를 말하면된다라는게 다시금 떠오른다

 

비가 계속해서 내려서 눅눅함이 사라지지 않는 밤, 사라지지 않는 빗소리 때문인지 머리가 아파서 잊고있었다

자기전에 생각해내어서 다행.

오늘치는 19,20일치인데 20일은 이미 끝나있고 19일치에 두문제가 남았다

어서 두문제만 끝내고 게임이나 해야지

 

1. 배열 만들기 6

배열 순환해서 조건에 맞는 요소만 뽑아내는 문제

  // i의 초기값을 0으로 설정하고 i가 arr의 길이보다 작으면 다음을 반복
  var i = 0
  var stk: [Int] = []
  
  while i < arr.count {
    if stk.isEmpty {
      stk.append(arr[i])
      i += 1
      continue
    }
    
    if stk.last! == arr[i] {
      _ = stk.popLast()
      i += 1
      continue
    }
    
    stk.append(arr[i])
    i += 1
  }
  
  guard !stk.isEmpty else { return [-1]}
          
  return stk
 

눅눅해서 찝찝하고 머리가 지끈지끈 거려서 아무 생각없이 그냥 문제 그대로를 코드로 바꿨더니 하는일에 비해 좀 길어보인다.

그냥 forEach로 돌리거나 filter로 돌려도 될거같기도하고?

 

2. 무작위로 K개의 수 뽑기

제목은 무작위지만 무작위가 아니라 뭐가 랜덤으로 나왔는지 주어진다. 랜덤도 아니였겠지만...

//  var copyArr: [Int] = Set(arr).map {$0}
  var copyArr: [Int] = []
  for num in arr {
    if copyArr.contains(num) {
      continue
    }
    copyArr.append(num)
    if copyArr.count >= k {
      break
    }
  }
  
  while copyArr.count < k {
    copyArr.append(-1)
  }
  
  return copyArr[..<k].map { $0 }

처음엔 그냥 Set으로 중복제거한후 k개수만큼 보내면 되겠다 싶었는데

이게 처음 주어진 배열에서 순서가 변경되면 아웃처리시켜버린다 "저장된 순서대로 주어질 예정이라고 했을 때," 라는 정의를 또 제대로 안읽고 넘겨버려서 그만 또 틀렸다

레벨0문제인데 뭐이리 자주 틀리는지

아무튼 그렇게 오늘치도 끝!

이제 남은 문제는 6문제!

물론 미리 문제를 풀지 않을거기에 이번주내내 할거같다

오늘치는 단 한문제!

1. 조건에 맞게 수열 변환하기 2

반복해서 배열에 대한 계산을 하는 문제인데...

  func arrProc(_ arr: [Int]) -> [Int] {
    
//    원소에 대해 값이 50보다 크거나 같은 짝수라면 2로 나누고, 50보다 작은 홀수라면 2를 곱하고 다시 1을 더합니다.
//    보다 크거나가 아니라 이상의 짝수라는건가?
    var result: [Int] = []
    for x in arr {
      let isEven: Bool = x % 2 == 0
      if x >= 50, isEven {
        result.append(x / 2)
        continue
      }
      if x < 50, !isEven {
        result.append(x * 2 + 1)
        continue
      }
      result.append(x)
    }
    return result
  }

  var befor: [Int] = arr
  
  for i in 0 ..< Int.max / 2 {
    let response = arrProc(befor)
    if befor == response {
      return i
    }
    befor = response
  }

  return -1

항상 타인답보면 이걸 이렇게나 줄일 수 있구나 하고 놀란다

for 조건문이 좀 마음에 걸리긴한데 문제에서 통과해버렸다

그리고 배열 비교를 == 로 했으나 이거는 좀 마음에 안든다 c스타일이였다면 이건 주소값 비교가 되서 무조건 false가 나오는거라 다르다는점은 인지하고 있고 오해를 방지하기위해 따로 다른걸로 비교하는게 좋지 않을까 하고있지만 귀찮아서 그냥 사용중이다 

그리고 타인답에 elementsEqual 라는게 사용되는걸 발견했다 이런 멋진게 있었다니 

오늘은 12,13일차

 

1. 배열 조각하기

  var copyArr: [Int] = arr
  for (i, target) in query.enumerated() {
    guard target < copyArr.count else {return []}
    let subArr =  i % 2 == 0 ? copyArr[...target] : copyArr[target...]
    copyArr = Array<Int>(subArr)
  }
  
  return copyArr

제목처럼 배열 깍아내는 문제

 

2. 리스트자르기

배열 순환문제

  func default_slicer(num_list:[Int], start s: Int, end e: Int, interval term: Int = 1) -> [Int] {
    guard s >= 0, e >= s, e < num_list.count, term < num_list.count else { return [] }
 
    let index_arr = Array(stride(from: s, through: e, by: term))
    return index_arr.map { index in
      num_list[index]
    }
  }
  
  guard slicer.count == 3 else { return [] }
  
  let a: Int = slicer[0], b: Int = slicer[1], c: Int = slicer[2]
  var result: [Int] = []
  
  switch n {
  case 1 : result = default_slicer(num_list: num_list, start: 0, end: b)
  case 2:  result = default_slicer(num_list: num_list, start: a, end: num_list.count - 1)
  case 3:  result = default_slicer(num_list: num_list, start: a, end: b)
  case 4:  result = default_slicer(num_list: num_list, start: a, end: b, interval: c)
  default: return []
  }
  
  return result

엄청 간단한 문제라고 생각했으나 문제를 잘못 생각해서 찾는데 몇 시간 걸린거같다.

아무리 생각해도 잘못된 부분이 없었는데 문제를 잘못 읽고 이해했다.

입력 제한을

  • 0 ≤ a ≤ b ≤ num_list의 길이 - 1

라는걸 a는 시작인덱스 b는 끝인덱스니 b는 항상 a보다 크겠지 라고 이해해버려서 s >= 0, e >s 라고 써버리고 이걸 찾지 못해서 고생많이했다.

입력제한을 따로 체크 하는게 영 귀찮아져서 대충했더니 이런 실수가 발생... 다음 문제부턴 입력제한을 바로 코드위 주석으로 달아두고 작성해야겠다.

아래는 내가 쓴 테스트 코드 공유.

print(solution(4,  [1, 5, 2], [1, 2, 3, 4, 5, 6, 7, 8, 9] ) ==  [2, 4, 6])
print(solution(4, [2, 7, 3], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) == [2, 5])
print(solution(4, [1, 5, 2], [4, 5, 6, 7, 8, 9]) == [5, 7, 9])
print(solution(1, [1, 5, 2], [1, 2, 3, 4, 5, 6, 7, 8, 9]) == [1, 2, 3, 4, 5, 6])
print(solution(2, [0, 1, 1], [10, 8, 6, 4, 2]) == [10, 8, 6, 4, 2])


print(solution(1, [0, 3, 1], [1, 2, 3, 4, 5]) == [1, 2, 3, 4]); // [1, 2, 3, 4]
print(solution(1, [0, 2, 1], [10, 20, 30, 40]) == [10, 20, 30]); // [10, 20, 30]
print(solution(1, [0, 1, 1], [5, 10, 15]) == [5, 10]); // [5, 10]
print(solution(1, [0, 4, 1], [7, 14, 21, 28, 35, 42]) == [7, 14, 21, 28, 35]); // [7, 14, 21, 28, 35]
print(solution(1, [0, 5, 1], [2, 4, 6, 8, 10, 12]) == [2, 4, 6, 8, 10, 12]); // [2, 4, 6, 8, 10, 12]

print(solution(2, [1, 0, 0], [1, 2, 3, 4, 5]) == [2, 3, 4, 5]); // [2, 3, 4, 5]
print(solution(2, [2, 0, 0], [10, 20, 30, 40]) == [30, 40]); // [30, 40]
print(solution(2, [1, 0, 0], [5, 10, 15]) == [10, 15]); // [10, 15]
print(solution(2, [3, 0, 0], [7, 14, 21, 28, 35, 42]) == [28, 35, 42]); // [28, 35, 42]
print(solution(2, [4, 0, 0], [2, 4, 6, 8, 10, 12]) == [10, 12]); // [10, 12]

print(solution(3, [1, 3, 0], [1, 2, 3, 4, 5]) == [2, 3, 4]); // [2, 3, 4]
print(solution(3, [0, 2, 0], [10, 20, 30, 40]) == [10, 20, 30]); // [10, 20, 30]
print(solution(3, [1, 1, 0], [5, 10, 15]) == [10]); // [10]
print(solution(3, [2, 4, 0], [7, 14, 21, 28, 35, 42]) == [21, 28, 35]); // [21, 28, 35]
print(solution(3, [3, 5, 0], [2, 4, 6, 8, 10, 12]) == [8, 10, 12]); // [8, 10, 12]

print(solution(4, [1, 4, 2], [1, 2, 3, 4, 5]) == [2, 4]); // [2, 4]
print(solution(4, [0, 3, 2], [10, 20, 30, 40]) ==  [10, 30]); // [10, 30]
print(solution(4, [0, 2, 1], [5, 10, 15]) ==  [5, 10, 15]); // [5, 10, 15]
print(solution(4, [1, 5, 2], [7, 14, 21, 28, 35, 42]) == [14, 28, 42]); // [14, 28, 42]
print(solution(4, [2, 5, 2], [2, 4, 6, 8, 10, 12]) == [6, 10]); // [6, 10]

따로 입력, 테스트에 대한 함수를 안만들어놔서 적는데 고생좀 했다

이번 기회로 하나 만들어둬야할까? 그건또 귀찮아서 모르겠다

 

3. 왼쪽 오른쪽

배열에서 원소 인덱스 찾기

  //  1 ≤ str_list의 길이 ≤ 20
  //  str_list는 "u", "d", "l", "r" 네 개의 문자열로 이루어져 있습니다.
  guard (1...20) ~= str_list.count else { return ["-1"] }
  let copy_arr = Array(str_list)
  
  let lIndex = str_list.firstIndex { $0 == "l" }
  let rIndex = str_list.firstIndex { $0 == "r" }
  
  // "l"이나 "r"이 없다면 빈 리스트를 return
  guard lIndex != nil || rIndex != nil else { return [] }
  let lValue = lIndex ?? str_list.count
  let rValue = rIndex ?? str_list.count
  
  if lValue < rValue {
    return copy_arr[..<lValue].map { $0 }
  } else if rValue < lValue {
    return copy_arr[(rValue + 1)...].map { $0 }
  }
  return ["error"]

그냥 둘다 찾아서 값 비교해줬다

 

끝!

어제치를 안해서 한주로 안끝나버렸다.

할일없어서 심심하면 진도좀 빼야지

기존대로 라면 하루에 day가 2일씩 열릴텐데 9일을 그냥 넘겨버렸다

이전에 미리 풀어놨던 문제들로 가득 차버리면 해당날짜가 된다해도 그냥 넘어가버리는듯하다

그래서 한문제만 적어야지 했던 포스트가 늘어나버리고...

1. qr code

문자열 순회

  var result: String = ""
  for (i, char) in Array<String.Element>(code).enumerated() {
    if i % q == r {
      result.append(String(char))
    }
  }
  return result
 

별 생각없이 배열로 만들고 돌렸는데

그냥 첫줄부터 filter로 빼서 반환해줬으면 두줄로 끝났을거같다

 

2. 문자 개수 세기

A~Z,a~z 의 알파벳 숫자 세는 문제

  let arr: [String.Element] = .init(my_string)
  var bigResult: [Int] = [], smallResult: [Int] = []
  let bigRange = UnicodeScalar("A").value...UnicodeScalar("Z").value
  for cValue in bigRange {
    let c: String = String(UnicodeScalar(cValue)!)
    let bigCount = arr.filter { String($0) == c }.count
    let smallCount = arr.filter { String($0) == c.lowercased()}.count
    bigResult.append(bigCount)
    smallResult.append(smallCount)
  }
  bigResult.append(contentsOf: smallResult)

알파벳의 범위를 만들어서 필터를 거치고 갯수를 해줬는데 그냥 배열을 미리 52개 만들고 문자열을 반복돌려서 count++ 해주는게 더 깔끔했을거같다

 

100여 문제가 반쯤 도전과제만 달성하고있는데 어느새 12문제만 남았다.

진행도로만 보면 이번주안에 기초트레이닝 문제는 다 끝나지 않을까?

끝나면 드디어 실 코딩 테스트 문제를!

24일날 시작한 기초 트레이닝이 27일까지 이어지고 day7,8의 란이 열렸다

1. 수열과 구간 쿼리 4

s,e,k 값이 주어질때 s~e 구간의 순회 문제.

  var copyArr = arr
  for query in queries {
    let s = query[0], e = query[1], k = query[2]
    for i in s...e {
      if i % k != 0 { continue }
      copyArr[i] += 1
    }
  }
  return copyArr

 

2. 배열 만들기 2

숫자 "0"과 "5"로만 이루어진 모든 정수를 오름차순으로 저장한 배열을 return

  let pattern: String = "^[0,5]*$"

  var result: [Int] = []
  for i in l ... r {
    let str: String = .init(i)
    if (str.range(of: pattern, options: .regularExpression) != nil) {
      result.append(i)
    }
  }
  return result.isEmpty ? [-1] : result

처음엔 5와 0으로된 이진법으로 계산해서 하려고했으나 잘 안풀려서 결국 그냥 모든 배열에서 필터하는 방법으로 변경

작성하고나니 필터함수로 썻으면 더 짧게 했을거같다

 

3. 배열 만들기 4

배열을 순회해서 필터링하기

var stk: [Int] = []
  var i: Int = 0
  
  while i < arr.count {
    if stk.isEmpty {
      stk.append(arr[i])
      i += 1
    } else if stk.last! < arr[i] {
      stk.append(arr[i])
      i += 1
    } else if stk.last! >= arr[i] {
      _ = stk.popLast()
    }
  }
  return stk

문제 지문 그대로 코드로 옴겼더니 좀 길어졌다 조건문 위 두개를 하나로 합칠수 있지않았을까

 

4. 주사위 게임 3

주사위 네개의 값이 주어졌을때 각각 계산하는게 달라지는 문제.

  var dice: [Int : Int] = [:]
  [a,b,c,d].forEach { num in
    if dice[num] == nil {
      dice[num] = 1
    } else {
      dice[num]! += 1
    }
  }
  
  if dice.count == 1 {
    return 1111 * a
  }
  
  if dice.count == 2 {
    var max: Int = 0, p: Int = 0, q: Int = 0
    
    for (key, value) in dice {
      if max < value {
        max = value
        p = key
      }
    }
    q = dice.keys.filter { key in
      key != p
    }.first!
    
    // 주사위가 3개가같을때와 2개가 같을때
    return max == 3 ? (10 * p + q) * (10 * p + q) : (p + q) * abs(p-q)
  }
  
  if dice.count == 3 {
    // 주사위 한쌍이 같고 나머지 달라
    var max: Int = 0, p: Int = 0
    
    for (key, value) in dice {
      if max < value {
        max = value
        p = key
      }
    }
    
    let res: [Int] =  dice.keys.filter { key in
      key != p
    }.map { $0 }
    
    guard res.count == 2 else { return -1 }
    return res[0] * res[1]
  }
  
  return min(a, b, c, d)

문제 순서대로 쭉 적어서 겹치는 부분이 좀 보인다. 반은 줄일 수 있을거같다 하지만 귀찮다 점수는 받았으니 괜찮겠지

 

5. 문자열 여러 번 뒤집기

원본 문자열과 문자열 인덱스 범위가 배열로 주어지고 각 인덱스 범위를 뒤집어서 출력하는 문제

  func reverse(_ str: String, _ s: Int, _ e: Int) -> String {
    var copy_arr = Array(str).map { String($0) }
    let target = copy_arr[s...e].map { $0 }
    for i in s...e {
      copy_arr[i] = target[e - i]
    }
    return copy_arr.joined()
  }
  
  var copy_str: String = my_string
  
  for q in queries {
    copy_str = reverse(copy_str, q[0], q[1])
  }
  return copy_str

이전에 비슷한 문제가 있어서 해당 코드를 reverse로 함수화해서 그대로 사용.

답을 내고 보니 replaceSubrange 라는걸 사용해서 문자열 수정해본다는게 잊고있었다.

 

아무튼 이렇게 8일치까지 끝

9일치는 이미 달성되어있고 10일치는 한문제니 다음 포스트는 한문제가 될것같다. 오늘 더이상 문제를 안푼다면 말이다

어제 기초 트레이닝 문제를 전부 끝내려했으나 하다 결국 질려서 day5,6이 열려버렸다... 

1. 코드 처리하기

주어지는 mode에 따라 글자를 파싱하는 문제

  let copyCode: [String.Element] = Array(code)
  var mode: Int = 0
  var ret: [String.Element] = []
  
  for (idx, char) in copyCode.enumerated() {
    if mode == 0 {
      if char == "1" {
        mode = 1
        continue
      }
      
      if (idx % 2 == 0) {
        ret.append(char)
      }
    } else {
      // mode == 1
      if char == "1" {
        mode = 0
        continue
      }
      if (idx % 2 != 0) {
        ret.append(char)
      }
    }
  }
    
  let result: String = ret.reduce("") { partialResult, char in
    partialResult + String(char)
  }
  if result.isEmpty { return "EMPTY" }
  return result

문제에 적힌 순서대로 그대로 코드로 만들어 썻어니 라인이 길어졌다.... 

줄이면 반은 줄일수 있겠으나 귀찮으니 패스

 

2. 수열과 구간 쿼리 2

범위 필터 연산?

  var result: [Int] = []
  for query in queries {
    guard query.count == 3 else { return [] }
    let s = query[0], e = query[1], k = query[2]
    let filtered = arr[s...e].filter { num in
      num > k
    }
    let find = filtered.min() ?? -1
    result.append(find)
  }
   return result

프로그래머스는 타인의 답을 보는 기능이 있는데 항상 볼때마다 이걸 이렇게나 줄일수있네 라고 놀랍다.

값 체크는 항상 하고싶긴한데 주어진 문제에 일일이 하고있으면 재미가 없고 오래걸려서 그냥 넘기려한다.

그런데도 종종 아무 생각없이 값 검사하는게 추가된다

 

3. 수열과 구간 쿼리 3

배열 순환 스왑 문제

  var copyArr: [Int] = arr
  for query in queries {
    guard query.count == 2 else { return [] }
    let i = query[0], j = query[1]
    guard (0 ..< copyArr.count) ~= i ,  (0 ..< copyArr.count) ~= j else { return [] }
    let temp = copyArr[i]
    copyArr[i] = copyArr[j]
    copyArr[j] = temp
  }
  return copyArr

그냥 적힌 그대로 쭉쭉 코드로 작성했으나 타인 답을 보니  swapAt 라는 함수가 따로 있었다..... 아마 이문제는 swapAt이라는 함수 기능을 사용해보는 문제였겠지싶다

 

 

+ Recent posts