From 7e57162e962a02d8292398059c642238c463b165 Mon Sep 17 00:00:00 2001 From: Chris Jefferson Date: Mon, 21 Nov 2016 16:15:53 +0100 Subject: [PATCH] Add PositionMaximum and PositionMinimum --- doc/ref/lists.xml | 1 + lib/list.gd | 40 ++++++++++++++++++++++ lib/list.gi | 68 +++++++++++++++++++++++++++++++++++++ tst/testinstall/listgen.tst | 36 ++++++++++++++++++++ 4 files changed, 145 insertions(+) diff --git a/doc/ref/lists.xml b/doc/ref/lists.xml index 3170ca3ae0..bc0aa7797b 100644 --- a/doc/ref/lists.xml +++ b/doc/ref/lists.xml @@ -1416,6 +1416,7 @@ The latter can be done also using . <#Include Label="PositionNthOccurrence"> <#Include Label="PositionSorted"> <#Include Label="PositionSet"> +<#Include Label="PositionMaximum"> <#Include Label="PositionProperty"> <#Include Label="PositionsProperty"> <#Include Label="PositionBound"> diff --git a/lib/list.gd b/lib/list.gd index 02117375de..90df732986 100644 --- a/lib/list.gd +++ b/lib/list.gd @@ -869,6 +869,44 @@ DeclareGlobalFunction( "PositionSet" ); DeclareOperation( "PositionProperty", [ IsList, IsFunction ] ); DeclareOperation( "PositionProperty", [ IsList, IsFunction, IS_INT ] ); +############################################################################# +## +#O PositionMaximum( [, ] ) +#O PositionMinimum( [, ] ) +## +## <#GAPDoc Label="PositionMaximum"> +## +## +## +## +## +## returns the position of maximum (with ) or +## minimum (with ) entry in the list list. +## If a second argument func is passed, then return instead the position +## of the largest/smallest entry in List( list , func ). +## If several entries of the list are equal +## to the maximum/minimum, the first such position is returned. +##

+## PositionMaximum( [2,4,-6,2,4] ); +## 2 +## gap> PositionMaximum( [2,4,-6,2,4], x -> -x); +## 3 +## gap> PositionMinimum( [2,4,-6,2,4] ); +## 3 +## gap> PositionMinimum( [2,4,-6,2,4], x -> -x); +## 2 +## ]]> +##

+## and +## +## allow you to find the maximum or minimum element of a list directly. +## +## +## <#/GAPDoc> +## +DeclareGlobalFunction( "PositionMaximum" ); +DeclareGlobalFunction( "PositionMinimum" ); ############################################################################# ## @@ -1717,6 +1755,7 @@ DeclareOperation( "StableSortParallel", ## gap> Maximum( [1,2], [0,15], [1,5], [2,-11] ); ## [ 2, -11 ] ## ]]> +## To get the index of the maximum element use ## ## ## <#/GAPDoc> @@ -1759,6 +1798,7 @@ DeclareGlobalFunction( "Maximum" ); ## gap> Minimum( [ 1, 2 ], [ 0, 15 ], [ 1, 5 ], [ 2, -11 ] ); ## [ 0, 15 ] ## ]]> +## To get the index of the minimum element use ## ## ## <#/GAPDoc> diff --git a/lib/list.gi b/lib/list.gi index 3712ba443d..1c03276813 100644 --- a/lib/list.gi +++ b/lib/list.gi @@ -1571,6 +1571,74 @@ InstallMethod( PositionProperty, end ); +############################################################################# +## +#M PositionMaximum([, ]) . position of the largest element +#M PositionMinimum([, ]) . position of the smallest element +## + +InstallGlobalFunction( PositionMaximum, + function ( args... ) + local list, func, i, bestval, bestindex, ival; + + if Length(args) < 1 or Length(args) > 2 + or not(IsList(args[1])) + or (Length(args) = 2 and not(IsFunction(args[2]))) then + ErrorNoReturn("Usage: PositionMaximum(, [])"); + fi; + + list := args[1]; + if Length(args) = 2 then + func := args[2]; + else + func := IdFunc; + fi; + + bestindex := fail; + for i in [ 1 .. Length( list ) ] do + if IsBound( list[i] ) then + ival := func ( list[ i ] ); + + if not( IsBound(bestval) ) or ival > bestval then + bestval := ival; + bestindex := i; + fi; + fi; + od; + return bestindex; + end ); + +InstallGlobalFunction( PositionMinimum, + function ( args... ) + local list, func, i, bestval, bestindex, ival; + + if Length(args) < 1 or Length(args) > 2 + or not(IsList(args[1])) + or (Length(args) = 2 and not(IsFunction(args[2]))) then + ErrorNoReturn("Usage: PositionMinimum(, [])"); + fi; + + list := args[1]; + if Length(args) = 2 then + func := args[2]; + else + func := IdFunc; + fi; + + bestindex := fail; + for i in [ 1 .. Length( list ) ] do + if IsBound( list[i] ) then + ival := func ( list[ i ] ); + + if not( IsBound(bestval) ) or ival < bestval then + bestval := ival; + bestindex := i; + fi; + fi; + od; + return bestindex; + end ); + ############################################################################# ## #M PositionsProperty(,) . positions of elements with a property diff --git a/tst/testinstall/listgen.tst b/tst/testinstall/listgen.tst index bb8eefdae0..7d7d17cb3d 100644 --- a/tst/testinstall/listgen.tst +++ b/tst/testinstall/listgen.tst @@ -90,6 +90,42 @@ gap> MinimumList( [ 1, 2 .. 20 ] ); 1 gap> MinimumList( [ 10, 8 .. 2 ] ); 2 +gap> PositionMaximum([2,4,6,4,2,6]); +3 +gap> PositionMaximum([2,4,6,4,2,6], x -> -x); +1 +gap> PositionMinimum([2,4,6,4,2,6]); +1 +gap> PositionMinimum([2,4,6,4,2,6], x -> -x); +3 +gap> PositionMaximum(); +Error, Usage: PositionMaximum(, []) +gap> PositionMaximum(2); +Error, Usage: PositionMaximum(, []) +gap> PositionMaximum([1,2], 2); +Error, Usage: PositionMaximum(, []) +gap> PositionMaximum([1,2], x -> x, 2); +Error, Usage: PositionMaximum(, []) +gap> PositionMinimum(); +Error, Usage: PositionMinimum(, []) +gap> PositionMinimum([1,2], 2); +Error, Usage: PositionMinimum(, []) +gap> PositionMinimum(2); +Error, Usage: PositionMinimum(, []) +gap> PositionMinimum([1,2], x -> x, 2); +Error, Usage: PositionMinimum(, []) +gap> PositionMaximum([]); +fail +gap> PositionMaximum([,,,]); +fail +gap> PositionMaximum([2,,4,,6]); +5 +gap> PositionMinimum([2,,4,,6]); +1 +gap> PositionMinimum([,,,]); +fail +gap> PositionMinimum([]); +fail gap> String( l ); "[ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]" gap> String( [ 1 .. 10 ] );