aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mass-graduation.js16
-rw-r--r--src/utils-common.ts15
-rw-r--r--src/utils-mock.js1
-rw-r--r--src/utils-prod.js1
4 files changed, 30 insertions, 3 deletions
diff --git a/src/mass-graduation.js b/src/mass-graduation.js
index 335ba16..3bce288 100644
--- a/src/mass-graduation.js
+++ b/src/mass-graduation.js
@@ -1,7 +1,6 @@
import { GraduationChange, submitGraduationChange } from "./graduation-ENV.ts";
import { fetchStudents } from "./student-ENV.ts";
-
-import { getName } from "./utils-ENV.js";
+import { CourseLocalStorage, getName, splitmix32 } from "./utils-ENV.js";
let name;
@@ -23,8 +22,19 @@ function toggle(btn, others) {
// https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
function shuffleArray(array) {
+ var seed = JSON.parse(CourseLocalStorage.getItem("bycs-sol-mandatory-seed"));
+ if (seed === null || Date(seed.endOfLife) < Date()) {
+ seed = {
+ seed: (Math.random() * 2 ** 32) >>> 0,
+ // Keep the same seed for 45 minutes
+ endOfLife: new Date(new Date().getTime() + 45 * 60000),
+ };
+ CourseLocalStorage.setItem("bycs-sol-mandatory-seed", JSON.stringify(seed));
+ }
+ const rng = splitmix32(seed.seed);
+
for (let i = array.length - 1; i > 0; i--) {
- const j = Math.floor(Math.random() * (i + 1));
+ const j = Math.floor(rng() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
diff --git a/src/utils-common.ts b/src/utils-common.ts
index 8053043..153bbaa 100644
--- a/src/utils-common.ts
+++ b/src/utils-common.ts
@@ -33,3 +33,18 @@ export async function getUserIconUrl(userId: number): Promise<string> {
return (userpicture as HTMLImageElement).src ?? "";
}
+
+// SplitMix32 implementation taken from:
+// https://github.com/bryc/code/blob/master/jshash/PRNGs.md
+// We only need a seeded PRNG to choose students to observe.
+export function splitmix32(a: number) {
+ return function () {
+ a |= 0;
+ a = (a + 0x9e3779b9) | 0;
+ let t = a ^ (a >>> 16);
+ t = Math.imul(t, 0x21f0aaad);
+ t = t ^ (t >>> 15);
+ t = Math.imul(t, 0x735a2d97);
+ return ((t = t ^ (t >>> 15)) >>> 0) / 4294967296;
+ };
+}
diff --git a/src/utils-mock.js b/src/utils-mock.js
index 563f685..4fb2b10 100644
--- a/src/utils-mock.js
+++ b/src/utils-mock.js
@@ -5,6 +5,7 @@ export {
dateStringNow,
datetimeStringNow,
getUserIconUrl,
+ splitmix32,
} from "./utils-common.ts";
export function isTeacher() {
diff --git a/src/utils-prod.js b/src/utils-prod.js
index b53f535..447a17a 100644
--- a/src/utils-prod.js
+++ b/src/utils-prod.js
@@ -4,6 +4,7 @@ export {
dateStringNow,
datetimeStringNow,
getUserIconUrl,
+ splitmix32,
} from "./utils-common.ts";
export function isTeacher() {