관리 메뉴

솜씨좋은장씨

[BaekJoon] 3613번 : Java vs C++ (Python) (feat.ChatGPT) 본문

Programming/코딩 1일 1문제

[BaekJoon] 3613번 : Java vs C++ (Python) (feat.ChatGPT)

솜씨좋은장씨 2023. 4. 16. 23:29
728x90
반응형

코딩 1일 1문제! 오늘은 문제를 푼 1,000번째 날입니다.

오늘의 문제는 이전에 호기롭게 도전하여 풀다가

예외처리에 스트레스를 받고 잠시 미뤄뒀던 백준의 Java vs C++ 입니다.

1,000일 버프를 받아 스트레스 받아도 다시 풀어보았습니다.

 

3613번: Java vs C++

Java 예찬론자 김동규와 C++ 옹호가 김동혁은 서로 어떤 프로그래밍 언어가 최고인지 몇 시간동안 토론을 하곤 했다. 동규는 Java가 명확하고 에러가 적은 프로그램을 만든다고 주장했고, 동혁이는

www.acmicpc.net

👨🏻‍💻 문제 풀이 - SOMJANG

1. 변환할 변수가 C++ 인지 java 인지 "_" 가 문자열에 존재하는지 존재하지않는지로 구분합니다.

- "_" 가 문자열에 존재 O -> c++ -> java 변환

- "_" 가 문자열에 존재 X -> java -> c++ 변환

2. C++ -> java 변환

- Error! 인 경우

  ㄴ "__" 가 변수에 존재하는 경우

  ㄴ 변수의 첫번째 값 또는 마지막 값이 "_" 인 경우

  ㄴ 변수에 대문자가 포함되어있는 경우

- 변환 방법

  ㄴ "_" 로 split 한 다음 하나씩 꺼내서

     ㄴ 첫번째 값은 그대로 변환 값 리스트에 넣고

     ㄴ 나머지 값은 Capitalize 시켜 리스트에 넣은 뒤

     ㄴ 문자열로 "".join() 하면 끝!

3. java -> C++ 변환

- Error! 인 경우

  ㄴ 첫번째 값이 대문자인 경우

- 변환 방법

  ㄴ 문자열에서 값을 하나씩 꺼내오면서 

      ㄴ 대문자인 경우 "_소문자변환값" 을 리스트에 넣고

      ㄴ 소문자인 경우 그냥 해당 값을 리스트에 넣은 뒤

     ㄴ 문자열로 "".join() 하면 끝!

👨🏻‍💻 코드 ( Solution ) - SOMJANG

def java_to_cplusplus(variable):
    error = "Error!"
    
    converted_result = []
    
    for idx in range(len(variable)):
        if variable[idx].isupper():
            if idx == 0:
                return error
            else:
                converted_result.append(f"_{variable[idx].lower()}")
        else:
            converted_result.append(variable[idx].lower())
            
    return "".join(converted_result)


def cplusplus_to_java(variable):
    error = "Error!"
    
    converted_result = []
    
    if "__" in variable:
        return error
    if variable[0] == "_" or variable[-1] == "_":
        return error
    if not variable.islower():
        return error
    
    for word in variable.split("_"):
        if not converted_result:
            converted_result.append(word)
        else:
            converted_result.append(word.capitalize())
        
    return "".join(converted_result)


if __name__ == "__main__":
    variable = input()
    
    if "_" in variable:
        print(cplusplus_to_java(variable=variable))
    else:
        print(java_to_cplusplus(variable=variable))

👨🏻‍💻 결과 - 수많은 실패 끝에....! ( 예외처리가 많구나...! )

👨🏻‍💻 문제 풀이 - ChatGPT 너는 잘 풀 수 있지!

오늘은 프롬프트를 조금 더 상세하게 작성해보았습니다.

👨🏻‍💻 SOMJANG

당신은 Python3 개발자입니다.

문제가 주어지면 문제의 의도를 잘 파악하고 파악한 바를 Python3 코드로 작성합니다.

코드를 작성하면서 설명이 필요한 부분은 주석으로 작성합니다.

마지막으로 여러 예시를 들어 작성한 코드에 대한 설명을 작성합니다.

문제를 드리겠습니다.

문제

Java 예찬론자 김동규와 C++ 옹호가 김동혁은 서로 어떤 프로그래밍 언어가 최고인지 몇 시간동안 토론을 하곤 했다. 동규는 Java가 명확하고 에러가 적은 프로그램을 만든다고 주장했고, 동혁이는 Java는 프로그램이 느리고, 긴 소스 코드를 갖는 점과 제네릭 배열의 인스턴스화의 무능력을 비웃었다.

 

또, 김동규와 김동혁은 변수 이름을 짓는 방식도 서로 달랐다. Java에서는 변수의 이름이 여러 단어로 이루어져있을 때, 다음과 같은 방법으로 변수명을 짓는다.

 

첫 단어는 소문자로 쓰고, 다음 단어부터는 첫 문자만 대문자로 쓴다. 또, 모든 단어는 붙여쓴다. 따라서 Java의 변수명은 javaIdentifier, longAndMnemonicIdentifier, name, bAEKJOON과 같은 형태이다.

 

반면에 C++에서는 변수명에 소문자만 사용한다. 단어와 단어를 구분하기 위해서 밑줄('_')을 이용한다. C++ 변수명은 c_identifier, long_and_mnemonic_identifier, name, b_a_e_k_j_o_o_n과 같은 형태이다.

 

이 둘의 싸움을 부질없다고 느낀 재원이는 C++형식의 변수명을 Java형식의 변수명으로, 또는 그 반대로 바꿔주는 프로그램을 만들려고 한다. 각 언어의 변수명 형식의 위의 설명을 따라야 한다.

 

재원이의 프로그램은 가장 먼저 변수명을 입력으로 받은 뒤, 이 변수명이 어떤 언어 형식인지를 알아내야 한다. 그 다음, C++형식이라면 Java형식으로, Java형식이라면 C++형식으로 바꾸면 된다. 만약 C++형식과 Java형식 둘 다 아니라면, 에러를 발생시킨다. 변수명을 변환할 때, 단어의 순서는 유지되어야 한다.

 

재원이는 프로그램을 만들려고 했으나, 너무 귀찮은 나머지 이를 문제를 읽는 사람의 몫으로 맡겨놨다.

 

재원이가 만들려고 한 프로그램을 대신 만들어보자.

 

입력

첫째 줄에 변수명이 주어진다. 영어 알파벳과 밑줄('_')로만 이루어져 있고, 길이는 100을 넘지 않는다.

출력

입력으로 주어진 변수명이 Java형식이면, C++형식으로 출력하고, C++형식이라면 Java형식으로 출력한다. 둘 다 아니라면 "Error!"를 출력한다.

💻 ChatGPT - 실패!

이 문제는 입력된 변수명이 C++형식인지, Java형식인지 판별한 후, 해당 형식에 맞추어 변수명을 변환하는 것이다.

 

Python3에서는 문자열에 대한 조작이 용이하므로, 입력된 변수명에서 밑줄의 유무와 대소문자를 판별해 변수명의 형식을 구분할 수 있다. 그리고 형식에 맞추어 변수명을 변환하는 것은 문자열을 자르고 합치는 과정으로 이루어진다.

 

따라서 Python3으로 작성한 소스코드는 다음과 같다.

# 변수명 입력 받기
variable_name = input()

# 변수명의 첫 문자가 대문자인 경우, Java형식으로 판별
if variable_name[0].isupper():
    # 변수명에서 밑줄을 제거하고 단어 첫 글자를 대문자로 변경
    new_name = ''.join([word.capitalize() for word in variable_name.split('_')])
    # Java형식을 C++형식으로 변환하여 출력
    print(new_name[0].lower() + new_name[1:].replace('_', ''))
    
# 변수명에 밑줄이 포함된 경우, C++형식으로 판별
elif '_' in variable_name:
    # 변수명에서 밑줄을 제거하고 각 단어 사이에 밑줄 추가
    new_name = '_'.join([word.lower() for word in variable_name.split(sep='_')])
    # C++형식을 Java형식으로 변환하여 출력
    print(''.join([word.capitalize() for word in new_name.split('_')]))
    
# 위 경우가 아니면 에러 메시지 출력
else:
    print("Error!")

이 코드는 입력된 변수명의 첫 문자가 대문자인 경우 Java형식으로 판별하고, 밑줄이 포함된 경우 C++형식으로 판별한다. 이를 위해 str.isupper() 메소드와 '_' in str을 사용한다.

 

그리고 변수명 변환은 각 형식에 맞는 문자열 처리를 통해 이루어진다. Java형식을 C++형식으로 변환할 때는 문자열을 자르고 대소문자를 변경하며, C++형식을 Java형식으로 변환할 때는 밑줄을 추가하고 각 단어의 첫 글자를 대문자로 변경한다.

 

다음은 이 코드의 몇 가지 예시이다.

예시 1

입력:

javaIdentifier

출력:

java_identifier

예시 2

입력:

long_and_mnemonic_identifier

출력:

longAndMnemonicIdentifier

예시 3

입력:

c_identifier

출력:

cIdentifier

예시 4

입력:

name

출력:

Error!

위 예시에서 볼 수 있듯이, 이 코드는 변수명의 형식에 따라 적절한 변환을 수행하며, 형식이 맞지 않는 경우 에러 메시지를 출력한다.

-> 코드를 작성하면서 설명이 필요한 부분에 주석을 해달라고 하니 주석도 달아주고 예시를 들어서 설명을 해달라고 하니 예시까지 들어주었습니다.

-> 하지만 답은 틀려 다시 풀어달라고 해보았습니다.

👨🏻‍💻 SOMJANG

입력 값이 name 일때는 name 이 그대로 출력되어야합니다.

 

Error! 가 출력으로 나오는 경우는 아래와 같습니다.

1. 맨 앞에 대문자가 들어오는 경우

2. 맨 앞 또는 맨뒤에 _ 가 있는 경우

3. _ 가 두번 이상 나오는 경우

4. c++ 변수명인데 대문자가 포함되어있는 경우

 

위 예외 케이스까지 포함해서 풀어주세요.

💻 ChatGPT - 실패!

이전에 작성한 코드에 예외 케이스를 추가하여 수정하겠습니다.

variable_name = input()

if variable_name[0].isupper() or variable_name.endswith('_') or '__' in variable_name:
    print('Error!')
elif '_' in variable_name:
    # C++ 형식 변수명을 Java 형식으로 바꾸기
    java_style = variable_name.split('_')
    result = java_style[0] + ''.join(word.capitalize() for word in java_style[1:])
    print(result)
else:
    # Java 형식 변수명을 C++ 형식으로 바꾸기
    c_style = ''
    for i, char in enumerate(variable_name):
        if char.isupper():
            if i != 0:
                c_style += '_'
            c_style += char.lower()
        else:
            c_style += char
    print(c_style)

변수명이 맨 앞에 대문자인 경우나 맨 앞이나 끝에 밑줄이 있는 경우, 그리고 밑줄이 두 번 이상 나오는 경우는 모두 C++ 형식 변수명이 아니므로 "Error!"를 출력합니다. 그리고 C++ 형식 변수명이면서 대문자가 포함되어 있는 경우도 예외 케이스로 추가하였습니다. 나머지 경우에는 변수명을 각각의 형식으로 변환합니다.

-> 47% 에서 실패를 하길래 테스트를 해보고 틀린 케이스를 알려주었습니다.

👨🏻‍💻 SOMJANG

back_Joon 일 경우 c++ 변수임에도 대문자가 포함되어있어서 Error! 로 처리해야해

💻 ChatGPT

네, 맞습니다. "back_Joon"은 C++ 변수명이지만 대문자가 포함되어 있으므로 Java 변수명으로 변환이 불가능합니다. 따라서 "Error!"를 출력해야 합니다.

👨🏻‍💻 SOMJANG

해당 예외처리를 추가해서 코드를 수정해줘

💻 ChatGPT

앞서 언급한 예외 처리를 포함하여 코드를 수정한 결과는 다음과 같습니다.

import re

# 변수명 입력 받기
variable_name = input().strip()

# 변수명 형식 확인하기
is_java = variable_name[0].islower() and "_" not in variable_name
is_cpp = variable_name.islower() and re.search(r'_', variable_name) is not None

# 변수명 변환하기
if is_java:
    # Java -> C++
    converted = ""
    for i, char in enumerate(variable_name):
        if char.isupper() and i > 0:
            converted += "_"
        converted += char.lower()
    print(converted)
elif is_cpp:
    # C++ -> Java
    words = variable_name.split("_")
    if any(word == "" for word in words):
        print("Error!")
    else:
        converted = words[0] + "".join(word.capitalize() for word in words[1:])
        print(converted)
else:
    print("Error!")

변수명의 형식을 확인하는 부분에서, C++ 변수명인 경우 대문자가 포함되어 있지 않는지를 추가적으로 확인하도록 하였습니다.

 

Java 형식의 변수명에서 C++ 형식으로의 변환은, 대문자 앞에 언더스코어를 추가하여 변환하는 것으로 수정하였습니다. 이는 대문자가 변수명에서 단어의 시작을 나타낼 때, 해당 단어와 다른 단어로 인식하기 위함입니다.

 

또한, C++ 형식의 변수명에서 Java 형식으로의 변환은, 대문자가 나오는 부분 앞에 언더스코어를 추가하고, 그 다음 문자를 대문자로 바꾸어 변환하는 것으로 수정하였습니다.

 

이러한 수정으로, 입력 값이 back_Joon 일 때 Error! 가 출력되도록 변경되었습니다.

-> 프롬프트를 조금 더 상세하게 작성해서 그런지

-> 이 문제는 최신 문제가 아니어서 그런지

-> 이번에는 최근 문제들 보다 훨씬 더 잘 풀어주었습니다.

 

코딩 1일 1문제! 이렇게 1000일째 문제를 ChatGPT 에게까지 풀어달라고 해보았습니다.

1000일까지 오는 동안 솔직히 오늘 문제 빨리 풀고 치워야지 하는 마음에 

쉬운 문제를 찾아다녔고 쉬운 문제만 그냥 후딱 풀고 끝낸 적이 더 많은 것 같습니다.

앞으로는 1일 1문제 보다는 조금 더 심도 깊은 문제를 조금 더 고민해보고 풀어보려고 합니다.

 

읽어주셔서 감사합니다.

 

GitHub - SOMJANG/CODINGTEST_PRACTICE: 1일 1문제 since 2020.02.07

1일 1문제 since 2020.02.07. Contribute to SOMJANG/CODINGTEST_PRACTICE development by creating an account on GitHub.

github.com

Comments