clc, clearvars, clear

filename = 'F1_DATA.xlsx'

T1 = readtable(filename, 'Sheet', "Teams-Drivers", 'Range', 'A1:J11');
T2 = readtable(filename, 'Sheet', "Points System", 'Range', 'A1:K4');
T3 = readtable(filename, 'Sheet', "Qualifications", 'Range', 'A1:AC31');
T4 = readtable(filename, 'Sheet', "Results", 'Range', 'A1:AD31');

disp(T1(1:5,1:6)) %Task I.a
disp(T3(1:5,1:6))
disp(T4(1:5,1:6))

%Task I.b
disp"The dataset covers 30 races, 25 drivers, and 10 teams. It was an exciting season, with Verstappen winning convincingly and a tight battle for second between Norris and Leclerc."

[~, sheetNames] = xlsfinfo(filename);

requiredSheets = {'Teams-Drivers', 'Points System', 'Results'};
for i = 1:length(requiredSheets)
    if ~ismember(requiredSheets{i}, sheetNames)
        error('Required sheet "%s" not found in Excel file', requiredSheets{i});
    end
end

pointsSystem = readtable(filename, 'Sheet', 'Points System');

gpPoints = pointsSystem{2, 2:11}; 
sprintPoints = pointsSystem{1, 2:9}; 


teamsDrivers = readtable(filename, 'Sheet', 'Teams-Drivers');

allDrivers = [teamsDrivers.Driver1_Name; teamsDrivers.Driver2_Name; teamsDrivers.ReserveDriver_Name];
allTeams = [repmat(teamsDrivers.Team, 3, 1)]; 
allTeams = allTeams(1:numel(allDrivers));

driverStats = struct();
for i = 1:numel(allDrivers)
    if ~isempty(allDrivers{i})
        fieldName = matlab.lang.makeValidName(allDrivers{i});
        driverStats.(fieldName) = struct(...
            'TotalPoints', 0, ...
            'GP_Points', 0, ...
            'Sprint_Points', 0, ...
            'GP_Races', 0, ...
            'Sprint_Races', 0, ...
            'Team', allTeams{i});
    end
end

results = readtable(filename, 'Sheet', 'Results', 'VariableNamingRule', 'preserve');

for race = 1:height(results)
    raceType = results.Race_Type{race};
    fastestLap = results.Fastest_Lap{race};
    
    if strcmpi(raceType, 'GP')
        points = gpPoints;
        maxPositions = 10;
        isGP = true;
    else
        points = sprintPoints;
        maxPositions = 8;
        isGP = false;
    end
    
    for col = 5:(width(results)-1)
        colName = results.Properties.VariableNames{col};
        driverName = extractDriverName(colName);
        
        pointsScored = results{race, col};
        if isempty(pointsScored) || isnan(pointsScored) || pointsScored == 0
            continue;
        end
        
        fieldName = matlab.lang.makeValidName(driverName);
        if ~isfield(driverStats, fieldName)
            continue;
        end
        
        if pointsScored <= maxPositions
            racePoints = points(pointsScored);
            driverStats.(fieldName).TotalPoints = driverStats.(fieldName).TotalPoints + racePoints;
            
            if isGP
                driverStats.(fieldName).GP_Points = driverStats.(fieldName).GP_Points + racePoints;
                driverStats.(fieldName).GP_Races = driverStats.(fieldName).GP_Races + 1;
                
            
                if strcmpi(driverName, fastestLap) && pointsScored <= 10
                    driverStats.(fieldName).TotalPoints = driverStats.(fieldName).TotalPoints + 1;
                    driverStats.(fieldName).GP_Points = driverStats.(fieldName).GP_Points + 1;
                end
            else
                driverStats.(fieldName).Sprint_Points = driverStats.(fieldName).Sprint_Points + racePoints;
                driverStats.(fieldName).Sprint_Races = driverStats.(fieldName).Sprint_Races + 1;
            end
        end
    end
end

driverNames = fieldnames(driverStats)';
outputData = cell(length(driverNames), 9);
outputVars = {'Driver', 'Team', 'TotalPoints', 'GP_Points', 'GP_Races', 'GP_Avg', 'Sprint_Points', 'Sprint_Races', 'Sprint_Avg'};

for i = 1:numel(driverNames)
    stats = driverStats.(driverNames{i});
    name = strrep(driverNames{i}, '_', ' ');
    
    gpAvg = stats.GP_Points / max(1, stats.GP_Races);
    sprintAvg = stats.Sprint_Points / max(1, stats.Sprint_Races);
    
    outputData(i,:) = {name, stats.Team, stats.TotalPoints, ...
                      stats.GP_Points, stats.GP_Races, gpAvg, ...
                      stats.Sprint_Points, stats.Sprint_Races, sprintAvg};
end

outputTable = cell2table(outputData, 'VariableNames', outputVars);
outputTable = sortrows(outputTable, 'TotalPoints', 'descend');

try
    writetable(outputTable, filename, 'Sheet', 'DriverStats', 'WriteMode', 'overwritesheet');
    fprintf('Successfully exported results to "%s" in sheet "DriverStats"\n', filename);
catch e
    warning('Could not write to Excel file: %s', e.message);
    disp('Displaying results instead:');
    disp(outputTable);
end

function driverName = extractDriverName(colName)
    parts = split(colName, {'_', '-'});
    if numel(parts) >= 2
        driverName = strjoin(parts(2:end), ' ');
    else
        driverName = colName;
    end
end


%Task II.2.b
ConP=zeros(1,10);
TpointsA=zeros(1,26);
Alpine = TpointsA(1, 2) + TpointsA(1, 3) + TpointsA(1, 4);
ConP(1,1) = Alpine;

Aston = TpointsA(1, 5) + TpointsA(1, 6);
ConP(1,2) = Aston;

Ferrari = TpointsA(1, 7) + TpointsA(1, 8) + TpointsA(1, 9);
ConP(1,3) = Ferrari;

Haas = TpointsA(1, 10) + TpointsA(1, 11) + TpointsA(1, 12);
ConP(1,4) = Haas;

Mclaren = TpointsA(1, 13) + TpointsA(1, 14) ;
ConP(1,5) = Mclaren;

Merc = TpointsA(1, 15) + TpointsA(1, 16) ;
ConP(1,6) = Merc;

RB = TpointsA(1, 17) + TpointsA(1, 18) + TpointsA(1, 19);
ConP(1,7) = RB;

RBR = TpointsA(1, 20) + TpointsA(1, 21) ;
ConP(1,8) = RBR;

Sauber = TpointsA(1, 22) + TpointsA(1, 23) ;
ConP(1,9) = Sauber;

Will = TpointsA(1, 24) + TpointsA(1, 25) + TpointsA(1, 26);
ConP(1,10) = Will;

figure
x = ["Alpine" "AstonMartin" "Ferrari" "Haas" "Mclaren" "Mercedes" "RB" "RBR" "Sauber" "Williams"];
bar(x,ConP)


%Task III.1.b
qualifyingData = readtable('F1_DATA.xlsx', 'Sheet', 'Qualifications');
resultsData = readtable('F1_DATA.xlsx', 'Sheet', 'Results');
gpQualifying = qualifyingData(strcmp(qualifyingData.Race_Type, 'GP'), :);
gpResults = resultsData(strcmp(resultsData.Race_Type, 'GP'), :);
qualifyingPositions = [];
racePoints = [];
driverColumns = 5:width(gpQualifying); 
for col = driverColumns
    driverName = gpQualifying.Properties.VariableNames{col};
    if contains(driverName, 'Doohan') || contains(driverName, 'Bearman') || contains(driverName, 'Colapinto') || contains(driverName, 'Burren') || contains(driverName, 'Maloney')
        continue;
    end
    driverQualifying = gpQualifying.(driverName);
    driverResults = gpResults.(driverName);
    validIndices = ~isnan(driverQualifying) & ~isnan(driverResults);
    qualifyingPositions = [qualifyingPositions; driverQualifying(validIndices)];
    racePoints = [racePoints; driverResults(validIndices)];
end
R = corrcoef(qualifyingPositions, racePoints);
correlation = R(1, 2);
disp(['Pearson Correlation Coefficient (Qualifying Position vs. Race Points): ', num2str(correlation)]);
scatter(qualifyingPositions, racePoints, "o","filled" );
xlabel('Qualifying Position');
ylabel('Race Points');
title('Qualifying Position vs. Race Points (GP Races)');
grid on;

%Task III.2.a 

teamsDrivers = readtable('F1_DATA.xlsx', 'Sheet', 'Teams-Drivers');
results = readtable('F1_DATA.xlsx', 'Sheet', 'Results');
gpResults = results(strcmp(results.Race_Type, 'GP'), :);
teams = teamsDrivers.Team;
nTeams = height(teamsDrivers);

pointsDiff = [];

for i = 1:nTeams
    team = teams{i};
    

    driver1 = teamsDrivers.Driver1_Name{i};
    driver2 = teamsDrivers.Driver2_Name{i};
    

    driver1Col = [team '_' strrep(driver1, ' ', '_')];
    driver2Col = [team '_' strrep(driver2, ' ', '_')];
    

    if ~ismember(driver1Col, gpResults.Properties.VariableNames) || ...
       ~ismember(driver2Col, gpResults.Properties.VariableNames)
        fprintf('Skipping team %s (missing data for %s or %s)\n', team, driver1, driver2);
        continue;
    end
    
    driver1Points = gpResults.(driver1Col);
    driver2Points = gpResults.(driver2Col);
 

    validRaces = ~isnan(driver1Points) & ~isnan(driver2Points);
    driver1Points = driver1Points(validRaces);
    driver2Points = driver2Points(validRaces);
    

    teamDiff = driver1Points - driver2Points;
    pointsDiff = [pointsDiff; teamDiff];
end

n = length(pointsDiff);
meanDiff = mean(pointsDiff);
stdDiff = std(pointsDiff);
stdErr = stdDiff / sqrt(n);

t_stat = meanDiff / stdErr;
df = n - 1;

x = abs(t_stat);
t = 1 / (1 + 0.2316419 * x);
p = 1 - 0.5 * (1 + t*(0.319381530 + t*(-0.356563782 + ...
    t*(1.781477937 + t*(-1.821255978 + t*1.330274429))))) * exp(-x*x/2);

p_value = 2 * (1 - p); 

if df > 30
    t_critical = 1.96;
else
    t_table = [12.71 4.303 3.182 2.776 2.571 2.447 2.365 2.306 2.262 2.228 ...
               2.201 2.179 2.160 2.145 2.131 2.120 2.110 2.101 2.093 2.086 ...
               2.080 2.074 2.069 2.064 2.060 2.056 2.052 2.048 2.045 2.042];
    if df <= length(t_table)
        t_critical = t_table(df);
    else
        t_critical = 2.0; 
    end
end

ci_low = meanDiff - t_critical * stdErr;
ci_high = meanDiff + t_critical * stdErr;


fprintf('\n--- t-test Results (Toolbox-Free Implementation) ---\n');
fprintf('  Sample size (n pairs) = %d\n', n);
fprintf('  t-statistic = %.3f\n', t_stat);
fprintf('  p-value ≈ %.4f\n', p_value);
fprintf('  95%% Confidence Interval ≈ [%.2f, %.2f]\n', ci_low, ci_high);

if p_value < 0.05
    fprintf('\nConclusion: REJECT H0 (significant difference between drivers).\n');
else
    fprintf('\nConclusion: FAIL TO REJECT H0 (no significant difference).\n');
end

figure;
histogram(pointsDiff, 'BinWidth', 2, 'FaceColor', [0.2 0.6 0.8]);
xlabel('Points Difference (Driver1 - Driver2)');
ylabel('Frequency');
title('Distribution of Paired Differences in GP Race Points');
grid on;



%Task IV.a

filename = 'F1_DATA.xlsx';

resultsTable = readtable(filename, 'Sheet', 'Results');

driverColumns = resultsTable.Properties.VariableNames(5:end-1); 
driverNames = cell(size(driverColumns));
teamNames = cell(size(driverColumns));

for i = 1:length(driverColumns)
    parts = strsplit(driverColumns{i}, '_');
    teamNames{i} = parts{1};
    driverNames{i} = parts{2};
end

totalPoints = zeros(1, length(driverColumns));

for i = 1:length(driverColumns)
    columnName = driverColumns{i};
    points = resultsTable.(columnName);
    totalPoints(i) = sum(points, 'omitnan');
end

driverData = table(driverNames', teamNames', totalPoints', ...
    'VariableNames', {'Driver', 'Team', 'TotalPoints'});

sortedDrivers = sortrows(driverData, 'TotalPoints', 'descend');

top5 = sortedDrivers(1:5, :);
disp('Top 5 Drivers by Total Points:');
disp(top5);

figure;
bar(top5.TotalPoints);
set(gca, 'XTickLabel', top5.Driver);
title('Top 5 F1 Drivers by Total Points');
xlabel('Driver');
ylabel('Total Points');
grid on;


%Task IV.b

filename = 'F1_DATA.xlsx';

resultsTable = readtable(filename, 'Sheet', 'Results');

driverColumns = resultsTable.Properties.VariableNames(5:end-1); 
driverNames = cell(size(driverColumns));
teamNames = cell(size(driverColumns));

for i = 1:length(driverColumns)
    parts = strsplit(driverColumns{i}, '_');
    teamNames{i} = parts{1};
    driverNames{i} = parts{2};
end

totalPoints = zeros(1, length(driverColumns));
racesWithPoints = zeros(1, length(driverColumns));

for i = 1:length(driverColumns)
    columnName = driverColumns{i};
    points = resultsTable.(columnName);
    totalPoints(i) = sum(points, 'omitnan');
    racesWithPoints(i) = sum(points > 0); 
end

driverData = table(driverNames', teamNames', totalPoints', racesWithPoints', ...
    'VariableNames', {'Driver', 'Team', 'TotalPoints', 'RacesWithPoints'});

consistentDrivers = driverData(driverData.RacesWithPoints >= 25, :);

consistentDrivers = sortrows(consistentDrivers, 'TotalPoints', 'descend');

disp('Drivers Who Scored Points in ≥25 Races (Ranked by Total Points):');
disp(consistentDrivers);

figure;
bar(consistentDrivers.TotalPoints);
set(gca, 'XTickLabel', consistentDrivers.Driver);
title('Drivers Scoring Points in ≥25 Races (Ranked by Total Points)');
xlabel('Driver');
ylabel('Total Points');
grid on;