Loading ...
Sorry, an error occurred while loading the content.

19834Finding Minimum Value in Array

Expand Messages
  • flo.gehrke
    Nov 1, 2009
    • 0 Attachment
      Hi all,

      What's the best way to find the minimum value in an array of numbers?

      For example, in: 3,8,329,1,1.25,7,10.34,4,9,6,2,5,11.

      To do it with commands like 'If A > B' etc seems to be a complicated undertaking. Also the MIN or MAX operators to be used with ^$Calc$ are not very useful. As far as I can see, they compare two numbers only:

      ^!Info ^$Calc(MIN(3;6))$

      outputs '3' but 'MIN(3;6;9)' returns an "error in expression" message.

      I found a small utility called EVAL.EXE that you can download from

      http://tp.lc.ehu.es/jma/msdos.html

      for free. It's from Juan M. Aguirregabiria, teaching Theoretical Physics at Euskal Herriko Unibertsitatea, Bilbao. I copied the EVAL.EXE and EVAL.HLP to C:\Windows, and it seemes to work fine.

      For example...

      ^!Set %Array%=3,8,329,1,1.25,7,10.34,4,9,6,2,5,11
      ^!Info ^$GetDosOutput(EVAL MIN(^%Array%))$

      correctly outputs '1'.

      The only problem I've seen so far: It seems to return a CRNL with the output. So we get into trouble when using the result in a command like ^!IfDiff. So...


      ^!Set %Array%=3,8,329,1,1.25,7,10.34,4,9,6,2,5,11
      ^!Set %Min%=^$GetDosOutput(EVAL MIN(^%Array%))$
      ^!IfDiff "^%Min%" "1" Next Else Skip_2
      ^!Info Different!
      ^!Goto End
      ^!Info Not different!


      provides a wrong result. But when removing the CRNL, the result will be correct:


      ^!Set %Array%=3,8,329,1,1.25,7,10.34,4,9,6,2,5,11
      ^!Set %Min%=^$GetDosOutput(EVAL MIN(^%Array%))$
      ^!Set %Min%=^$StrReplace("^P";"";^%Min%;0;0)$
      ^!IfDiff "^%Min%" "1" Next Else Skip_2
      ^!Info Different!
      ^!Goto End
      ^!Info Not different!


      Please let me know if there are more problems with this utility or if there is any better solution. Thanks!

      Flo


      P.S. I created a little "Sorting Machine" for a more intensive testing of Eval:


      ^!SetListDelimiter ,
      ^!SetArray %Dig%=3,8,329,1,1.25,7,10.34,4,9,6,2,5,11
      ^!Set %Nr%=1; %From%=1; %Final%=^%Dig0%

      :Loop
      ^!Set %Val%=^%Dig^%Nr%%
      ^!Append %SubArray%=^%Val%,
      ^!Inc %Nr%
      ^!If ^%Nr% > ^%Final% Check
      ^!Goto Loop

      :Check
      ; Remove last comma in SubArray
      ^!Set %SubArray%=^$StrDeleteRight(^%SubArray%;1)$
      ; Use EVAL.EXE to find minimum value in SubArray
      ^!Set %Min%=^$GetDosOutput(EVAL MIN(^%SubArray%))$
      ; Remove CRNL produced by EVAL
      ^!Set %Min%=^$StrReplace("^P";"";"^%Min%";0;0)$
      ^!ClearVariable %SubArray%
      ^!Set %ANr%=1

      :ANrLoop
      ; Find number of minimum value in array
      ^!IfDiff "^%Min%" "^%Dig^%ANr%%" Next Else Reorder
      ^!Inc %ANr%
      ^!Goto ANrLoop

      :Reorder
      ^!Set %Park%=^%Dig^%ANr%%
      ^!Set %Dig^%ANr%%=^%Dig^%From%%
      ^!Set %Dig^%From%%=^%Park%
      ^!Inc %From%
      ^!If ^%From%=^%Final% End
      ^!Set %Nr%=^%From%
      ^!Goto Loop

      :End
      ^!Info Sorted: ^%Dig%
      ^!ClearVariable %SubArray%


      (Please note: No duplicate numbers allowed)
    • Show all 15 messages in this topic