Not a year goes by where we don't see at least one person Sorted into each House, and it's usually a fairly even distribution.
Let's do the math. Assume there are N students per year, and the probability for any one student is always 1/4 to be sorted into house h, where h ∊ {G, S, R, H } =: ℋ. Define "a fairly even distribution" as
nmin ≤ nhy ≤ nmax ∀ h ∊ ℋ, y ∊ {1991, ... 1997}
where nhy is the number of students in house h in year y. The probability for this is Py7, where Py is the probability that any one year is evenly-distributed. That value is calculated by the Haskell program below (it's not very well done, essentially brute force).
To get a result, we need to know the number of students in each year. Let's first try the estimate by the article Slytherincess already linked to, i.e. 10 students per house per year / 40 in total. Allowing for a range from 6 to 16 students per house, we find out
GHCi> ( p_YearHasFairlyEvenDistrib (6,16) 40 )^7
0.22543290063072918
that the probability is only 22.5% that Harry will never have observed a year with not-fairly-even distribution. But it becomes quite a lot bigger if we allow just a slightly larger margin
GHCi> (p_YearHasFairlyEvenDistrib (4,20) 40)^7
0.8725318786933933
makes 87%! Now, only 4 students per house can't really be called even distribution anymore, but I don't think we can prove this never happened in the course of the books.
If we rather use the number of students JKR herself gave, 1000 in the whole school ⇒ 143 per year (the program as given below won't do that, at least not within 8 GB of memory – I had to optimize it a little) ⇒ on average 35 students per house, we can restrict ourselves to the substantially more even-looking range (25,50)
and still get a probability of 66%.
So, all in all, it's really a question we can answer with Hogwarts doesn't really need quotas; even with perfectly equal treatment of all students there will very seldom be a problematically uneven distribution of students in the houses.
import Data.List
data HousesDistrib = HousesDistrib { studentDistribution :: (Int,Int,Int,Int)
, distribProbability :: Double
}
instance Show HousesDistrib where
show (HousesDistrib d p) = " " ++ show d ++ " @" ++ show p
studentIntoHousePossibilities :: HousesDistrib -> [HousesDistrib]
studentIntoHousePossibilities (HousesDistrib (g,s,r,h) p)
= [ HousesDistrib (g+1,s, r, h ) p'
, HousesDistrib (g, s+1,r, h ) p'
, HousesDistrib (g, s, r+1,h ) p'
, HousesDistrib (g, s, r, h+1) p'
]
where p' = p/4
summarizeEqualDistribs :: [HousesDistrib] -> [HousesDistrib]
summarizeEqualDistribs = map sumup . groupBy distribEquals . sortBy distribOrdering
where sumup = foldl1' (\a b -> HousesDistrib
(studentDistribution a)
(distribProbability a + distribProbability b) )
a`distribEquals`b = (studentDistribution a == studentDistribution b)
a`distribOrdering`b = compare (studentDistribution a) (studentDistribution b)
allPossibleDistribs :: Int -> [HousesDistrib]
allPossibleDistribs n = distribSequence [HousesDistrib (0,0,0,0) 1] !! n
where distribSequence = iterate ( summarizeEqualDistribs
. (>>=studentIntoHousePossibilities) )
allFairlyEvenDistribs rng = filter (isFairlyEvenDistrib rng) . allPossibleDistribs
isFairlyEvenDistrib (nmin, nmax) (HousesDistrib (g,s,r,h) _)
= ok g && ok s && ok r && ok h
where ok n = n>=nmin && n<=nmax
p_YearHasFairlyEvenDistrib rng nStudents
= sum . map distribProbability $ allFairlyEvenDistribs rng nStudents