Hi there! Today’s challenge is quite similar to the last one. Again, there are quartiles, but the input is a little different and the output is the interquartile range: $Q_3 - Q_1$. The first input is $n$ followed by an array $X$ of size $n$ with our data, but the frequencies of each point are included in another array of $n$ elements, $F$, that is the next input. After reading this we need to construct the actual data array $S$. My solution is below.
package main
import (
"fmt"
"sort"
)
// assumes already sorted
func getMedian(a []int) float64 {
n := len(a)
if n%2 == 0 {
return float64(a[n/2]+a[n/2-1]) / 2.0
}
return float64(a[n/2])
}
func sum(a []int) int {
sum := 0
for i := 0; i < len(a); i++ {
sum += a[i]
}
return sum
}
func main() {
N := 0
fmt.Scanf("%d", &N)
// allocate memory
X := make([]int, N)
F := make([]int, N)
// read numbers from stdin
for i := 0; i < N; i++ {
fmt.Scanf("%d", &X[i])
}
for i := 0; i < N; i++ {
fmt.Scanf("%d", &F[i])
}
// construct array from numbers
// and frequencies
S := make([]int, sum(F))
k := 0
for i := 0; i < len(S); {
for j := 0; j < F[k]; j++ {
S[i+j] = X[k]
}
i += F[k]
k++
}
// sort
sort.Ints(S)
n := len(S)
var Q1, Q3 float64
// get quartiles
Q1 = getMedian(S[0 : n/2])
if n%2 == 0 {
Q3 = getMedian(S[n/2:])
} else {
Q3 = getMedian(S[n/2+1:])
}
fmt.Printf("%.1f\n", Q3-Q1)
}
The biggest problem I had was actually constructing $S$. I simply forgot to construct it the first time and I was thinking the problem was in the median function, but it was fine. When I noticed I forgot it, it was quite easy to solve.