ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 숫자 게임 4=10 솔루션 프로그램
    취미 코딩 2023. 11. 10. 13:59

     

    https://play.google.com/store/apps/details?id=app.fourequalsten.fourequalsten_app&pcampaignid=web_share

     

    4=10 - Google Play 앱

    캐주얼하고 재미있는 숫자 퍼즐

    play.google.com

     

    최근에 숫자 퍼즐 게임 4=10을 하고 있다.

    광고가 없고, 평가가 아주 좋아서 시작하게 되었다.

    숫자 4개를 가지고 사칙연산과 괄호를 사용해 10을 만들면 되는 간단한 게임이다.

    500 레벨이 정말 재미있다고 해서 열심히 달리고 있다.

     

    역시나 이 문제를 풀어주는 프로그램을 만들었다..

    250 레벨까진 머리로 했는데,

    생각하기가 너무 귀찮았고,

    만드는 것도 재밋겠다 싶어서 만들어봤다.

     

    그래도 500 까지 머리로 풀어볼 예정!

     

    그리고 앱을 사면 4=12, 4=24, 4=100 을 할 수 있다!

     

    Chat GPT의 도움으로 쉽게 만들었다 :)

    LINQPad에서 실행하면 됨.

     

    LINQPad를 이용한 4=10 솔루션 프로그램

     

     

     

    int[] values = new int[] { 1, 3, 9, 8 };
    
    List<Formula> result = new List<Formula>();
    Req(new Formula(), values, BracketStatus.None, result);
    
    result
        .Select(x => new { Formula = x.ToString(), Result = x.CalcResult() })
        .Where(x => x.Result == 10)
        // .Where(x => !x.Formula.Contains("("))
        .Dump();
    
    
    void Req(Formula curr, int[] values, BracketStatus bracketStatus, List<Formula> result)
    {
        char[] operators = new char[] { '+', '-', '*', '/' };
        if (values.Length == 1)
        {
            var value = values[0];
            if (bracketStatus == BracketStatus.Opened)
            {
                // 앞에서 괄호를 연 경우
                // 괄호를 닫는다.
                var next = curr.Append(value).Append(')');
                result.Add(next);
            }
            else
            {
                var next = curr.Append(value);
                result.Add(next);
            }
        }
        else
        {
            for (var i = 0; i < values.Length; i++)
            {
                var value = values[i];
                var nextValues = values.Where((x, index) => index != i).ToArray();
                foreach (var op in operators)
                {
                    switch (bracketStatus)
                    {
                        case BracketStatus.None:
                            {
                                // 괄호를 아직 사용하지 않은 경우
    
                                // 괄호를 연다.
                                var next1 = curr.Append('(').Append(value).Append(op);
                                Req(next1, nextValues, BracketStatus.Opened, result);
    
                                // 괄호를 열지 않는다.
                                var next2 = curr.Append(value).Append(op);
                                Req(next2, nextValues, BracketStatus.None, result);
                                break;
                            }
                        case BracketStatus.Opened:
                            {
                                // 앞에서 괄호를 연 경우
    
                                // 괄호를 닫는다.
                                var next1 = curr.Append(value).Append(')').Append(op);
                                Req(next1, nextValues, BracketStatus.Closed, result);
    
                                // 괄호를 닫지 않는다.
                                var next2 = curr.Append(value).Append(op);
                                Req(next2, nextValues, BracketStatus.Opened, result);
                                break;
                            }
                        case BracketStatus.Closed:
                            {
                                // 괄호를 열었다 닫은 경우
                                var next = curr.Append(value).Append(op);
                                Req(next, nextValues, BracketStatus.Closed, result);
                                break;
                            }
                    }
                }
            }
        }
    }
    
    enum BracketStatus
    {
        None,
        Opened,
        Closed,
    }
    
    public class Formula
    {
        private string[] Items = new string[] { };
    
        public Formula Append(int value)
        {
            return new Formula
            {
                Items = Items.Append(value.ToString()).ToArray()
            };
        }
    
        public Formula Append(char op)
        {
            return new Formula
            {
                Items = Items.Append(op.ToString()).ToArray()
            };
        }
    
        public override string ToString()
        {
            return string.Join(string.Empty, Items);
        }
    
        public double CalcResult()
        {
            try
            {
                return InfixToPostfixCalculator.Calculate(Items);
            }
            catch
            {
                return double.MinValue;
            }
        }
    }
    
    
    public class InfixToPostfixCalculator
    {
        public static double Calculate(string[] input)
        {
            Stack<double> operandStack = new Stack<double>();
            Stack<char> operatorStack = new Stack<char>();
    
            Dictionary<char, int> precedence = new Dictionary<char, int>
            {
                { '+', 1 },
                { '-', 1 },
                { '*', 2 },
                { '/', 2 },
                { '(', 0 }, // (의 우선 순위를 가장 낮게 설정
                { ')', 0 }, // )의 우선 순위를 가장 낮게 설정
            };
    
            foreach (string token in input)
            {
                if (double.TryParse(token, out double number))
                {
                    operandStack.Push(number);
                }
                else if (token == "(")
                {
                    operatorStack.Push('(');
                }
                else if (token == ")")
                {
                    while (operatorStack.Count > 0 && operatorStack.Peek() != '(')
                    {
                        char op = operatorStack.Pop();
                        double operand2 = operandStack.Pop();
                        double operand1 = operandStack.Pop();
                        operandStack.Push(ApplyOperator(op, operand1, operand2));
                    }
                    operatorStack.Pop(); // Pop the '('
                }
                else
                {
                    while (operatorStack.Count > 0 && precedence[operatorStack.Peek()] >= precedence[token[0]])
                    {
                        char op = operatorStack.Pop();
                        double operand2 = operandStack.Pop();
                        double operand1 = operandStack.Pop();
                        operandStack.Push(ApplyOperator(op, operand1, operand2));
                    }
                    operatorStack.Push(token[0]);
                }
            }
    
            while (operatorStack.Count > 0)
            {
                char op = operatorStack.Pop();
                double operand2 = operandStack.Pop();
                double operand1 = operandStack.Pop();
                operandStack.Push(ApplyOperator(op, operand1, operand2));
            }
    
            return operandStack.Pop();
        }
    
        private static double ApplyOperator(char op, double operand1, double operand2)
        {
            switch (op)
            {
                case '+':
                    return operand1 + operand2;
                case '-':
                    return operand1 - operand2;
                case '*':
                    return operand1 * operand2;
                case '/':
                    if (operand2 == 0)
                        throw new DivideByZeroException("Division by zero is not allowed.");
                    return operand1 / operand2;
                default:
                    throw new ArgumentException("Invalid operator: " + op);
            }
        }
    }
Designed by Tistory.