It would be simple if you see it as cutting a circle. How to cut a circle to 3 pieces randomly? Just choose 3 points randomly! Then the three pieces should have equal expectation of length.
Due to symmetry, we can fix one point at zero, so we just need to choose the other two points. If the problem is continuous, that should be it. We sort the points and find their differences. For discrete problem, we need to make a little adjustment, since we should "round" the result to nearest integer. We could use another random number to do that.
E.g, for n=30, in C++, we can choose the numbers this way:
#include <bits/stdc++.h>
using namespace std;
int main(){
srand(time(0));
int n=30;
int cnt=0,A=0,B=0,C=0;
for(;cnt<10000;++cnt){
int t1=rand()%n+rand()%2;
int t2=rand()%n+rand()%2;
A+=min(t1,t2);
B+=abs(t1-t2);
C+=n-max(t1,t2);
}
cout<<"A="<<double(A)/cnt<<",B="<<double(B)/cnt<<",C="<<double(C)/cnt;
return 0;
}
possible output:
A=9.9646,B=9.9869,C=10.0485
Or we could just choose $n$ points, since adding one more point doesn't make much difference.
#include <bits/stdc++.h>
using namespace std;
const int N=3;
int n=30;
int main(){
srand(time(0));
int points[N];
int len[N];
for(int i=0;i<N;++i){
len[i]=0;
}
int cnt=0;
for(;cnt<10000;++cnt){
for(int i=0;i<N;++i){
points[i]=rand()%n;
}
sort(points,points+N);
int j=rand()%N; // need to choose starting point randomly,
// because the points are distributed in [0,n-1],
// if j starts at 0, there will be discrepancy,
// since there is always a "gap" between n-1 and 0.
for(int i=1;i<N;++i,++j) len[j%N]+=points[i]-points[i-1];
len[j%N]+=points[0]+n-points[N-1];
}
for(int i=0;i<N;++i) cout<<(double)len[i]/cnt<<",";
cout<<endl;
return 0;
}
possible output:
10.0401,9.9872,9.9727,