@@ -5,14 +5,18 @@ export const SKIPPED_VALUE = 0;
55export const DNF_VALUE = - 1 ;
66export const DNS_VALUE = - 2 ;
77
8- function isComplete ( attemptResult ) {
8+ export function isComplete ( attemptResult ) {
99 return attemptResult > 0 ;
1010}
1111
12- function isSkipped ( attemptResult ) {
12+ export function isSkipped ( attemptResult ) {
1313 return attemptResult === SKIPPED_VALUE ;
1414}
1515
16+ export function toMonotonic ( attemptResult ) {
17+ return isComplete ( attemptResult ) ? attemptResult : Infinity ;
18+ }
19+
1620function compareAttemptResults ( attemptResult1 , attemptResult2 ) {
1721 if ( ! isComplete ( attemptResult1 ) && ! isComplete ( attemptResult2 ) ) return 0 ;
1822 if ( ! isComplete ( attemptResult1 ) && isComplete ( attemptResult2 ) ) return 1 ;
@@ -80,7 +84,7 @@ export function average(attemptResults, eventId) {
8084 const scaled = attemptResults . map ( ( attemptResult ) => attemptResult * 100 ) ;
8185 switch ( attemptResults . length ) {
8286 case 3 :
83- return meanOf3 ( scaled ) ;
87+ return meanOfX ( scaled ) ;
8488 case 5 :
8589 return averageOf5 ( scaled ) ;
8690 default :
@@ -92,7 +96,7 @@ export function average(attemptResults, eventId) {
9296
9397 switch ( attemptResults . length ) {
9498 case 3 :
95- return truncateOver10Mins ( meanOf3 ( attemptResults ) ) ;
99+ return truncateOver10Mins ( meanOfX ( attemptResults ) ) ;
96100 case 5 :
97101 return truncateOver10Mins ( averageOf5 ( attemptResults ) ) ;
98102 default :
@@ -111,10 +115,10 @@ function truncateOver10Mins(value) {
111115
112116function averageOf5 ( attemptResults ) {
113117 const [ , x , y , z ] = attemptResults . slice ( ) . sort ( compareAttemptResults ) ;
114- return meanOf3 ( [ x , y , z ] ) ;
118+ return meanOfX ( [ x , y , z ] ) ;
115119}
116120
117- function meanOf3 ( attemptResults ) {
121+ function meanOfX ( attemptResults ) {
118122 if ( ! attemptResults . every ( isComplete ) ) return DNF_VALUE ;
119123 return mean ( attemptResults ) ;
120124}
@@ -124,6 +128,48 @@ function mean(values) {
124128 return Math . round ( sum / values . length ) ;
125129}
126130
131+ /**
132+ * Returns projected average.
133+ *
134+ * Note that contrarily to other functions in this module, this
135+ * function expects a non-padded and incomplete list of attempt
136+ * results (without trailing skipped values).
137+ *
138+ * Projections are defined as follows:
139+ *
140+ * - mo3 events: mean of current solves
141+ * - ao5 events:
142+ * - 1-2 solves: mean of current solves
143+ * - 3-4 solves: median of current solves
144+ *
145+ * When all result attempts are present, the return value is the same
146+ * as the usual average.
147+ */
148+ export function projectedAverage ( attemptResults , format ) {
149+ if ( attemptResults . length === 0 ) return SKIPPED_VALUE ;
150+
151+ if ( format . numberOfAttempts === 3 ) {
152+ return meanOfX ( attemptResults ) ;
153+ }
154+
155+ if ( format . numberOfAttempts === 5 ) {
156+ if ( attemptResults . length < 3 ) {
157+ return meanOfX ( attemptResults ) ;
158+ }
159+ if ( attemptResults . length === 3 ) {
160+ const [ , x ] = attemptResults . slice ( ) . sort ( compareAttemptResults ) ;
161+ return x ;
162+ }
163+ if ( attemptResults . length === 4 ) {
164+ const [ , x , y ] = attemptResults . slice ( ) . sort ( compareAttemptResults ) ;
165+ return meanOfX ( [ x , y ] ) ;
166+ }
167+ return averageOf5 ( attemptResults ) ;
168+ }
169+
170+ throw new Error ( "Unexpected format" ) ;
171+ }
172+
127173/**
128174 * Calculates the best possible average of 5 for the given attempts.
129175 *
@@ -142,7 +188,7 @@ export function bestPossibleAverage(attemptResults) {
142188 }
143189
144190 const [ x , y , z ] = attemptResults . slice ( ) . sort ( compareAttemptResults ) ;
145- const mean = meanOf3 ( [ x , y , z ] ) ;
191+ const mean = meanOfX ( [ x , y , z ] ) ;
146192 return truncateOver10Mins ( mean ) ;
147193}
148194
@@ -164,7 +210,7 @@ export function worstPossibleAverage(attemptResults) {
164210 }
165211
166212 const [ , x , y , z ] = attemptResults . slice ( ) . sort ( compareAttemptResults ) ;
167- const mean = meanOf3 ( [ x , y , z ] ) ;
213+ const mean = meanOfX ( [ x , y , z ] ) ;
168214 return truncateOver10Mins ( mean ) ;
169215}
170216
0 commit comments