Advertisement
Luarockr

o2SubsetSum

Jun 20th, 2017
204
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. MODULE PowerSet;
  2.  
  3. IMPORT Out, Bit;
  4.  
  5. TYPE
  6.     NodePtr- = POINTER TO Node;
  7.     Node- = RECORD
  8.         num- : INTEGER;
  9.         prev- : NodePtr;
  10.     END;
  11.     ListPtr- = POINTER TO ListType;
  12.     ListType- = RECORD
  13.         last- : NodePtr;
  14.     END;
  15.     SubsetsType- = POINTER TO ARRAY OF ListPtr;
  16.  
  17. PROCEDURE AddNode(VAR l : ListPtr; nn : NodePtr);
  18. BEGIN
  19.     ASSERT(nn # NIL);
  20.     IF l.last = NIL THEN l.last := nn;
  21.     ELSE nn.prev := l.last; l.last := nn;
  22.     END;
  23. END AddNode;
  24.  
  25. PROCEDURE PowerSetForArray*(VAR ai : ARRAY OF INTEGER) : SubsetsType;
  26. VAR subsetCount : INTEGER;
  27.     subsetIndex, itemIndex : INTEGER;
  28.     subsets : SubsetsType;
  29.     subset : ListPtr;
  30.     node : NodePtr;
  31. BEGIN
  32.     subsetCount := ASH(1, LEN(ai));
  33.     subsetIndex := 0;
  34.     NEW(subsets, subsetCount);
  35.     WHILE subsetIndex < subsetCount DO
  36.         NEW(subset);
  37.         subset.last := NIL;
  38.         FOR itemIndex := 0 TO LEN(ai) - 1 DO
  39.             IF (Bit.And(ASH(subsetIndex, -itemIndex), 1) > 0) THEN
  40.                 NEW(node);
  41.                 node.num := ai[itemIndex];
  42.                 AddNode(subset, node);
  43.             END;
  44.         END;
  45.         subsets[subsetIndex] := subset;
  46.         INC(subsetIndex);
  47.     END;
  48.     RETURN subsets;
  49. END PowerSetForArray;
  50.  
  51. PROCEDURE PrintSubsets*(s : SubsetsType);
  52. VAR i, l : INTEGER;
  53.     lp : ListPtr;
  54.     np : NodePtr;    
  55. BEGIN
  56.     ASSERT(s # NIL);
  57.     l := LEN(s^);
  58.     FOR i := 0 TO l - 1 DO
  59.         lp := s[i];
  60.         ASSERT(lp # NIL);
  61.         np := lp.last;
  62.         WHILE(np # NIL) DO
  63.             Out.Int(np.num,0); Out.String(" ");
  64.             np := np.prev;
  65.         END;
  66.         Out.Ln;
  67.     END;
  68.     Out.Ln;
  69. END PrintSubsets;
  70.  
  71. BEGIN
  72. END PowerSet.
  73.  
  74. (* ---------- CUT HERE ---------- *)
  75.  
  76. MODULE SubsetSum;
  77.  
  78. IMPORT PowerSet, Out;
  79.  
  80. PROCEDURE PrintArr(a : ARRAY OF INTEGER);
  81. VAR i  :INTEGER;
  82. BEGIN
  83.   Out.String("[");
  84.   FOR i := 0 TO LEN(a) - 1 DO
  85.     Out.LongInt(a[i], 0);
  86.     IF i < LEN(a) - 1 THEN Out.String(", "); END;
  87.   END;
  88.   Out.String("]");
  89. END PrintArr;
  90.  
  91. PROCEDURE PrintBool(b : BOOLEAN);
  92. BEGIN
  93.   IF b THEN Out.String("TRUE"); ELSE Out.String("FALSE"); END;
  94. END PrintBool;
  95.  
  96. PROCEDURE Check(a : ARRAY OF INTEGER) : BOOLEAN;
  97. VAR i, j : INTEGER;
  98. BEGIN
  99.   FOR i := 0 TO LEN(a) - 2 DO
  100.     FOR j := i + 1 TO LEN(a) - 1 DO
  101.       IF (a[i] = 0) OR (a[j] = 0) THEN RETURN TRUE; END;
  102.       IF (a[i] + a[j]) = 0 THEN RETURN TRUE; END;
  103.     END;
  104.   END;
  105.   RETURN FALSE;
  106. END Check;
  107.  
  108. PROCEDURE CheckAllSubsets(a : ARRAY OF INTEGER) : BOOLEAN;
  109. VAR subsets : PowerSet.SubsetsType;
  110.     i, l : INTEGER;
  111.     lp : PowerSet.ListPtr;
  112.     np : PowerSet.NodePtr;    
  113.     res : LONGINT;
  114.     isZero : BOOLEAN;
  115. BEGIN
  116.   subsets := PowerSet.PowerSetForArray(a);
  117.   ASSERT(subsets # NIL);
  118.   l := LEN(subsets^);
  119.   i := 0;
  120.   isZero := FALSE;
  121.   WHILE (i < l) & (isZero = FALSE) DO
  122.     lp := subsets[i]; (* array of lists *)
  123.     ASSERT(lp # NIL);
  124.     np := lp.last; (* end node of list *)
  125.     IF np # NIL THEN
  126.       res := 0;
  127.       WHILE (np # NIL)  & (isZero = FALSE) DO
  128.         IF np.num = 0 THEN isZero := TRUE; END;
  129.         res := res + np.num;
  130.         np := np.prev;
  131.       END;
  132.       IF res = 0 THEN isZero := TRUE; END;
  133.     END;
  134.     INC(i);
  135.   END;
  136.   subsets := NIL;
  137.   RETURN isZero;
  138. END CheckAllSubsets;
  139.  
  140. PROCEDURE PerformSingleTest(a : ARRAY OF INTEGER; allSubs : BOOLEAN);
  141. VAR res : BOOLEAN;
  142. BEGIN
  143.   res := FALSE;
  144.   IF allSubs THEN res := CheckAllSubsets(a);
  145.   ELSE res := Check(a);
  146.   END;
  147.   PrintArr(a);
  148.   Out.String(" => ");
  149.   PrintBool(res);
  150.   Out.Ln;
  151. END PerformSingleTest;
  152.  
  153. PROCEDURE Test();
  154. VAR a0 : ARRAY 0 OF INTEGER;
  155.     a1 : ARRAY 1 OF INTEGER;    
  156.     a2 : ARRAY 2 OF INTEGER;
  157.     a3 : ARRAY 3 OF INTEGER;
  158.     a6 : ARRAY 6 OF INTEGER;
  159.     a10 : ARRAY 10 OF INTEGER;
  160.     a18 : ARRAY 18 OF INTEGER;
  161. BEGIN
  162.   a3[0] := 1; a3[1] := 2; a3[2] := 3;
  163.   PerformSingleTest(a3, FALSE);
  164.  
  165.   a6[0] := -5; a6[1] := 2; a6[2] := -1; a6[3] := 2; a6[4] := 4; a6[5] := 6;
  166.   PerformSingleTest(a6, FALSE);
  167.  
  168.   PerformSingleTest(a0, FALSE);
  169.  
  170.   a2[0] := -1; a2[1] := 1;
  171.   PerformSingleTest(a2, FALSE);
  172.  
  173.   a6[0] := -97364; a6[1] := -71561; a6[2] := -69336; a6[3] := 19675;
  174.   a6[4] := 71561; a6[5] := 97863;
  175.   PerformSingleTest(a6, FALSE);
  176.  
  177.   a6[0] := -53974; a6[1] := -39140; a6[2] := -36561; a6[3] := -23935;
  178.   a6[4] := -15680; a6[5] := 0;
  179.   PerformSingleTest(a6, FALSE);
  180.  
  181.   (* CheckBonus *)
  182.   a1[0] := 0;
  183.   PerformSingleTest(a1, TRUE);
  184.  
  185.   a3[0] := -3; a3[1] := 1; a3[2] := 2;
  186.   PerformSingleTest(a3, TRUE);
  187.  
  188.   a10[0] := -98634; a10[1] := -86888; a10[2] := -48841; a10[3] := -40483;
  189.   a10[4] := 2612; a10[5] := 9225; a10[6] := 17848; a10[7] := 71967;
  190.   a10[8] := 84319; a10[9] := 88875;
  191.   PerformSingleTest(a10, TRUE);
  192.  
  193.   (* FALSE *)
  194.   a18[0] := -83314; a18[1] := -82838; a18[2] := -80120; a18[3] := -63468;
  195.   a18[4] := -62478; a18[5] := -59378; a18[6] := -56958; a18[7] := -50061;
  196.   a18[8] := -34791; a18[9] := -32264; a18[10] := -21928; a18[11] := -14988;
  197.   a18[12] := 23767; a18[13] := 24417; a18[14] := 26403; a18[15] := 26511;
  198.   a18[16] := 36399; a18[17] := 78055;
  199.   PerformSingleTest(a18, TRUE);
  200.  
  201.   a18[0] := -92953; a18[1] := -91613; a18[2] := -89733; a18[3] := -50673;
  202.   a18[4] := -16067; a18[5] := -9172; a18[6] := 8852; a18[7] := 30883;
  203.   a18[8] := 46690; a18[9] := 46968; a18[10] := 56772; a18[11] := 58703;
  204.   a18[12] := 59150; a18[13] := 78476; a18[14] := 84413; a18[15] := 90106;
  205.   a18[16] := 94777; a18[17] := 95148;
  206.   PerformSingleTest(a18, TRUE);
  207.  
  208.   (* TRUE *)
  209.   a18[0] := -97162; a18[1] := -95761; a18[2] := -94672; a18[3] := -87254;
  210.   a18[4] := -57207; a18[5] := -22163; a18[6] := -20207; a18[7] := -1753;
  211.   a18[8] := 11646; a18[9] := 13652; a18[10] := 14572; a18[11] := 30580;
  212.   a18[12] := 52502; a18[13] := 64282; a18[14] := 74896; a18[15] := 83730;
  213.   a18[16] := 89889; a18[17] := 92200;
  214.   PerformSingleTest(a18, TRUE);
  215.  
  216.   (* TRUE *)
  217.   a18[0] := -93976; a18[1] := -93807; a18[2] := -64604; a18[3] := -59939;
  218.   a18[4] := -44394; a18[5] := -36454; a18[6] := -34635; a18[7] := -16483;
  219.   a18[8] := 267; a18[9] := 3245; a18[10] := 8031; a18[11] := 10622;
  220.   a18[12] := 44815; a18[13] := 46829; a18[14] := 61689; a18[15] := 65756;
  221.   a18[16] := 69220; a18[17] := 70121;
  222.   PerformSingleTest(a18, TRUE);
  223. END Test;
  224.  
  225. BEGIN
  226.   Test;
  227. END SubsetSum.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement