0% found this document useful (0 votes)
2 views

AppScript

The document is a JavaScript code for a Google Apps Script that updates a Google Sheets document with submission details from the CodeForces API. It styles problem columns, fetches user submissions, and displays the latest submission status, problem ratings, and submission dates. The script organizes the data into a structured format for easy viewing and tracking of programming contest submissions.

Uploaded by

ss240102222
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

AppScript

The document is a JavaScript code for a Google Apps Script that updates a Google Sheets document with submission details from the CodeForces API. It styles problem columns, fetches user submissions, and displays the latest submission status, problem ratings, and submission dates. The script organizes the data into a structured format for easy viewing and tracking of programming contest submissions.

Uploaded by

ss240102222
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 5

// ============== CONFIGURATION ==============

const CONFIG = {
// Styling for Problem Column (Column A)
PROBLEM_BG: "#fce4d6",
PROBLEM_TEXT_COLOR: "#000000",

// Styling for Submission Status Column (Column B)


STATUS_BG_DEFAULT: "#f4f4f4",
STATUS_BG_AC: "#a9d18e", // For accepted submissions.
STATUS_BG_WA: "#f4b084", // For wrong answer, runtime error, compilation
error.
STATUS_BG_TLE: "#ffff99", // For time limit exceeded.
STATUS_BG_MLE: "#d1c4e9", // For memory limit exceeded.

// Font settings (applied to rich text)


FONT_BOLD: true,
FONT_SIZE_STATUS: 10
};
// ============================================

function updateSubmissions() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();

// Use your CodeForces handle here:


var cfHandle = "Ahmed_Aasim";

// Fetch all submissions for your handle using the CodeForces API
var apiUrl = "https://codeforces.com/api/user.status?handle=" + cfHandle;
var response = UrlFetchApp.fetch(apiUrl);
var data = JSON.parse(response.getContentText());
if (data.status !== "OK") {
Logger.log("Error fetching submissions: " + data.comment);
return;
}
var submissions = data.result;

// Build a map keyed by "contestId + problemIndex", e.g. "69A".


// Each key stores:
// - latestSubmission,
// - latestAccepted (if exists),
// - rating: taken from the submission's problem (if present)
var submissionMap = {};
submissions.forEach(function (sub) {
if (!sub.problem || !sub.problem.contestId || !sub.problem.index) return;
var key = sub.problem.contestId.toString() + sub.problem.index.toUpperCase();
if (!submissionMap[key]) {
submissionMap[key] = {
latestSubmission: sub,
latestAccepted: null,
rating: sub.problem.rating || "N/A"
};
} else {
if (sub.creationTimeSeconds >
submissionMap[key].latestSubmission.creationTimeSeconds) {
submissionMap[key].latestSubmission = sub;
// Update rating if available (it may change if a new submission has a
rating)
submissionMap[key].rating = sub.problem.rating || "N/A";
}
}
if (sub.verdict === "OK") {
if (!submissionMap[key].latestAccepted ||
sub.creationTimeSeconds >
submissionMap[key].latestAccepted.creationTimeSeconds) {
submissionMap[key].latestAccepted = sub;
}
}
});

// Fetch the complete list of CodeForces problems to get their full names and
ratings.
// This is useful if you haven't solved or attempted a problem.
var allProblems = {};
try {
var responseProblems =
UrlFetchApp.fetch("https://codeforces.com/api/problemset.problems");
var dataProblems = JSON.parse(responseProblems.getContentText());
if (dataProblems.status === "OK") {
dataProblems.result.problems.forEach(function (prob) {
if (prob.contestId && prob.index) {
var key = prob.contestId.toString() + prob.index.toUpperCase();
allProblems[key] = {
name: prob.name,
rating: prob.rating || "N/A"
};
}
});
}
} catch (e) {
Logger.log("Error fetching problemset problems: " + e);
}

// Get all values in column A starting from row 2.


var dataRange = sheet.getRange("A2:A");
var problemIds = dataRange.getValues();

// Process each row in column A.


for (var i = 0; i < problemIds.length; i++) {
var value = problemIds[i][0].toString().trim();
if (value === "") continue; // Skip empty cells.

// Expect problem IDs in the format "69A"


var match = value.match(/^(\d+)([A-Za-z]+)$/);
if (!match) continue;

var contestId = match[1];


var problemIndex = match[2].toUpperCase();
var key = contestId + problemIndex;

// Build the URL for the problem statement.


var probUrl = "https://codeforces.com/problemset/problem/" + contestId + "/" +
problemIndex;
var cellA = sheet.getRange(i + 2, 1); // Column A

// Determine the full problem name and rating.


var problemName = null;
var problemRating = "N/A";
if (submissionMap.hasOwnProperty(key)) {
problemName = submissionMap[key].latestSubmission.problem.name;
problemRating = submissionMap[key].rating;
} else if (allProblems.hasOwnProperty(key)) {
problemName = allProblems[key].name;
problemRating = allProblems[key].rating;
}
var displayText = value;
if (problemName) {
displayText = value + " - " + problemName;
}

// Build the text style for Column A.


var textStyleA = SpreadsheetApp.newTextStyle()
.setForegroundColor(CONFIG.PROBLEM_TEXT_COLOR)
.setUnderline(false)
.setBold(CONFIG.FONT_BOLD)
.build();
var richTextA = SpreadsheetApp.newRichTextValue()
.setText(displayText)
.setLinkUrl(probUrl)
.setTextStyle(0, displayText.length, textStyleA)
.build();
cellA.setRichTextValue(richTextA);
cellA.setHorizontalAlignment("center");
cellA.setBackground(CONFIG.PROBLEM_BG);

// -----------------------------
// Column B: Submission Status
// -----------------------------
var cellB = sheet.getRange(i + 2, 2);
var shortStatus = "N/A";
var emoji = "❔";
var bgColorStatus = CONFIG.STATUS_BG_DEFAULT;
var statusText = "";
var richTextB = null;
var chosenSub = null;
var submissionDateTime = null;

if (submissionMap.hasOwnProperty(key)) {
var record = submissionMap[key];
if (record.latestAccepted) {
chosenSub = record.latestAccepted;
shortStatus = "AC";
emoji = "✅";
bgColorStatus = CONFIG.STATUS_BG_AC;
} else if (record.latestSubmission) {
chosenSub = record.latestSubmission;
submissionDateTime = new Date(chosenSub.creationTimeSeconds * 1000);
var verdict = chosenSub.verdict;
switch (verdict) {
case "WRONG_ANSWER":
shortStatus = "WA";
emoji = "❌";
bgColorStatus = CONFIG.STATUS_BG_WA;
break;
case "TIME_LIMIT_EXCEEDED":
shortStatus = "TLE";
emoji = "⌛";
bgColorStatus = CONFIG.STATUS_BG_TLE;
break;
case "MEMORY_LIMIT_EXCEEDED":
shortStatus = "MLE";
emoji = "💾";
bgColorStatus = CONFIG.STATUS_BG_MLE;
break;
case "RUNTIME_ERROR":
shortStatus = "RE";
emoji = "⚠️";
bgColorStatus = CONFIG.STATUS_BG_WA;
break;
case "COMPILATION_ERROR":
shortStatus = "CE";
emoji = "🚫";
bgColorStatus = CONFIG.STATUS_BG_WA;
break;
default:
shortStatus = verdict.substring(0, 3).toUpperCase();
emoji = "❓";
bgColorStatus = CONFIG.STATUS_BG_WA;
break;
}
}
statusText = shortStatus + " " + emoji;
// Build the hyperlink for the status (linking to the submission).
if (chosenSub) {
var submissionUrl = "https://codeforces.com/contest/" + contestId +
"/submission/" + chosenSub.id;
var textStyleB = SpreadsheetApp.newTextStyle()
.setForegroundColor(CONFIG.PROBLEM_TEXT_COLOR)
.setUnderline(false)
.setBold(CONFIG.FONT_BOLD)
.build();
richTextB = SpreadsheetApp.newRichTextValue()
.setText(statusText)
.setLinkUrl(submissionUrl)
.setTextStyle(0, statusText.length, textStyleB)
.build();
cellB.setRichTextValue(richTextB);
} else {
cellB.setValue(statusText);
}
} else {
statusText = "N/A ❌";
cellB.setValue(statusText);
}
cellB.setHorizontalAlignment("center");
cellB.setFontSize(CONFIG.FONT_SIZE_STATUS);
cellB.setBackground(bgColorStatus);

// -----------------------------
// Column C: Problem Rating
// -----------------------------
var cellC = sheet.getRange(i + 2, 3);
cellC.setValue(problemRating);
cellC.setHorizontalAlignment("center");
cellC.setFontSize(CONFIG.FONT_SIZE_STATUS);
// -----------------------------
// Column D: Submission Date & Time
// -----------------------------
var cellD = sheet.getRange(i + 2, 4);
if (chosenSub && submissionDateTime) {
// Format the date as "dd/MM/yyyy - HH:mm"
var formattedDate = Utilities.formatDate(
submissionDateTime,
Session.getScriptTimeZone(),
"dd/MM/yyyy - HH:mm"
);
cellD.setValue(formattedDate);
} else {
cellD.setValue("N/A");
}
cellD.setHorizontalAlignment("center");

}
}

You might also like