Skip to content

Instantly share code, notes, and snippets.

@nesteruk
Created December 26, 2019 13:04
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nesteruk/71406d6bf6065e2202fc630bc96c837a to your computer and use it in GitHub Desktop.
Save nesteruk/71406d6bf6065e2202fc630bc96c837a to your computer and use it in GitHub Desktop.
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
namespace PatternDemoCore
{
public enum Op : byte
{
[Description("*")]
Mul = 0,
[Description("/")]
Div = 1,
[Description("+")]
Add = 2,
[Description("—")]
Sub = 3
}
public static class OpExtensions
{
static OpExtensions()
{
var type = typeof(Op);
foreach (Op op in Enum.GetValues(type))
{
MemberInfo[] memInfo = type.GetMember(op.ToString());
if (memInfo.Length > 0)
{
var attrs = memInfo[0].GetCustomAttributes(
typeof(DescriptionAttribute), false);
if (attrs.Length > 0)
{
opNames[op] = ((DescriptionAttribute) attrs[0]).Description[0];
}
}
}
}
private static readonly Dictionary<Op, char> opNames
= new Dictionary<Op, char>();
public static char Name(this Op op)
{
return opNames[op];
}
private static readonly Dictionary<Op, Func<int, int, int>>
opImpl = new Dictionary<Op, Func<int, int, int>>
{
[Op.Mul] = ((x,y) => x*y),
[Op.Div] = ((x,y) => x/y),
[Op.Add] = ((x,y) => x+y),
[Op.Sub] = ((x,y) => x-y),
};
public static int Call(this Op op, int x, int y)
{
return opImpl[op](x, y);
}
}
public class Problem
{
private readonly List<int> numbers;
private readonly List<Op> ops;
public Problem(
IEnumerable<int> numbers,
IEnumerable<Op> ops)
{
this.numbers = new List<int>(numbers);
this.ops = new List<Op>(ops);
}
public int Eval()
{
var opGroups = new[]
{
new[] {Op.Mul, Op.Div},
new[] {Op.Add, Op.Sub}
};
startAgain:
foreach (var group in opGroups)
{
for (var idx = 0; idx < ops.Count; ++idx)
{
var op = ops[idx];
if (group.Contains(op))
{
numbers[idx] = op.Call(numbers[idx], numbers[idx + 1]);
numbers.RemoveAt(idx+1);
ops.RemoveAt(idx);
if (numbers.Count == 1) return numbers[0];
goto startAgain;
}
}
}
return numbers[0];
}
public override string ToString()
{
var sb = new StringBuilder();
int i = 0;
for (; i < ops.Count; ++i)
{
sb.Append(numbers[i]);
sb.Append(ops[i].Name());
}
sb.Append(numbers[i]);
return sb.ToString();
}
}
public class TwoBitSet
{
private readonly ulong data;
// 64 bit --> 32 values
public TwoBitSet(ulong data)
{
this.data = data;
}
public static implicit operator TwoBitSet(ulong value)
{
return new TwoBitSet(value);
}
public byte this[int index]
{
get
{
var shift = index << 1;
ulong mask = (0b11U << shift);
return (byte) ((data & mask) >> shift);
}
}
}
public class Demo
{
public static void Main(string[] args)
{
// 2 2 2 2
// ↑ ↑ ↑
var numbers = new[] {2, 2, 2, 2, 2};
int numberOfOps = numbers.Length - 1;
for (int result = 0; result <= 10; ++result)
{
for (ulong key = 0UL; key < (1UL << 2 * numberOfOps); ++key)
{
var tbs = new TwoBitSet(key);
var ops = Enumerable.Range(0, numberOfOps)
.Select(i => tbs[i]).Cast<Op>().ToArray();
var problem = new Problem(numbers, ops);
var s = problem.ToString();
if (problem.Eval() == result)
{
Console.WriteLine($"{s} = {result}");
break;
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment