20230807 TIL

조광희·2023년 8월 7일
post-thumbnail

프로그래머스 코딩테스트

이진수 더하기

이진수를 의미하는 두 개의 문자열 bin1과 bin2가 매개변수로 주어질 때, 두 이진수의 합을 return하도록 solution 함수를 완성해주세요.

코드를 짜기 전에 이진수의 계산방법을 이해해야 한다.
우리는 이진수를 계산할 때, 숫자의 뒷자리 수에서 부터 계산을 하여 오른쪽으로 나아간다.

예시로
1011(2)
1001(2)
를 계산한다고 생각하면,
오른쪽 수인 1과 1을 먼저 계산한다.
이를 수행하기 위해 입력받은 값을 뒤집어준다.

        for(i in 0 until max1){
            tempBin1 = tempBin1 + bin1.substring(f1-1,f1)//입력받은 값 1번째
            f1--
        }
        for(i in 0 until max2){
            tempBin2 = tempBin2 + bin2.substring(f2-1,f2)//입력받은 값 2번째
            f2--
        }

배열을 뒤집은 후, 계산을 진행할 때, 두 자리의 수가 1 임으로 1+1 = 2라는 값이 나오면 다음 계산 때 1의 값을 추가로 더해주고, 계산한 자리에는 0을 입력한다.
1011(2)
1001(2)

계산된 값 0(2)
+1
다음자릿수를 계산하면 1+0인데, 아까 생긴 +1을 추가로 더 해주면 1+0+1 =2의 값이 됨으로 자릿값은 0이 되고 다음 계산에 +1을 추가한다.

계산된 값 00(2)
+1
다음 자리를 계산하면 0+0+1=1 임으로 자리에는 1의 값을 추가하고, 추가적인 숫자를 제공하지 않는다.

계산된 값 100(2)

마지막 자리값은 1+1=2 임으로 해당 자리에는 0이 추가되고, 남은 1은 더이상 계산 할 숫자가 없으므로 앞 자리에 1을 추가해준다.

이러한식으로 최종적으로 나온 답은 10100(2)이다.

이진수를 십진법으로 바꿔 계산하여 답이 맞게 나왔는지 확인해보자.
1 0 1 1(2)
8 4 2 1
8+2+1 = 11
1 0 0 1(2)
8 4 2 1
8+1=9
11+9 = 20
20의 이진수는
1 1 1 1 1(2)
16 8 4 2 1
1 0 1 0 0(2)
16+4=20
10100(2)인 것을 확인할 수 있다.
이렇게 두 수와 추가된 숫자를 비교하여 이진수를 계산할 수 있다.
하지만 이를 코딩으로 구현하려 할 때 문제가 있는데, for문을 돌릴 때 두 이진수의 크기가 다르면 에러가 날 수 있다는 문제점이 있다.
이를 해결하기 위해서 if문을 통해 2가지 가정을한다.

if(max1 >= max2){
.....
}else{
.....
}

이런식으로 첫 번째 입력값이 클 경우와 두 번째 입력값이 클 경우를 나누어 계산을 진행한다.
이런식으로 짜여진 이진수의 계산법 코드이다.

   if(max1 >= max2){
            for (i in 0 until max2){
            if (tempBin1.substring(i,i+1) == "1" && tempBin2.substring(i,i+1)== "1" && num1 == "1"){
                answer = "1" + answer
                num1 = "1"
            }else if(tempBin1.substring(i,i+1)== "1" && tempBin2.substring(i,i+1)== "1" && num1 == "0" ){
                 answer = "0" + answer
                num1 = "1"
            }else if(tempBin1.substring(i,i+1)== "1" && tempBin2.substring(i,i+1)== "0" && num1 == "1" ){
                 answer = "0"+answer
                num1 = "1"
            }else if(tempBin1.substring(i,i+1)== "1" && tempBin2.substring(i,i+1)== "0" && num1 == "0"){
                 answer = "1"+answer
                num1 = "0"
            }else if(tempBin1.substring(i,i+1)== "0" && tempBin2.substring(i,i+1)== "0" && num1 == "1"){
                answer = "1"+answer
                num1 = "0"
            }else if(tempBin1.substring(i,i+1)== "0" && tempBin2.substring(i,i+1)== "1" && num1 == "0"){
                answer = "1"+answer
                num1 = "0"
            }else if(tempBin1.substring(i,i+1)== "0" && tempBin2.substring(i,i+1)== "1" && num1 == "1"){
                answer = "0"+answer
                num1 = "1"
            }else if(tempBin1.substring(i,i+1)== "0" && tempBin2.substring(i,i+1)== "0" && num1 == "0"){
                answer = "0"+answer
                num1 = "0"
            }    

       
        }else{
            for (i in 0 until max1){
            if (tempBin1.substring(i,i+1) == "1" && tempBin2.substring(i,i+1)== "1" && num1 == "1"){
                answer = "1" + answer
                num1 = "1"
            }else if(tempBin1.substring(i,i+1)== "1" && tempBin2.substring(i,i+1)== "1" && num1 == "0" ){
                 answer = "0" + answer
                num1 = "1"
            }else if(tempBin1.substring(i,i+1)== "1" && tempBin2.substring(i,i+1)== "0" && num1 == "1" ){
                 answer = "0"+answer
                num1 = "1"
            }else if(tempBin1.substring(i,i+1)== "1" && tempBin2.substring(i,i+1)== "0" && num1 == "0"){
                 answer = "1"+answer
                num1 = "0"
            }else if(tempBin1.substring(i,i+1)== "0" && tempBin2.substring(i,i+1)== "0" && num1 == "1"){
                answer = "1"+answer
                num1 = "0"
            }else if(tempBin1.substring(i,i+1)== "0" && tempBin2.substring(i,i+1)== "1" && num1 == "0"){
                answer = "1"+answer
                num1 = "0"
            }else if(tempBin1.substring(i,i+1)== "0" && tempBin2.substring(i,i+1)== "1" && num1 == "1"){
                answer = "0"+answer
                num1 = "1"
            }else if(tempBin1.substring(i,i+1)== "0" && tempBin2.substring(i,i+1)== "0" && num1 == "0"){
                answer = "0"+answer
                num1 = "0"
            }   
             
        }


        return answer
    }
}

하지만 여기에도 문제가 있다.
바로 해당 코드는 for문이 입력값중 작은 변수의 크기만큼만 돌아간다.
이를 해결하기 위해 if문과 for문을 하나 더 추가하였다.

            if(max1>count){
                for(f in count until max1){
                    if(tempBin1.substring(f,f+1) == "0" && num1=="0"){
                        answer = "0" + answer    
                    }else if(tempBin1.substring(f,f+1) == "0" && num1=="1"){
                        answer= "1" + answer
                        num1 = "0"
                    }else if(tempBin1.substring(f,f+1) == "1" && num1=="0"){
                        answer = "1"+answer
                    }else if(tempBin1.substring(f,f+1) == "1" && num1=="1"){
                        answer = "0"+answer
                        num1 = "1"
                    }
                }
            }
            if(num1 == "1" ){
                answer="1"+answer
                
            }

이를 통해 이진법을 계산을 마치었다. 전체 코드는 이렇게 구성된다.

class Solution {
    fun solution(bin1: String, bin2: String): String {
        var answer: String = ""
        var num1:String="0"
        var tempBin1:String =""
        var tempBin2:String =""
        var max1 = bin1.length
        var f1 = max1
        var max2 = bin2.length
        var f2 = max2
        var count = 0
        
        for(i in 0 until max1){
            tempBin1 = tempBin1 + bin1.substring(f1-1,f1)
            f1--
        }
        for(i in 0 until max2){
            tempBin2 = tempBin2 + bin2.substring(f2-1,f2)
            f2--
        }

        if(max1 >= max2){
            for (i in 0 until max2){
            if (tempBin1.substring(i,i+1) == "1" && tempBin2.substring(i,i+1)== "1" && num1 == "1"){
                answer = "1" + answer
                num1 = "1"
            }else if(tempBin1.substring(i,i+1)== "1" && tempBin2.substring(i,i+1)== "1" && num1 == "0" ){
                 answer = "0" + answer
                num1 = "1"
            }else if(tempBin1.substring(i,i+1)== "1" && tempBin2.substring(i,i+1)== "0" && num1 == "1" ){
                 answer = "0"+answer
                num1 = "1"
            }else if(tempBin1.substring(i,i+1)== "1" && tempBin2.substring(i,i+1)== "0" && num1 == "0"){
                 answer = "1"+answer
                num1 = "0"
            }else if(tempBin1.substring(i,i+1)== "0" && tempBin2.substring(i,i+1)== "0" && num1 == "1"){
                answer = "1"+answer
                num1 = "0"
            }else if(tempBin1.substring(i,i+1)== "0" && tempBin2.substring(i,i+1)== "1" && num1 == "0"){
                answer = "1"+answer
                num1 = "0"
            }else if(tempBin1.substring(i,i+1)== "0" && tempBin2.substring(i,i+1)== "1" && num1 == "1"){
                answer = "0"+answer
                num1 = "1"
            }else if(tempBin1.substring(i,i+1)== "0" && tempBin2.substring(i,i+1)== "0" && num1 == "0"){
                answer = "0"+answer
                num1 = "0"
            }    
            count = i+1

        }
            if(max1>count){
                for(f in count until max1){
                    if(tempBin1.substring(f,f+1) == "0" && num1=="0"){
                        answer = "0" + answer    
                    }else if(tempBin1.substring(f,f+1) == "0" && num1=="1"){
                        answer= "1" + answer
                        num1 = "0"
                    }else if(tempBin1.substring(f,f+1) == "1" && num1=="0"){
                        answer = "1"+answer
                    }else if(tempBin1.substring(f,f+1) == "1" && num1=="1"){
                        answer = "0"+answer
                        num1 = "1"
                    }
                }
            }
            if(num1 == "1" ){
                answer="1"+answer
                
            }
        }else{
            for (i in 0 until max1){
            if (tempBin1.substring(i,i+1) == "1" && tempBin2.substring(i,i+1)== "1" && num1 == "1"){
                answer = "1" + answer
                num1 = "1"
            }else if(tempBin1.substring(i,i+1)== "1" && tempBin2.substring(i,i+1)== "1" && num1 == "0" ){
                 answer = "0" + answer
                num1 = "1"
            }else if(tempBin1.substring(i,i+1)== "1" && tempBin2.substring(i,i+1)== "0" && num1 == "1" ){
                 answer = "0"+answer
                num1 = "1"
            }else if(tempBin1.substring(i,i+1)== "1" && tempBin2.substring(i,i+1)== "0" && num1 == "0"){
                 answer = "1"+answer
                num1 = "0"
            }else if(tempBin1.substring(i,i+1)== "0" && tempBin2.substring(i,i+1)== "0" && num1 == "1"){
                answer = "1"+answer
                num1 = "0"
            }else if(tempBin1.substring(i,i+1)== "0" && tempBin2.substring(i,i+1)== "1" && num1 == "0"){
                answer = "1"+answer
                num1 = "0"
            }else if(tempBin1.substring(i,i+1)== "0" && tempBin2.substring(i,i+1)== "1" && num1 == "1"){
                answer = "0"+answer
                num1 = "1"
            }else if(tempBin1.substring(i,i+1)== "0" && tempBin2.substring(i,i+1)== "0" && num1 == "0"){
                answer = "0"+answer
                num1 = "0"
            }   
            count = i+1

        }
             if(max2>count){

                for(f in count until max2){
                    if(tempBin2.substring(f,f+1) == "0" && num1=="0"){
                        answer = "0" + answer   
                    }else if(tempBin2.substring(f,f+1) == "0" && num1=="1"){
                        answer= "1" + answer
                        num1 = "0"
                    }else if(tempBin2.substring(f,f+1) == "1" && num1=="0"){
                        answer = "1"+answer
                    }else if(tempBin2.substring(f,f+1) == "1" && num1=="1"){
                        answer = "0"+answer
                        num1 = "1"
                    }
                }
            }
            if(num1 == "1" ){
                answer="1"+answer
                
            }
        }




        return answer
    }
}

제출하면 문제없이 돌아가는 모습을 보인다.

연속된 수의 합
연속된 세 개의 정수를 더해 12가 되는 경우는 3, 4, 5입니다. 두 정수 num과 total이 주어집니다. 연속된 수 num개를 더한 값이 total이 될 때, 정수 배열을 오름차순으로 담아 return하도록 solution함수를 완성해보세요.

연속된 세 개의 정수가 total값이 되는 경우를 먼저 찾아보아야한다.

입출력 예
num total result
3 12 [3, 4, 5]
5 15 [1, 2, 3, 4, 5]
4 14 [2, 3, 4, 5]
5 5 [-1, 0, 1, 2, 3]

아래 예시를 보았을 때, 2가지로 나뉘어서 보이는 내용이 있다.

  1. num이 홀수일 때,
    num이 홀수일 때, num과 total을 이용하여 한 가지의 수식을 이용할 수 있는 모습을 볼 수 있다.
    total을 num으로 나누고, num의 값을 2로 눈 몫값을 빼 준 다음 1을 더해주면 최솟값이 나오고, 이를 num값만큼 수행하면 result가 나오는 모습을 볼 수 있다.
    num이 5이고 total이 15일 때 상황으로 계산을 해보자.

15/5 = 3
3 - 2 + 0 = 1
3 - 2 + 1 = 2
3 - 2 + 2 = 3
3 - 2 + 3 = 4
3 - 2 + 4 = 5

result = [1,2,3,4,5]가 나오는 모습을 볼 수 있다.
추가 예시인 num이 5일때, total이 5일 때도 계산을 해보자

5/5= 1
1 - 2 + 0 = -1
1 - 2 + 1 = 0
1 - 2 + 2 = 1
1 - 2 + 3 = 2
1 - 2 + 4 = 3
result = [-1,0,1,2,3]이 나오는 모습을 볼 수 있다.
이를 코드로 작성하면

        for(i in 0 until num){
             answer[i] = total/num - num/2 + i
         }

로 표현할 수 있다.
2.num이 짝수일 때
짝수일때는 조금 다르다, 홀수와 같이 num의 값을 2로 눈 몫값을 빼 준 다음 1을 더해주고, +1을 더하면 최솟값이 나오고, 이를 num값만큼 수행하면 result가 나오는 모습을 볼 수 있다.

num이 4이고 total이 14인 상황으로 계산해보자.
14/4 = 3
3 - 2 + 0 + 1 = 2
3 - 2 + 0 + 2 = 3
3 - 2 + 0 + 3 = 4
3 - 2 + 0 + 4 = 5
result = [2,3,4,5]값이 나오는 모습을 볼 수 있다.

이러한 2가지 방식을 합쳐 결과값이 나오게 코드를 작성하면 아래와 같다.

class Solution {
    fun solution(num: Int, total: Int): IntArray {
        var answer = IntArray(num)
        
        if(num % 2 == 0){

            for(i in 0 until num){
             answer[i] = total/num - num/2 + i + 1
         }
        }else{
        for(i in 0 until num){
             answer[i] = total/num - num/2 + i
         }
        }



        
        
        
        return answer
    }
}

이런 식으로 알고리즘 2문제를 풀고 제출을 마무리하였다.

다음으로 선택과제를 추가적으로 구성을 해보았다.

1. 화면 이동 + @

  • 회원 가입페이지에서 입력한 아이디/비밀번호가 로그인 화면으로 돌아올 때 자동 입력되는 기능!
  • Hint! registerForActivityResult 를 알아봅시다.

registerForActivityResult는 다른화면에서 변수값을 입력받아 콜백을 할 수 있게 도와주는 기능이다.
이를 사용하기 위해서는 입력을 받아줄 Activity에 콜백을 선언하여야 한다.

 fun setResultNext(){
        resultLauncher = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()){ result ->

            if(result.resultCode == RESULT_OK){

                val id = result.data?.getStringExtra("id") ?: ""
                val pw = result.data?.getStringExtra("pw") ?: ""

                inputID.text = Editable.Factory.getInstance().newEditable(id)
                inputPassword.text =Editable.Factory.getInstance().newEditable(pw)



            }

        }

    }

registerForActivityResult 메소드를 활용하여 resultLauncher를 만든다
콜백을 통해서 받은 인자를 id 변수와 pw변수에 대입하고, 이를 통해 inputID의 text값과, inputPasword의 text값에 넣었는데, EditText값에 text는 String()상태의 문자를 그대로 입력하면 에러가 생겨, Editable.Factory.getInstance().newEditable()를 사용하여 값의 파라미터를 바꾸고 등록을 해주었다.

이를 onCreate에서 사용하기위해 해당 기능이 필요한 곳에 함수를 입력해준다.

class SigninActivity : AppCompatActivity() {//프로젝트 생성 후 MainActivity > SigninActivity로 수정
    private lateinit var resultLauncher: ActivityResultLauncher<Intent>
    private lateinit var inputID : EditText
    private lateinit var inputPassword : EditText

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)

        var loginBtn =findViewById<Button>(R.id.loginBtn)
        var regiBtn = findViewById<Button>(R.id.regiBtn)
        inputID = findViewById(R.id.inputID)
        inputPassword = findViewById(R.id.inputPassword)

        setResultNext()


    loginBtn.setOnClickListener{
        Log.d(TAG, "로그인 버튼 클릭")

        val id = inputID.text.toString()
        var pw = inputPassword.text.toString()

        if(id.isEmpty()){
            Toast.makeText(this, "아이디를 입력해주세요", Toast.LENGTH_SHORT).show()
        }else if(pw.isEmpty()){
            Toast.makeText(this, "비밀번호를 입력해주세요", Toast.LENGTH_SHORT).show()
        }else{
            Toast.makeText(this,"로그인 성공",Toast.LENGTH_SHORT).show()


            var intent = Intent(this, HomeActivity::class.java)
            intent.putExtra("id",id)
            startActivity(intent)
        }


    regiBtn.setOnClickListener{
        var intent = Intent(this, SignUpActivity::class.java)
        resultLauncher.launch(intent) //resultLuancher 지정
    }



    }
    fun setResultNext(){
        resultLauncher = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()){ result ->

            if(result.resultCode == RESULT_OK){

                val id = result.data?.getStringExtra("id") ?: ""
                val pw = result.data?.getStringExtra("pw") ?: ""

                inputID.text = Editable.Factory.getInstance().newEditable(id)
                inputPassword.text =Editable.Factory.getInstance().newEditable(pw)



            }

        }

    }



}


signInActivity의 원문이다. 우리는 regiActivity에서 인자를 받아올 예정으로 resultLauncher를 regiBtn이 클릭됬을 때 실행시켜준다.

regiBtn이 클릭되면 SignUpActivity가 실행이 된다.
이곳에서 우리는 id와 pw를 받아와야 한다.

package com.example.myapp

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast

class SignUpActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_signup)

        var signUpBtn = findViewById<Button>(R.id.signUpBtn)
        var inputName = findViewById<EditText>(R.id.nameEditText)
        var inputId = findViewById<EditText>(R.id.idEditText)
        var inputPw = findViewById<EditText>(R.id.pwEditText)



        signUpBtn.setOnClickListener{
            var name = inputName.text.toString()
            var id = inputId.text.toString()
            var pw = inputPw.text.toString()
            if(name.isEmpty()){
                Toast.makeText(this, "이름을 입력해주세요", Toast.LENGTH_SHORT).show()
            }else if(id.isEmpty()){
                Toast.makeText(this, "아이디를 입력해주세요", Toast.LENGTH_SHORT).show()
            }else if(pw.isEmpty()){
                Toast.makeText(this, "비밀번호를 입력해주세요", Toast.LENGTH_SHORT).show()
            }else{
                Toast.makeText(this, "회원가입을 완료하였습니다!", Toast.LENGTH_SHORT).show()

                intent.putExtra("id",inputId.text.toString())// id 인자 넘기기
                intent.putExtra("pw",inputPw.text.toString())// pw 인자 넘기기
                setResult(RESULT_OK,intent)
                finish()
            }

        }
    }
}

intent.putExtra를 통해 인자값을 전달해준다.
setResult를 통해 결과값의 문제가 없음을 지정하고, intent를 전송한다.

이러한 코드를 실행시키면 아이디와 비밀번호가 문제없이 입력되는 모습을 볼 수 있다.

profile
다시시작

0개의 댓글