문제/프로그래머스

[프로그래머스] [PCCP 기출문제] 4번 / 수식 복원하기 - Java

icodesiuuuu 2024. 11. 26. 23:29

문제

https://school.programmers.co.kr/learn/courses/30/lessons/340210

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 


문제 개요

주어진 수식에서 2~9진법 중 하나를 사용하고 있다는 전제하에, 수식의 진법을 판단하고 지워진 결괏값(X)을 올바르게 채워넣는 문제입니다. 모든 수식은 덧셈(+) 또는 뺄셈(-) 연산으로 이루어져 있으며, 정확한 결과를 도출하거나 불확실할 경우 ?로 표기해야 합니다.

 

접근 방법

  1. 진법 검증을 위한 데이터 구조 설정
    • 2진법부터 9진법까지의 유효성을 확인하기 위해, 각 진법에서 해당 수식이 성립하는 횟수를 기록하는 배열(base)을 선언합니다.
  2. 수식 분류
    • 주어진 수식을 순회하며 결괏값이 X인지 아닌지에 따라 분류:
      • X가 포함된 경우: 나중에 처리하기 위해 리스트(target)에 저장.
      • 결과값이 명확한 경우: 각 진법에서 수식의 유효성을 확인하고, 해당 진법의 카운트를 증가.
  3. 미지수 수식 처리
    • X로 표시된 수식은 모든 진법(2~9)을 기준으로 가능한 결괏값을 계산하며, 진법별로 유효성을 확인합니다.
  4. 최다 카운트 진법 판별
    • 유효성이 가장 많이 성립한 진법을 기준으로 미지수 수식의 결괏값을 계산합니다.
  5. 결과 생성
    • 각 수식에 대해 계산된 결과값이 모든 진법에서 동일하면 해당 값을 사용.
    • 결과값이 진법에 따라 달라질 경우 ?로 표시.

 

코드

import java.util.*;
class Solution {
    public String[] solution(String[] expressions) {
        int[] base = new int[10];
        List<String> target = new ArrayList<>();
        
        for(String s : expressions) {
            String[] bucket = s.split(" ");
            if(bucket[4].equals("X")) {
                target.add(s);
            } else {
                checkAndCnt(base, bucket);
            }
        }
        
        for(String s : target) {
            String[] bucket = s.split(" ");
            countForUnkown(base, bucket);
        }
        
        int max = Arrays.stream(base).max().orElseThrow();
        String[] answer = new String[target.size()];
        
        for(int i=0; i<target.size(); i++) {
            String[] bucket = target.get(i).split(" ");
            Set<String> set = new HashSet<>();            
            generateAns(answer, bucket, base, target, set, i, max);
        }
        
        return answer;
    }
    
    public void generateAns(String[] answer, String[] bucket, int[] base, List<String> target, Set<String> set, int i, int max) {
        for(int j=2; j<=9; j++) {
            if(max == base[j]) {
                try {
                    int num1 = Integer.parseInt(bucket[0], j);
                    int num2 = Integer.parseInt(bucket[2], j);
                    int result = bucket[1].equals("+") ? num1 + num2 : num1 - num2;
                    set.add(Integer.toString(result, j));
                } catch (Exception e) {
                    continue;
                }                    
            }
        }
        if(set.size() == 1) {
            String s = target.get(i).substring(0, target.get(i).length()-1);
            answer[i] = s + set.iterator().next();
        } else {
            String s = target.get(i).substring(0, target.get(i).length()-1);
            answer[i] = s + "?";
        }
    }
    
    public void cntForUnkown(int[] base, String[] bucket) {
        for(int j=2; j<=9; j++) {
            try {
                int num1 = Integer.parseInt(bucket[0], j);
                int num2 = Integer.parseInt(bucket[2], j);
                base[j]++;
            } catch (Exception e) {
                continue;
            }
        }
    }
    
    public void checkAndCnt(int[] base, String[] bucket) {
        for(int j=2; j<=9; j++) {
            try {
                int num1 = Integer.parseInt(bucket[0], j);
                int num2 = Integer.parseInt(bucket[2], j);
                int result = Integer.parseInt(bucket[4], j);
                if(bucket[1].equals("+")) {
                    if(num1 + num2 == result) {
                        base[j]++;
                    }
                } else {
                    if(num1 - num2 == result) {
                        base[j]++;
                    }
                }
            } catch (Exception e) {
                    continue;
            }
        }
    }
}