Greatest element of a list: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|Scala}}: add reduce-based solution)
Line 244: Line 244:


=={{header|Fortran}}==
=={{header|Fortran}}==
{{works with|Fortran|2003}}


The intrinsic function <tt>max</tt> accepts any number of arguments. The type of these arguments can be integer, real, character, string of characters or arrays of these.
Fortran's <tt>max</tt> (Fortran 77 and later) accepts any number of argument.
<lang fortran>program test_max


implicit none
<lang fortran>program maximum


write (*, '(i0)') &
print *, max(1, 2, 3, 20, 7) ! returns 20
& max (1, 2, 3)
write (*, '(f3.1)') &
& max (1.0, 2.0, 3.0)
write (*, '(a)') &
& max ('a', 'b', 'c')
write (*, '(a)') &
& max ('abc', 'bca', 'cab')
write (*, '(i0, 2 (1x, i0))') &
& max ([1, 8, 6], [7, 5, 3], [4, 2, 9])
write (*, '(f3.1, 2 (1x, f3.1))') &
& max ([1.0, 8.0, 6.0], [7.0, 5.0, 3.0], [4.0, 2.0, 9.0])
write (*, '(a, 2 (1x, a))') &
& max (['a', 'h', 'f'], ['g', 'e', 'c'], ['d', 'b', 'i'])
write (*, '(a, 2 (1x, a))') &
& max (['abc', 'hig', 'fde'], ['ghi', 'efd', 'cab'], ['def', 'bca', 'igh'])


end program maximum</lang>
end program test_max</lang>
Output:
3
3.0
c
cab
7 8 9
7.0 8.0 9.0
g h i
ghi hig igh


=={{header|Groovy}}==
=={{header|Groovy}}==

Revision as of 11:06, 5 November 2009

Task
Greatest element of a list
You are encouraged to solve this task according to the task description, using any language you may know.

Create a function that returns the maximum value in a provided set of values, where the number of values isn't known until runtime.

Ada

The keys for this task are initializing the compared value to the 'First value of the element type, and use of an unconstrained array type. <lang ada> with Ada.Text_Io;

procedure Max_Test is

  -- substitute any array type with a scalar element
  type Flt_Array is array (Natural range <>) of Float;
  
  -- Create an exception for the case of an empty array
  Empty_Array : Exception;
  
  function Max(Item : Flt_Array) return Float is
     Max_Element : Float := Float'First;
  begin
     if Item'Length = 0 then 
        raise Empty_Array;
     end if;
 
     for I in Item'range loop
        if Item(I) > Max_Element then
           Max_Element := Item(I);
        end if;
     end loop;
     return Max_Element;
  end Max;
   
  Buf : Flt_Array := (-275.0, -111.19, 0.0, -1234568.0, 3.14159, -3.14159);

begin

  Ada.Text_IO.Put_Line(Float'Image(Max(Buf)));

end Max_Test;</lang> A generic function Max to deal with any floating-point type. <lang ada> generic

  type Item is digits <>;
  type Items_Array is array (Positive range <>) of Item;

function Generic_Max (List : Items_Array) return Item; </lang> Implementation of: <lang ada> function Generic_Max (List : Items_Array) return Item is

  Result : Item := List (List'First);

begin

  for Index in List'First + 1..List'Last loop
     Result := Item'Max (Result, List (Index));
  end loop;
  return Result;

end Generic_Max; </lang> When the argument array is empty, Constraint_Error exception is propagated, because array indexing is checked in Ada. Note also use of the floating-type attribute Max.

ALGOL 68

Works with: ALGOL 68 version Standard - no extensions to language used
Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386 - using print instead of printf
# substitute any array type with a scalar element #
MODE FLT = REAL;

# create an exception for the case of an empty array #
PROC raise empty array = VOID:(
  GO TO except empty array
);

PROC max = ([]FLT item)FLT:
BEGIN
   IF LWB item > UPB item THEN
      raise empty array; SKIP
   ELSE
     FLT max element := item[LWB item];

     FOR i FROM LWB item + 1 TO UPB item DO
       IF item[i] > max element THEN
         max element := item[i]
       FI
     OD;
     max element
   FI
END # max #;

[]FLT buf = (-275.0, -111.19, 0.0, -1234568.0, pi, -pi);
print((max(buf),new line)) EXIT
except empty array:
  SKIP

Output:

+3.14159265358979e  +0

AutoHotkey

<lang AutoHotkey> values = 3,4,5,8,2,14 Sort, values, NRD`, Loop, Parse, values, `, {

 MsgBox % A_LoopField
 Break

} </lang>

AWK

<lang awk> $ awk 'func max(a){for(i in a)if(a[i]>r)r=a[i];return r}BEGIN{a[0]=42;a[1]=33;a[2]=21;print max(a)}' 42 </lang>

C

This works well with floats. Replace with double, int or what-have-you before passing a different data type. <lang c>#include <assert.h>

float max(unsigned int count, float values[]) {

    float themax;
    unsigned int idx;
    assert(count > 0);
    themax = values[0];
    for(unsigned int idx = 1; idx < count; ++idx) {
         themax = values[idx] > themax ? values[idx] : themax;
    }
    return themax;

}</lang>

The following macro can be used with any number and type of arguments, provided that the arguments are simple, i.e. must not contain subexpressions where commas appear (this is because of the way the arguments are counted; the macro can be modified so that it is up to the caller to count the number of arguments passed).

Works with: GCC

<lang c>#include <stdarg.h>

  1. define MAX(A,...) ({ inline __typeof__ (A) _max_(__typeof__ (A) a, ...) {\
 va_list l; int i,c; const char *s = #__VA_ARGS__; __typeof__ (A) max = a;\
 __typeof__ (A) t;\
 for(c=1;*s!=0;s++) if (*s==',') c++;\
 va_start(l, a);\
 for(i=0;i<=c;i++) {\
 if ((t=va_arg(l,__typeof__ (A))) > max) max = t;\
 }\
 va_end(l); return max;\

}\ _max_((A),__VA_ARGS__);\ })</lang>

C++

This will work for any type with a < operator defined. Uses the standard library function max_element(). <lang cpp>#include <algorithm>

  1. include <cassert>

template<typename Ty> Ty max(unsigned int count, Ty values[]) {

    assert(count > 0);
    return *std::max_element(values, values + count);

}</lang>

C#

C# already have a "Maximum Value" function.

<lang csharp>using System.Linq;

values.Max();</lang>

Common Lisp

The built-in Common Lisp function max takes the max of all its arguments. <lang lisp>(max 1 2 3 4) (reduce #'max values) ; find max of a list (loop for x in values

     maximize x) ; alternative way to find max of a list</lang>

D

The standard library (Phobos) has a max function in D2.0:

<lang D>import std.algorithm; max(values);</lang>

E

This function works for any value which responds to max/1:

<lang e>pragma.enable("accumulator") # non-finalized syntax feature

def max([first] + rest) {

   return accum first for x in rest { _.max(x) }

}</lang>

<lang e>? max([1, 2, 3])

  1. value: 3</lang>

To require only the comparison protocol, one needs to write out the algorithm a little more explicitly:

<lang e>def max([var bestSoFar] + rest) {

   for x ? (x > bestSoFar) in rest {
       bestSoFar := x
   }
   return bestSoFar

}</lang>

<lang e>? max([1, 3, 2])

  1. value: 3

? max([[1].asSet(), [2].asSet(), [1, 2].asSet()])

  1. value: [1, 2].asSet()</lang>

Emacs Lisp

<lang lisp> (defun max (first-arg &rest more-args)

 (if more-args
     (let ((max-rest (apply 'max more-args)))

(if (> first-arg max-rest) first-arg max-rest))

   first-arg))

</lang> Example use: <lang lisp> (max 2 7 5) 7 </lang>

Erlang

From here <lang erlang> list_max([Head|Rest]) ->

 list_max(Rest, Head).

list_max([], Res) -> Res; list_max([Head|Rest], Max) when Head > Max ->

 list_max(Rest, Head);

list_max([_Head|Rest], Max) -> list_max(Rest, Max). </lang> or an alternative [shorter] version using the standard function max/2 within a fold: <lang erlang> list_max([H|T]) -> lists:foldl(fun erlang:max/2, H, T). </lang> Using it. <lang erlang> >list_max([9,4,3,8,5]). 9 </lang>

Forth

: array-max ( addr len -- max )
  dup 0= if nip exit then
  over @  rot cell+  rot 1-
  cells bounds ?do  i @ max  cell +loop ;
: stack-max ( n ... m count -- max ) 1 ?do max loop ;

Fortran

Works with: Fortran version 2003

The intrinsic function max accepts any number of arguments. The type of these arguments can be integer, real, character, string of characters or arrays of these. <lang fortran>program test_max

 implicit none
 write (*, '(i0)') &
   & max (1, 2, 3)
 write (*, '(f3.1)') &
   & max (1.0, 2.0, 3.0)
 write (*, '(a)') &
   & max ('a', 'b', 'c')
 write (*, '(a)') &
   & max ('abc', 'bca', 'cab')
 write (*, '(i0, 2 (1x, i0))') &
   & max ([1, 8, 6], [7, 5, 3], [4, 2, 9])
 write (*, '(f3.1, 2 (1x, f3.1))') &
   & max ([1.0, 8.0, 6.0], [7.0, 5.0, 3.0], [4.0, 2.0, 9.0])
 write (*, '(a, 2 (1x, a))') &
   & max (['a', 'h', 'f'], ['g', 'e', 'c'], ['d', 'b', 'i'])
 write (*, '(a, 2 (1x, a))') &
   & max (['abc', 'hig', 'fde'], ['ghi', 'efd', 'cab'], ['def', 'bca', 'igh'])

end program test_max</lang> Output:

3
3.0
c
cab
7 8 9
7.0 8.0 9.0
g h i
ghi hig igh

Groovy

<lang groovy>println ([2,4,0,3,1,2,-12].max())</lang>

Output:

4

Haskell

The built-in Haskell function maximum already does this.

my_max = maximum

It can alternately be defined as a "fold" on the built-in two-argument max function.

my_max = foldl1 max

Icon

procedure main()
   local l
   l := [7,8,6,9,4,5,2,3,1]
   write(max(l))
end

procedure max(l)
   local i, max
   max := l[1]
   every i := 1 to !l & i > max do
       max := i
   return max
end

J

Verb maxatom returns the maximum value among atoms (smallest indivisible components) of the input, without regard to the shape of the input. The output of verb maxitem has the shape of an item of the input, and the value of each atom is the maximum along the largest axis. For a list of scalars these are equivalent.

maxatom=: >./ @ ,
maxitem=: >./

Java

The first function works with arrays of floats. Replace with arrays of double, int, or other primitive data type. <lang java>public static float max(float[] values) throws NoSuchElementException {

   if (values.length == 0)
       throw new NoSuchElementException();
   float themax = values[0];
   for (int idx = 1; idx < values.length; ++idx) {
       if (values[idx] < themax)
           themax = values[idx];
   }
   return themax;

}</lang>

Optionally, if it is OK to rearrange the contents of the original array: <lang java>public static float max(float[] values) throws NoSuchElementException {

   if (values.length == 0)
       throw new NoSuchElementException();
   Arrays.sort(values);//sorts the values in ascending order
   return values[values.length-1];

}</lang>

The following functions work with Lists or arrays of reference types, respectively. Note that the type is required to implement Comparable, to ensure we can compare them. For Lists, there is a utility method Collections.max() that already does this. For arrays, we can just use the Arrays.asList() wrapper to wrap it into a list and then use the function for lists. <lang java>import java.util.List; import java.util.Collections; import java.util.Arrays;

public static <T extends Comparable<? super T>> T max(List<T> values) {

   return Collections.max(values);

}

public static <T extends Comparable<? super T>> T max(T[] values) {

   return Collections.max(Arrays.asList(values));

}</lang>

JavaScript

<lang javascript> Array.prototype.max = function() { var max = this[0]; var len = this.length; for (var i = 1; i < len; i++) if (this[i] > max) max = this[i]; return max; }

// Test it a = [0,1,2,5,4]; alert(a.max()); </lang>

Works with: UCB Logo

If the template is, like SUM, the name of a procedure that is capable of accepting arbitrarily many inputs, it is more efficient to use APPLY instead of REDUCE. The latter is good for associative procedures that have been written to accept exactly two inputs:

to max :a :b
output ifelse :a > :b [:a] [:b]
end
print reduce "max [...]

Alternatively, REDUCE can be used to write MAX as a procedure that accepts any number of inputs, as SUM does:

to max [:inputs] 2
if emptyp :inputs ~
   [(throw "error [not enough inputs to max])]
output reduce [ifelse ?1 > ?2 [?1] [?2]] :inputs
end

Mathematica

Input: <lang Mathematica>

Max[1, 3, 3, 7]
Max[Pi,E+2/5,17 Cos[6]/5,Sqrt[91/10]]
Max[1,6,Infinity]
Max[]

</lang> Output <lang Mathematica>

7
17 Cos[6]/5
Infinity

-Infinity </lang> Note that Max returns minus infinity if supplied with no arguments; as it should: <lang Mathematica> Max[Max[],Max[a,b,c]] Max[Max[a],Max[b,c]] Max[Max[a,b],Max[c]] Max[Max[a,b,c],Max[]] </lang> should all give the same results, therefore max[] should give -Infinity. If it WOULD give 0 strange this can happen: <lang Mathematica> Max[Max[], Max[-4, -3]] </lang> WOULD give 0 instead of -3

MATLAB

<lang Matlab>function [maxValue] = findmax(setOfValues)

  maxValue = max(setOfValues);</lang>

Modula-3

Modula-3 provides a builtin MAX function, but it only works on two elements (or enumerations) but not arrays or sets.

We provide a generic Maximum implementation: <lang modula3>GENERIC INTERFACE Maximum(Elem);

EXCEPTION Empty;

PROCEDURE Max(READONLY a: ARRAY OF Elem.T): Elem.T RAISES {Empty};

END Maximum.</lang>

<lang modula3>GENERIC MODULE Maximum(Elem);

PROCEDURE Max(READONLY arr: ARRAY OF Elem.T): Elem.T RAISES {Empty} =

 VAR max := FIRST(Elem.T);
 BEGIN
   IF NUMBER(arr) = 0 THEN
     RAISE Empty;
   END;
   FOR i := FIRST(arr) TO LAST(arr) DO
     IF arr[i] > max THEN
       max := arr[i];
     END;
   END;
   RETURN max;
 END Max;

BEGIN END Maximum.</lang>

Elem can be instantiated to any type (any type that can be compared with the '>' function). For convenience Modula-3 provides interfaces/modules for the built in types, like Integer, Real, LongReal, etc, which contain type definitions as well as properties specific to the type.

To make a generic interface/module for a specific type, you must instantiate it: <lang modula3>INTERFACE RealMax = Maximum(Real) END RealMax.</lang> <lang modula3>MODULE RealMax = Maximum(Real) END RealMax.</lang>

Now we can import RealMax into our source and use the Max function: <lang modula3>MODULE Main;

IMPORT RealMax, IO, Fmt;

VAR realarr := ARRAY [1..5] OF REAL {1.1, 1.0, 0.0, 2.4, 3.3};

BEGIN

 IO.Put(Fmt.Real(RealMax.Max(realarr)) & "\n");

END Main.</lang>

MAXScript

MAXScript has a built-in function called amax(), which will return the maximum of an array or the values supplied to it. The following custom function will return the maximum of the array supplied to it, or 'undefined' if an empty array is supplied. <lang MAXScript> fn MaxValue AnArray = ( if AnArray.count != 0 then ( local maxVal = 0 for i in AnArray do if i > maxVal then maxVal = i maxVal ) else undefined ) </lang>

Metafont

The max macro (in the base set of macro for Metafont) accepts any number of arguments, and accepts both numerics (numbers), pairs (bidimensional vectors), and strings (not mixed).

<lang metafont>show max(4,5,20,1); show max((12,3), (10,10), (25,5)); show max("hello", "world", "Hello World");</lang>

Nial

The behavior of multi-dimensional arrays is like J

max 1 2 3 4
=4

Objective-C

Works with: GNUstep
Works with: Cocoa

This code "extends" (through Objective-C categories) the NSArray adding the method maximumValue; this one iterates over the objects of the collection calling the method compare, if it exists for the object of the collection. Since normally comparing makes sense between numbers, the code also check if the objects being compared are of "kind" NSNumber. If one eliminates this check (substituting it maybe with one that checks if the two object are of the same "kind"), the code is able to get a maximum value for any objects for which make sense a compare method (e.g. strings), that must be implemented.

If there's no a known way of comparing two objects of the collection (or if the objects are not "NSNumber"), the the method return nil (the void object).


<lang objc>#import <Foundation/Foundation.h>

@interface NSArray (WithMaximum) - (id)maximumValue; @end

@implementation NSArray (WithMaximum) - (id)maximumValue {

 if ( [self count] == 0 ) return nil;
 id maybeMax = [self objectAtIndex: 0];
 NSEnumerator *en = [self objectEnumerator];
 id el;
 while ( (el=[en nextObject]) != nil ) {
   if ( [maybeMax respondsToSelector: @selector(compare:)] &&

[el respondsToSelector: @selector(compare:)] && [el isKindOfClass: [NSNumber class]] && [maybeMax isKindOfClass: [NSNumber class]] ) {

     if ( [maybeMax compare: el] == NSOrderedAscending )

maybeMax = el;

   } else { return nil; }
 }
 return maybeMax;

} @end</lang>

This example mixes integers with a double value, just to show that everything is fine until they are NSNumber.

<lang objc> int main() {

 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 NSArray *collection = [NSArray arrayWithObjects: 

[NSNumber numberWithInt: 1], [NSNumber numberWithInt: 2], [NSNumber numberWithInt: 10], [NSNumber numberWithInt: 5], [NSNumber numberWithDouble: 10.5], nil];

 NSLog(@"%@", [collection maximumValue]);
 [pool release];
 return 0;

}</lang>

OCaml

<lang ocaml>let my_max = function

   [] -> invalid_arg "empty list"
 | x::xs -> List.fold_left max x xs</lang>
# my_max [4;3;5;9;2;3] ;;
- : int = 9

Octave

Octave's max accepts a vector (and can return also the index of the maximum value in the vector)

<lang octave> m = max( [1,2,3,20,10,9,8] );  % m = 20 [m, im] = max( [1,2,3,20,10,9,8] ); % im = 4</lang>

Perl

<lang perl>sub max {

    my @list = @_;
    my $themax = $list[0];
    foreach ( @list ) {
         $themax = $_ > $themax ? $_ : $themax;
    }
    return $themax;

}</lang>

It is already implemented in the module List::Util's max() function: <lang perl>use List::Util qw(max);

max(@values);</lang>

PHP

The built-in PHP function max() already does this. <lang php>max($values)</lang>

PowerShell

The Measure-Object cmdlet in PowerShell already has this capability: <lang powershell>function Get-Maximum ($a) {

   return ($a | Measure-Object -Maximum).Maximum

}</lang>

Python

The built-in Python function max() already does this. <lang python>max(values)</lang>

Of course this assumes we have a list or tuple (or other sequence like object). (One can even find the max() or min() character of a string since that's treated as a sequence of characters and there are "less than" and "greater than" operations (object methods) associate with those characters).

If we truly were receiving a stream of data then in Python, such streams are usually iterable, meaning they have a way of generating one item at a time from the stream.

max(), (and min()), can take iterables and a key argument which takes a function that can transform each item into a type that we can compare, for example, if the stream were returning string representations of integers, one to a line, you could do <lang python>>>> floatstrings = ['1\n', ' 2.3\n', '4.5e-1\n', '0.01e4\n', '-1.2'] >>> max(floatstrings, key = float) '0.01e4\n' >>> </lang> Normally we would want the converted form as the maximum and we could just as easily write: <lang python>>>> max(float(x) for x in floatstrings) 100.0 >>> </lang>

R

<lang R>v <- c(1, 2, 100, 50, 0) print(max(v)) # 100</lang>

Ruby

max is a method of all Enumerables <lang ruby>values.max</lang>

Scala

<lang scala> def max(x: Int, y: Int) = if (x < y) y else x List(1,2,3,4) reduceLeft (max _) </lang>

Scheme

The built-in Scheme function max takes the max of all its arguments. <lang scheme>(max 1 2 3 4) (apply max values) ; find max of a list</lang>

Slate

<lang slate>

  1. (1 2 3 4 20 10 9 8) reduce: [| :a :b | a max: b]

</lang>

Smalltalk

Using fold it is very simple to find the maximum value among a collection.

<lang smalltalk>Smalltalk at: #maximum put: nil. maximum := [ :c | c fold: [:a :b | a max: b] ]. maximum value: #(1 2 3 4 20 10 9 8). "returns 20"</lang>

Standard ML

Comparisons are specific for each type. Here is a max function for a list of ints: <lang ocaml>fun max_of_ints [] = raise Empty

 | max_of_ints (x::xs) = foldl Int.max x xs</lang>
- max_of_ints [4,3,5,9,2,3];
val it = 9 : int

Tcl

Works with: Tcl version 8.5

Use the {*} expansion operator to substitute the list value with it's constituent elements <lang tcl>package require Tcl 8.5

set values {4 3 2 7 8 9}

tcl::mathfunc::max {*}$values ;# ==> 9</lang>

TI-89 BASIC

The builtin max function can be applied to lists. max({1, 3, 2}) = 3.

Ursala

The built in $^ operator takes a binary predicate of any type to a function extracting the maximum value from a non-empty list. In this case it is used with fleq, the partial order relation on floating point numbers. <lang Ursala>#import flo

  1. cast %e

example = fleq$^ <-1.,-2.,0.,5.,4.,6.,1.,-5.></lang> output:

6.000000e+00

V

Assuming it is a list of positive numbers

[4 3 2 7 8 9] 0 [max] fold
=9

If it is not

[4 3 2 7 8 9] dup first [max] fold
=9