ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Algo RhythmπŸ•ΊπŸ’ƒ] 2020 카카였 인턴십 μˆ˜μ‹ μ΅œλŒ€ν™”
    Algo RhythmπŸ•ΊπŸ’ƒ/others 2020. 7. 5. 23:40

    문제 μ„€λͺ…

    IT 벀처 νšŒμ‚¬λ₯Ό μš΄μ˜ν•˜κ³  μžˆλŠ” λΌμ΄μ–Έμ€ 맀년 사내 해컀톀 λŒ€νšŒλ₯Ό κ°œμ΅œν•˜μ—¬ μš°μŠΉμžμ—κ²Œ μƒκΈˆμ„ μ§€κΈ‰ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

    이번 λŒ€νšŒμ—μ„œλŠ” μš°μŠΉμžμ—κ²Œ μ§€κΈ‰λ˜λŠ” μƒκΈˆμ„ 이전 λŒ€νšŒμ™€λŠ” λ‹€λ₯΄κ²Œ λ‹€μŒκ³Ό 같은 λ°©μ‹μœΌλ‘œ κ²°μ •ν•˜λ €κ³  ν•©λ‹ˆλ‹€.

    해컀톀 λŒ€νšŒμ— μ°Έκ°€ν•˜λŠ” λͺ¨λ“  μ°Έκ°€μžλ“€μ—κ²ŒλŠ” μˆ«μžλ“€κ³Ό 3κ°€μ§€μ˜ μ—°μ‚°λ¬Έμž(+, -, *) 만으둜 이루어진 μ—°μ‚° μˆ˜μ‹μ΄ μ „λ‹¬λ˜λ©°, μ°Έκ°€μžμ˜ λ―Έμ…˜μ€ 전달받은 μˆ˜μ‹μ— ν¬ν•¨λœ μ—°μ‚°μžμ˜ μš°μ„ μˆœμœ„λ₯Ό 자유둭게 μž¬μ •μ˜ν•˜μ—¬ λ§Œλ“€ 수 μžˆλŠ” κ°€μž₯ 큰 숫자λ₯Ό μ œμΆœν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

    단, μ—°μ‚°μžμ˜ μš°μ„ μˆœμœ„λ₯Ό μƒˆλ‘œ μ •μ˜ν•  λ•Œ, 같은 μˆœμœ„μ˜ μ—°μ‚°μžλŠ” μ—†μ–΄μ•Ό ν•©λ‹ˆλ‹€. 즉, + > - > * λ˜λŠ” - > * > + λ“±κ³Ό 같이 μ—°μ‚°μž μš°μ„ μˆœμœ„λ₯Ό μ •μ˜ν•  수 μžˆμœΌλ‚˜ +,* > - λ˜λŠ” * > +,-처럼 2개 μ΄μƒμ˜ μ—°μ‚°μžκ°€ λ™μΌν•œ μˆœμœ„λ₯Ό 가지도둝 μ—°μ‚°μž μš°μ„ μˆœμœ„λ₯Ό μ •μ˜ν•  μˆ˜λŠ” μ—†μŠ΅λ‹ˆλ‹€. μˆ˜μ‹μ— ν¬ν•¨λœ μ—°μ‚°μžκ°€ 2개라면 μ •μ˜ν•  수 μžˆλŠ” μ—°μ‚°μž μš°μ„ μˆœμœ„ 쑰합은 2! = 2가지이며, μ—°μ‚°μžκ°€ 3개라면 3! = 6가지 쑰합이 κ°€λŠ₯ν•©λ‹ˆλ‹€.

    λ§Œμ•½ κ³„μ‚°λœ κ²°κ³Όκ°€ 음수라면 ν•΄λ‹Ή 숫자의 μ ˆλŒ“κ°’μœΌλ‘œ λ³€ν™˜ν•˜μ—¬ μ œμΆœν•˜λ©° μ œμΆœν•œ μˆ«μžκ°€ κ°€μž₯ 큰 μ°Έκ°€μžλ₯Ό 우승자둜 μ„ μ •ν•˜λ©°, μš°μŠΉμžκ°€ μ œμΆœν•œ 숫자λ₯Ό μš°μŠΉμƒκΈˆμœΌλ‘œ μ§€κΈ‰ν•˜κ²Œ λ©λ‹ˆλ‹€.

    예λ₯Ό λ“€μ–΄, μ°Έκ°€μž 쀑 λ„€μ˜€κ°€ μ•„λž˜μ™€ 같은 μˆ˜μ‹μ„ μ „λ‹¬λ°›μ•˜λ‹€κ³  κ°€μ •ν•©λ‹ˆλ‹€.

     

    "100-200*300-500+20"

     

    일반적으둜 μˆ˜ν•™ 및 μ „μ‚°ν•™μ—μ„œ μ•½μ†λœ μ—°μ‚°μž μš°μ„ μˆœμœ„μ— λ”°λ₯΄λ©΄ λ”ν•˜κΈ°μ™€ λΉΌκΈ°λŠ” μ„œλ‘œ λ™λ“±ν•˜λ©° κ³±ν•˜κΈ°λŠ” λ”ν•˜κΈ°, 빼기에 λΉ„ν•΄ μš°μ„ μˆœμœ„κ°€ λ†’μ•„ * > +,- λ‘œ μš°μ„ μˆœμœ„κ°€ μ •μ˜λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

    λŒ€νšŒ κ·œμΉ™μ— 따라 + > - > * λ˜λŠ” - > * > + λ“±κ³Ό 같이 μ—°μ‚°μž μš°μ„ μˆœμœ„λ₯Ό μ •μ˜ν•  수 μžˆμœΌλ‚˜ +,* > - λ˜λŠ” * > +,- μ²˜λŸΌ 2개 μ΄μƒμ˜ μ—°μ‚°μžκ°€ λ™μΌν•œ μˆœμœ„λ₯Ό 가지도둝 μ—°μ‚°μž μš°μ„ μˆœμœ„λ₯Ό μ •μ˜ν•  μˆ˜λŠ” μ—†μŠ΅λ‹ˆλ‹€.

    μˆ˜μ‹μ— μ—°μ‚°μžκ°€ 3개 μ£Όμ–΄μ‘ŒμœΌλ―€λ‘œ κ°€λŠ₯ν•œ μ—°μ‚°μž μš°μ„ μˆœμœ„ 쑰합은 3! = 6가지이며, κ·Έ 쀑 + > - > * λ‘œ μ—°μ‚°μž μš°μ„ μˆœμœ„λ₯Ό μ •ν•œλ‹€λ©΄ 결괏값은 22,000원이 λ©λ‹ˆλ‹€.

    λ°˜λ©΄μ— * > + > - λ‘œ μ—°μ‚°μž μš°μ„ μˆœμœ„λ₯Ό μ •ν•œλ‹€λ©΄ μˆ˜μ‹μ˜ 결괏값은 -60,420 μ΄μ§€λ§Œ, κ·œμΉ™μ— 따라 우승 μ‹œ μƒκΈˆμ€ μ ˆλŒ“κ°’μΈ 60,420원이 λ©λ‹ˆλ‹€.

    μ°Έκ°€μžμ—κ²Œ 주어진 μ—°μ‚° μˆ˜μ‹μ΄ λ‹΄κΈ΄ λ¬Έμžμ—΄ expression이 λ§€κ°œλ³€μˆ˜λ‘œ μ£Όμ–΄μ§ˆ λ•Œ, 우승 μ‹œ 받을 수 μžˆλŠ” κ°€μž₯ 큰 μƒκΈˆ κΈˆμ•‘μ„ return ν•˜λ„λ‘ solution ν•¨μˆ˜λ₯Ό μ™„μ„±ν•΄μ£Όμ„Έμš”.

     

    [μ œν•œμ‚¬ν•­]

    • expression은 길이가 3 이상 100 μ΄ν•˜μΈ λ¬Έμžμ—΄μž…λ‹ˆλ‹€.

    • expression은 곡백문자, κ΄„ν˜Έλ¬Έμž 없이 μ˜€λ‘œμ§€ μˆ«μžμ™€ 3κ°€μ§€μ˜ μ—°μ‚°μž(+, -, *) 만으둜 이루어진 μ˜¬λ°”λ₯Έ μ€‘μœ„ν‘œκΈ°λ²•(μ—°μ‚°μ˜ 두 λŒ€μƒ 사이에 μ—°μ‚°κΈ°ν˜Έλ₯Ό μ‚¬μš©ν•˜λŠ” 방식)으둜 ν‘œν˜„λœ μ—°μ‚°μ‹μž…λ‹ˆλ‹€. 잘λͺ»λœ 연산식은 μž…λ ₯으둜 주어지지 μ•ŠμŠ΅λ‹ˆλ‹€.

      • 즉, "402+-561*"처럼 잘λͺ»λœ μˆ˜μ‹μ€ μ˜¬λ°”λ₯Έ μ€‘μœ„ν‘œκΈ°λ²•μ΄ μ•„λ‹ˆλ―€λ‘œ 주어지지 μ•ŠμŠ΅λ‹ˆλ‹€.

    • expression의 ν”Όμ—°μ‚°μž(operand)λŠ” 0 이상 999 μ΄ν•˜μ˜ μˆ«μžμž…λ‹ˆλ‹€.

      • 즉, "100-2145*458+12"처럼 999λ₯Ό μ΄ˆκ³Όν•˜λŠ” ν”Όμ—°μ‚°μžκ°€ ν¬ν•¨λœ μˆ˜μ‹μ€ μž…λ ₯으둜 주어지지 μ•ŠμŠ΅λ‹ˆλ‹€.

      • "-56+100"처럼 ν”Όμ—°μ‚°μžκ°€ 음수인 μˆ˜μ‹λ„ μž…λ ₯으둜 주어지지 μ•ŠμŠ΅λ‹ˆλ‹€.

    • expression은 적어도 1개 μ΄μƒμ˜ μ—°μ‚°μžλ₯Ό ν¬ν•¨ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

    • μ—°μ‚°μž μš°μ„ μˆœμœ„λ₯Ό μ–΄λ–»κ²Œ μ μš©ν•˜λ”λΌλ„, expression의 쀑간 계산값과 μ΅œμ’… 결괏값은 μ ˆλŒ“κ°’μ΄ 263 - 1 μ΄ν•˜κ°€ λ˜λ„λ‘ μž…λ ₯이 μ£Όμ–΄μ§‘λ‹ˆλ‹€.

    • 같은 μ—°μ‚°μžλΌλ¦¬λŠ” μ•žμ— μžˆλŠ” κ²ƒμ˜ μš°μ„ μˆœμœ„κ°€ 더 λ†’μŠ΅λ‹ˆλ‹€.

     

    μ–΄λ–»κ²Œ ν’€μ—ˆλ‚˜

    import java.util.ArrayList;
    import java.lang.StringBuilder;
    import java.util.Arrays;
    import java.util.stream.Collectors;
    
    class Solution {
        public long solution(String expression) {
            long maxPrizeMoney = Long.MIN_VALUE;
            ArrayList<String> tokens = tokenize(expression);
            ArrayList<String> optrs = extractOptr(expression);
            
            // get permuations of operators
            ArrayList<ArrayList<String>> permOfOptrs = new ArrayList<ArrayList<String>>();
            permutate(permOfOptrs, optrs.toArray(new String[0]), 0, optrs.size());
            
            // get maximum of prize money
            for(ArrayList<String> priorityOfOptrs : permOfOptrs) {
                ArrayList<String> copyOfTokens = new ArrayList<>(tokens);
                long prizeMoney = 0;
                
                // reduce
                for(String pOptr : priorityOfOptrs) {
                    while(copyOfTokens.indexOf(pOptr) != -1) {
                        int idx = copyOfTokens.indexOf(pOptr);
                        
                        long result = 0;
                        long opd1 = Long.parseLong(copyOfTokens.get(idx - 1));
                        long opd2 = Long.parseLong(copyOfTokens.get(idx + 1));
                        
                        switch(pOptr) {
                            case "+":
                                result = opd1 + opd2;
                                break;
                            case "*":
                                result = opd1 * opd2;
                                break;
                            case "-":
                                result = opd1  - opd2;
                                break;
                        }
                        
                        for(int a = 0; a < 3; a++) copyOfTokens.remove(idx - 1);
                        copyOfTokens.add(idx - 1, String.valueOf(result));
                    }
                }
                
                prizeMoney = Math.abs(Long.parseLong(copyOfTokens.get(0)));
                
                // renew the maximum of prize money
                maxPrizeMoney = (maxPrizeMoney >= prizeMoney) ? maxPrizeMoney : prizeMoney;
            }
        
            return maxPrizeMoney;
        } 
        
        public void permutate(ArrayList<ArrayList<String>> permOfOptrs, String[] optrs, int depth, int n) {
            if(depth == n) {
                ArrayList<String> list = Arrays.stream(optrs).collect(Collectors.toCollection(ArrayList::new));   
                permOfOptrs.add(list);
                return;
            }
            
            for(int i = depth; i < n; i++) {
                swap(optrs, depth, i);
                permutate(permOfOptrs, optrs, depth + 1, n);
                swap(optrs, depth, i);
            }
        }
        
        public void swap(String[] arr, int depth, int i) {
            String temp = arr[depth];
            arr[depth] = arr[i];
            arr[i] = temp;
        }
        
        public ArrayList<String> extractOptr(String exp) {
            ArrayList<String> optrs = new ArrayList<>();
            
            if(exp.contains("-")) optrs.add("-");
            if(exp.contains("+")) optrs.add("+");
            if(exp.contains("*")) optrs.add("*");
            
            return optrs;
        }
        
        public ArrayList<String> tokenize(String exp) {
            ArrayList<String> tokens = new ArrayList<>();
            char[] expArr = exp.toCharArray();
            StringBuilder sbd = new StringBuilder();
            
            for(int i = 0; i < expArr.length; i++) {
                if(expArr[i] == '-' || expArr[i] == '+' || expArr[i] == '*') {
                    tokens.add(sbd.toString());
                    sbd.setLength(0); // clear
                    
                    sbd.append(expArr[i]);
                    tokens.add(sbd.toString());
                    sbd.setLength(0); // clear
                }
                else {
                   sbd.append(expArr[i]); 
                }
            	
                if(i == expArr.length - 1) tokens.add(sbd.toString()); // add last number
            }
            
            return tokens;
        }
    }

     

    μ™œ μ €λ ‡κ²Œ ν’€μ—ˆλ‚˜

    λ¨Όμ € 주어진 μˆ˜μ‹μ„ tokenizeν•œλ‹€.

    κ·Έλ¦¬κ³ λ‚˜μ„œ μˆ˜μ‹μ— μžˆλŠ” μ—°μ‚°μžλ“€μ„ νŒŒμ•…ν•œ λ’€ κ·Έκ²ƒλ“€μ˜ μˆœμ—΄μ„ κ΅¬ν•œλ‹€.

    μˆœμ—΄λ“€μ˜ μ§‘ν•©μ—μ„œ μˆœμ—΄ 즉, μ—°μ‚°μžμ˜ μš°μ„ μˆœμœ„λ₯Ό ν•˜λ‚˜μ”© κ°€μ Έμ˜¨λ‹€.

     

    κ·Έλ¦¬κ³ λ‚˜μ„œ μˆ˜μ‹μ„ tokenizeν•œ listμ—μ„œ κ·Έ μ—°μ‚°μžλ₯Ό 가지고 μžˆλŠ” indexλ₯Ό μ°ΎλŠ”λ‹€.

    λ§Œμ•½ -1이 returnλ˜μ—ˆμœΌλ©΄ μ—†λ‹€λŠ” 뜻이기 λ•Œλ¬Έμ— λ°˜λ³΅λ¬Έμ—μ„œ νƒˆμΆœν•œλ‹€.

    λ§Œμ•½ κ·Έ μ—°μ‚°μžκ°€ μ‘΄μž¬ν•˜λ©΄ μ—°μ‚°μžμ— λ§žλŠ” 연산을 ν•œ λ’€ resultλΌλŠ” λ³€μˆ˜μ— μ €μž₯ν•œλ‹€.

    그리고 κ·Έ μ—°μ‚°μžμ™€ μ™Όμͺ½, 였λ₯Έμͺ½μ— μžˆλŠ” ν”Όμ—°μ‚°μž 두 개λ₯Ό μ‚­μ œν•œλ‹€.

    λ‹€μŒμœΌλ‘œ μ™Όμͺ½ μ—°μ‚°μžκ°€ 있던 index에 resultλ₯Ό string으둜 λ³€ν™˜ν•˜μ—¬ addν•œλ‹€.

     

    μœ„ 과정을 μˆœμ—΄μ— μžˆλŠ” λͺ¨λ“  μ—°μ‚°μžμ— λŒ€ν•΄ λ°˜λ³΅ν•˜λ©΄ κ²°κ³Ό 즉, μš°μŠΉμƒκΈˆμ΄ λ‚˜μ˜¨λ‹€.

    μš°μŠΉμƒκΈˆμ„ long으둜 parseν•œ λ’€ κ°€μž₯ λ§Žμ€ μš°μŠΉμƒκΈˆμΈμ§€ ν™•μΈν•œλ‹€.

     

    μœ„ 과정을 μˆœμ—΄λ“€μ˜ μ§‘ν•©μ—μ„œ λͺ¨λ“  μˆœμ—΄μ„ 확인할 λ•ŒκΉŒμ§€ λ°˜λ³΅ν•œλ‹€.

     

    무엇을 λ°°μ› λ‚˜

    μ•„λž˜ λΈ”λ‘œκ·Έλ₯Ό μ°Έκ³ ν•΄μ„œ μˆœμ—΄ κ΅¬ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜μ„ κ΅¬ν˜„ν–ˆλ‹€.

    https://bcp0109.tistory.com/14

     

    문제λ₯Ό μ½κ³ λ‚˜μ„œ ν•œμ°Έ κ³ λ―Όν•˜λ‹€κ°€ 이 μ•Œκ³ λ¦¬μ¦˜μ„ μƒκ°ν–ˆλ‹€. ν•˜μ§€λ§Œ λ„ˆλ¬΄ brute force방식이기 λ•Œλ¬Έμ— 이건 μ‹€νŒ¨ν•  것이라고 μƒκ°ν–ˆλ‹€.

    ν•˜μ§€λ§Œ 이게 μ™  κ±Έ…! 3쀑 λ°˜λ³΅λ¬Έμ„ ν†΅κ³Όμ‹œμΌœμ€€λ‹€…!πŸ˜…πŸ˜…

    λΆ„λͺ… μΉ΄μΉ΄μ˜€μ—μ„œ μ˜λ„ν•œ 효율적인 μ½”λ“œκ°€ μžˆμ„ 것 같은데... 흠... 아직 λ‚΄ λ¨Έλ¦¬λ‘œλŠ” 잘 λͺ¨λ₯΄κ² λ‹€...

    λŒ“κΈ€

Designed by Tistory.