-
숫자 게임 4=10 솔루션 프로그램취미 코딩 2023. 11. 10. 13:59
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); } } }