// excuse my uhh bad coding practices, also hopefully this code is correct 
// and I have replicated Minecraft's mechanics precisely

// (AI didn't assist me in making this but did help me a lot in finding 
// where and understanding the functions in Minecraft's source code. 
// Well.... uhh except for randomizing the direction vector 
// vec3(-sin(yawRad)*cos(pitchRad),-sin(pitchRad),cos(yawRad)*cos(pitchRad)).unit() 
// cuz I haven't learned the sin cos tan radians stuff in depth yet and 
// we haven't even got to radians at school so it was kinda hard to wrap my head around those things
// and it also checked my code at the end) 

#include<bits/stdc++.h>
using namespace std;
using namespace chrono;
const long double pHeight=1.7999999523L;
const long double eHeight=1.6200000047L;
const long double degToRad=acos(-1.0L)/180.0L;
const long double degToRad90=90.0L*degToRad;
const long double power=3.15L;
const long double offset=0.0172275L;
const long double uncertainty=1.0L;
const long double ou=offset*uncertainty;
const long double airDrag=0.99L;
const long double gravity=0.05L;
const long double epsilon=1e-9L;
struct vec3
{
    long double x,y,z;
    vec3(long double _x,long double _y,long double _z): x(_x), y(_y), z(_z) {};
    long double length()
    {
        return sqrt(x*x+y*y+z*z);
    }
    vec3 unit()
    {
        long double l=length();
        return vec3(x/l,y/l,z/l);
    }
    vec3 operator + (const vec3&other)
    {
        return vec3(x+other.x,y+other.y,z+other.z);
    }
    vec3 operator * (const long double n)
    {
        return vec3(x*n,y*n,z*n);
    }
};
mt19937 gen(steady_clock::now().time_since_epoch().count());
uniform_real_distribution<long double>dis(0.0L,1.0L);
long double randReal(long double l,long double r)
{
    return l+dis(gen)*(r-l);
}
long double triRandReal(long double mode,long double spread)
{
    return mode+(randReal(0.0L,1.0L)-randReal(0.0L,1.0L))*spread;
}
long long randInt(long long l,long long r)
{
    return l+gen()%(r-l+1);
}
int main()
{
    auto start=steady_clock::now().time_since_epoch();
    int sims=1000000; // Tweaked to 1M for you, this is the count of the simulations it is gonna run. However, if it exceeds 2147483647, some stuff uh are going to go wrong, not that wrong just that the program might do some weird stuff idk
    long double sum=0.0L;
    cout<<fixed<<setprecision(3);
    for(int sim=1;sim<=sims;++sim)
    {
        vec3 pos(0.0L,eHeight,0.0L);
        long double yawRad=randReal(0.0L,1.0L)*degToRad90,pitchRad=randReal(0.0L,1.0L)*degToRad90;
        vec3 vel=(vec3(-sin(yawRad)*cos(pitchRad),-sin(pitchRad),cos(yawRad)*cos(pitchRad)).unit()+vec3(triRandReal(0.0L,ou),triRandReal(0.0L,ou),triRandReal(0.0L,ou)))*power;
        vector<vec3>vP={pos},vV={vel};
        bool ok=false;
        while(true)
        {
            pos=pos+vel;
            if(!ok and pos.y>pHeight+epsilon)
                ok=true;
            if(pos.y<=-epsilon)
                break;
            vP.push_back(pos);
            vV.push_back(vel);
            vel.x*=airDrag;
            vel.y*=airDrag;
            vel.z*=airDrag;
            vel.y-=gravity;
        }
        if(vP.size()==1)
        {
            --sim;
            continue;
        }
        long double endVel;
        if(ok)
        {
            bool passedPHeight=false;
            int s=-1;
            for(int i=0;i<vP.size();++i)
            {
                if(vP[i].y>pHeight+epsilon)
                    passedPHeight=true;
                else if(passedPHeight and vP[i].y<pHeight-epsilon)
                {
                    s=i;
                    break;
                }
            }
            if(s==-1)
                endVel=vV[randInt(1,vV.size()-1)].length();
            else
                endVel=vV[randInt(s,vV.size()-1)].length();
        }
        else
            endVel=vV[randInt(1,vV.size()-1)].length();
        sum+=endVel;
        if(sim%100000==0)
        {
            auto end=steady_clock::now().time_since_epoch();
            cout<<"| SIMULATIONS RAN: "<<sim<<" | ";
            cout<<"ESTIMATED TIME REMAINING: "<<(long double)duration_cast<milliseconds>(end-start).count()/sim*(sims-sim)/60000.0L<<" MINUTES | ";
            cout<<"AVERAGE ENDING VELOCITY: "<<sum/sim<<" |\n";
        }
    }
    auto end=steady_clock::now().time_since_epoch();
    cout<<"\nANSWER: "<<fixed<<setprecision(10)<<sum/sims<<'\n';
    cout<<"TIME ELAPSED: "<<fixed<<setprecision(3)<<(long double)duration_cast<milliseconds>(end-start).count()/60000.0L<<" MINUTES";
    return 0;
}