Dynamic programming to solve two printers with different speeds

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
2
down vote

favorite












I solved this problem using a Class, but thought I might try to figure out this memoization thing.




Problem

There are two printers that print pages at different speeds (X, Y).
What is the minimum amount of time it takes to print (N) pages?



Input Data
First line contains the number of test cases
Each test case
is on a new line in the form of X Y N



Output
The minimum printing time for each test case separated by spaces




e.g.




input data:
2
1 1 5
3 5 4

output:
3 9



The math here is trickier than it appears, so make the assumption that my math is correct (it is).



Code



Option Explicit On
Option Strict On
Option Infer On
Option Compare Text

Module Module1

<STAThread>
Sub Main()
Const inputPath As String = "C:Tempprinters.txt"
Dim delimiters As String = " " & System.Environment.NewLine
Dim data() As Integer = System.IO.File.ReadAllText(inputPath).Split(delimiters.ToCharArray(), StringSplitOptions.RemoveEmptyEntries) _
.Select(Function(i) Integer.Parse(i)).ToArray
Dim result As String

For i As Integer = 0 To data(0) - 1
result = result & BestTime(data(i * 3 + 1), data(i * 3 + 2), data(i * 3 + 3)) & " "
Next

result = result.Trim()
System.IO.File.AppendAllText(inputPath, Environment.NewLine & result)
End Sub

Public Function BestTime(ByVal X As Double, ByVal Y As Double, ByVal N As Integer) As Double
Dim myTimes(1) As Double
For nextpage As Integer = N To 1 Step -1
If myTimes(0) + X <= myTimes(1) + Y Then
myTimes(0) = myTimes(0) + X
Else
myTimes(1) = myTimes(1) + Y
End If
Next
Return myTimes.Max
End Function

End Module


For some reason I couldn't get the delimiters to work as a constant. I'm using doubles because I kept getting overflow.




Additional test data



Input



16
206 120 2925144
5680 2268 173606
443 144 2231807
1336 1966 235314
251936 215499 755
1 1 610653060
27229864 68593621 7
13 11 58925803
25 13 39786943
936 301 970391
6811369 9145334 90
3070457 3923385 93
111 126 4757640
16350510 10897861 9
171127 91014 3379
2 2 373415582


Output



221808480 281383956 242540784 187180894 87708093 305326530 137187242 
351099580 340283073 221013936 354191188 160858785 280761012 65387166
200776884 373415582






share|improve this question

























    up vote
    2
    down vote

    favorite












    I solved this problem using a Class, but thought I might try to figure out this memoization thing.




    Problem

    There are two printers that print pages at different speeds (X, Y).
    What is the minimum amount of time it takes to print (N) pages?



    Input Data
    First line contains the number of test cases
    Each test case
    is on a new line in the form of X Y N



    Output
    The minimum printing time for each test case separated by spaces




    e.g.




    input data:
    2
    1 1 5
    3 5 4

    output:
    3 9



    The math here is trickier than it appears, so make the assumption that my math is correct (it is).



    Code



    Option Explicit On
    Option Strict On
    Option Infer On
    Option Compare Text

    Module Module1

    <STAThread>
    Sub Main()
    Const inputPath As String = "C:Tempprinters.txt"
    Dim delimiters As String = " " & System.Environment.NewLine
    Dim data() As Integer = System.IO.File.ReadAllText(inputPath).Split(delimiters.ToCharArray(), StringSplitOptions.RemoveEmptyEntries) _
    .Select(Function(i) Integer.Parse(i)).ToArray
    Dim result As String

    For i As Integer = 0 To data(0) - 1
    result = result & BestTime(data(i * 3 + 1), data(i * 3 + 2), data(i * 3 + 3)) & " "
    Next

    result = result.Trim()
    System.IO.File.AppendAllText(inputPath, Environment.NewLine & result)
    End Sub

    Public Function BestTime(ByVal X As Double, ByVal Y As Double, ByVal N As Integer) As Double
    Dim myTimes(1) As Double
    For nextpage As Integer = N To 1 Step -1
    If myTimes(0) + X <= myTimes(1) + Y Then
    myTimes(0) = myTimes(0) + X
    Else
    myTimes(1) = myTimes(1) + Y
    End If
    Next
    Return myTimes.Max
    End Function

    End Module


    For some reason I couldn't get the delimiters to work as a constant. I'm using doubles because I kept getting overflow.




    Additional test data



    Input



    16
    206 120 2925144
    5680 2268 173606
    443 144 2231807
    1336 1966 235314
    251936 215499 755
    1 1 610653060
    27229864 68593621 7
    13 11 58925803
    25 13 39786943
    936 301 970391
    6811369 9145334 90
    3070457 3923385 93
    111 126 4757640
    16350510 10897861 9
    171127 91014 3379
    2 2 373415582


    Output



    221808480 281383956 242540784 187180894 87708093 305326530 137187242 
    351099580 340283073 221013936 354191188 160858785 280761012 65387166
    200776884 373415582






    share|improve this question





















      up vote
      2
      down vote

      favorite









      up vote
      2
      down vote

      favorite











      I solved this problem using a Class, but thought I might try to figure out this memoization thing.




      Problem

      There are two printers that print pages at different speeds (X, Y).
      What is the minimum amount of time it takes to print (N) pages?



      Input Data
      First line contains the number of test cases
      Each test case
      is on a new line in the form of X Y N



      Output
      The minimum printing time for each test case separated by spaces




      e.g.




      input data:
      2
      1 1 5
      3 5 4

      output:
      3 9



      The math here is trickier than it appears, so make the assumption that my math is correct (it is).



      Code



      Option Explicit On
      Option Strict On
      Option Infer On
      Option Compare Text

      Module Module1

      <STAThread>
      Sub Main()
      Const inputPath As String = "C:Tempprinters.txt"
      Dim delimiters As String = " " & System.Environment.NewLine
      Dim data() As Integer = System.IO.File.ReadAllText(inputPath).Split(delimiters.ToCharArray(), StringSplitOptions.RemoveEmptyEntries) _
      .Select(Function(i) Integer.Parse(i)).ToArray
      Dim result As String

      For i As Integer = 0 To data(0) - 1
      result = result & BestTime(data(i * 3 + 1), data(i * 3 + 2), data(i * 3 + 3)) & " "
      Next

      result = result.Trim()
      System.IO.File.AppendAllText(inputPath, Environment.NewLine & result)
      End Sub

      Public Function BestTime(ByVal X As Double, ByVal Y As Double, ByVal N As Integer) As Double
      Dim myTimes(1) As Double
      For nextpage As Integer = N To 1 Step -1
      If myTimes(0) + X <= myTimes(1) + Y Then
      myTimes(0) = myTimes(0) + X
      Else
      myTimes(1) = myTimes(1) + Y
      End If
      Next
      Return myTimes.Max
      End Function

      End Module


      For some reason I couldn't get the delimiters to work as a constant. I'm using doubles because I kept getting overflow.




      Additional test data



      Input



      16
      206 120 2925144
      5680 2268 173606
      443 144 2231807
      1336 1966 235314
      251936 215499 755
      1 1 610653060
      27229864 68593621 7
      13 11 58925803
      25 13 39786943
      936 301 970391
      6811369 9145334 90
      3070457 3923385 93
      111 126 4757640
      16350510 10897861 9
      171127 91014 3379
      2 2 373415582


      Output



      221808480 281383956 242540784 187180894 87708093 305326530 137187242 
      351099580 340283073 221013936 354191188 160858785 280761012 65387166
      200776884 373415582






      share|improve this question











      I solved this problem using a Class, but thought I might try to figure out this memoization thing.




      Problem

      There are two printers that print pages at different speeds (X, Y).
      What is the minimum amount of time it takes to print (N) pages?



      Input Data
      First line contains the number of test cases
      Each test case
      is on a new line in the form of X Y N



      Output
      The minimum printing time for each test case separated by spaces




      e.g.




      input data:
      2
      1 1 5
      3 5 4

      output:
      3 9



      The math here is trickier than it appears, so make the assumption that my math is correct (it is).



      Code



      Option Explicit On
      Option Strict On
      Option Infer On
      Option Compare Text

      Module Module1

      <STAThread>
      Sub Main()
      Const inputPath As String = "C:Tempprinters.txt"
      Dim delimiters As String = " " & System.Environment.NewLine
      Dim data() As Integer = System.IO.File.ReadAllText(inputPath).Split(delimiters.ToCharArray(), StringSplitOptions.RemoveEmptyEntries) _
      .Select(Function(i) Integer.Parse(i)).ToArray
      Dim result As String

      For i As Integer = 0 To data(0) - 1
      result = result & BestTime(data(i * 3 + 1), data(i * 3 + 2), data(i * 3 + 3)) & " "
      Next

      result = result.Trim()
      System.IO.File.AppendAllText(inputPath, Environment.NewLine & result)
      End Sub

      Public Function BestTime(ByVal X As Double, ByVal Y As Double, ByVal N As Integer) As Double
      Dim myTimes(1) As Double
      For nextpage As Integer = N To 1 Step -1
      If myTimes(0) + X <= myTimes(1) + Y Then
      myTimes(0) = myTimes(0) + X
      Else
      myTimes(1) = myTimes(1) + Y
      End If
      Next
      Return myTimes.Max
      End Function

      End Module


      For some reason I couldn't get the delimiters to work as a constant. I'm using doubles because I kept getting overflow.




      Additional test data



      Input



      16
      206 120 2925144
      5680 2268 173606
      443 144 2231807
      1336 1966 235314
      251936 215499 755
      1 1 610653060
      27229864 68593621 7
      13 11 58925803
      25 13 39786943
      936 301 970391
      6811369 9145334 90
      3070457 3923385 93
      111 126 4757640
      16350510 10897861 9
      171127 91014 3379
      2 2 373415582


      Output



      221808480 281383956 242540784 187180894 87708093 305326530 137187242 
      351099580 340283073 221013936 354191188 160858785 280761012 65387166
      200776884 373415582








      share|improve this question










      share|improve this question




      share|improve this question









      asked Apr 18 at 3:58









      Raystafarian

      5,4331046




      5,4331046




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          1
          down vote



          accepted










          Your BestTime method looks great. The nextpage variable is never used, so it doesn't really matter which direction the loop goes. I'd be curious why you are using a decrementing loop, but it doesn't matter which direction you use in the grand scheme of things.




          Choosing Double because Integer gives you overflow seems misleading. At first I thought "oh good, it handles decimal rates, like 2 1/2 pages per minute". The algorithm looks like it should work for floating point, though.



          If you only want to support integral types, you can use Long or ULong. Based on the test cases you provided, Long is sufficient.




          myTimes(0) + X and myTimes(1) + Y are calculated twice. For this scale of number it's not a huge performance loss. But if you were extending this to BigInteger levels, you could calculate them both once and assign the number if needed.



          This is the kind of optimization that would require benchmarking before deciding if it is worthwhile.




          A Const for delimeters won't work because System.Environment.NewLine is read only property that is not available at compile time. There are a couple of alternatives:



          • use a ReadOnly field instead of Const

          • use vbNewLine instead of System.Environment.NewLine

            • Note, this will (possibly) be different functionality.


          However, you only use delimeters in one spot, so a method variable like you currently have is fine.




          You did a good job separating the algorithm from input/output. You could take it further by wrapping input handling in its own function outside of Main.




          If this weren't for a "competition" style of programming, I would recommend a parameter for the input file name so that the user can change it. I'd also strongly encourage a separate parameter for output. Right now, the user needs to perform an extra step before running your program a second time.



          Additionally, you could use more descriptive variable names than X, Y, and N. It matches the competition specs so it's perfect in this instance. But for a long term program I would recommend something like printerXSpeed or numberOfPagesToPrint. The caveat is you never know when that one off function you write gets put in production for years.






          share|improve this answer





















          • Great points, thank you
            – Raystafarian
            Apr 20 at 23:55










          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f192345%2fdynamic-programming-to-solve-two-printers-with-different-speeds%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          1
          down vote



          accepted










          Your BestTime method looks great. The nextpage variable is never used, so it doesn't really matter which direction the loop goes. I'd be curious why you are using a decrementing loop, but it doesn't matter which direction you use in the grand scheme of things.




          Choosing Double because Integer gives you overflow seems misleading. At first I thought "oh good, it handles decimal rates, like 2 1/2 pages per minute". The algorithm looks like it should work for floating point, though.



          If you only want to support integral types, you can use Long or ULong. Based on the test cases you provided, Long is sufficient.




          myTimes(0) + X and myTimes(1) + Y are calculated twice. For this scale of number it's not a huge performance loss. But if you were extending this to BigInteger levels, you could calculate them both once and assign the number if needed.



          This is the kind of optimization that would require benchmarking before deciding if it is worthwhile.




          A Const for delimeters won't work because System.Environment.NewLine is read only property that is not available at compile time. There are a couple of alternatives:



          • use a ReadOnly field instead of Const

          • use vbNewLine instead of System.Environment.NewLine

            • Note, this will (possibly) be different functionality.


          However, you only use delimeters in one spot, so a method variable like you currently have is fine.




          You did a good job separating the algorithm from input/output. You could take it further by wrapping input handling in its own function outside of Main.




          If this weren't for a "competition" style of programming, I would recommend a parameter for the input file name so that the user can change it. I'd also strongly encourage a separate parameter for output. Right now, the user needs to perform an extra step before running your program a second time.



          Additionally, you could use more descriptive variable names than X, Y, and N. It matches the competition specs so it's perfect in this instance. But for a long term program I would recommend something like printerXSpeed or numberOfPagesToPrint. The caveat is you never know when that one off function you write gets put in production for years.






          share|improve this answer





















          • Great points, thank you
            – Raystafarian
            Apr 20 at 23:55














          up vote
          1
          down vote



          accepted










          Your BestTime method looks great. The nextpage variable is never used, so it doesn't really matter which direction the loop goes. I'd be curious why you are using a decrementing loop, but it doesn't matter which direction you use in the grand scheme of things.




          Choosing Double because Integer gives you overflow seems misleading. At first I thought "oh good, it handles decimal rates, like 2 1/2 pages per minute". The algorithm looks like it should work for floating point, though.



          If you only want to support integral types, you can use Long or ULong. Based on the test cases you provided, Long is sufficient.




          myTimes(0) + X and myTimes(1) + Y are calculated twice. For this scale of number it's not a huge performance loss. But if you were extending this to BigInteger levels, you could calculate them both once and assign the number if needed.



          This is the kind of optimization that would require benchmarking before deciding if it is worthwhile.




          A Const for delimeters won't work because System.Environment.NewLine is read only property that is not available at compile time. There are a couple of alternatives:



          • use a ReadOnly field instead of Const

          • use vbNewLine instead of System.Environment.NewLine

            • Note, this will (possibly) be different functionality.


          However, you only use delimeters in one spot, so a method variable like you currently have is fine.




          You did a good job separating the algorithm from input/output. You could take it further by wrapping input handling in its own function outside of Main.




          If this weren't for a "competition" style of programming, I would recommend a parameter for the input file name so that the user can change it. I'd also strongly encourage a separate parameter for output. Right now, the user needs to perform an extra step before running your program a second time.



          Additionally, you could use more descriptive variable names than X, Y, and N. It matches the competition specs so it's perfect in this instance. But for a long term program I would recommend something like printerXSpeed or numberOfPagesToPrint. The caveat is you never know when that one off function you write gets put in production for years.






          share|improve this answer





















          • Great points, thank you
            – Raystafarian
            Apr 20 at 23:55












          up vote
          1
          down vote



          accepted







          up vote
          1
          down vote



          accepted






          Your BestTime method looks great. The nextpage variable is never used, so it doesn't really matter which direction the loop goes. I'd be curious why you are using a decrementing loop, but it doesn't matter which direction you use in the grand scheme of things.




          Choosing Double because Integer gives you overflow seems misleading. At first I thought "oh good, it handles decimal rates, like 2 1/2 pages per minute". The algorithm looks like it should work for floating point, though.



          If you only want to support integral types, you can use Long or ULong. Based on the test cases you provided, Long is sufficient.




          myTimes(0) + X and myTimes(1) + Y are calculated twice. For this scale of number it's not a huge performance loss. But if you were extending this to BigInteger levels, you could calculate them both once and assign the number if needed.



          This is the kind of optimization that would require benchmarking before deciding if it is worthwhile.




          A Const for delimeters won't work because System.Environment.NewLine is read only property that is not available at compile time. There are a couple of alternatives:



          • use a ReadOnly field instead of Const

          • use vbNewLine instead of System.Environment.NewLine

            • Note, this will (possibly) be different functionality.


          However, you only use delimeters in one spot, so a method variable like you currently have is fine.




          You did a good job separating the algorithm from input/output. You could take it further by wrapping input handling in its own function outside of Main.




          If this weren't for a "competition" style of programming, I would recommend a parameter for the input file name so that the user can change it. I'd also strongly encourage a separate parameter for output. Right now, the user needs to perform an extra step before running your program a second time.



          Additionally, you could use more descriptive variable names than X, Y, and N. It matches the competition specs so it's perfect in this instance. But for a long term program I would recommend something like printerXSpeed or numberOfPagesToPrint. The caveat is you never know when that one off function you write gets put in production for years.






          share|improve this answer













          Your BestTime method looks great. The nextpage variable is never used, so it doesn't really matter which direction the loop goes. I'd be curious why you are using a decrementing loop, but it doesn't matter which direction you use in the grand scheme of things.




          Choosing Double because Integer gives you overflow seems misleading. At first I thought "oh good, it handles decimal rates, like 2 1/2 pages per minute". The algorithm looks like it should work for floating point, though.



          If you only want to support integral types, you can use Long or ULong. Based on the test cases you provided, Long is sufficient.




          myTimes(0) + X and myTimes(1) + Y are calculated twice. For this scale of number it's not a huge performance loss. But if you were extending this to BigInteger levels, you could calculate them both once and assign the number if needed.



          This is the kind of optimization that would require benchmarking before deciding if it is worthwhile.




          A Const for delimeters won't work because System.Environment.NewLine is read only property that is not available at compile time. There are a couple of alternatives:



          • use a ReadOnly field instead of Const

          • use vbNewLine instead of System.Environment.NewLine

            • Note, this will (possibly) be different functionality.


          However, you only use delimeters in one spot, so a method variable like you currently have is fine.




          You did a good job separating the algorithm from input/output. You could take it further by wrapping input handling in its own function outside of Main.




          If this weren't for a "competition" style of programming, I would recommend a parameter for the input file name so that the user can change it. I'd also strongly encourage a separate parameter for output. Right now, the user needs to perform an extra step before running your program a second time.



          Additionally, you could use more descriptive variable names than X, Y, and N. It matches the competition specs so it's perfect in this instance. But for a long term program I would recommend something like printerXSpeed or numberOfPagesToPrint. The caveat is you never know when that one off function you write gets put in production for years.







          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered Apr 20 at 17:38









          Brian J

          26618




          26618











          • Great points, thank you
            – Raystafarian
            Apr 20 at 23:55
















          • Great points, thank you
            – Raystafarian
            Apr 20 at 23:55















          Great points, thank you
          – Raystafarian
          Apr 20 at 23:55




          Great points, thank you
          – Raystafarian
          Apr 20 at 23:55












           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f192345%2fdynamic-programming-to-solve-two-printers-with-different-speeds%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Python Lists

          Aion

          JavaScript Array Iteration Methods