programmers.co.kr/learn/courses/30/lessons/42583

 

코딩테스트 연습 - 다리를 지나는 트럭

트럭 여러 대가 강을 가로지르는 일 차선 다리를 정해진 순으로 건너려 합니다. 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 알아내야 합니다. 트럭은 1초에 1만큼 움직이며, 다리 길이

programmers.co.kr

문제에 테스트케이스가 다양하게 안되있었으면 뭐가 틀렸는지 모르고 끙끙 거렸을거같네요.

 

이번 문제는 큐는 어떻게 동작하는가에 대한 문제입니다.

스위프트에는 스택과 큐를 따로 자료형으로 정의되어 있지 않는걸로 알기에 따로 구현을 해서 할까 하다가 그냥 진행했습니다.

문제는 별 이상없이 이해가 되는데 문제에 제시된 예시용 표때문에 이게 무슨소리인가 난감해졌었습니다.

문제의 표처럼 하지말고

아래 처럼 하는게 문제 이해가 쉽습니다

 

지나는중의 숫자 뒤의 괄호는 현재 지나는 정도를 나타내봤습니다

문제에 제시된 다리길이가 10일경우 괄호의 수가 10이 되야 지난 트럭에 들어갑니다.

아래표는 다리 길이가 2이고 최대하중에 10입니다. 지난 트럭은 안적었습니다.

시간 대기중 지나는중
0 7 4 5 6  
1 4 5 6 7(0)
2 4 5 6 7(1)
3 5 6 4(0)
4 6 4(1) 5(0)
5 6 5(1)
6   6(0)
7   6(1)

 

계속 루프 해주면서 대기중에 있는 애가 지나는중 배열에 들어갈 수 있는가를 체크하고

지나는중의 배열에 있는 애는 다 지나갔는지 체크해주면 됩니다.

 

  struct Truck {
    let weight:Int
    var position:Int = 0
  }
  
  func solution(_ bridge_length:Int, _ weight:Int, _ truck_weights:[Int]) -> Int {
    func totalTruckWeight(truckArray:[Truck]) -> Int {
      var result = 0
      for item in truckArray {
        result += item.weight
      }
      return result
    }
    
    var passingArray = [Truck]() // 지나는 도중인 트럭을 저장할 배열
    var endArray = [Truck]() // 도착한 트럭을 저장할 배열
    var truckArray = [Truck]()  // 모든 트럭을 넣어둘 배열 
    
    // 매개변수로 받은 애들 Truck구조체 형태로 변경해주기
    
    var waitArray:[Truck] = truckArray // 대기중인 트럭을 넣어두는 배열
    var time = 0 // 반환할 값, 전체 지난 시간
    
    while endArray.count < truckArray.count {
      if passingArray.count > 0 {
      	// 트럭들 포지션 변화
		// 도착한애들 빼주기
      }
      if waitArray.count > 0 {
        // 대기 중인 애들 다리에 올리기 
      }
      time += 1
    }
    return time
  }

 

 

전체 소스는 아래 링크에 있습니다.

github.com/wiwi-git/Programmers-learn/blob/master/swift/Practice/Practice/TruckPassingBridge.swift

 

wiwi-git/Programmers-learn

Contribute to wiwi-git/Programmers-learn development by creating an account on GitHub.

github.com

 

programmers.co.kr/learn/courses/30/lessons/42584

 

코딩테스트 연습 - 주식가격

초 단위로 기록된 주식가격이 담긴 배열 prices가 매개변수로 주어질 때, 가격이 떨어지지 않은 기간은 몇 초인지를 return 하도록 solution 함수를 완성하세요. 제한사항 prices의 각 가격은 1 이상 10,00

programmers.co.kr

이번 문제는 swift가 지원되지않는다. java로 적는다.

 

난 문제 자체가 어떤걸 물어보는지 이해가 잘안됐다.

 

문제에서 주어진 prices배열에서 

첫번째 인덱스를 가진 값이 다음 값을 비교하고 쭉 배열의 끝까지 비교했을때 비교하려는 대상값보다 작아지는 카운트를 구하는 문제이다.

막상 글로 쓰니 무슨 말을 하는지 잘모르겠다.

코드를 보면 이해가 갈것이다.

 

class Solution {
    public int[] solution(int[] prices) {
        int[] answer = new int[prices.length];
        for(int i = 0 ; i < prices.length ; i++) {
            int sec = 0;
            for(int k = (i + 1) ; k < prices.length ; k++ ){
                sec++;
                if (prices[i] > prices[k]) { break; }
            }
            answer[i] = sec;
        }
        return answer;
    }
}

 

이 문제때문에 자바용 ide를 어떻게 할까 고민하다 시간많이 갔다.

 

난 결국 visual code에다가 외부확장용 자바포맷을 설치해 작성했다.

 

이클립스를 할까 하다가 이미 깔아있는 xcode로 할까하고 열심히 뒤졌다가

한번 돌려봤다가 이건 java를 종종 사용하면 너무 귀찮아질거같다 포기했다.

programmers.co.kr/learn/courses/30/lessons/59034

 

코딩테스트 연습 - 모든 레코드 조회하기

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디

programmers.co.kr

이번 문제는 select문의 구성을 아는가.

select문에서 order by 절을 이해했는가 이다.

 

select문의 구성은 아래와 같다.( 프로그래머스 - 최대값 구하기 편에서 복사한 부분)

 

형식:

SELECT 표시될튜플

FROM 대상테이블

WHERE 테이블에 걸을 조건

GROUP BY 묶을 튜플

HAVING  그룹으로 묶은 내용중에 걸을 조건

ORDER BY 정렬 조건


출처: https://wiwi-pe.tistory.com/109 [선생님 개발블로그가 하고싶었어요.]

 

order by 는 결과값의 정렬에 사용한다.

문제에서는 animal_id라는 튜플을 오름차순으로 정렬하라고 하였다

답은 아래와 같다.

 

select * from ANIMAL_INS
order by ANIMAL_ID ASC

 

오름차순이라 asc라 붙엿다.

내림차순 이라면 desc이다.

 

문제 : programmers.co.kr/learn/courses/30/lessons/59415

 

코딩테스트 연습 - 최댓값 구하기

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디

programmers.co.kr

 

SQL을 작성하는데 select문을 사용 할 줄 아는가.

select문에서 사용되는 집계함수중에 MAX를 아는가에 대해 묻는 문제이다.

 

select문의 구성은

형식:

SELECT 표시될튜플

FROM 대상테이블

WHERE 테이블에 걸을 조건

GROUP BY 묶을 튜플

HAVING  그룹으로 묶은 내용중에 걸을 조건

ORDER BY 정렬 조건

 

으로 구성된다.

자세한 내용이 궁굼할시 

GROUP BY절

HAVING절 이런식으로 검색하면 자세한 내용을 볼 수 있을것이다.

 

이번 문제에 필요한 것은 집계함수중에 최대값을 보여주는 MAX함수이다.

답은 아래와 같다.

 

SELECT MAX(DATETIME) as 시간
from ANIMAL_INS

 

문제에선 Alias, 그러니까 시간이라고 적은 부분(별칭)을 하지 않아도 좋다고 명시하고 있어서 'as 시간' 부분은 빼도 괜찮다.

 

문제: 크레인 인형뽑기 게임 (programmers.co.kr/learn/courses/30/lessons/64061)

 

문제는 엄청 긴데 실상 요약해보자면 간단하다

 

2차원 배열이 주어졌을때 x의 값으로 y값 루프를 돌 수 있는가

 

 

우선 기본으로 주어지는건 

board:[[Int]] 와

moves:[Int] 이다.

그리고 추가로 선언할 배열 basket이 필요하다.

 

moves의 값을 foreach로 받으면서

0이 아닌 y배열을 찾는 문제이다.

 

아래 배열은 예시로 주어진 배열이다.

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

이 배열에서 만약 moves의 값이 1이 나왔을경우

x값은 첫번째 인덱스인 0으로 주어지고

해당 열을 탐색하고 값을 찾으면 다음 moves값을 받으면 될것이다.

moves값이 1이였으니 찾는 값은 4가 나오고 해당 값을 basket에 넣으면서 이전 넣었던 값과 비교하여 같을경우 두 아이템을 삭제하고 count를 +2 하면 된다.

 

for x in moves {
  let index = x - 1
  for y in 0 ..< board.count {
    if board[y][index] != 0 {
      바스켓값 비교 및 바스켓에 삽입 등 삭제시 카운트 증가
      break
    }
  }
}

 

 

 

해당 내용의 깃허브에 올려놨다.

github.com/wiwi-git/Programmers-learn/blob/master/swift/Practice/Practice/UFOGame.swift

 

wiwi-git/Programmers-learn

Contribute to wiwi-git/Programmers-learn development by creating an account on GitHub.

github.com

 

슬슬 기본 연산자 파트가 마무리 되어간다.

달에 한두개씩 올리던 기본서는 기본연산자 파트에서 그만두게 되고,

이후에는 기본 연산자가 아닌 다른 내용으로 짬짬히 올리게 될듯하다.

 

우선 닐 코레싱? 뭐라 읽어야할지도 난감한 파트가 왔다.

내 짐작컨데 옵셔널의 해제를 해보는 파트인듯해서 우선 옵셔널에대해 예시를 들것이다.

 

내가 학부때 공부할때만 해도 자바에 옵셔널에대해 들어본적이 없었는데 요즘 뭔가 생긴듯하여

스위프트만의 특징이다! 라고 말할 수 는 없게되어 아쉽다.

 

이 옵셔널은 값의 존재 유무를 모를때 사용 할 수 있는 하나의 안전장치이다.

일반적인 경우에서 어떠한 변수 a값을 사용하려고 할때 이 a값에 아무런 값이 설정되어 있지않다면 아마 nullpoter error가 뜨게 될것이다.

비어 있는 값을 참조했기에 진행할 수 없다고 말하는것인데

이러한 사태에 대해 안전장치로 사용할 수 있는것이 바로 옵셔널이다.

 

형식은 매우 단순하다

형식)

 

var 변수이름:변수타입? 

 

위와같이 타입에 물음표를 붙이면된다.

이 타입인건가 하며 묻는듣한 모습에 바로 이해가 갈 것이라 생각된다.

 

이 옵셔널에 예시를하나 들어보자면

var name : String? 이 있겠다

참고로 이렇게 바로 선언하면 name값에는 nil 값이 들어가게 된다.

여기서 nil은 아무런 값이 없다는 뜻이다.

 

이제 값을 넣고 출력해보면 아래와같이 나온다.

 

예시1)

    var name:String? = "wiwi"

    print(name)

결과:

Optional("wiwi")

 

값이 wiwi지만 겉에 Optional()이라고 붙어있는게 바로 물음표의 역할이다.

옵셔널로 나오기에 바로 이값을 사용할 수는 없다.

그래서 이 옵셔널에서 값을 추출해줘야한다.

 

이옵셔널에 대해 이야기한적이 있나 살펴보지 3편에서 다뤘었다.

3편의8항 옵셔널 편에서 

값을 추출하기위해 느낌표, !를 붙인다고 적었다.

실제로 위 예시1)을 느낌표를 붙이고 출력하면 아래와같이 무사히 값이 나온다.

 

예시2)

    var name:String? = "wiwi"

    print(name!)

결과:

wiwi

 

이러한 옵셔널을 다루기위해선 위의 ! 와 같이 값을 추출해야하는데

이럴때 값을 더 안전하게 추출하는 연산자가 이 nil-coalescing 연사자로 추측된다.

 

위의 name을 이전편 3항연산자를 이용해서 풀어보자면

 

(name != nil ? name! : "wiwi2")

로 표현할 수 있겠는데

이는 name의 값이 nil 이 아닐경우 name을 ! 를 사용해서 바로 값을 추출한다는것이고

만약 값이 없을경우 wiwi2를 반환한다는 간략한 식이다.

 

이를 더 간략히 이번 편의 주제인 nil-coalescing 연산자를 이용하자면 ( 형태: ?? )

 

name ?? "wiwi2" 가 되겠다

코드로 돌려보자면 아래와같다.

 

예시3)

    var name:String?

    print(name ?? "wiwi2")

    

    name = "wiwi"

    print(name ?? "wiwi2")

결과:

wiwi2

wiwi

 

라인 1의 name은 값을 할당하지 않았기에 print시에 ?? 를 통해 wiwi2값이 나오게되고

라인 4의 name은 wiwi값을 할당한 상태이기에

라인 5의 print에선 wiwi값이 나오게된다.

 

2편에서 

연산자 4번

3차 조건 연산자라고 썻던걸 번역이 이상한지 아님 스위프트는 그렇게 부르는지 모르겠지만 일단 잘 아는 3항 연산자로 이름을 변경했다.

 

이번 편의 내용은 홈페이지에선 Ternary Conditional Operator  라고 적혀있는 부분의 내용이다.

 

이전편, 6편에서 한 조건문을 다시좀 보자

 

예시1)

    let flag = "apple"

    var a = 0

    if flag == "apple" {

      a = 10

    } else {

      a = 20

    }

    print(a)

결과:

10

 

flag라는 이름의 변수가 apple일때 a값을 10 그렇지 않으면 20으로 설정하는 간단한 예시이다.

3항 연산자는 이렇게 하나의 값에 의해 값이 두가지로 나눠져 선택해야할때 쓰면 간편하게 사용 가능한 연산자이다.

 

형태)

조건문 ? 조건문이 참일때 값 : 조건문이 거짓일때 값

 

예시1번을 3항연사자로 변경하면 아래와 같다

 

예시2)

    let flag = "apple"

    let a = flag == "apple" ? 10 : 20

    print(a)

결과:

10

 

a값을 저장할때 if flag == "apple"부분을 예씨2 번과 같이 적으면 동일한 결과가 된다.

값을 꼭 선언한 변수에 저장하지 않아도 된다.

 

예시3)

    let flag = false

    let sum = 10 + 20 + (flag ? 30 : 40)

    print(sum)

결과:

70

 

예시3번 처럼 연산 중간에 바로 사용해도 가능하다.

 

원래는 6편을 스위프트 언어 공식문서에 Ternary Conditional Operator 라 소개되어있는 연산자에 대해 쓰려고 했으나

해당 내용에 들어갈 조건문부분을 따로 쓰는게 좋을듯하여 본편은 조건문을 다룬다.

 

조건문은 별 다른게없다 분기문이라고 할 수 있다.

 

1~5편 사이의 예제문을 실행해봤다면 알겠지만

여태 실행은 위에서 아래로 차례차례 한줄한줄 실행이 되었다.

 

그런데 모든일이 그렇듯 순서대로 해결하려하면 일이 제대로 처리되지않는 일이 있다.

이를 조건문으로 해당 일들을 분기하여 처리한다.

 

 

조건문

 

1. if 

우선 다룰 if문은 단순하다

네이버사전에서 if에 대해 검색하면 " 만약 ~ 한다면 " 이라는 뜻으로 나온다.

예시도 If you see him ~ 그를 만난다면 으로 예시를 들고있다

 

스위프트에서의 if의 취급도 동일하다

단 if 뒤에 붙는녀석은 이전의 비교연산자와 같은 Bool형태의 값이 붙어서 사용된다.

 

형식-

if 조건  {

  실행문

}

 

이전편에서 나온 비교연산자를 이용해 if문의 예시를 들자면 아래와같다.

 

예시1)

    if 41 {

      print("1번 출력")

    }

    

    print("2번 출력")

결과:

2번 출력

 

해당 소스는 프린트 출력이

2번 출력 

으로 나오게 될것인데

if 4 < 1 의 대괄호 안에 들어가 있는 애는 출력이 되지않는다.

if다음에 나오는 비교연산 4 < 1 이 거짓이기에 해당 if문 안의 내용은 실행되지 않는다.

 

이와 같이 어떠한 조건에 따라 실행 유무를 가리는게 if문 이고 조건문이다.

 

예시2)

    let a = 30

    let b = 40

    

    if a < b {

      print("1번 출력")

    }

    

    print("2번 출력")

 

결과:

1 출력

2 출력

 

 

2. if - else if - else

1번에서 if문은 if뒤에 나오는 조건에 따라 실행 여부를 가렸다.

조건에 따라 실행여부가 두가지 이상일때는 계속 if문만 쓰기에는 힘들다 

 

if문 만을 사용해 두 수를 비교했을때의 경우 아래와 같이 할 수 있다.

 

예시3)

    let a = 30

    let b = 30

    

    if a < b {

      print("1")

    }

    if a > b {

      print("2")

    }

    if a == b {

      print("3")

    }

결과:

3

 

이를 줄이려면 else 와 elseif 를 사용하면된다.

 

 

형식)

if 조건1 {

   실행문1

} else if 조건2 {

  실행문2

} else if 조건3 {

  실행문3

} else {

  실행문4

}

 

 

else if는 연속되게 이전 if 조건이 거짓일경우 확인해보는 것이고

else 는 위의 if들이 전부 거짓일때 실행되는 경우이다

위의 소스를 아래와같이 변경할 수 있다.

 

예시4)

    let a = 30

    let b = 30

    

    if a < b {

      print("1")

    } else if a > b {

      print("2")

    } else {

      print("3")

    }

결과:

3

 

위 예시4는 예시3과 비교했을때 라인수에 대한 이득은 없다.

코드로만 보면 단순히 조건문이 연결되어 가독성이 조금 좋아질뿐이다.

하지만 실제로 돌려보면 예시4에선 저 조건문 총 세번 결과를 보지만

만약 첫번째 조건문이 참일경우 뒤의 연결된 조건은 보지않는다.

실행하는쪽에서 연산을 아끼는 이득이된다.

 

3. swich 문

switch문은 조건문 이라고 부르기가 좀 이상했는데 일단 이곳에 포함시켰다.

스위치문은 조건이 되는 어느 한 값이 어떠한 값을 가질때 이를 실행해라와 같은 느낌이다

예를 들어

let a = "바나나" 라는 a가 있을때

이 a가 바나나가 저장되어 있을 수 잇고.

사과, 또는 멜론 등의 여러가지가 있을 수 있을때 해당 내역을 적는 조건문이다.

 

형식)

 

switch 대상 {

  case 대상과 일치하는지 비교하는 값1: 

    실행문1

  case 대상과 일치하는지 비교하는 값2:

    실행문2

  case 대상과 일치하는지 비교하는 값3:

    실행문3

  default: //위의 모든 case들이 대상과 다를경우 실행

    실행문4

}

 

예시 5)

    var a = "banana"

    switch a {

      case "banana" : print("banana")

      case "apple" : print("apple")

      case "melon" : print("melon")

      case "lemon" : print("lemon")

      case "peach" : print("peach")

      default: print("다른 종류이다.")

    }

결과:

banana

 

이 스위치문은 enum타입의 변수일때 정말 편함을 느낄 수 있는 좋은 녀석인데 이전 3편의 데이터형에서 깜빡한건지 enum에 대한걸 다루지 않았다.

나중에 다루게될것같다. 

 

 

 

 

 

반복문 

반복문은 말그대로 반복하는데 사용한다.

여러 가지 계산에대해 반복적으로 해야하는 사항이 있을때 사용한다.

 

1. while

대상 조건이 거짓이 될때까지 반복하고자 할때 사용한다.

 

형식)

while 조건 { //조건은 시작할땐 참이여야 한다. 참이 아닐경우 시작을 안하고 넘어간다.

  반복할 실행문

  조건을 변화시킬 실행문

} // while문 내부 블록의 조건을 변화시킬 실행문은 없어도 된다. 단 블록 외부에서도 조건에 대한 변화가 없다면 무한루프에 빠지게된다.

 

간략히 어느한 값을 30번정도 반복시키는 while문의 예시를 들어본다.

 

예시6)

    var count = 0

    

    while count < 5 {

      count += 1

    }

    print(count)

결과: 

30

 

count에 계속 +1 식하면서 count값이 30보다 작은지에 대해 검사한다.

해당 루프문은 5보다 작으면 실행하라 인데 실 결과는 30인 이유는

순서가

1. count가 5보다 작은가

2. count에 1 더하기

이런순으로 하기에 그렇다.

 

 

2. repeat - while

위에 while은 순서가 count의 조건을 먼저 확인했는데

반대로 실행먼저하고 조건을 보고싶을 경우도 있다

이럴땐 repeat while문을 쓰면된다.

 

형식)

repeat {

실행문

} while 조건

 

 

위와 결과는 같으나 실행순서만 다른 예제를 들면

 

예시7)

    var count = 0

    

    repeat {

      count += 1

    } while count < 5

    print(count)

 

결과: 5

 

예시6번을 뒤집어본 소스이다

실제로 일단 count값을 먼저 증가시키고 

그후에 다시 실행시킬것인가에 대해 검사를한다.

 

 

3. for문

for문은 주로 인덱스에 해당하는 변수와 같이 사용할때 쓴다.

위에서 count를 사용한것과 비슷한데

while은 사실 저렇게 단순히 +1할때 쓰지는 않는다. for문이 이러한 순서대로 증가하는 값이 필요할때 사용한다.

 

형식)

for 변수1 in 변수1에 담을것 {

  실행문

}

 

예를 들어

1 부터 10까지의 합을 구하려고한다 그러면 아래와 같다

 

예시8)

    var sum = 0

    for i in 1 ... 10 {

      sum += i

    }

    print(sum)

결과:

55

 

sum에 1부터 10까지 변하는 i의 값을 모조리 더하는 반복문이다.

 

1 ... 10 은 Range 타입의 변수를 바로 정의하면서 사용하는것이다.

이 부분은 배열이 들어가도 좋고, 실제로 배열을 넣어서 많이 사용한다.

배열을 넣어서 사용하자면

 

예시9)

    let exArray = ["banana", "apple", "melon","lemon" ,"peach"]

    for i in exArray {

      print(i)

    }

결과:

banana
apple
melon
lemon
peach

 

와 같이 된다.

오른쪽에 있는 값이 여러가지를 가지고있는 녀석을 왼쪽의 변수에 하나씩 차례대로 넣어서 활용하는것이다.

 

Range에 대해서는 나중에 좀더 다뤄볼 수도 있고 없을 수도 있으니 만약 이글로 swift를 공부중이라면 따로 찾아보는것을 권한다.

 

 

 

+ Recent posts