Task: Subset sum problem



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

namespace SubsetSum {
    class Item {
        public Item(string word, int weight) {
            Word = word;
            Weight = weight;
        }

        public string Word { get; set; }
        public int Weight { get; set; }

        public override string ToString() {
            return string.Format("({0}, {1})", Word, Weight);
        }
    }

    class Program {
        private static readonly List<Item> items = new List<Item>() {
            new Item("alliance", -624),
            new Item("archbishop", -915),
            new Item("balm", 397),
            new Item("bonnet", 452),
            new Item("brute", 870),
            new Item("centipede", -658),
            new Item("cobol", 362),
            new Item("covariate", 590),
            new Item("departure", 952),
            new Item("deploy", 44),
            new Item("diophantine", 645),
            new Item("efferent", 54),
            new Item("elysee", -326),
            new Item("eradicate", 376),
            new Item("escritoire", 856),
            new Item("exorcism", -983),
            new Item("fiat", 170),
            new Item("filmy", -874),
            new Item("flatworm", 503),
            new Item("gestapo", 915),
            new Item("infra", -847),
            new Item("isis", -982),
            new Item("lindholm", 999),
            new Item("markham", 475),
            new Item("mincemeat", -880),
            new Item("moresby", 756),
            new Item("mycenae", 183),
            new Item("plugging", -266),
            new Item("smokescreen", 423),
            new Item("speakeasy", -745),
            new Item("vein", 813),
        };

        private static readonly int n = items.Count;
        private static readonly int LIMIT = 5;

        private static int[] indices = new int[n];
        private static int count = 0;

        private static void ZeroSum(int i, int w) {
            if (i != 0 && w == 0) {
                for (int j = 0; j < i; j++) {
                    Console.Write("{0} ", items[indices[j]]);
                }
                Console.WriteLine("\n");
                if (count < LIMIT) count++;
                else return;
            }
            int k = (i != 0) ? indices[i - 1] + 1 : 0;
            for (int j = k; j < n; j++) {
                indices[i] = j;
                ZeroSum(i + 1, w + items[j].Weight);
                if (count == LIMIT) return;
            }
        }

        static void Main(string[] args) {
            Console.WriteLine("The weights of the following {0} subsets add up to zero:\n", LIMIT);
            ZeroSum(0, 0);
        }
    }
}









Ada: with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
procedure SubsetSum is
   function "+"(S:String) return Unbounded_String renames To_Unbounded_String;
   type Point is record
      str : Unbounded_String;
      num : Integer;
   end record;
   type Points is array (Natural range <>) of Point;
   type Indices is array (Natural range <>) of Natural;

   procedure Print (data : Points; list : Indices; len : Positive) is begin
      Put (len'Img & ":");
      for i in 0..len-1 loop
         Put (" "& To_String(data(list(i)).str));
      end loop; New_Line;
   end Print;

   function Check (data : Points; list : Indices; len : Positive) return Boolean is
      sum : Integer := 0;
   begin
      for i in 0..len-1 loop sum := sum + data(list(i)).num; end loop;
      return sum = 0;
   end Check;

   procedure Next (list : in out Indices; n, r : Positive ) is begin
      for i in reverse 0..r-1 loop
         if list(i)/=i+n-r then list(i):=list(i)+1;
            for j in i+1..r-1 loop list(j):=list(j-1)+1; end loop; exit;
         end if;
      end loop;
   end Next;

   data : constant Points := ((+"alliance", -624), (+"archbishop", -915),
      (+"balm", 397), (+"bonnet", 452), (+"brute", 870),
      (+"centipede", -658), (+"cobol", 362), (+"covariate", 590),
      (+"departure", 952), (+"deploy", 44), (+"diophantine", 645),
      (+"efferent", 54), (+"elysee", -326), (+"eradicate", 376),
      (+"escritoire", 856), (+"exorcism", -983), (+"fiat", 170),
      (+"filmy", -874), (+"flatworm", 503), (+"gestapo", 915),
      (+"infra", -847), (+"isis", -982), (+"lindholm", 999),
      (+"markham", 475), (+"mincemeat", -880), (+"moresby", 756),
      (+"mycenae", 183), (+"plugging", -266), (+"smokescreen", 423),
      (+"speakeasy", -745), (+"vein", 813));
   list, last : Indices (data'Range);
begin
   for len in 2..data'Length loop
      for i in 0..len-1 loop list(i):=i; end loop;
      loop
         if Check(data, list, len) then Print(data, list, len); exit; end if;
         last := list;
         Next(list, data'Length, len);
         exit when last=list;
      end loop;
   end loop;
end SubsetSum;