Project 2 Logic Value Table Generator: Find All Combinations and Sums Candace Burwell University of North Carolina, Wilmington CLB1038@uncw.edu ABSTRACT This lab assignment was to use a binary logic value table to determine every possible combination of n=35 variables split into two separate groups. These variables were to be randomly generated integers between 0 and 99. The focus was to then determine if the sum of each possible combination would equal an integer value k=1789. We were asked to print the randomly generated set of 35 numbers and then print each combination of these integers that sums to k. The purpose was to generate a logic value table and work with sets produced in an efficient manner. The overall deduction from this lab was to realize that the logic value table does repeat itself with regards to the sets produced, once you have reached the halfway mark. That is of course when you are only creating two sets per split. The challenge was to develop a recursive method to efficiently generate the logic value table and then find a way to stop the program once the repetition of sets has been realized. 1. INTRODUCTION Logic value tables or truth tables are used in logic to compute functional values of logical expressions on each of their functional arguments, meaning to find each combination of values determined by their corresponding logical variable. The significance of this exercise was to understand the usefulness of a logic value table. As well as to see how quickly its size can grow by simply adding a few variables to be evaluated or in other words increasing n. In this example only logic variables 0 and 1 were assigned to produce two different sets of values. 35 different input variables were used for computations. The logic value table was composed of one column for each input variable and 2^n rows where n equals the total number of input variables. I knew that producing this table would be difficult and imagined it would require a recursive method. The goal was to create an efficient method that would produce results with the lowest possible runtime. 2. BACKGROUND Truth tables were developed by Charles Peirce in the 1880’s. They show values, relationships, and results of performing logical operations on logical expressions. Logical operators consists of not, and, or, conditional, and biconditional. Whereas logical expressions are necessarily true, contingently true, or necessarily false. These tables are used in everyday life by engineers to find the simplest possible circuit that will perform a desired logic function. This will produce a feasibly efficient method by minimizing the number of operations that must be performed to accomplish a given task. 3. EXPERIMENTAL DESIGN First I used a random number generator method name Rand to generate a number between 0 and 99 then I used a loop to assign this number to an array (randnum) that will hold 35 total random numbers. This is done with a loop calling the Rand method each time until 35 random integers are held in randnum. For this exercise we are simply assigning true or false to all variables, then determining the sum of all variables in the true or 1 set and in the false or 0 set. The first issue to address was the generation of the logic value table which was done through iteration and recursion. I used CalcRow method that would accept the following parameters, an array holding 0 and 1 as well as the depth value = 35. This method calls a CalcRownRecur method that will accept the parameters of CalcRow in addition to the index location and combinations array. The combinations array holds the current assignments of the corresponding row in the logic value table. A loop is placed inside the CalcRowRecur method to iterate from 0 to 1. First 0 is assigned to the index point then CalcRowRecur is called recursively inside this loop with the passing an index incremented by 1. Before you enter the loop in CalcRowRecur however, you pass over an if statement asking if the index = depth (35) if true you would then increment count by 1 check to make sure you are not at halfway mark and call the Sum method passing the combinations array that holds the current row assignments of 0s and 1s. This if statement is followed by and else that will bring you back into the recursive calling loop described above, if you are not at an index = depth. There is a small if statement inside the first if statement that will check to make sure you are not at the halfway mark. If this is true, then System.exit is called to stop the program because at this point your possible combinations will begin to repeat. Once you reach an index = depth and the Sum method is called the loop will then iterate for the 1 (it has already run for 0) with the index of the index -1 (because you jump back to iteration before the recursive call was done to increment the index). Therefore, it will place a 1 in the last slot and call CalcRowRecur again with the incremented the index that will in turn call meet the requirements of the catcher if statement at the top and call the Sum method again. This basically works like a tree diagram and will follow branches all the way down one side (0) back up then down the other branch at same level (1) then backing up to the index prior’s branch and go all the way down the next set of branches. I guess you would call it down all the way, up, down, up up, next branch same pattern (if that makes any sense). This method will assign 0s and 1s to indexes generating one row at a time then pass back the combinations array to be written over again for the next row. At the end of each row the Sum method is call that contains the two if statements that follow. If the index or the combinations array holds a 0 then add the value at the same index of the randnum array to an array named suma, if the index holds a 1 then add the value corresponding to the array named sumb. Eventually this will run completely through the combinations array holding 0s and 1s. At this point you can sum each suma and sumb array and compare these sums to the k the value you are searching for. If there is a match then print the corresponding array holding the combination of numbers. If there are no matches the method call is complete and the CalcRowRecur method continues with the next row on the logic value table where it left off, until the halfway mark is reach. 4. FINDINGS I started this problem by attempting to generate a logic value table that’s rows and columns would be held in a 2D array. I quickly discovered that this would be a ridiculously large array with an impossibly large runtime when you increase the number of columns to 35. Therefore, I had to move on to generating a method to determine one row at a time, run the necessary calculations, and then move onto the next row. This eliminates the need for storing each row and would make the runtime feasible for larger values of n. I found that not every set of randomly generated numbers would sum to 1789. In fact, the first time I ran the program there were no possible combinations printed. My first thought was that I had an error somewhere but then realized that the total sum was not over 1789, meaning that there would not be any combinations that would equal that value. This is due to the fact that 50*35 = 1750 which is lower than the sum we are looking. Therefore, roughly half of times you run the program there will not be any possible combinations printed. Some of the randomly generated numbers will fall above 50 and some will fall below but should average out to about 50 as the mean. After the third run the program generated a random set up numbers that would work and results began to populate in the console screen. I then discovered that the results would populate twice in a mirrored format. After looking over a simple version of the logic value table with only three variables and all combinations of 0s and 1s drawn as: ABC 111 110 101 1 0 0 (HAULT) 011 010 001 000 1 = A, B, C 1 = A, B 1 = A, C 1=A 1 = B, C 1=B 1=C 1 = empty | | | | | | | | 2= empty 2= C 2= B 2= B, C 2= A 2= A,C 2= A, B 2= A, B, C I came to realize that there was no need to continue calculations past the stopping point shown above. At this point I decided to add a counter and an if statement with a System.exit call that would stop the program when it reached the row = (2^n)/2. When I first ran the program it took approximately 2.5 hours. However, after adding the feature mentioned above I was able to cut the runtime in half to about 2 hours and 15 minutes. 5. CONCULSIONS I have concluded that first it is impossible or shall I say wasteful to store a complete logic value table to represent every possible combination of an array when dealing with larger values of n. Therefore you must produce each row one by one, perform necessary calculations, and then move onto next row in table. Second I have discovered that when randomly generating 35 numbers from 0 to 99, you will not always reach a total sum over the value of 1789. I found that if you did not see combinations being printed within a minute or so, stop the program and run it again to generate a new set of random numbers. Finally, the combination sets produced by the logic value table when using n=35 starts to repeat as soon as reach row 17,179,869,184 or (2^n)/2. 6. FUTURE WORK I would like to change the random number generator to only generate number from 50 to 99 because this will create a higher overall sum therefore never causing the problem of no possible results. It seems this will also create more possible sets that will sum to desired total of 1789. However, I have not tested so I am not certain on this fact. I tried to run the program with n=64 and not only did the randomly generated list take longer to print but my mouse started moving around the screen extremely slowly leading to my cease and desist.