↓Recommended Follow↓
Introduction
I often play the 24-point game with my son. Sometimes it’s quite challenging, and after a while, we can’t solve it, so we just give up, treating it as unsolvable.
With my mathematical ability, generally speaking, if we can’t solve it, it’s likely unsolvable.
However, when encountering particularly tricky ones, it’s possible to treat them as unsolvable, so I’ve always wanted to find a program that can directly solve the 24-point game.
But after searching online for a while, I couldn’t find one.
I thought about writing one myself, but I couldn’t figure out the logic behind it, and I didn’t know how to write the algorithm.
While sitting in front of the computer in the afternoon, for some reason, it felt like I suddenly had an epiphany. As I wrote, I actually managed to create it.
I’m sharing it here for reference for those who are interested. Please point out any problems.
Revision 1: Added the algorithm for (a,b) and (c,d)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace Calc24Point
{
internal class Program
{
private static void Main(string[] args)
{
while (true)
{
var a = int.Parse(Console.ReadLine());
var b = int.Parse(Console.ReadLine());
var c = int.Parse(Console.ReadLine());
var d = int.Parse(Console.ReadLine());
Console.Clear();
Console.WriteLine($"{a}, {b}, {c}, {d}");
Console.WriteLine("------------------------");
var items = CalcHelper.CalcResult(a, b, c, d);
if (items?.Any() == true)
{
foreach (var item in items)
{
Console.WriteLine(item);
}
}
else
{
Console.WriteLine("No solution");
}
Console.WriteLine("------------------------");
}
}
public class CalcHelper
{
public static List<string> CalcResult(double a, double b, double c, double d)
{
List<string> myList = new List<string>();
List<CalcInfo> items = MakeCalcs(a, b, c, d);
foreach (var item in items)
{
var result = item.GetResult();
if (double.IsNaN(result) == false && IsEqual(result, 24))
{
var text = item.GetString();
if (myList.Contains(text) == false)
{
myList.Add(text);
}
}
}
return myList;
}
private static bool IsEqual(double a, double b)
{
return Math.Abs(a - b) < 0.000001;
}
private static List<CalcInfo> MakeCalcs(double a, double b, double c, double d)
{
var items = new List<CalcInfo>();
items.AddRange(MakeCalcs(a, (b, c, d)));
items.AddRange(MakeCalcs(b, (a, c, d)));
items.AddRange(MakeCalcs(c, (b, a, d)));
items.AddRange(MakeCalcs(d, (b, c, a)));
items.AddRange(MakeCalcs((a, b), (c, d)));
items.AddRange(MakeCalcs((a, c), (b, d)));
items.AddRange(MakeCalcs((a, d), (c, b)));
return items;
}
private static IEnumerable<CalcInfo> MakeCalcs((double a, double b) p1, (double c, double d) p2)
{
foreach (CalcInfo item1 in MakeCalcs(p1.a, p1.b))
{
foreach (CalcInfo item2 in MakeCalcs(p2.c, p2.d))
{
yield return new CalcInfo(item1, item2, EMode.Add);
yield return new CalcInfo(item1, item2, EMode.Subtract);
yield return new CalcInfo(item2, item1, EMode.Subtract);
yield return new CalcInfo(item1, item2, EMode.Multiply);
yield return new CalcInfo(item1, item2, EMode.Divide);
yield return new CalcInfo(item2, item1, EMode.Divide);
}
}
}
private static IEnumerable<CalcInfo> MakeCalcs(double item1, (double b, double c, double d) p)
{
foreach (CalcInfo item2 in MakeCalcs(p.b, (p.c, p.d)))
{
yield return new CalcInfo(item1, item2, EMode.Add);
yield return new CalcInfo(item1, item2, EMode.Subtract);
yield return new CalcInfo(item2, item1, EMode.Subtract);
yield return new CalcInfo(item1, item2, EMode.Multiply);
yield return new CalcInfo(item1, item2, EMode.Divide);
yield return new CalcInfo(item2, item1, EMode.Divide);
}
foreach (CalcInfo item2 in MakeCalcs(p.c, (p.b, p.d)))
{
yield return new CalcInfo(item1, item2, EMode.Add);
yield return new CalcInfo(item1, item2, EMode.Subtract);
yield return new CalcInfo(item2, item1, EMode.Subtract);
yield return new CalcInfo(item1, item2, EMode.Multiply);
yield return new CalcInfo(item1, item2, EMode.Divide);
yield return new CalcInfo(item2, item1, EMode.Divide);
}
foreach (CalcInfo item2 in MakeCalcs(p.d, (p.b, p.c)))
{
yield return new CalcInfo(item1, item2, EMode.Add);
yield return new CalcInfo(item1, item2, EMode.Subtract);
yield return new CalcInfo(item2, item1, EMode.Subtract);
yield return new CalcInfo(item1, item2, EMode.Multiply);
yield return new CalcInfo(item1, item2, EMode.Divide);
yield return new CalcInfo(item2, item1, EMode.Divide);
}
}
private static IEnumerable<CalcInfo> MakeCalcs(double item1, double item2)
{
yield return new CalcInfo(item1, item2, EMode.Add);
yield return new CalcInfo(item1, item2, EMode.Subtract);
yield return new CalcInfo(item2, item1, EMode.Subtract);
yield return new CalcInfo(item1, item2, EMode.Multiply);
yield return new CalcInfo(item1, item2, EMode.Divide);
yield return new CalcInfo(item2, item1, EMode.Divide);
}
}
public class CalcInfo
{
public CalcInfo Items1 { get; set; }
public CalcInfo Items2 { get; set; }
public EMode? Mode { get; set; }
public double Result { get; set; }
public CalcInfo(double value)
{
Result = value;
}
public CalcInfo(double value1, double value2, EMode mode) : this(new CalcInfo(value1), new CalcInfo(value2), mode)
{
}
public CalcInfo(double value1, CalcInfo value2, EMode mode) : this(new CalcInfo(value1), value2, mode)
{
}
public CalcInfo(CalcInfo value1, double value2, EMode mode) : this(value1, new CalcInfo(value2), mode)
{
}
public CalcInfo(CalcInfo value1, CalcInfo value2, EMode mode)
{
Items1 = value1;
Items2 = value2;
Mode = mode;
}
public double GetResult()
{
if (Mode == null)
{
return Result;
}
var item1 = Items1.GetResult();
var item2 = Items2.GetResult();
if (double.IsNaN(item1) || double.IsNaN(item1))
{
return double.NaN;
}
switch (Mode.Value)
{
case EMode.Add:
return item1 + item2;
case EMode.Subtract:
return item1 - item2;
case EMode.Multiply:
return item1 * item2;
case EMode.Divide:
if (item2 == 0)
{
return double.NaN;
}
return item1 / item2;
default:
Debug.Assert(false);
break;
}
return double.NaN;
}
public string GetString()
{
if (Mode == null)
{
return Result.ToString();
}
switch (Mode.Value)
{
case EMode.Add:
return $"({Items1.GetString()} + {Items2.GetString()})";
case EMode.Subtract:
return $"({Items1.GetString()} - {Items2.GetString()})";
case EMode.Multiply:
return $"({Items1.GetString()} * {Items2.GetString()})";
case EMode.Divide:
return $"({Items1.GetString()} / {Items2.GetString()})";
default:
Debug.Assert(false);
break;
}
return null;
}
}
public enum EMode
{
Add,
Subtract,
Multiply,
Divide,
}
}
Source Code Address: https://gitee.com/wzwyc/Calc24Point
Source: wzwyc
Link: cnblogs.com/wzwyc/p/14899751.html
– EOF –
.NET Core with Microservices – Consul Registration Center
Did you gain something from reading this article? Please share it with more people
Recommended follow “DotNet” to improve .Net skills
Likes and views are the biggest support ❤️