티스토리 뷰

코드카타

 

푸드파이트 대회

 

문제

 

문제가 설명이 좀 길어서 테스트케이스를 보며 뭘 구현해야 되는지 정리해보겠다.

 

 

테스트케이스 확인

 

저렇게 문제가 답도 없이 길 때는 테스트케이스를 통해 

코드에서 무엇을 구현해야될지 감을 잡으면 된다.

 

첫번째 테스트케이스를 통해 설명을 하자면 food 배열인 [1, 3, 4, 6]에서

1은 물, 3은 첫번째 음식, 4는 두번째 음식, 6은 세번째 음식에 해당한다.

 

두 사람이 먹을 n번째 음식들을 각각 공평하게 2로 나눈 다음 n을 그 수만큼 반복해서 result에 더하고,

"왼쪽의 선수가 먹을 음식의 배치 + 0 + 오른쪽 선수가 먹을 음식의 배치" 를 반환하면 된다. 

 

 

정답

class Solution {
    fun solution(food: IntArray): String {
        var res: String = ""
        for(i in food.indices){
            res += i.toString().repeat(food[i]/2)
        }
        return res + '0' + res.reversed()
    }
}

food배열의 인덱스 범위만큼 for문을 돌려 i번째 음식을 2로 나눈 값만큼

반복하여 i를 문자열로 변환한 값을 res문자열에 추가한다.

 

food[0]은 물의 양에 해당하며 항상 1의 값을 가진다고

제한사항에 언급이 되어있어 고려할 필요가 없다.

 

res.reversed()는 res문자열을 뒤집은 문자열을 반환해

결과적으로 오른쪽 사람이 먹을 음식의 배치에 해당하는 문자열이 된다.

 


 

질문지 화면 마무리

 

onCreateView

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    val view = inflater.inflate(R.layout.fragment_question, container, false)

    val title: TextView = view.findViewById(R.id.tv_question_title)
    title.text = getString(questionTitle[questionType])

    val questionTextView = listOf<TextView>(
        view.findViewById(R.id.tv_question_1),
        view.findViewById(R.id.tv_question_2),
        view.findViewById(R.id.tv_question_3)
    )

    val answerRadioGroup = listOf<RadioGroup>(
        view.findViewById(R.id.rg_answer_1),
        view.findViewById(R.id.rg_answer_2),
        view.findViewById(R.id.rg_answer_3)
    )

    for (i in questionTextView.indices) {
        questionTextView[i].text = getString(questionTexts[questionType][i])

        val radioButton1 = answerRadioGroup[i].getChildAt(0) as RadioButton
        val radioButton2 = answerRadioGroup[i].getChildAt(1) as RadioButton

        radioButton1.text = getString(questionAnswers[questionType][i][0])
        radioButton2.text = getString(questionAnswers[questionType][i][1])
    }
    return view
}

onCreateView에선 질문지 화면을 구성하는데 사용할 변수를 초기화해준다.

 

 

val view = inflater.inflate(R.layout.fragment_question, container, false)

inflate로 레이아웃에 해당하는 xml을 코드로 갖고온다.

fragment_question이라는 레이아웃을 컨테이너 안에 넣은 뷰를 하나 만들어준다.

 

val title: TextView = view.findViewById(R.id.tv_question_title)
title.text = getString(questionTitle[questionType])

val questionTextView = listOf<TextView>(
    view.findViewById(R.id.tv_question_1),
    view.findViewById(R.id.tv_question_2),
    view.findViewById(R.id.tv_question_3)
)

val answerRadioGroup = listOf<RadioGroup>(
    view.findViewById(R.id.rg_answer_1),
    view.findViewById(R.id.rg_answer_2),
    view.findViewById(R.id.rg_answer_3)
)

저번시간에 추가했던 리스트들을 이용해서 3개의 위젯 리스트를 선언해준다.

텍스트뷰에 해당하는 제목과 질문 리스트, 라디오 그룹에 해당하는 선택지 리스트를 선언한다.

 

가져온 위젯의 텍스트를 리스트의 요소로 설정하려면 getString으로 값을 받아야 한다.

 

for (i in questionTextView.indices) {
    questionTextView[i].text = getString(questionTexts[questionType][i])

    val radioButton1 = answerRadioGroup[i].getChildAt(0) as RadioButton
    val radioButton2 = answerRadioGroup[i].getChildAt(1) as RadioButton

    radioButton1.text = getString(questionAnswers[questionType][i][0])
    radioButton2.text = getString(questionAnswers[questionType][i][1])
}

i가 '0 ~ (질문개수 - 1)' 의 범위를 가지는 for문을 돌려

질문과 라디오그룹 위젯의 텍스트를 해당하는 값으로 초기화한다.

 

라디오그룹에서 getChildAt(n)를 이용해 첫번째 버튼과 두번째 버튼을

구분해서 선언해준 뒤 라디오버튼 위젯의 텍스트를 각각 해당하는 값으로 초기화 한다.

 

해당 구문에서 questionType은 페이지 번호에 해당한다.

 

 

onViewCreated

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    val answerRadioGroup = listOf<RadioGroup>(
        view.findViewById(R.id.rg_answer_1),
        view.findViewById(R.id.rg_answer_1),
        view.findViewById(R.id.rg_answer_1),
    )

    val btn_next: Button = view.findViewById(R.id.btn_next)

    btn_next.setOnClickListener {
        val isAllAnswered = answerRadioGroup.all { it.checkedRadioButtonId != -1 }

        if (isAllAnswered) {
            val responses = answerRadioGroup.map { radioGroup ->
                val firstRadioButton = radioGroup.getChildAt(0) as RadioButton
                if (firstRadioButton.isChecked) 1 else 2
            }
            (activity as? TestActivity)?.questionnaireResults?.addResponses(responses)
            (activity as? TestActivity)?.moveToNextQuestion()

        } else {
            Toast.makeText(context, "모든 질문에 답해주세요", Toast.LENGTH_SHORT).show()
        }
    }
}

onViewCreated에서는 버튼의 동작을 정의한다.

 

어떤 라디오 버튼이 선택됬는지 알아내기 위해 라디오그룹 리스트를 선언하고,

다음 버튼을 눌렀을 때의 동작을 정의하기 위해 다음 버튼을 id로 불러온다.

 

btn_next.setOnClickListener {
    val isAllAnswered = answerRadioGroup.all { it.checkedRadioButtonId != -1 }

    if (isAllAnswered) {
        val responses = answerRadioGroup.map { radioGroup ->
            val firstRadioButton = radioGroup.getChildAt(0) as RadioButton
            if (firstRadioButton.isChecked) 1 else 2
        }
        (activity as? TestActivity)?.questionnaireResults?.addResponses(responses)
        (activity as? TestActivity)?.moveToNextQuestion()

    } else {
        Toast.makeText(context, "모든 질문에 답해주세요", Toast.LENGTH_SHORT).show()
    }
}

다음 버튼을 눌렀을 때의 동작을 정의하는 코드이다.

 

모든 라디오그룹의 값이 선택되었으면 isAllAnswered는 true, 아니라면 false값을 가진다.

isAllAnswered값에 따라 모든 질문에 대한 응답을 선택하였을 때와 아닐때의 동작을 구분한다.

 

response는 라디오 버튼의 선택값을 저장하는 배열에 해당한다.

radioButton(변수).isChecked로 라디오 버튼의 체크여부를 알아낼 수 있는데

하나의 질문에 대한 답변은 2개밖에 없기때문에 첫번째 버튼만 체크여부를 확인하면 된다.

첫번째 버튼이 라디오 체크된 상태라면 1, 두번째 라디오 버튼이 2를 추가한다.

 

 addResponse함수의 인자값을 response로 줘서 호출함으로써

라디오 버튼의 선택값이 담긴 배열은 n번째 버튼이 더 많이 선택됬다면 n으로 초기화 되고

mbti 결과를 반환하는데 쓰이는 results배열에 그 값이 저장되게 된다.

 

그 다음엔 현재 페이지의 번호에 따라 화면을 이동하는 함수를 호출한다.

 

모든 질문에 답하지 않았다면 토스트 메시지를 띄운다.

 

(activity as? TestActivity)?.questionnaireResults?.addResponses(responses)
(activity as? TestActivity)?.moveToNextQuestion()

이해가 잘안된다면 사전캠프 TIL 13일차 < 여기로 들어가서

addResponses와 moveToNextQuestion함수에 대한 설명을 참고해주자.

 

// TestActivity.kt에 해당 구문 추가

val questionnaireResults = QuestionnaireResults()

아 그리고 선언한 클래스를 사용하려면 해당 클래스의 인스턴스를 생성해줘야 한다.

원래 저 코드치기 전에 이걸 먼저 해야되는데 강사님이 까먹은 모양이다.

 

 

테스트

 

아직 결과화면은 구현하지 않아 마지막 페이지로 이동하지 않는다.

 

모든 질문에 대한 답을 선택하고 확인 버튼을 누르면 뷰페이저에 의해

화면이 옆으로 넘어가게 되고 질문지의 내용이 바뀌는 것을 확인할 수 있다.

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함