pfes
This commit is contained in:
parent
a94776695a
commit
8b3bb9c382
6 changed files with 119 additions and 80 deletions
38
pfes/sort/api.ts
Executable file
38
pfes/sort/api.ts
Executable file
|
@ -0,0 +1,38 @@
|
||||||
|
#!/bin/env -S deno run -A
|
||||||
|
|
||||||
|
import { group_inputs, members_from_cells, Memeber, write_to_csv } from "./converter.ts";
|
||||||
|
import { enumerate } from "./utils.ts";
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const sheet_id = "il9cnn4s9ugc";
|
||||||
|
const sheet = await get_sheet(sheet_id);
|
||||||
|
const members = extract_members(sheet, [0, 4]);
|
||||||
|
const groups = group_inputs(members, 4);
|
||||||
|
await write_to_csv("./output.csv", groups);
|
||||||
|
}
|
||||||
|
|
||||||
|
type Sheet = Awaited<ReturnType<typeof get_sheet>>;
|
||||||
|
async function get_sheet(sheet_id: string) {
|
||||||
|
const response = await fetch(`https://ethercalc.net/${sheet_id}.csv`);
|
||||||
|
const body = await response.text();
|
||||||
|
return body.split("\n").map((line) => line.split(","));
|
||||||
|
}
|
||||||
|
|
||||||
|
function extract_members(sheet: Sheet, input_top_left: coords): Memeber[] {
|
||||||
|
const [tl_x, tl_y] = input_top_left;
|
||||||
|
const filtered = [] as string[][];
|
||||||
|
for (const [y, line] of enumerate(sheet)) {
|
||||||
|
if (y < tl_y) continue;
|
||||||
|
const filtered_line = [] as string[];
|
||||||
|
for (const [x, cell] of enumerate(line)) {
|
||||||
|
if (x < tl_x) continue;
|
||||||
|
filtered_line.push(cell);
|
||||||
|
}
|
||||||
|
filtered.push(filtered_line);
|
||||||
|
}
|
||||||
|
return members_from_cells(filtered);
|
||||||
|
}
|
||||||
|
|
||||||
|
type coords = [number, number];
|
||||||
|
|
||||||
|
if (import.meta.main) await main();
|
58
pfes/sort/converter.ts
Executable file
58
pfes/sort/converter.ts
Executable file
|
@ -0,0 +1,58 @@
|
||||||
|
#!/bin/env -S deno run -A
|
||||||
|
|
||||||
|
import { enumerate, range, to_int } from "./utils.ts";
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
const max_in_group = 4;
|
||||||
|
const input = read_input("./input.csv");
|
||||||
|
const groups = group_inputs(input, max_in_group);
|
||||||
|
write_to_csv("./output.csv", groups);
|
||||||
|
}
|
||||||
|
|
||||||
|
function read_input(path: string) {
|
||||||
|
const content = Deno.readTextFileSync(path);
|
||||||
|
const cells = content.split("\n").filter((line) => line !== "").map((line) => line.split("\t"));
|
||||||
|
const result = members_from_cells(cells);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Memeber = ReturnType<typeof members_from_cells>[0];
|
||||||
|
export function members_from_cells(cells: string[][]) {
|
||||||
|
return cells.map((
|
||||||
|
[login, s1, s2, s3, s4, s5, s6],
|
||||||
|
) => ({ login, choices: ([s1, s2, s3, s4, s5, s6] as const).map(to_int), placed: false }));
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Group = ReturnType<typeof group_inputs>[0];
|
||||||
|
export function group_inputs(input: Memeber[], max_in_group: number) {
|
||||||
|
const groups = range(1, 7)
|
||||||
|
.arr()
|
||||||
|
.map((sujet_no) => ({ sujet_no, members: [] as { login: string; prio: number }[] }));
|
||||||
|
|
||||||
|
for (const prio of range(1, 7)) {
|
||||||
|
for (const entry of input) {
|
||||||
|
if (entry.placed) continue;
|
||||||
|
for (const [index, choice] of enumerate(entry.choices)) {
|
||||||
|
if (choice !== prio) continue;
|
||||||
|
if (groups[index].members.length >= max_in_group) continue;
|
||||||
|
groups[index].members.push({ login: entry.login, prio });
|
||||||
|
entry.placed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function groups_to_cells(groups: Group[]) {
|
||||||
|
return groups.map(({ sujet_no, members }) => [
|
||||||
|
`Sujet ${sujet_no}`,
|
||||||
|
...members.map(({ login, prio }) => `${prio} ${login}`),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function write_to_csv(path: string, groups: Group[]) {
|
||||||
|
const result = groups_to_cells(groups).map((line) => line.join("\t")).join("\n");
|
||||||
|
Deno.writeTextFileSync(path, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (import.meta.main) main();
|
|
@ -1,25 +0,0 @@
|
||||||
alexandre.di-santo
|
|
||||||
anas.el-khatir 2 5 3 1 4 6
|
|
||||||
arnaud.avare
|
|
||||||
baptiste.mabille
|
|
||||||
bastien.taur
|
|
||||||
clement.thollet 2 6 3 1 5 4
|
|
||||||
edwin.galibert 1 2 6 5 3 4
|
|
||||||
enzo.laik
|
|
||||||
julia.royer 5 4 1 2 6 3
|
|
||||||
loick.balloy
|
|
||||||
luna.zozor 4 5 1 2 6 3
|
|
||||||
matthieu.jolimaitre 6 1 5 4 2 3
|
|
||||||
nicolas.bruguet 3 4 2 1 6 5
|
|
||||||
nicolas.marc 4 3 2 1 6 5
|
|
||||||
noe.bigorre
|
|
||||||
quentin.de-capele
|
|
||||||
theo.dedaele 1 2 4 3 6 5
|
|
||||||
theo.loret
|
|
||||||
thomas.didier
|
|
||||||
valentin.champenois
|
|
||||||
valentin.giaufer 5 4 3 1 6 2
|
|
||||||
vincent.goguyer-lalande 3 5 2 1 6 4
|
|
||||||
vincent.guillen
|
|
||||||
yann.goulvestre 2 6 3 1 5 4
|
|
||||||
yannis.breleur 4 5 3 1 6 2
|
|
|
|
@ -1,49 +0,0 @@
|
||||||
#!/bin/env -S deno run -A
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
const input = read_input("./input.csv");
|
|
||||||
|
|
||||||
const MAX_IN_GROUP = 4;
|
|
||||||
const groups = Array.from(range(1, 7))
|
|
||||||
.map((sujet_no) => ({ sujet_no, members: [] as { login: string; prio: number }[] }));
|
|
||||||
|
|
||||||
for (const prio of range(1, 7)) {
|
|
||||||
for (const entry of input) {
|
|
||||||
if (entry.placed) continue;
|
|
||||||
for (const [index, choice] of enumerate(entry.choices)) {
|
|
||||||
if (choice !== prio) continue;
|
|
||||||
if (groups[index].members.length >= MAX_IN_GROUP) continue;
|
|
||||||
groups[index].members.push({ login: entry.login, prio });
|
|
||||||
entry.placed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let result = "";
|
|
||||||
for (const group of groups) {
|
|
||||||
const members = group.members.map((item) => `${item.login}(${item.prio})`).join("\t");
|
|
||||||
const line = `Sujet ${group.sujet_no}\t${members}`;
|
|
||||||
result += line + "\n";
|
|
||||||
}
|
|
||||||
Deno.writeTextFileSync("./output.csv", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
function read_input(path: string) {
|
|
||||||
const content = Deno.readTextFileSync(path);
|
|
||||||
const cells = content.split("\n").filter((line) => line !== "").map((line) => line.split("\t"));
|
|
||||||
const toint = (n: string) => ((parsed) => isNaN(parsed) ? 0 : parsed)(parseInt(n));
|
|
||||||
return cells.map((
|
|
||||||
[login, s1, s2, s3, s4, s5, s6],
|
|
||||||
) => ({ login, choices: ([s1, s2, s3, s4, s5, s6] as const).map(toint), placed: false }));
|
|
||||||
}
|
|
||||||
|
|
||||||
function* range(from: number, to: number) {
|
|
||||||
while (from < to) yield from++;
|
|
||||||
}
|
|
||||||
|
|
||||||
function* enumerate<T>(iterable: Iterable<T>) {
|
|
||||||
let index = 0;
|
|
||||||
for (const item of iterable) yield [index++, item] as const;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (import.meta.main) main();
|
|
|
@ -1,6 +0,0 @@
|
||||||
Sujet 1 edwin.galibert(1) theo.dedaele(1) yann.goulvestre(2)
|
|
||||||
Sujet 2 matthieu.jolimaitre(1)
|
|
||||||
Sujet 3 julia.royer(1) luna.zozor(1) vincent.goguyer-lalande(2)
|
|
||||||
Sujet 4 anas.el-khatir(1) clement.thollet(1) nicolas.bruguet(1) nicolas.marc(1)
|
|
||||||
Sujet 5
|
|
||||||
Sujet 6 valentin.giaufer(2) yannis.breleur(2)
|
|
|
23
pfes/sort/utils.ts
Normal file
23
pfes/sort/utils.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
export const to_int = (n: string) => ((parsed) => isNaN(parsed) ? 0 : parsed)(parseInt(n));
|
||||||
|
|
||||||
|
export function range(from: number, to: number) {
|
||||||
|
function* gen() {
|
||||||
|
while (from < to) yield from++;
|
||||||
|
}
|
||||||
|
return iterable_to_arrayable(gen());
|
||||||
|
}
|
||||||
|
|
||||||
|
export function enumerate<T>(iterable: Iterable<T>) {
|
||||||
|
function* gen() {
|
||||||
|
let index = 0;
|
||||||
|
for (const item of iterable) yield [index++, item] as const;
|
||||||
|
}
|
||||||
|
return iterable_to_arrayable(gen());
|
||||||
|
}
|
||||||
|
|
||||||
|
function iterable_to_arrayable<T>(iterator: Iterable<T>) {
|
||||||
|
// deno-lint-ignore no-explicit-any
|
||||||
|
const anyfied = iterator as any;
|
||||||
|
anyfied.arr = () => Array.from(iterator);
|
||||||
|
return anyfied as Iterable<T> & { arr: () => T[] };
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue