2 Replies Latest reply on Jun 10, 2016 3:43 AM by alexh90310518

    A Knapsack problem

    alexh90310518 Level 1

      Hello,

      So I've been given something a little out of my depth the chew on.

      I have a knapsack problem style idea for the document I'm working on and I have been given a "sort of half" solution for it written in VB.

      I've never used VB before so I have done my best at translating it into JavaScript, I'll post the 2 for comparison below.

       

      What I'm trying to achieve is when someone types in a number, say, 120 into a text field it calculates exactly how many of the 4 items, 50, 35 20 and 15 it would require to make this value in as little as possible then display the results accordingly on the screen. It would also tell the person if that amount was impossible to create using those 4 values. e.g 115 would be possible via (50 x 2) + 15 and 25 is impossible to combine.

       

      Here is the original VB script;

      Function calc(Target) As String
          Dim Counts(1 To 4) As Integer
          Dim addOns(1 To 4) As Integer
          Dim remainder As Integer
          Dim lastMatch As Integer
          Dim loopy As Integer
          Dim failed As Boolean
          
          addOns(1) = 50
          addOns(2) = 35
          addOns(3) = 20
          addOns(4) = 15
          Counts(1) = 0
          Counts(2) = 0
          Counts(3) = 0
          Counts(4) = 0
          
      
      
          remainder = Target
          lastMatch = 0
          loopy = 1
          
          While remainder <> 0 And Not ((failed) And (loopy <> 4))
              While ((loopy < 5) And (remainder > 0))
                  failed = True
                  If remainder >= addOns(loopy) Then
                      Counts(loopy) = Counts(loopy) + 1
                      failed = False
                      lastMatch = loopy
                      remainder = remainder - addOns(loopy)
                  Else
                      loopy = loopy + 1
                  End If
              Wend
              If ((failed) And (remainder <> 0)) Then
                  Counts(lastMatch) = Counts(lastMatch) - 1
                  remainder = remainder + addOns(lastMatch)
                  loopy = lastMatch + 1
                  lastMatch = 0
                  failed = False
              End If
          Wend
          If (failed And (loopy = 4)) Then
              ErrorMsg = "Error: " & Target & " Not Matched - "
          Else
              ErrorMsg = "Matched: " & Target & " - "
          End If
          
          calc = ErrorMsg & "50=" & Counts(1) & ": 35=" & Counts(2) & ": 20=" & Counts(3) & ": 15=" & Counts(4)
      
      
      End Function
      

      And here is my attempt at translating it into JavaScript

      function KnapCalc (FieldTxt) {
           var addOns = [
           50, 35, 20, 15];
           var counts = [    
           0, 0, 0, 0];
      
           var remainder = target;
           var target = this.getField(FieldTxt);
           var lastMatch = 0;
           var loopy = 1;
           var failed = true;
      
           while (remainder !== 0 && failed == true && loopy !== 4) {
                while (loopy < 5 && remainder > 0) {
                     if (remainder >= addOns[loopy] + 1) {
                          counts[loopy] = counts[loopy];
                          failed.value = false;
                          lastMatch = loopy;
                          remainder = remainder - addOns[loopy];
                          }
                     else {
                          loopy = loopy + 1;
                          }
                     }
                if (failed == true && remainder !== 0) {
                     counts[lastMatch] = counts[lastMatch] - 1;
                     remainder = remainder + addOns[lastMatch];
                     loopy = lastMatch + 1;
                     lastMatch = 0
                     failed.value = false;
                     }
                }
           if (failed == true) {
                app.alert("Error: " + target + " Not Matched - " + addOnCalc);
           }
           else {
                app.alert("Matched: " + target + " - " + addOnCalc);
           }
           var addOnCalc = "50 = " + counts[1] + "35 = " + counts [2] + "20 = " + counts[3] +
           "15 = " + counts[4];
      }
      

      I think this conversion works and I am also sure that it gets stuck into an infinite loop when the program is required to step back more that once as acrobat seizes up and then crashes when I pass the textfield target the value of 120.

      As I mentioned I'm out of my depth with this and could use some help.

      Any help is much appreciated

      Thank you in advance!