steelfeathers Posted October 10, 2014 Share Posted October 10, 2014 I'm working on a script for an ability, and I need to be able to find the actor's top 3 skills. However, I can't seem to figure out a clean way to find the maximum of a set of numbers - there doesn't seem to be a generic "max/min" function for papyrus. Has anyone worked out a method for taking more than 2 numbers and finding the maximum? There are 15 skills to look at, which quickly gets out of hand when trying to compare each skill to every other skill. Link to comment Share on other sites More sharing options...
Mattiewagg Posted October 10, 2014 Share Posted October 10, 2014 Well it wouldn't be incredibly difficult to make the function itself, theoretically. The issue comes from when you have multiple values with the same value. What do you return then? Link to comment Share on other sites More sharing options...
rainbowhyphen Posted October 11, 2014 Share Posted October 11, 2014 (edited) The function is trivial:int function maxIndex(float[] numbers) ; Indicate an error for an empty array. if numbers.length < 1 return -1 endif ; Set up variables to track current maximum. int maxIndex = 0 float maxValue = numbers[0] ; Loop through all array elements. int i = 1 while i < numbers.length ; Update maximum whenever we find a larger value if numbers[i] > maxValue maxIndex = i maxValue = numbers[i] endif i += 1 endwhile ; maxIndex now contains the index of the max value in the input array. return maxIndex endfunctionIf you're not familiar with this algorithm, the idea is simple:Given an unsorted list of values, assume the first one is the largest value. This is called the candidate maximum. Starting with the second value, compare it with the current candidate. If the candidate is smaller, replace it with the new, larger value. When you get to the end of the list, the candidate is the maximum value.This particular function returns the position in the array rather than the value itself, since "the 4th skill in the list" is what we want to know, not "that skill that's at 58, you know the one." You'd want each position in the array to correspond to a particular skill. That way if you get 8 back, you can check that list and know 8 is One Handed or Destruction or Lockpicking or whatever. But if you want to get the top three, then rather than running max() three times and checking most of the skills multiple times, what you really want is a sort. And yes, you'll want to decide what you want to do for skills that have the same value. Edit: I went ahead and wrote a Papyrus implementation of quicksort, mostly out of boredom. Maybe it'll help? I haven't tested it yet, though, so it might not even compile.function fSwap(float[] a, int i, int k) float temp = a[i] a[i] = a[k] a[k] = temp endfunction function iSwap(int[] a, int i, int k) int temp = a[i] a[i] = a[k] a[k] = temp endfunction function quicksort(float[] numbers, int[] indexes, int start, int end) p = partition(numbers, indexes, start, end) quicksort(numbers, indexes, start, p - 1) quicksort(numbers, indexes, p + 1, end) endfunction int function partition(float[] numbers, int[] indexes, int start, int end) pivotIndex = start pivotValue = numbers[start] fSwap(numbers, pivotIndex, end) iSwap(indexes, pivotIndex, end) int storeIndex = start int i = start while i < end if numbers[i] < pivotValue fSwap(numbers, i, storeIndex) iSwap(indexes, i, storeIndex) storeIndex += 1 endif i += 1 endwhile fSwap(numbers, storeIndex, end) iSwap(indexes, storeIndex, end) return storeIndex endfunction int[] function indexSort(float[] numbers) int[] indexes = new int[numbers.length] float[] numCopy = new float[numbers.length] int i = 0 while i < indexes.length indexes[i] = i numCopy[i] = numbers[i] i += 1 endwhile quicksort(numCopy, indexes, 0, numbers.length) return indexes endfunction Note: the fSwap, iSwap, partition, quicksort, and indexSort functions are all required. The indexSort function is the one you want to actually call, and returns an array of integers containing the original order of the array, so if you put in [81, 4, 73] you'll get out [1, 2, 0]. That way if you had some other array in the same order like ["Lockpicking", "One Handed", "Speechcraft"], you could look up the skill. Edited October 11, 2014 by rainbowhyphen Link to comment Share on other sites More sharing options...
steelfeathers Posted October 12, 2014 Author Share Posted October 12, 2014 You are a scholar and a gentleman, thank you. Link to comment Share on other sites More sharing options...
Recommended Posts