Task: Sum to 100



C#: using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        
        var expressionsPlus = Enumerable.Range(0, (int)Math.Pow(3, 8)).AsParallel().Select(i => new Expression(i, 1));
        
        var expressionsMinus = Enumerable.Range(0, (int)Math.Pow(3, 8)).AsParallel().Select(i => new Expression(i, -1));
        var expressions = expressionsPlus.Concat(expressionsMinus);
        var results = new Dictionary<int, List<Expression>>();
        foreach (var e in expressions)
        {
            if (results.Keys.Contains(e.Value))
                results[e.Value].Add(e);
            else
                results[e.Value] = new List<Expression>() { e };
        }
        Console.WriteLine("Show all solutions that sum to 100");
        foreach (Expression e in results[100])
            Console.WriteLine("  " + e);
        Console.WriteLine("Show the sum that has the maximum number of solutions (from zero to infinity)");
        var summary = results.Keys.Select(k => new Tuple<int, int>(k, results[k].Count));
        var maxSols = summary.Aggregate((a, b) => a.Item2 > b.Item2 ? a : b);
        Console.WriteLine("  The sum " + maxSols.Item1 + " has " + maxSols.Item2 + " solutions.");
        Console.WriteLine("Show the lowest positive sum that can't be expressed (has no solutions), using the rules for this task");
        var lowestPositive = Enumerable.Range(1, int.MaxValue).First(x => !results.Keys.Contains(x));
        Console.WriteLine("  " + lowestPositive);
        Console.WriteLine("Show the ten highest numbers that can be expressed using the rules for this task (extra credit)");
        var highest = from k in results.Keys
                      orderby k descending
                      select k;
        foreach (var x in highest.Take(10))
            Console.WriteLine("  " + x);
    }
}
public enum Operations { Plus, Minus, Join };
public class Expression
{
    protected Operations[] Gaps;
    
    
    public int Value; 
    protected int _one;
    
    public Expression(int serial, int one)
    {
        _one = one;
        Gaps = new Operations[8];
        
        int divisor = 2187; 
        int times;
        for (int i = 0; i < 8; i++)
        {
            times = Math.DivRem(serial, divisor, out serial);
            divisor /= 3;
            if (times == 0)
                Gaps[i] = Operations.Join;
            else if (times == 1)
                Gaps[i] = Operations.Minus;
            else
                Gaps[i] = Operations.Plus;
        }
        
        
        Value = Evaluate();
    }
    public override string ToString()
    {
        string ret = _one.ToString();
        for (int i = 0; i < 8; i++)
        {
            switch (Gaps[i])
            {
                case Operations.Plus:
                    ret += "+";
                    break;
                case Operations.Minus:
                    ret += "-";
                    break;
            }
            ret += (i + 2);
        }
        return ret;
    }
    private int Evaluate()
        
    {
        var numbers = new int[9];
        int nc = 0;
        var operations = new List<Operations>();
        int a = 1;
        for (int i = 0; i < 8; i++)
        {
            if (Gaps[i] == Operations.Join)
                a = a * 10 + (i + 2);
            else
            {
                if (a > 0)
                {
                    if (nc == 0)
                        a *= _one;
                    numbers[nc++] = a;
                    a = i + 2;
                }
                operations.Add(Gaps[i]);
            }
        }
        if (nc == 0)
            a *= _one;
        numbers[nc++] = a;
        int ni = 0;
        int left = numbers[ni++];
        foreach (var operation in operations)
        {
            int right = numbers[ni++];
            if (operation == Operations.Plus)
                left = left + right;
            else
                left = left - right;
        }
        return left;
    }
}


Go: package main

import (
	"fmt"
	"sort"
)

const pow3_8 = 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 
const pow3_9 = 3 * pow3_8                    
const maxExprs = 2 * pow3_8                  

type op uint8

const (
	Add  op = iota 
	Sub            
	Join           
)




type code uint16


func (c code) evaluate() (sum int) {
	num, pow := 0, 1
	for k := 9; k >= 1; k-- {
		num += pow * k
		switch op(c % 3) {
		case Add:
			sum += num
			num, pow = 0, 1
		case Sub:
			sum -= num
			num, pow = 0, 1
		case Join:
			pow *= 10
		}
		c /= 3
	}
	return sum
}

func (c code) String() string {
	buf := make([]byte, 0, 18)
	a, b := code(pow3_9), code(pow3_8)
	for k := 1; k <= 9; k++ {
		switch op((c % a) / b) {
		case Add:
			if k > 1 {
				buf = append(buf, '+')
			}
		case Sub:
			buf = append(buf, '-')
		}
		buf = append(buf, '0'+byte(k))
		a, b = b, b/3
	}
	return string(buf)
}

type sumCode struct {
	sum  int
	code code
}
type sumCodes []sumCode

type sumCount struct {
	sum   int
	count int
}
type sumCounts []sumCount


func (p sumCodes) Len() int            { return len(p) }
func (p sumCodes) Swap(i, j int)       { p[i], p[j] = p[j], p[i] }
func (p sumCodes) Less(i, j int) bool  { return p[i].sum < p[j].sum }
func (p sumCounts) Len() int           { return len(p) }
func (p sumCounts) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
func (p sumCounts) Less(i, j int) bool { return p[i].count > p[j].count }


func (sc sumCode) String() string {
	return fmt.Sprintf("% 10d = %v", sc.sum, sc.code)
}
func (sc sumCount) String() string {
	return fmt.Sprintf("% 10d has %d solutions", sc.sum, sc.count)
}

func main() {
	
	expressions := make(sumCodes, 0, maxExprs/2)
	counts := make(sumCounts, 0, 1715)
	for c := code(0); c < maxExprs; c++ {
		
		
		
		sum := c.evaluate()
		if sum >= 0 {
			expressions = append(expressions, sumCode{sum, c})
		}
	}
	sort.Sort(expressions)

	
	sc := sumCount{expressions[0].sum, 1}
	for _, e := range expressions[1:] {
		if e.sum == sc.sum {
			sc.count++
		} else {
			counts = append(counts, sc)
			sc = sumCount{e.sum, 1}
		}
	}
	counts = append(counts, sc)
	sort.Sort(counts)

	

	fmt.Println("All solutions that sum to 100:")
	i := sort.Search(len(expressions), func(i int) bool {
		return expressions[i].sum >= 100
	})
	for _, e := range expressions[i:] {
		if e.sum != 100 {
			break
		}
		fmt.Println(e)
	}

	fmt.Println("\nThe positive sum with maximum number of solutions:")
	fmt.Println(counts[0])

	fmt.Println("\nThe lowest positive number that can't be expressed:")
	s := 1
	for _, e := range expressions {
		if e.sum == s {
			s++
		} else if e.sum > s {
			fmt.Printf("% 10d\n", s)
			break
		}
	}

	fmt.Println("\nThe ten highest numbers that can be expressed:")
	for _, e := range expressions[len(expressions)-10:] {
		fmt.Println(e)
	}
}