├── 2021
├── styles.css
├── index.html
└── scripts.js
├── 2022
├── src
│ ├── constants.js
│ ├── utils.js
│ ├── scripts.js
│ └── users.js
├── styles.css
└── index.html
├── 2023
├── src
│ ├── constants.js
│ ├── utils.js
│ ├── users.js
│ └── scripts.js
├── styles.css
└── index.html
├── 2024
├── src
│ ├── constants.js
│ ├── utils.js
│ ├── scripts.js
│ └── users.js
├── styles.css
└── index.html
├── CNAME
├── .gitignore
├── src
├── constants.js
├── utils.js
├── scripts.js
└── users.js
├── .editorconfig
├── LICENSE
├── styles.css
├── README.md
└── index.html
/CNAME:
--------------------------------------------------------------------------------
1 | aoc.inf-cau.de
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
2 | .DS_Store
3 | *.swp
4 |
--------------------------------------------------------------------------------
/src/constants.js:
--------------------------------------------------------------------------------
1 | export const year = 2025;
2 | export const shortYear = year % 100;
3 |
--------------------------------------------------------------------------------
/2022/src/constants.js:
--------------------------------------------------------------------------------
1 | export const year = 2022;
2 | export const shortYear = year % 100;
3 |
--------------------------------------------------------------------------------
/2023/src/constants.js:
--------------------------------------------------------------------------------
1 | export const year = 2023;
2 | export const shortYear = year % 100;
3 |
--------------------------------------------------------------------------------
/2024/src/constants.js:
--------------------------------------------------------------------------------
1 | export const year = 2024;
2 | export const shortYear = year % 100;
3 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*.{html,js,css}]
4 | indent_size = 2
5 | indent_style = space
6 |
7 |
--------------------------------------------------------------------------------
/2021/styles.css:
--------------------------------------------------------------------------------
1 | .nav, #users {
2 | position: sticky;
3 | }
4 |
5 | #users {
6 | top: 1em;
7 | }
8 |
9 | .nav {
10 | top: 0px;
11 | background-color: white;
12 | padding: 1em 0;
13 | margin-top: -1em;
14 | z-index: 1;
15 | }
16 |
17 | .list-group-item, .nav-link {
18 | cursor: pointer;
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/2022/src/utils.js:
--------------------------------------------------------------------------------
1 | /** Generates solution urls for GitHub. */
2 | export function gitHubUrls({ user, repo, branch = "main", path }) {
3 | return {
4 | solutionUrl: (day, part) => `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${path(day, part)}`,
5 | solutionWebUrl: (day, part) => `https://github.com/${user}/${repo}/blob/${branch}/${path(day, part)}`,
6 | };
7 | }
8 |
9 | /** Pads the given number with the given number of zeros. */
10 | export function pad(n, zeros) {
11 | return `${n}`.padStart(zeros, "0");
12 | }
13 |
--------------------------------------------------------------------------------
/src/utils.js:
--------------------------------------------------------------------------------
1 | /** Generates solution urls for GitHub. */
2 | export function gitHubUrls({ user, repo, branch = "main", path }) {
3 | return {
4 | solutionUrl: (day, part) => {
5 | const p = path(day, part);
6 | return p ? `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${p}` : null;
7 | },
8 | solutionWebUrl: (day, part) => {
9 | const p = path(day, part);
10 | return p ? `https://github.com/${user}/${repo}/blob/${branch}/${p}` : null;
11 | },
12 | };
13 | }
14 |
15 | /** Pads the given number with the given number of zeros. */
16 | export function pad(n, zeros) {
17 | return `${n}`.padStart(zeros, "0");
18 | }
19 |
--------------------------------------------------------------------------------
/2023/src/utils.js:
--------------------------------------------------------------------------------
1 | /** Generates solution urls for GitHub. */
2 | export function gitHubUrls({ user, repo, branch = "main", path }) {
3 | return {
4 | solutionUrl: (day, part) => {
5 | const p = path(day, part);
6 | return p ? `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${p}` : null;
7 | },
8 | solutionWebUrl: (day, part) => {
9 | const p = path(day, part);
10 | return p ? `https://github.com/${user}/${repo}/blob/${branch}/${p}` : null;
11 | },
12 | };
13 | }
14 |
15 | /** Pads the given number with the given number of zeros. */
16 | export function pad(n, zeros) {
17 | return `${n}`.padStart(zeros, "0");
18 | }
19 |
--------------------------------------------------------------------------------
/2024/src/utils.js:
--------------------------------------------------------------------------------
1 | /** Generates solution urls for GitHub. */
2 | export function gitHubUrls({ user, repo, branch = "main", path }) {
3 | return {
4 | solutionUrl: (day, part) => {
5 | const p = path(day, part);
6 | return p ? `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${p}` : null;
7 | },
8 | solutionWebUrl: (day, part) => {
9 | const p = path(day, part);
10 | return p ? `https://github.com/${user}/${repo}/blob/${branch}/${p}` : null;
11 | },
12 | };
13 | }
14 |
15 | /** Pads the given number with the given number of zeros. */
16 | export function pad(n, zeros) {
17 | return `${n}`.padStart(zeros, "0");
18 | }
19 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2022 The aoc-submissions contributors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/2021/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Advent of Code
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
21 |
22 | A
23 |
24 |
25 | B
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/2022/styles.css:
--------------------------------------------------------------------------------
1 | .nav {
2 | position: sticky;
3 | }
4 |
5 | #left {
6 | position: sticky;
7 | top: 1em;
8 | max-height: calc(100vh - 2em);
9 | height: 100%;
10 | display: grid;
11 | grid-template-rows: minmax(0, 1fr) 150px;
12 | }
13 |
14 | #users {
15 | top: 1em;
16 | overflow-y: scroll;
17 | }
18 |
19 | .nav {
20 | top: 0px;
21 | background-color: white;
22 | padding: 1em 0;
23 | margin-top: -1em;
24 | z-index: 1;
25 | }
26 |
27 | .list-group-item, .nav-link {
28 | cursor: pointer;
29 | }
30 |
31 | #users .list-group-item {
32 | display: flex;
33 | justify-content: space-between;
34 | }
35 |
36 | #keyboard {
37 | margin: 1em 0 0 1em;
38 | }
39 |
40 | #keyboard h5 {
41 | font-size: 1.1em;
42 | }
43 |
44 | #keyboard .key {
45 | background: #f0f0f0;
46 | padding: .125em .2em;
47 | font-family: monospace;
48 | border-radius: .125em;
49 | border: 1px solid #b0b0b0;
50 | margin: .25em;
51 | line-height: 1;
52 | display: inline-block;
53 | }
54 |
55 |
56 | /* X-Small devices (e.g. portrait phones) */
57 | @media (max-width: 576px) {
58 | #keyboard {
59 | display: none;
60 | }
61 |
62 | #left {
63 | grid-template-rows: unset;
64 | }
65 |
66 | #users {
67 | flex-direction: row;
68 | overflow: scroll;
69 | }
70 |
71 | .nav {
72 | margin-top: 0;
73 | flex-wrap: nowrap;
74 | overflow: scroll;
75 | }
76 |
77 | .user-name {
78 | white-space: nowrap;
79 | }
80 |
81 | .user-lang-name {
82 | display: none;
83 | }
84 | }
85 |
86 | @media (prefers-color-scheme: dark) {
87 | body, .nav, .list-group-item {
88 | background-color: #2d2d2d;
89 | color: white;
90 | border-color: rgba(255, 255, 255, .125);
91 | }
92 |
93 | .key {
94 | color: black;
95 | }
96 |
97 | .token {
98 | background: none !important;
99 | }
100 | }
101 |
102 |
--------------------------------------------------------------------------------
/styles.css:
--------------------------------------------------------------------------------
1 | .nav {
2 | position: sticky;
3 | }
4 |
5 | #left {
6 | position: sticky;
7 | top: 1em;
8 | max-height: calc(100vh - 2em);
9 | height: 100%;
10 | display: grid;
11 | grid-template-rows: minmax(0, 1fr) auto;
12 | }
13 |
14 | #users {
15 | top: 1em;
16 | overflow-y: auto;
17 | }
18 |
19 | .nav {
20 | top: 0px;
21 | background-color: white;
22 | padding: 1em 0;
23 | margin-top: -1em;
24 | z-index: 1;
25 | }
26 |
27 | .list-group-item, .nav-link {
28 | cursor: pointer;
29 | }
30 |
31 | #users .list-group-item {
32 | display: flex;
33 | justify-content: space-between;
34 | }
35 |
36 | .user-lang-annotation {
37 | opacity: 0.4;
38 | }
39 |
40 | #keyboard {
41 | margin: 1em 0 0 1em;
42 | }
43 |
44 | #keyboard h5 {
45 | font-size: 1.1em;
46 | }
47 |
48 | #keyboard .key {
49 | background: #f0f0f0;
50 | padding: .125em .2em;
51 | font-family: monospace;
52 | border-radius: .125em;
53 | border: 1px solid #b0b0b0;
54 | margin: .25em;
55 | line-height: 1;
56 | display: inline-block;
57 | }
58 |
59 |
60 | /* X-Small devices (e.g. portrait phones) */
61 | @media (max-width: 576px) {
62 | #keyboard {
63 | display: none;
64 | }
65 |
66 | #left {
67 | grid-template-rows: unset;
68 | }
69 |
70 | #users {
71 | flex-direction: row;
72 | overflow: scroll;
73 | }
74 |
75 | .nav {
76 | margin-top: 0;
77 | flex-wrap: nowrap;
78 | overflow: scroll;
79 | }
80 |
81 | .user-name {
82 | white-space: nowrap;
83 | }
84 |
85 | .user-lang {
86 | display: none;
87 | }
88 | }
89 |
90 | /* Medium Devices */
91 | @media (max-width: 768px) {
92 | .user-lang-annotation {
93 | display: none;
94 | }
95 | }
96 |
97 | @media (prefers-color-scheme: dark) {
98 | body, .nav, .list-group-item {
99 | background-color: #2d2d2d;
100 | color: white;
101 | border-color: rgba(255, 255, 255, .125);
102 | }
103 |
104 | .key {
105 | color: black;
106 | }
107 |
108 | .token {
109 | background: none !important;
110 | }
111 |
112 | a {
113 | color: white !important;
114 | }
115 | }
116 |
117 |
--------------------------------------------------------------------------------
/2023/styles.css:
--------------------------------------------------------------------------------
1 | .nav {
2 | position: sticky;
3 | }
4 |
5 | #left {
6 | position: sticky;
7 | top: 1em;
8 | max-height: calc(100vh - 2em);
9 | height: 100%;
10 | display: grid;
11 | grid-template-rows: minmax(0, 1fr) 190px;
12 | }
13 |
14 | #users {
15 | top: 1em;
16 | overflow-y: auto;
17 | }
18 |
19 | .nav {
20 | top: 0px;
21 | background-color: white;
22 | padding: 1em 0;
23 | margin-top: -1em;
24 | z-index: 1;
25 | }
26 |
27 | .list-group-item, .nav-link {
28 | cursor: pointer;
29 | }
30 |
31 | #users .list-group-item {
32 | display: flex;
33 | justify-content: space-between;
34 | }
35 |
36 | .user-lang-annotation {
37 | opacity: 0.4;
38 | }
39 |
40 | #keyboard {
41 | margin: 1em 0 0 1em;
42 | }
43 |
44 | #keyboard h5 {
45 | font-size: 1.1em;
46 | }
47 |
48 | #keyboard .key {
49 | background: #f0f0f0;
50 | padding: .125em .2em;
51 | font-family: monospace;
52 | border-radius: .125em;
53 | border: 1px solid #b0b0b0;
54 | margin: .25em;
55 | line-height: 1;
56 | display: inline-block;
57 | }
58 |
59 |
60 | /* X-Small devices (e.g. portrait phones) */
61 | @media (max-width: 576px) {
62 | #keyboard {
63 | display: none;
64 | }
65 |
66 | #left {
67 | grid-template-rows: unset;
68 | }
69 |
70 | #users {
71 | flex-direction: row;
72 | overflow: scroll;
73 | }
74 |
75 | .nav {
76 | margin-top: 0;
77 | flex-wrap: nowrap;
78 | overflow: scroll;
79 | }
80 |
81 | .user-name {
82 | white-space: nowrap;
83 | }
84 |
85 | .user-lang {
86 | display: none;
87 | }
88 | }
89 |
90 | /* Medium Devices */
91 | @media (max-width: 768px) {
92 | .user-lang-annotation {
93 | display: none;
94 | }
95 | }
96 |
97 | @media (prefers-color-scheme: dark) {
98 | body, .nav, .list-group-item {
99 | background-color: #2d2d2d;
100 | color: white;
101 | border-color: rgba(255, 255, 255, .125);
102 | }
103 |
104 | .key {
105 | color: black;
106 | }
107 |
108 | .token {
109 | background: none !important;
110 | }
111 |
112 | a {
113 | color: white !important;
114 | }
115 | }
116 |
117 |
--------------------------------------------------------------------------------
/2024/styles.css:
--------------------------------------------------------------------------------
1 | .nav {
2 | position: sticky;
3 | }
4 |
5 | #left {
6 | position: sticky;
7 | top: 1em;
8 | max-height: calc(100vh - 2em);
9 | height: 100%;
10 | display: grid;
11 | grid-template-rows: minmax(0, 1fr) auto;
12 | }
13 |
14 | #users {
15 | top: 1em;
16 | overflow-y: auto;
17 | }
18 |
19 | .nav {
20 | top: 0px;
21 | background-color: white;
22 | padding: 1em 0;
23 | margin-top: -1em;
24 | z-index: 1;
25 | }
26 |
27 | .list-group-item, .nav-link {
28 | cursor: pointer;
29 | }
30 |
31 | #users .list-group-item {
32 | display: flex;
33 | justify-content: space-between;
34 | }
35 |
36 | .user-lang-annotation {
37 | opacity: 0.4;
38 | }
39 |
40 | #keyboard {
41 | margin: 1em 0 0 1em;
42 | }
43 |
44 | #keyboard h5 {
45 | font-size: 1.1em;
46 | }
47 |
48 | #keyboard .key {
49 | background: #f0f0f0;
50 | padding: .125em .2em;
51 | font-family: monospace;
52 | border-radius: .125em;
53 | border: 1px solid #b0b0b0;
54 | margin: .25em;
55 | line-height: 1;
56 | display: inline-block;
57 | }
58 |
59 |
60 | /* X-Small devices (e.g. portrait phones) */
61 | @media (max-width: 576px) {
62 | #keyboard {
63 | display: none;
64 | }
65 |
66 | #left {
67 | grid-template-rows: unset;
68 | }
69 |
70 | #users {
71 | flex-direction: row;
72 | overflow: scroll;
73 | }
74 |
75 | .nav {
76 | margin-top: 0;
77 | flex-wrap: nowrap;
78 | overflow: scroll;
79 | }
80 |
81 | .user-name {
82 | white-space: nowrap;
83 | }
84 |
85 | .user-lang {
86 | display: none;
87 | }
88 | }
89 |
90 | /* Medium Devices */
91 | @media (max-width: 768px) {
92 | .user-lang-annotation {
93 | display: none;
94 | }
95 | }
96 |
97 | @media (prefers-color-scheme: dark) {
98 | body, .nav, .list-group-item {
99 | background-color: #2d2d2d;
100 | color: white;
101 | border-color: rgba(255, 255, 255, .125);
102 | }
103 |
104 | .key {
105 | color: black;
106 | }
107 |
108 | .token {
109 | background: none !important;
110 | }
111 |
112 | a {
113 | color: white !important;
114 | }
115 | }
116 |
117 |
--------------------------------------------------------------------------------
/2022/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Advent of Code
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
Keyboard shortcuts
21 |
22 | w /s move between users
23 | a /d move between tasks
24 | q switch between task parts
25 |
26 |
27 |
28 |
29 |
30 |
31 | A
32 |
33 |
34 | B
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/2023/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Submission Board – Advent of Code
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
Keyboard shortcuts
21 |
22 | w /s move between users
23 | a /d move between tasks
24 | q switch between task parts
25 |
26 |
(You may also use hjkl.)
27 |
28 |
29 |
30 |
31 |
32 |
33 | A
34 |
35 |
36 | B
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/2024/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Submission Board – Advent of Code
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
Keyboard shortcuts
21 |
22 | w /s move between users
23 | a /d move between tasks
24 | q switch between task parts
25 |
26 |
(You may also use hjkl.)
27 |
34 |
35 |
36 |
37 |
38 |
39 | A
40 |
41 |
42 | B
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # aoc-submissions
2 |
3 | A small website showcasing different solutions for the Advent of Code.
4 |
5 | [The live page can be found here.](https://melfkammholz.github.io/aoc-submissions/)
6 |
7 | ## Make Your Code Available
8 |
9 | Depending on how versed you are in managing your code with git, you might want
10 | to opt for different approaches.
11 | - If you have never worked with git before, then learning git might be a
12 | daunting task. If you want to take it easy, choose GitHub to host your code,
13 | [you can use the web UI upload and edit files](https://docs.github.com/en/repositories).
14 | GitLab offers [similar ways of managing code](https://docs.gitlab.com/ee/user/project/repository/)
15 | as well.
16 | - If you are up for the challenge, you may use [this resource](https://git-scm.com/)
17 | as a starting point. There are also many video tutorials and cheatsheets
18 | available online.
19 |
20 |
21 | ## Showcase Your Solutions
22 |
23 | If you want to showcase your solutions for Advent of Code, please issue a pull
24 | request. This pull request should contain your personal entry in
25 | `src/users.js`. An entry looks like this in its simplest form:
26 |
27 |
28 | ```js
29 | {
30 | // the name displayed in the submission board
31 | name: "Ron Swanson",
32 |
33 | // indicator for PrismJS which syntax highlighting to use
34 | // see https://prismjs.com/#supported-languages
35 | lang: _ => "clike",
36 |
37 | // the name of your programming language display in the submission board
38 | langName: _ => "C",
39 |
40 | // the URL used for fetching the raw source file of a given day and part
41 | solutionUrl: (day, part) =>
42 | `https://raw.githubusercontent.com/ronswanson/aoc2024/master/day${day}/${part}.c`,
43 |
44 | // the URL used for referring to your solution via "View Source"
45 | solutionWebUrl: (day, part) =>
46 | `https://github.com/ronswanson/aoc2024/blob/master/day${day}/${part}.c`
47 | }
48 | ```
49 |
50 | This website uses PrismJS for syntax highlighting. Please make sure that you
51 | [choose the correct abbreviation](https://prismjs.com/#supported-languages)
52 | for your programming language. There are some abstractions for providing all
53 | necessary URLs available. You may want to use the entries of others as an
54 | example. If you intend on using multiple programming languages, you have to
55 | maintain a JSON file that helps us in choosing the correct labels and syntax
56 | highlighting. Here is [an example of such a file](https://github.com/fwcd/advent-of-code-2023/blob/main/paths.json).
57 | These files are fetched in `src/users.js`.
58 |
59 | ## Local Development
60 |
61 | Since the page uses ES6 modules, you'll need a web server to test the page
62 | locally. If you have Python installed, you can e.g. run
63 |
64 | ```sh
65 | python3 -m http.server
66 | ```
67 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Submission Board – Advent of Code
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
Keyboard shortcuts
21 |
22 | w /s move between users
23 | a /d move between tasks
24 | q switch between task parts
25 |
26 | Pressing Ctrl|Cmd while clicking on a day
27 | opens the puzzle on Advent of Code.
28 |
29 |
30 |
(You may also use hjkl.)
31 |
39 |
40 |
41 |
42 |
43 |
44 | A
45 |
46 |
47 | B
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/2023/src/users.js:
--------------------------------------------------------------------------------
1 | import { year, shortYear } from './constants.js';
2 | import { gitHubUrls, pad } from './utils.js';
3 |
4 | /** Loads the list of users. */
5 | export async function loadUsers() {
6 | // TODO handle error if necessary?
7 | const fwcdPaths = await (await fetch(`https://raw.githubusercontent.com/fwcd/advent-of-code-${year}/main/paths.json`)).json().catch(() => ({}));
8 | const kazumiPaths = await (await fetch(`https://raw.githubusercontent.com/Dormanil/Advent-of-Code/${year}/exceptionInfo.json`)).json().catch(() => ({}));
9 |
10 | const fwcdSolution = (day, part) => (fwcdPaths[day]?.parts ?? [])[part] ?? fwcdPaths[day];
11 |
12 | const users = [
13 | {
14 | name: "Alexander P",
15 | lang: _ => "clike",
16 | langName: _ => "C++",
17 | ...gitHubUrls({
18 | user: "Zeldacrafter",
19 | repo: "CompProg-Solutions",
20 | branch: "master",
21 | path: (day, part) => `AdventOfCode/${year}/${day + 1}/${part + 1}.cc`
22 | })
23 | },
24 | {
25 | name: "I3J03RN",
26 | lang: _ => "clike",
27 | langName: _ => "C++",
28 | ...gitHubUrls({
29 | user: "I3J03RN",
30 | repo: "ProgrammingChallenges",
31 | branch: "master",
32 | path: day => `AoC/${year}/${day + 1}.cc`
33 | })
34 | },
35 | {
36 | name: "Melf",
37 | lang: _ => "lua",
38 | langName: _ => "Lua",
39 | ...gitHubUrls({
40 | user: "melfkammholz",
41 | repo: `aoc${shortYear}`,
42 | path: (day, part) => `day${pad(day + 1, 2)}/${["A", "B"][part]}.lua`
43 | })
44 | },
45 | {
46 | name: "fwcd",
47 | lang: (day, part) => fwcdSolution(day, part)?.lang?.codemirror,
48 | langAnnotation: "Today: ",
49 | langName: (day, part) => fwcdSolution(day, part)?.lang?.name ?? "Unknown",
50 | encoding: (day, part) => fwcdSolution(day, part)?.encoding,
51 | ...gitHubUrls({
52 | user: "fwcd",
53 | repo: `advent-of-code-${year}`,
54 | path: (day, part) => fwcdSolution(day, part)?.path
55 | })
56 | },
57 | {
58 | name: "Yorik Hansen",
59 | lang: _ => "python",
60 | langName: _ => "Python",
61 | ...gitHubUrls({
62 | user: "YorikHansen",
63 | repo: "AdventOfCode",
64 | path: (day, part) => `${year}/day${pad(day + 1, 2)}/part${part + 1}.py`
65 | })
66 | },
67 | {
68 | name: "Skgland",
69 | lang: _ => "rust",
70 | langName: _ => "Rust",
71 | ...gitHubUrls({
72 | user: "Skgland",
73 | repo: "Advent-of-Code",
74 | path: day => `crates/year${year}/src/day${pad(day + 1, 2)}.rs`
75 | })
76 | },
77 | {
78 | name: "b3z",
79 | lang: _ => "python",
80 | langName: _ => "Python",
81 | ...gitHubUrls({
82 | user: "b3z",
83 | repo: "aoc",
84 | branch: "master",
85 | path: (day, part) => `${year}/${pad(day + 1, 2)}/${part + 1}.py`
86 | })
87 | },
88 | {
89 | name: "H1tchhiker",
90 | lang: _ => "elixir",
91 | langName: _ => "Elixir",
92 | ...gitHubUrls({
93 | user: "n00on",
94 | repo: "AdventOfCode",
95 | path: day => `${year}/${pad(day + 1, 2)}/day${pad(day + 1, 2)}.ex`
96 | })
97 | },
98 | {
99 | name: "H1ghBre4k3r",
100 | lang: _ => "rust",
101 | langName: _ => "Rust",
102 | ...gitHubUrls({
103 | user: "H1ghBre4k3r",
104 | repo: `aoc-${year}`,
105 | path: day => `src/day_${pad(day + 1, 2)}.rs`
106 | })
107 | },
108 | {
109 | name: "Zihark",
110 | lang: _ => "haskell",
111 | langName: _ => "Haskell",
112 | ...gitHubUrls({
113 | user: "Ziharrk",
114 | repo: `aoc${year}`,
115 | path: day => `src/Day${day + 1}.hs`
116 | })
117 | },
118 | {
119 | name: "maclement",
120 | lang: _ => "haskell",
121 | langName: _ => "Haskell",
122 | ...gitHubUrls({
123 | user: "maclement",
124 | repo: `advent-of-code-${year}`,
125 | path: day => `Haskell/Day${day + 1}/A.hs`
126 | })
127 | },
128 | {
129 | name: "Magi3r",
130 | lang: _ => "esolang",
131 | langName: _ => "DDP",
132 | ...gitHubUrls({
133 | user: "Magi3r",
134 | repo: `AoC-${year}`,
135 | path: (day, part) => `${pad(day + 1, 2)}${["a", "b"][part]}.ddp`
136 | })
137 | },
138 | {
139 | name: "sebfisch",
140 | lang: _ => "zig",
141 | langName: _ => "Zig",
142 | ...gitHubUrls({
143 | user: "sebfisch",
144 | repo: "AdventOfCode",
145 | branch: "latest",
146 | path: (day, part) => `year${year}/day${pad(day + 1, 2)}/task${part + 1}.zig`
147 | })
148 | },
149 | {
150 | name: "Kazumi",
151 | lang: day => kazumiPaths[`${day + 1}`]?.lang ?? "csharp",
152 | langAnnotation: "Today: ",
153 | langName: day => kazumiPaths[`${day + 1}`]?.langName ?? "C#",
154 | ...gitHubUrls({
155 | user: "Dormanil",
156 | repo: "Advent-of-Code",
157 | branch: `${year}`,
158 | path: day => `Dec${day + 1}/Program.${kazumiPaths[`${day + 1}`]?.extension ?? "cs"}`
159 | })
160 | },
161 | ];
162 |
163 | if (new Set(users.map(u => u.name)).size != users.length) {
164 | throw new Error("Users must have unique names!")
165 | }
166 |
167 | return users;
168 | }
169 |
--------------------------------------------------------------------------------
/2022/src/scripts.js:
--------------------------------------------------------------------------------
1 | import { year } from './constants.js';
2 | import { loadUsers } from './users.js';
3 |
4 | window.addEventListener("load", async () => {
5 | const users = await loadUsers();
6 | const clamp = (min, max, val) => Math.min(max, Math.max(val, min));
7 |
8 | const days = new Date(clamp(new Date(`${year}-12-01`).valueOf(), new Date(`${year}-12-25`).valueOf(), Date.now() - 6 * 60 * 60 * 1000)).getDate();
9 | const state = {
10 | day: days - 1,
11 | part: 0,
12 | index: 0
13 | };
14 |
15 | async function loadSolution(user, day, part) {
16 | const url = user.solutionUrl(day, part);
17 | const preEl = document.createElement("pre");
18 | const codeEl = document.createElement("code");
19 | const lang = user.lang(day);
20 | const encoding = ("encoding" in user ? user.encoding(day) : null) || "utf-8";
21 | const decoder = new TextDecoder(encoding);
22 | try {
23 | const result = url ? await fetch(url) : null;
24 | if (!(result?.ok ?? false)) {
25 | throw new Error("No solution yet");
26 | }
27 | const buffer = await result.arrayBuffer();
28 | const code = decoder.decode(buffer);
29 | if (lang) {
30 | await Prism.plugins.autoloader.loadLanguages(
31 | lang,
32 | () => {
33 | codeEl.innerHTML = Prism.highlight(code, Prism.languages[lang], user.lang);
34 | }
35 | );
36 | } else {
37 | codeEl.innerText = code;
38 | }
39 | } catch (err) {
40 | codeEl.textContent = err.message;
41 | }
42 | preEl.appendChild(codeEl);
43 | document.getElementById("preview").innerHTML = "";
44 | document.getElementById("preview").appendChild(preEl);
45 | }
46 |
47 | function render(strings, ...values) {
48 | const html = String.raw({ raw: strings }, ...values);
49 | const el = document.createElement('div');
50 | el.innerHTML = html;
51 | return el.children[0];
52 | }
53 |
54 | function updateSolution() {
55 | loadSolution(users[state.index], state.day, state.part);
56 | }
57 |
58 | function setActive(selector, index) {
59 | const className = "active";
60 | const activatedEl = document.querySelectorAll(selector)[index];
61 | document.querySelectorAll(`${selector}.${className}`).forEach(el => el.classList.remove(className));
62 | activatedEl.classList.add(className);
63 | }
64 |
65 | function updateQueryParams() {
66 | const params = new URLSearchParams(window.location.search);
67 | for (const key in state) {
68 | params.set(key, `${state[key]}`);
69 | }
70 | history.pushState(null, "", `${window.location.pathname}?${params}`);
71 | }
72 |
73 | function updateState({ index = null, day = null, part = null, updateActive = false, updateQuery = true }) {
74 | state.index = index ?? state.index;
75 | state.day = day ?? state.day;
76 | state.part = part ?? state.part;
77 | if (index !== null || updateActive) {
78 | setActive("#users .list-group-item", state.index);
79 | }
80 | if (day !== null || updateActive) {
81 | setActive(".nav .day", state.day);
82 | }
83 | if (part !== null || updateActive) {
84 | setActive(".part", state.part);
85 | }
86 | if (updateQuery) {
87 | updateQueryParams();
88 | }
89 | updateSolution();
90 | }
91 |
92 | function loadStateFromQueryParams() {
93 | const params = new URLSearchParams(window.location.search);
94 | const loaded = {};
95 | for (const key in state) {
96 | const value = params.get(key);
97 | if (value !== null) {
98 | loaded[key] = parseInt(value);
99 | }
100 | }
101 | updateState({ ...loaded, updateActive: true, updateQuery: false });
102 | }
103 |
104 | const mod = (x, m) => (x % m + m) % m;
105 |
106 | window.addEventListener("keydown", (event) => {
107 | if (event.key === "w" || event.key === "k" ) updateState({ index: mod(state.index - 1, users.length) });
108 | else if (event.key === "s" || event.key === "j") updateState({ index: mod(state.index + 1, users.length) });
109 | else if (event.key === "a" || event.key === "h") updateState({ day: mod(state.day - 1, days) });
110 | else if (event.key === "d" || event.key === "l") updateState({ day: mod(state.day + 1, days) });
111 | else if (event.key === "q") updateState({ part: (state.part + 1) % 2 });
112 | });
113 |
114 | window.addEventListener("popstate", () => {
115 | loadStateFromQueryParams();
116 | });
117 |
118 | users.forEach((user, index) => {
119 | const el = render`
120 |
121 | ${user.name}
122 | ${user.langName}
123 |
124 | `;
125 | el.addEventListener("click", () => {
126 | updateState({ index });
127 | });
128 | document.getElementById("users").appendChild(el);
129 | });
130 |
131 | Array.from(document.querySelectorAll(".part")).forEach((el, i) => {
132 | el.addEventListener("click", () => {
133 | updateState({ part: i });
134 | });
135 | });
136 |
137 | [...Array(days)].forEach((_, i) => {
138 | const el = document.createElement("li");
139 | el.classList.add("nav-item");
140 | const aEl = document.createElement("a");
141 | aEl.classList.add("nav-link");
142 | aEl.classList.add("day");
143 | aEl.textContent = i + 1;
144 | aEl.addEventListener("click", () => {
145 | updateState({ day: i });
146 | });
147 | el.appendChild(aEl);
148 | document.querySelector(".nav").appendChild(el);
149 | });
150 |
151 | loadStateFromQueryParams();
152 | });
153 |
154 | if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
155 | const link = document.createElement("link");
156 | link.rel = "stylesheet";
157 | link.href = "https://cdnjs.cloudflare.com/ajax/libs/prism/1.25.0/themes/prism-tomorrow.min.css";
158 | document.querySelector("head").appendChild(link);
159 | }
160 |
161 |
--------------------------------------------------------------------------------
/2022/src/users.js:
--------------------------------------------------------------------------------
1 | import { year, shortYear } from './constants.js';
2 | import { gitHubUrls, pad } from './utils.js';
3 |
4 | /** Loads the list of users. */
5 | export async function loadUsers() {
6 | const fwcdPaths = await (await fetch(`https://raw.githubusercontent.com/fwcd/advent-of-code-${year}/main/paths.json`)).json();
7 | const estgPaths = await (await fetch(`https://raw.githubusercontent.com/estugon/advent-of-code-${year}/main/paths.json`)).json();
8 |
9 | const users = [
10 | {
11 | name: "Alexander P",
12 | lang: _ => "clike",
13 | langName: "C++",
14 | ...gitHubUrls({
15 | user: "Zeldacrafter",
16 | repo: "CompProg-Solutions",
17 | branch: "master",
18 | path: (day, part) => `AdventOfCode/${year}/${day + 1}/${part + 1}.cc`
19 | })
20 | },
21 | {
22 | name: "I3J03RN",
23 | lang: _ => "clike",
24 | langName: "C++",
25 | ...gitHubUrls({
26 | user: "I3J03RN",
27 | repo: "ProgrammingChallenges",
28 | branch: "master",
29 | path: day => `AoC/${year}/${day + 1}.cc`
30 | })
31 | },
32 | {
33 | name: "Melf",
34 | lang: _ => "haskell",
35 | langName: "Haskell",
36 | ...gitHubUrls({
37 | user: "melfkammholz",
38 | repo: `aoc${shortYear}`,
39 | path: (day, part) => `day${pad(day + 1, 2)}/${["A", "B"][part]}.hs`
40 | })
41 | },
42 | {
43 | name: "fwcd",
44 | lang: day => fwcdPaths[day]?.lang?.codemirror,
45 | langName: "Mixed",
46 | encoding: day => fwcdPaths[day]?.encoding,
47 | ...gitHubUrls({
48 | user: "fwcd",
49 | repo: `advent-of-code-${year}`,
50 | path: day => fwcdPaths[day]?.path
51 | })
52 | },
53 | {
54 | name: "xtay2",
55 | lang: _ => "java",
56 | langName: "Java",
57 | ...gitHubUrls({
58 | user: "xtay2",
59 | repo: "AdventOfCode",
60 | path: (day, part) => `src/year${year}/day${pad(day + 1, 2)}/Task_${["A", "B"][part]}.java`
61 | })
62 | },
63 | {
64 | name: "tuhhy",
65 | lang: _ => "python",
66 | langName: "Python",
67 | ...gitHubUrls({
68 | user: "tuhhy",
69 | repo: "aoc",
70 | branch: "master",
71 | path: (day, part) => `Day${day + 1}/Task${["A", "B"][part]}.py`
72 | })
73 | },
74 | {
75 | name: "Yorik Hansen",
76 | lang: _ => "python",
77 | langName: "Python",
78 | ...gitHubUrls({
79 | user: "YorikHansen",
80 | repo: "AdventOfCode",
81 | path: (day, part) => `${year}/day${pad(day + 1, 2)}/part${part + 1}.py`
82 | })
83 | },
84 | {
85 | name: "Skgland",
86 | lang: _ => "rust",
87 | langName: "Rust",
88 | ...gitHubUrls({
89 | user: "Skgland",
90 | repo: "Advent-of-Code",
91 | path: day => `crates/year${year}/src/day${pad(day + 1, 2)}.rs`
92 | })
93 | },
94 | {
95 | name: "Estugon",
96 | lang: day => estgPaths[day]?.lang,
97 | langName: "Mixed",
98 | ...gitHubUrls({
99 | user: "Estugon",
100 | repo: `advent-of-code-${year}`,
101 | path: day => estgPaths[day]?.path
102 | })
103 | },
104 | {
105 | name: "Dormanil",
106 | lang: _ => "fsharp",
107 | langName: "F#",
108 | ...gitHubUrls({
109 | user: "Dormanil",
110 | repo: "Advent-of-Code",
111 | branch: `${year}`,
112 | path: day => `Dec${day + 1}/Program.fs`
113 | })
114 | },
115 | {
116 | name: "b3z",
117 | lang: _ => "python",
118 | langName: "Python",
119 | ...gitHubUrls({
120 | user: "b3z",
121 | repo: "aoc",
122 | branch: "master",
123 | path: (day, part) => `${year}/${pad(day + 1, 2)}/${part + 1}.py`
124 | })
125 | },
126 | {
127 | name: "Dobiko",
128 | lang: _ => "clike",
129 | langName: "C#",
130 | ...gitHubUrls({
131 | user: "jnccd",
132 | repo: "AdventOfCode",
133 | path: day => `Dec${day + 1}/Program.cs`
134 | })
135 | },
136 | {
137 | name: "H1tchhiker",
138 | lang: _ => "python",
139 | langName: "Python",
140 | ...gitHubUrls({
141 | user: "n00on",
142 | repo: "AdventOfCode",
143 | path: day => `${year}/${pad(day + 1, 2)}/day${pad(day + 1, 2)}.py`
144 | })
145 | },
146 | {
147 | name: "H1ghBre4k3r",
148 | lang: _ => "rust",
149 | langName: "Rust",
150 | ...gitHubUrls({
151 | user: "H1ghBre4k3r",
152 | repo: `aoc-${year}`,
153 | path: day => `src/day_${pad(day + 1, 2)}.rs`
154 | })
155 | },
156 | {
157 | name: "Zihark",
158 | lang: _ => "haskell",
159 | langName: "Haskell",
160 | ...gitHubUrls({
161 | user: "Ziharrk",
162 | repo: `aoc${year}`,
163 | path: day => `src/Day${day + 1}.hs`
164 | })
165 | },
166 | {
167 | name: "sebfisch",
168 | lang: _ => "java",
169 | langName: "Java",
170 | ...gitHubUrls({
171 | user: "sebfisch",
172 | repo: "AdventOfCode",
173 | branch: "latest",
174 | path: (day, part) => `year${year}/day${pad(day + 1, 2)}/Part${part + 1}.java`
175 | })
176 | },
177 | {
178 | name: "hendrick404",
179 | lang: _ => "python",
180 | langName: "Python",
181 | ...gitHubUrls({
182 | user: "hendrick404",
183 | repo: `advent-of-code-${year}`,
184 | path: day => `day${pad(day + 1, 2)}/day${pad(day + 1, 2)}.py`
185 | })
186 | },
187 | {
188 | name: "maclement",
189 | lang: _ => "haskell",
190 | langName: "Haskell",
191 | ...gitHubUrls({
192 | user: "maclement",
193 | repo: `advent-of-code-${year}`,
194 | path: day => `Haskell/Day${day + 1}/A.hs`
195 | })
196 | },
197 | {
198 | name: "Felioh",
199 | lang: _ => "python",
200 | langName: "Python",
201 | ...gitHubUrls({
202 | user: "Felioh",
203 | repo: "AdventOfCode",
204 | path: (day, part) => `${day + 1}/part${part + 1}.py`
205 | })
206 | }
207 | ];
208 |
209 | return users;
210 | }
211 |
--------------------------------------------------------------------------------
/2021/scripts.js:
--------------------------------------------------------------------------------
1 | window.addEventListener("load", async () => {
2 | const fwcdPathsResponse = await fetch('https://raw.githubusercontent.com/fwcd/advent-of-code-2021/main/paths.json');
3 | const fwcdPaths = JSON.parse(await fwcdPathsResponse.text());
4 |
5 | const users = [
6 | {
7 | name: "Alexander P",
8 | lang: _ => "clike",
9 | solutionUrl: (day, part) => {
10 | return `https://raw.githubusercontent.com/Zeldacrafter/CompProg-Solutions/master/AdventOfCode/2021/${day + 1}/${part + 1}.cc`
11 | }
12 | },
13 | {
14 | name: "I3J03RN",
15 | lang: _ => "clike",
16 | solutionUrl: (day, part) => {
17 | return `https://raw.githubusercontent.com/I3J03RN/ProgrammingChallenges/master/AoC/2021/${day + 1}.cc`
18 | }
19 | },
20 | {
21 | name: "Melf",
22 | lang: _ => "clike",
23 | solutionUrl: (day, part) => {
24 | const _day = (day + 1).toString().padStart(2, "0");
25 | const _part = ["A", "B"][part];
26 | return `https://raw.githubusercontent.com/melfkammholz/aoc21/main/day${_day}/${_part}.cc`
27 | }
28 | },
29 | {
30 | name: "Estugon",
31 | lang: _ => "clike",
32 | solutionUrl: (day, part) => {
33 | return `https://raw.githubusercontent.com/Estugon/Advent-Of-Code-2021/main/day${day + 1}/day${day + 1}.cpp`
34 | }
35 | },
36 | {
37 | name: "JulianGrabitzky",
38 | lang: _ => "clike",
39 | solutionUrl: (day, part) => {
40 | const _part = ["a", "b"][part];
41 | return `https://raw.githubusercontent.com/JulianGrabitzky/advent-of-code-2021/main/day/${day + 1}/${_part}.py`
42 | }
43 | },
44 | {
45 | name: "H1ghBre4k3r",
46 | lang: _ => "js",
47 | solutionUrl: (day, part) => {
48 | const _day = (day + 1).toString().padStart(2, "0");
49 | return `https://raw.githubusercontent.com/H1ghBre4k3r/advent-of-code-2021/main/day${_day}/solution0${part + 1}.js`
50 | }
51 | },
52 | {
53 | name: "l1k3ab0t",
54 | lang: _ => "rust",
55 | solutionUrl: (day, part) => {
56 | return `https://raw.githubusercontent.com/l1k3ab0t/aoc2021/main/src/day${day + 1}.rs`
57 | }
58 | },
59 | {
60 | name: "LeoVerto",
61 | lang: _ => "python",
62 | solutionUrl: (day, part) => {
63 | const _day = (day + 1).toString().padStart(2, "0");
64 | const _part = ["a", "b"][part];
65 | return `https://raw.githubusercontent.com/LeoVerto/advent-of-code-2021/main/days/${_day}/${_day}${_part}.py`
66 | }
67 | },
68 | {
69 | name: "Niatsuna",
70 | lang: _ => "python",
71 | solutionUrl: (day, part) => {
72 | const _day = (day + 1).toString().padStart(2, "0");
73 | return `https://raw.githubusercontent.com/Niatsuna/advent-of-code-2021/master/${_day}.py`
74 | }
75 | },
76 | {
77 | name: "mjt001",
78 | lang: _ => "python",
79 | solutionUrl: (day, part) => {
80 | const _day = (day + 1).toString().padStart(2, "0");
81 | return `https://raw.githubusercontent.com/mjt001/AdventofCode2021_mirror/main/${_day}/main${day + 1}${part + 1}.py`
82 | }
83 | },
84 | {
85 | name: "integermainvoid",
86 | lang: _ => "python",
87 | solutionUrl: (day, part) => {
88 | return `https://raw.githubusercontent.com/integermainvoid/advent_of_code/main/day%20${day + 1}/aoc_${part + 1}.py`
89 | }
90 | },
91 | {
92 | name: "fwcd",
93 | lang: day => day < fwcdPaths.length ? fwcdPaths[day].lang : null,
94 | solutionUrl: (day, part) =>
95 | day < fwcdPaths.length
96 | ? `https://raw.githubusercontent.com/fwcd/advent-of-code-2021/main/${fwcdPaths[day].path}`
97 | : null
98 | },
99 | {
100 | name: "maclement",
101 | lang: _ => "haskell",
102 | solutionUrl: (day, part) =>
103 | `https://raw.githubusercontent.com/maclement/advent-of-code-2021/main/Day${day + 1}/Day${day + 1}.hs`
104 | },
105 | {
106 | name: "xtay2",
107 | lang: _ => "java",
108 | solutionUrl: (day, part) => {
109 | const _day = (day + 1).toString().padStart(2, "0");
110 | return `https://raw.githubusercontent.com/xtay2/AdventOfCode/main/src/year2021/day${_day}/Task_${part == 0 ? 'A' : 'B'}.java`;
111 | }
112 | },
113 | {
114 | name: "Skgland",
115 | lang: _ => "rust",
116 | solutionUrl: (day, part) => {
117 | const _day = (day + 1).toString().padStart(2, "0");
118 | return `https://raw.githubusercontent.com/Skgland/Advent-of-Code/main/crates/year2021/src/day${_day}.rs`
119 | }
120 | }
121 | ];
122 |
123 | const days = new Date(Math.min(new Date("2021-12-25").valueOf(), Date.now())).getDate();
124 | const state = {
125 | day: days - 1,
126 | part: 0,
127 | index: 0
128 | };
129 |
130 | async function loadSolution(user, day, part) {
131 | const url = user.solutionUrl(day, part);
132 | const preEl = document.createElement("pre");
133 | const codeEl = document.createElement("code");
134 | const lang = user.lang(day);
135 | try {
136 | const code = await fetch(url)
137 | .then(res => res.ok ? res.text() : Promise.reject(new Error("No solution yet!")));
138 | await Prism.plugins.autoloader.loadLanguages(
139 | lang,
140 | () => {
141 | codeEl.innerHTML = Prism.highlight(code, Prism.languages[lang], user.lang);
142 | }
143 | );
144 | } catch (err) {
145 | codeEl.textContent = err.message;
146 | }
147 | preEl.appendChild(codeEl);
148 | document.getElementById("preview").innerHTML = "";
149 | document.getElementById("preview").appendChild(preEl);
150 | }
151 |
152 | users.forEach((user, index) => {
153 | const el = document.createElement("li");
154 | el.classList.add("list-group-item");
155 | el.textContent = user.name;
156 | el.addEventListener("click", () => {
157 | state.index = index;
158 | document.querySelector(".list-group-item.active").classList.remove("active");
159 | el.classList.add("active");
160 | loadSolution(users[state.index], state.day, state.part);
161 | });
162 | document.getElementById("users").appendChild(el);
163 | });
164 |
165 | Array.from(document.querySelectorAll(".part")).forEach((el, i) => {
166 | el.addEventListener("click", () => {
167 | state.part = i;
168 | document.querySelector(".part.active").classList.remove("active");
169 | el.classList.add("active");
170 | loadSolution(users[state.index], state.day, state.part);
171 | });
172 | });
173 |
174 | [...Array(days)].forEach((_, i) => {
175 | const el = document.createElement("li");
176 | el.classList.add("nav-item");
177 | const aEl = document.createElement("a");
178 | aEl.classList.add("nav-link");
179 | aEl.classList.add("day");
180 | aEl.textContent = i + 1;
181 | aEl.addEventListener("click", () => {
182 | state.day = i;
183 | document.querySelector(".day.active").classList.remove("active");
184 | aEl.classList.add("active");
185 | loadSolution(users[state.index], state.day, state.part);
186 | });
187 | el.appendChild(aEl);
188 | document.querySelector(".nav").appendChild(el);
189 | });
190 |
191 | document.querySelectorAll(".list-group-item")[state.index].classList.add("active");
192 | document.querySelectorAll(".part")[state.part].classList.add("active");
193 | document.querySelectorAll(".day")[state.day].classList.add("active");
194 |
195 | loadSolution(users[state.index], state.day, state.part);
196 | });
197 |
--------------------------------------------------------------------------------
/2023/src/scripts.js:
--------------------------------------------------------------------------------
1 | import { year } from './constants.js';
2 | import { loadUsers } from './users.js';
3 |
4 | window.addEventListener("load", async () => {
5 | const mod = (x, m) => (x % m + m) % m;
6 | const clamp = (min, max, val) => Math.min(max, Math.max(val, min));
7 |
8 | const minBy = (xs, p) => xs.reduce((y, x) => p(y, x) < 0 ? y : x, xs[0]);
9 | const comps = (...ps) => (a, b) => ps.reduce((r, p) => r == 0 ? p(a, b) : r, 0);
10 | const userComp = (day, part) => comps(
11 | (a, b) => a.langName(day, part).localeCompare(b.langName(day, part)),
12 | (a, b) => a.name.localeCompare(b.name)
13 | );
14 |
15 | const users = await loadUsers();
16 |
17 | const days = new Date(clamp(
18 | new Date(`${year}-12-01`).valueOf(),
19 | new Date(`${year}-12-25`).valueOf(),
20 | Date.now() - 6 * 60 * 60 * 1000
21 | )).getDate();
22 |
23 | const state = {
24 | day: days - 1,
25 | part: 0,
26 | userName: minBy(users, userComp(days - 1, 0)).name,
27 | };
28 |
29 | async function loadSolution(user, day, part) {
30 | const url = user.solutionUrl(day, part);
31 | const preEl = document.createElement("pre");
32 | const codeEl = document.createElement("code");
33 | const lang = user.lang(day, part);
34 | const encoding = ("encoding" in user ? user.encoding(day, part) : null) || "utf-8";
35 | const decoder = new TextDecoder(encoding);
36 | try {
37 | const result = url ? await fetch(url) : null;
38 | if (!(result?.ok ?? false)) {
39 | throw new Error("No solution yet");
40 | }
41 | const buffer = await result.arrayBuffer();
42 | const code = decoder.decode(buffer);
43 | if (lang) {
44 | await Prism.plugins.autoloader.loadLanguages(
45 | lang,
46 | () => {
47 | codeEl.innerHTML = Prism.highlight(code, Prism.languages[lang], user.lang);
48 | },
49 | () => {
50 | codeEl.innerText = code;
51 | }
52 | );
53 | } else {
54 | codeEl.innerText = code;
55 | }
56 | } catch (err) {
57 | codeEl.textContent = err.message;
58 | }
59 | preEl.appendChild(codeEl);
60 | document.getElementById("preview").innerHTML = "";
61 | document.getElementById("preview").appendChild(preEl);
62 | }
63 |
64 | function render(strings, ...values) {
65 | const html = String.raw({ raw: strings }, ...values);
66 | const el = document.createElement('div');
67 | el.innerHTML = html;
68 | return el.children[0];
69 | }
70 |
71 | function userIndex(userName) {
72 | const index = users.findIndex(u => u.name === userName);
73 | if (index < 0) {
74 | throw new Error(`Could not find index for user ${userName}`);
75 | }
76 | return index;
77 | }
78 |
79 | function currentUser() {
80 | return state.userName ? users.find(u => u.name === state.userName) : null;
81 | }
82 |
83 | function updateSolution() {
84 | loadSolution(currentUser(), state.day, state.part);
85 | }
86 |
87 | function setActive(selector, index) {
88 | const className = "active";
89 | const activatedEl = document.querySelectorAll(selector)[index];
90 | document.querySelectorAll(`${selector}.${className}`).forEach(el => el.classList.remove(className));
91 | activatedEl.classList.add(className);
92 | }
93 |
94 | function updateQueryParams() {
95 | const params = new URLSearchParams();
96 | for (const key in state) {
97 | params.set(key, `${state[key]}`);
98 | }
99 | history.pushState(null, "", `${window.location.pathname}?${params}`);
100 | }
101 |
102 | function updateUsers() {
103 | const usersEl = document.getElementById("users");
104 | usersEl.innerHTML = "";
105 |
106 | users.sort(userComp(state.day, state.part));
107 |
108 | users.forEach(user => {
109 | const el = render`
110 |
111 | ${user.name}
112 |
113 | ${user.langAnnotation ? `${user.langAnnotation} ` : ""}
114 | ${user.langName(state.day, state.part)}
115 |
116 |
117 | `;
118 | el.addEventListener("click", () => {
119 | updateState({ userName: user.name });
120 | });
121 | usersEl.appendChild(el);
122 | });
123 | }
124 |
125 | function updateState({ userName = null, day = null, part = null, updateActive = false, updateQuery = true }) {
126 | if (userName !== null && !users.find(u => u.name === userName)) {
127 | console.warn(`User ${userName} could not be found!`);
128 | userName = null;
129 | }
130 |
131 | state.day = day ?? state.day;
132 | state.part = part ?? state.part;
133 | state.userName = userName ?? (updateQuery ? state.userName : minBy(users, userComp(state.day, state.part)).name);
134 |
135 | if (day !== null || part !== null || updateActive) {
136 | updateUsers();
137 | }
138 | if (userName !== null || day !== null || part !== null || updateActive) {
139 | setActive("#users .list-group-item", userIndex(state.userName));
140 | }
141 | if (day !== null || updateActive) {
142 | setActive(".nav .day", state.day);
143 | }
144 | if (part !== null || updateActive) {
145 | setActive(".part", state.part);
146 | }
147 | if (updateQuery) {
148 | updateQueryParams();
149 | }
150 | updateSolution();
151 | }
152 |
153 | function loadStateFromQueryParams() {
154 | const params = new URLSearchParams(window.location.search);
155 | const loaded = {};
156 | for (const key in state) {
157 | const value = params.get(key);
158 | if (value !== null) {
159 | const parsed = parseInt(value);
160 | loaded[key] = isNaN(parsed) ? value : parsed;
161 | }
162 | }
163 | updateState({ ...loaded, updateActive: true, updateQuery: false });
164 | }
165 |
166 | function userNameWithOffset(userName, offset) {
167 | return users[mod(userIndex(userName) + offset, users.length)].name;
168 | }
169 |
170 | window.addEventListener("keydown", (event) => {
171 | if (event.key === "w" || event.key === "k" ) updateState({ userName: userNameWithOffset(state.userName, -1) });
172 | else if (event.key === "s" || event.key === "j") updateState({ userName: userNameWithOffset(state.userName, 1) });
173 | else if (event.key === "a" || event.key === "h") updateState({ day: mod(state.day - 1, days) });
174 | else if (event.key === "d" || event.key === "l") updateState({ day: mod(state.day + 1, days) });
175 | else if (event.key === "q") updateState({ part: (state.part + 1) % 2 });
176 |
177 | // scroll when keyboard shortcuts are used for navigation
178 | if (["w", "s", "k", "j"].indexOf(event.key) !== -1) {
179 | const li = document.querySelector("#users .list-group-item.active");
180 | li.parentElement.scrollTop =
181 | li.offsetTop - 0.5 * (li.parentElement.offsetHeight - li.offsetHeight);
182 | }
183 | });
184 |
185 | window.addEventListener("popstate", () => {
186 | loadStateFromQueryParams();
187 | });
188 |
189 | Array.from(document.querySelectorAll(".part")).forEach((el, i) => {
190 | el.addEventListener("click", () => {
191 | updateState({ part: i });
192 | });
193 | });
194 |
195 | function createNavItem({ label = "", classes = [], onClick = () => {} }) {
196 | const el = render` `;
197 | const aEl = render`${label} `;
198 | aEl.addEventListener("click", onClick);
199 | el.appendChild(aEl);
200 | return el;
201 | }
202 |
203 | const navEl = document.querySelector(".nav");
204 |
205 | [...Array(days)].forEach((_, day) => {
206 | navEl.appendChild(createNavItem({ label: `${day + 1}`, classes: ["day"], onClick: () => {
207 | updateState({ day });
208 | }}));
209 | });
210 |
211 | navEl.appendChild(createNavItem({ label: "View Source", onClick: () => {
212 | const webUrl = currentUser().solutionWebUrl(state.day, state.part);
213 | if (webUrl) {
214 | window.location.href = webUrl;
215 | } else {
216 | alert("No web URL is available for this solution!");
217 | }
218 | }}));
219 |
220 | loadStateFromQueryParams();
221 | });
222 |
223 | if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
224 | const link = document.createElement("link");
225 | link.rel = "stylesheet";
226 | link.href = "https://cdnjs.cloudflare.com/ajax/libs/prism/1.25.0/themes/prism-tomorrow.min.css";
227 | document.querySelector("head").appendChild(link);
228 | }
229 |
230 |
--------------------------------------------------------------------------------
/2024/src/scripts.js:
--------------------------------------------------------------------------------
1 | import { year } from './constants.js';
2 | import { loadUsers } from './users.js';
3 |
4 | window.addEventListener("load", async () => {
5 | const mod = (x, m) => (x % m + m) % m;
6 | const clamp = (min, max, val) => Math.min(max, Math.max(val, min));
7 |
8 | const minBy = (xs, p) => xs.reduce((y, x) => p(y, x) < 0 ? y : x, xs[0]);
9 | const comps = (...ps) => (a, b) => ps.reduce((r, p) => r == 0 ? p(a, b) : r, 0);
10 | const userComp = (day, part) => comps(
11 | (a, b) => a.langName(day, part).localeCompare(b.langName(day, part)),
12 | (a, b) => a.name.localeCompare(b.name)
13 | );
14 |
15 | const users = await loadUsers();
16 |
17 | const days = new Date(clamp(
18 | new Date(`${year}-12-01`).valueOf(),
19 | new Date(`${year}-12-25`).valueOf(),
20 | Date.now() - 6 * 60 * 60 * 1000
21 | )).getDate();
22 |
23 | const state = {
24 | day: days - 1,
25 | part: 0,
26 | userName: minBy(users, userComp(days - 1, 0)).name,
27 | };
28 |
29 | async function loadSolution(user, day, part) {
30 | const url = user.solutionUrl(day, part);
31 | const preEl = document.createElement("pre");
32 | const codeEl = document.createElement("code");
33 | const lang = user.lang(day, part);
34 | const encoding = ("encoding" in user ? user.encoding(day, part) : null) || "utf-8";
35 | const decoder = new TextDecoder(encoding);
36 | try {
37 | const result = url ? await fetch(url) : null;
38 | if (!(result?.ok ?? false)) {
39 | throw new Error("No solution yet");
40 | }
41 | const buffer = await result.arrayBuffer();
42 | const code = decoder.decode(buffer);
43 | if (lang) {
44 | await Prism.plugins.autoloader.loadLanguages(
45 | lang,
46 | () => {
47 | codeEl.innerHTML = Prism.highlight(code, Prism.languages[lang], user.lang);
48 | },
49 | () => {
50 | codeEl.innerText = code;
51 | }
52 | );
53 | } else {
54 | codeEl.innerText = code;
55 | }
56 | } catch (err) {
57 | codeEl.textContent = err.message;
58 | }
59 | preEl.appendChild(codeEl);
60 | document.getElementById("preview").innerHTML = "";
61 | document.getElementById("preview").appendChild(preEl);
62 | }
63 |
64 | function render(strings, ...values) {
65 | const html = String.raw({ raw: strings }, ...values);
66 | const el = document.createElement('div');
67 | el.innerHTML = html;
68 | return el.children[0];
69 | }
70 |
71 | function userIndex(userName) {
72 | const index = users.findIndex(u => u.name === userName);
73 | if (index < 0) {
74 | throw new Error(`Could not find index for user ${userName}`);
75 | }
76 | return index;
77 | }
78 |
79 | function currentUser() {
80 | return state.userName ? users.find(u => u.name === state.userName) : null;
81 | }
82 |
83 | function updateSolution() {
84 | loadSolution(currentUser(), state.day, state.part);
85 | }
86 |
87 | function setActive(selector, index) {
88 | const className = "active";
89 | const activatedEl = document.querySelectorAll(selector)[index];
90 | document.querySelectorAll(`${selector}.${className}`).forEach(el => el.classList.remove(className));
91 | activatedEl.classList.add(className);
92 | }
93 |
94 | function updateQueryParams() {
95 | const params = new URLSearchParams();
96 | for (const key in state) {
97 | params.set(key, `${state[key]}`);
98 | }
99 | history.pushState(null, "", `${window.location.pathname}?${params}`);
100 | }
101 |
102 | function updateUsers() {
103 | const usersEl = document.getElementById("users");
104 | usersEl.innerHTML = "";
105 |
106 | users.sort(userComp(state.day, state.part));
107 |
108 | users.forEach(user => {
109 | const el = render`
110 |
111 | ${user.name}
112 |
113 | ${user.langAnnotation ? `${user.langAnnotation} ` : ""}
114 | ${user.langName(state.day, state.part)}
115 |
116 |
117 | `;
118 | el.addEventListener("click", () => {
119 | updateState({ userName: user.name });
120 | });
121 | usersEl.appendChild(el);
122 | });
123 | }
124 |
125 | function updateState({ userName = null, day = null, part = null, updateActive = false, updateQuery = true }) {
126 | if (userName !== null && !users.find(u => u.name === userName)) {
127 | console.warn(`User ${userName} could not be found!`);
128 | userName = null;
129 | }
130 |
131 | state.day = day ?? state.day;
132 | state.part = part ?? state.part;
133 | state.userName = userName ?? (updateQuery ? state.userName : minBy(users, userComp(state.day, state.part)).name);
134 |
135 | if (day !== null || part !== null || updateActive) {
136 | updateUsers();
137 | }
138 | if (userName !== null || day !== null || part !== null || updateActive) {
139 | setActive("#users .list-group-item", userIndex(state.userName));
140 | }
141 | if (day !== null || updateActive) {
142 | setActive(".nav .day", state.day);
143 | }
144 | if (part !== null || updateActive) {
145 | setActive(".part", state.part);
146 | }
147 | if (updateQuery) {
148 | updateQueryParams();
149 | }
150 | updateSolution();
151 | }
152 |
153 | function loadStateFromQueryParams() {
154 | const params = new URLSearchParams(window.location.search);
155 | const loaded = {};
156 | for (const key in state) {
157 | const value = params.get(key);
158 | if (value !== null) {
159 | const parsed = parseInt(value);
160 | loaded[key] = isNaN(parsed) ? value : parsed;
161 | }
162 | }
163 | updateState({ ...loaded, updateActive: true, updateQuery: false });
164 | }
165 |
166 | function userNameWithOffset(userName, offset) {
167 | return users[mod(userIndex(userName) + offset, users.length)].name;
168 | }
169 |
170 | window.addEventListener("keydown", (event) => {
171 | if (event.key === "w" || event.key === "k" ) updateState({ userName: userNameWithOffset(state.userName, -1) });
172 | else if (event.key === "s" || event.key === "j") updateState({ userName: userNameWithOffset(state.userName, 1) });
173 | else if (event.key === "a" || event.key === "h") updateState({ day: mod(state.day - 1, days) });
174 | else if (event.key === "d" || event.key === "l") updateState({ day: mod(state.day + 1, days) });
175 | else if (event.key === "q") updateState({ part: (state.part + 1) % 2 });
176 |
177 | // scroll when keyboard shortcuts are used for navigation
178 | if (["w", "s", "k", "j"].indexOf(event.key) !== -1) {
179 | const li = document.querySelector("#users .list-group-item.active");
180 | li.parentElement.scrollTop =
181 | li.offsetTop - 0.5 * (li.parentElement.offsetHeight - li.offsetHeight);
182 | }
183 | });
184 |
185 | window.addEventListener("popstate", () => {
186 | loadStateFromQueryParams();
187 | });
188 |
189 | Array.from(document.querySelectorAll(".part")).forEach((el, i) => {
190 | el.addEventListener("click", () => {
191 | updateState({ part: i });
192 | });
193 | });
194 |
195 | function createNavItem({ label = "", classes = [], onClick = () => {} }) {
196 | const el = render` `;
197 | const aEl = render`${label} `;
198 | aEl.addEventListener("click", onClick);
199 | el.appendChild(aEl);
200 | return el;
201 | }
202 |
203 | const navEl = document.querySelector(".nav");
204 |
205 | [...Array(days)].forEach((_, day) => {
206 | navEl.appendChild(createNavItem({ label: `${day + 1}`, classes: ["day"], onClick: () => {
207 | updateState({ day });
208 | }}));
209 | });
210 |
211 | navEl.appendChild(createNavItem({ label: "View Source", onClick: () => {
212 | const webUrl = currentUser().solutionWebUrl(state.day, state.part);
213 | if (webUrl) {
214 | window.location.href = webUrl;
215 | } else {
216 | alert("No web URL is available for this solution!");
217 | }
218 | }}));
219 |
220 | loadStateFromQueryParams();
221 | });
222 |
223 | if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
224 | const link = document.createElement("link");
225 | link.rel = "stylesheet";
226 | link.href = "https://cdnjs.cloudflare.com/ajax/libs/prism/1.25.0/themes/prism-tomorrow.min.css";
227 | document.querySelector("head").appendChild(link);
228 | }
229 |
230 |
--------------------------------------------------------------------------------
/src/scripts.js:
--------------------------------------------------------------------------------
1 | import { year } from './constants.js';
2 | import { loadUsers } from './users.js';
3 |
4 | window.addEventListener("load", async () => {
5 | const mod = (x, m) => (x % m + m) % m;
6 | const clamp = (min, max, val) => Math.min(max, Math.max(val, min));
7 |
8 | const minBy = (xs, p) => xs.reduce((y, x) => p(y, x) < 0 ? y : x, xs[0]);
9 | const comps = (...ps) => (a, b) => ps.reduce((r, p) => r == 0 ? p(a, b) : r, 0);
10 | const userComp = (day, part) => comps(
11 | (a, b) => a.langName(day, part).localeCompare(b.langName(day, part)),
12 | (a, b) => a.name.localeCompare(b.name)
13 | );
14 |
15 | const users = await loadUsers();
16 |
17 | const days = new Date(clamp(
18 | new Date(`${year}-12-01`).valueOf(),
19 | new Date(`${year}-12-12`).valueOf(),
20 | Date.now() - 6 * 60 * 60 * 1000
21 | )).getDate();
22 |
23 | const state = {
24 | day: days - 1,
25 | part: 0,
26 | userName: minBy(users, userComp(days - 1, 0)).name,
27 | };
28 |
29 | async function loadSolution(user, day, part) {
30 | const url = user.solutionUrl(day, part);
31 | const preEl = document.createElement("pre");
32 | const codeEl = document.createElement("code");
33 | const lang = user.lang(day, part);
34 | const encoding = ("encoding" in user ? user.encoding(day, part) : null) || "utf-8";
35 | const decoder = new TextDecoder(encoding);
36 | try {
37 | const result = url ? await fetch(url) : null;
38 | if (!(result?.ok ?? false)) {
39 | throw new Error("No solution yet");
40 | }
41 | const buffer = await result.arrayBuffer();
42 | const code = decoder.decode(buffer);
43 | if (lang) {
44 | await Prism.plugins.autoloader.loadLanguages(
45 | lang,
46 | () => {
47 | codeEl.innerHTML = Prism.highlight(code, Prism.languages[lang], user.lang);
48 | },
49 | () => {
50 | codeEl.innerText = code;
51 | }
52 | );
53 | } else {
54 | codeEl.innerText = code;
55 | }
56 | } catch (err) {
57 | codeEl.textContent = err.message;
58 | }
59 | preEl.appendChild(codeEl);
60 | document.getElementById("preview").innerHTML = "";
61 | document.getElementById("preview").appendChild(preEl);
62 | }
63 |
64 | function render(strings, ...values) {
65 | const html = String.raw({ raw: strings }, ...values);
66 | const el = document.createElement('div');
67 | el.innerHTML = html;
68 | return el.children[0];
69 | }
70 |
71 | function userIndex(userName) {
72 | const index = users.findIndex(u => u.name === userName);
73 | if (index < 0) {
74 | throw new Error(`Could not find index for user ${userName}`);
75 | }
76 | return index;
77 | }
78 |
79 | function currentUser() {
80 | return state.userName ? users.find(u => u.name === state.userName) : null;
81 | }
82 |
83 | function updateSolution() {
84 | loadSolution(currentUser(), state.day, state.part);
85 | }
86 |
87 | function setActive(selector, index) {
88 | const className = "active";
89 | const activatedEl = document.querySelectorAll(selector)[index];
90 | document.querySelectorAll(`${selector}.${className}`).forEach(el => el.classList.remove(className));
91 | activatedEl.classList.add(className);
92 | }
93 |
94 | function updateQueryParams() {
95 | const params = new URLSearchParams();
96 | for (const key in state) {
97 | params.set(key, `${state[key]}`);
98 | }
99 | history.pushState(null, "", `${window.location.pathname}?${params}`);
100 | }
101 |
102 | function updateUsers() {
103 | const usersEl = document.getElementById("users");
104 | usersEl.innerHTML = "";
105 |
106 | users.sort(userComp(state.day, state.part));
107 |
108 | users.forEach(user => {
109 | const el = render`
110 |
111 | ${user.name}
112 |
113 | ${user.langAnnotation ? `${user.langAnnotation} ` : ""}
114 | ${user.langName(state.day, state.part)}
115 |
116 |
117 | `;
118 | el.addEventListener("click", () => {
119 | updateState({ userName: user.name });
120 | });
121 | usersEl.appendChild(el);
122 | });
123 | }
124 |
125 | function updateState({ userName = null, day = null, part = null, updateActive = false, updateQuery = true }) {
126 | if (userName !== null && !users.find(u => u.name === userName)) {
127 | console.warn(`User ${userName} could not be found!`);
128 | userName = null;
129 | }
130 |
131 | state.day = day ?? state.day;
132 | state.part = part ?? state.part;
133 | state.userName = userName ?? (updateQuery ? state.userName : minBy(users, userComp(state.day, state.part)).name);
134 |
135 | if (day !== null || part !== null || updateActive) {
136 | updateUsers();
137 | }
138 | if (userName !== null || day !== null || part !== null || updateActive) {
139 | setActive("#users .list-group-item", userIndex(state.userName));
140 | }
141 | if (day !== null || updateActive) {
142 | setActive(".nav .day", state.day);
143 | }
144 | if (part !== null || updateActive) {
145 | setActive(".part", state.part);
146 | }
147 | if (updateQuery) {
148 | updateQueryParams();
149 | }
150 | updateSolution();
151 | }
152 |
153 | function loadStateFromQueryParams() {
154 | const params = new URLSearchParams(window.location.search);
155 | const loaded = {};
156 | for (const key in state) {
157 | const value = params.get(key);
158 | if (value !== null) {
159 | const parsed = parseInt(value);
160 | loaded[key] = isNaN(parsed) ? value : parsed;
161 | }
162 | }
163 | updateState({ ...loaded, updateActive: true, updateQuery: false });
164 | }
165 |
166 | function userNameWithOffset(userName, offset) {
167 | return users[mod(userIndex(userName) + offset, users.length)].name;
168 | }
169 |
170 | window.addEventListener("keydown", (event) => {
171 | if (event.key === "w" || event.key === "k" ) updateState({ userName: userNameWithOffset(state.userName, -1) });
172 | else if (event.key === "s" || event.key === "j") updateState({ userName: userNameWithOffset(state.userName, 1) });
173 | else if (event.key === "a" || event.key === "h") updateState({ day: mod(state.day - 1, days) });
174 | else if (event.key === "d" || event.key === "l") updateState({ day: mod(state.day + 1, days) });
175 | else if (event.key === "q") updateState({ part: (state.part + 1) % 2 });
176 |
177 | // scroll when keyboard shortcuts are used for navigation
178 | if (["w", "s", "k", "j"].indexOf(event.key) !== -1) {
179 | const li = document.querySelector("#users .list-group-item.active");
180 | li.parentElement.scrollTop =
181 | li.offsetTop - 0.5 * (li.parentElement.offsetHeight - li.offsetHeight);
182 | }
183 | });
184 |
185 | window.addEventListener("popstate", () => {
186 | loadStateFromQueryParams();
187 | });
188 |
189 | Array.from(document.querySelectorAll(".part")).forEach((el, i) => {
190 | el.addEventListener("click", () => {
191 | updateState({ part: i });
192 | });
193 | });
194 |
195 | function createNavItem({ label = "", classes = [], onClick = () => {} }) {
196 | const el = render` `;
197 | const aEl = render`${label} `;
198 | aEl.addEventListener("click", onClick);
199 | el.appendChild(aEl);
200 | return el;
201 | }
202 |
203 | const navEl = document.querySelector(".nav");
204 |
205 | [...Array(days)].forEach((_, day) => {
206 | navEl.appendChild(createNavItem({ label: `${day + 1}`, classes: ["day"], onClick: (event) => {
207 | if (event.ctrlKey || event.metaKey) {
208 | location.href = "https://adventofcode.com/2025/day/" + (day + 1);
209 | } else {
210 | updateState({ day });
211 | }
212 | }}));
213 | });
214 |
215 | navEl.appendChild(createNavItem({ label: "View Source", onClick: () => {
216 | const webUrl = currentUser().solutionWebUrl(state.day, state.part);
217 | if (webUrl) {
218 | window.location.href = webUrl;
219 | } else {
220 | alert("No web URL is available for this solution!");
221 | }
222 | }}));
223 |
224 | loadStateFromQueryParams();
225 | });
226 |
227 | if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
228 | const link = document.createElement("link");
229 | link.rel = "stylesheet";
230 | link.href = "https://cdnjs.cloudflare.com/ajax/libs/prism/1.25.0/themes/prism-tomorrow.min.css";
231 | document.querySelector("head").appendChild(link);
232 | }
233 |
234 |
--------------------------------------------------------------------------------
/2024/src/users.js:
--------------------------------------------------------------------------------
1 | import { year, shortYear } from './constants.js';
2 | import { gitHubUrls, pad } from './utils.js';
3 |
4 | /** Loads the list of users. */
5 | export async function loadUsers() {
6 | // TODO handle error if necessary?
7 | const fwcdPaths = await (await fetch(`https://raw.githubusercontent.com/fwcd/advent-of-code-${year}/main/paths.json`)).json().catch(() => ({}));
8 | const SGPaths = await (await fetch(`https://raw.githubusercontent.com/SergejGleithmann/aoc/main/${year}/paths.json`)).json().catch(() => ({}));
9 | const kazumiPaths = await (await fetch(`https://raw.githubusercontent.com/Dormanil/Advent-of-Code/${year}/exceptionInfo.json`)).json().catch(() => ({}));
10 | const magi3rPaths = await (await fetch(`https://raw.githubusercontent.com/Magi3r/AoC-${year}/main/paths.json`)).json().catch(() => ({}));
11 | const hendrick404Paths = await (await fetch(`https://raw.githubusercontent.com/hendrick404/advent-of-code-${year}/main/paths.json`)).json().catch(() => ({}));
12 |
13 | const fwcdSolution = (day, part) => (fwcdPaths[day]?.parts ?? [])[part] ?? fwcdPaths[day];
14 | const SGSolution = (day, part) => (SGPaths[day]?.parts ?? [])[part] ?? SGPaths[day];
15 | const magi3rSolution = (day, part) => (magi3rPaths[day]?.parts ?? [])[part] ?? magi3rPaths[day];
16 |
17 | const users = [
18 | {
19 | name: "Alexander P",
20 | lang: _ => "clike",
21 | langName: _ => "C++",
22 | ...gitHubUrls({
23 | user: "Zeldacrafter",
24 | repo: "CompProg-Solutions",
25 | branch: "master",
26 | path: (day, part) => `AdventOfCode/${year}/${day + 1}/${part + 1}.cc`
27 | })
28 | },
29 | {
30 | name: "I3J03RN",
31 | lang: _ => "clike",
32 | langName: _ => "C++",
33 | ...gitHubUrls({
34 | user: "I3J03RN",
35 | repo: "ProgrammingChallenges",
36 | branch: "master",
37 | path: day => `AoC/${year}/${day + 1}.cc`
38 | })
39 | },
40 | {
41 | name: "Melf",
42 | lang: _ => "scala",
43 | langName: _ => "Scala",
44 | ...gitHubUrls({
45 | user: "melfkammholz",
46 | repo: `aoc${shortYear}`,
47 | path: (day, part) => `day${pad(day + 1, 2)}/${["A", "B"][part]}.scala`
48 | })
49 | },
50 | {
51 | name: "fwcd",
52 | lang: (day, part) => fwcdSolution(day, part)?.lang?.codemirror,
53 | langAnnotation: "Today: ",
54 | langName: (day, part) => fwcdSolution(day, part)?.lang?.name ?? "Unknown",
55 | encoding: (day, part) => fwcdSolution(day, part)?.encoding,
56 | ...gitHubUrls({
57 | user: "fwcd",
58 | repo: `advent-of-code-${year}`,
59 | path: (day, part) => fwcdSolution(day, part)?.path
60 | })
61 | },
62 | {
63 | name: "Yorik Hansen",
64 | lang: _ => "python",
65 | langName: _ => "Python",
66 | ...gitHubUrls({
67 | user: "YorikHansen",
68 | repo: "AdventOfCode",
69 | path: (day, part) => `${year}/day${pad(day + 1, 2)}/part${part + 1}.py`
70 | })
71 | },
72 | {
73 | name: "Skgland",
74 | lang: _ => "rust",
75 | langName: _ => "Rust",
76 | ...gitHubUrls({
77 | user: "Skgland",
78 | repo: "Advent-of-Code",
79 | path: day => `crates/year${year}/src/day${pad(day + 1, 2)}.rs`
80 | })
81 | },
82 | {
83 | name: "b3z",
84 | lang: _ => "python",
85 | langName: _ => "Python",
86 | ...gitHubUrls({
87 | user: "b3z",
88 | repo: "aoc",
89 | branch: "master",
90 | path: (day, part) => `${year}/${pad(day + 1, 2)}/${part + 1}.py`
91 | })
92 | },
93 | {
94 | name: "H1tchhiker",
95 | lang: _ => "elixir",
96 | langName: _ => "Elixir",
97 | ...gitHubUrls({
98 | user: "n00on",
99 | repo: "AdventOfCode",
100 | path: day => `${year}/${pad(day + 1, 2)}/day${pad(day + 1, 2)}.ex`
101 | })
102 | },
103 | {
104 | name: "H1ghBre4k3r",
105 | lang: _ => "rust",
106 | langName: _ => "Rust",
107 | ...gitHubUrls({
108 | user: "H1ghBre4k3r",
109 | repo: `aoc-${year}`,
110 | path: day => `src/day_${pad(day + 1, 2)}.rs`
111 | })
112 | },
113 | {
114 | name: "Zihark",
115 | lang: _ => "haskell",
116 | langName: _ => "Haskell",
117 | ...gitHubUrls({
118 | user: "Ziharrk",
119 | repo: `aoc${year}`,
120 | path: day => `src/Day${day + 1}.hs`
121 | })
122 | },
123 | {
124 | name: "maclement",
125 | lang: _ => "haskell",
126 | langName: _ => "Haskell",
127 | ...gitHubUrls({
128 | user: "maclement",
129 | repo: `advent-of-code-${year}`,
130 | path: day => `Haskell/Day${day + 1}/A.hs`
131 | })
132 | },
133 | {
134 | name: "Magi3r",
135 | lang: (day, part) => magi3rSolution(day, part)?.lang?.codemirror,
136 | langAnnotation: "Today: ",
137 | langName: (day, part) => magi3rSolution(day, part)?.lang?.name ?? "Unknown",
138 | encoding: (day, part) => magi3rSolution(day, part)?.encoding,
139 | ...gitHubUrls({
140 | user: "Magi3r",
141 | repo: `AoC-${year}`,
142 | path: (day, part) => magi3rSolution(day, part)?.path
143 | })
144 | },
145 | {
146 | name: "sebfisch",
147 | lang: _ => "zig",
148 | langName: _ => "Zig",
149 | ...gitHubUrls({
150 | user: "sebfisch",
151 | repo: "AdventOfCode",
152 | branch: "latest",
153 | path: (day, part) => `year${year}/day${pad(day + 1, 2)}/task${part + 1}.zig`
154 | })
155 | },
156 | {
157 | name: "Kazumi",
158 | lang: day => kazumiPaths[`${day + 1}`]?.lang ?? "csharp",
159 | langAnnotation: "Today: ",
160 | langName: day => kazumiPaths[`${day + 1}`]?.langName ?? "C#",
161 | ...gitHubUrls({
162 | user: "Dormanil",
163 | repo: "Advent-of-Code",
164 | branch: `${year}`,
165 | path: day => `Dec${day + 1}/Program.${kazumiPaths[`${day + 1}`]?.extension ?? "cs"}`
166 | })
167 | },
168 | {
169 | name: "Sesquil",
170 | lang: _ => "python",
171 | langName: _ => "Python",
172 | ...gitHubUrls({
173 | user: "sesquil",
174 | repo: `aoc${shortYear}`,
175 | path: (day, part) => `day${pad(day + 1, 2)}/part_${part + 1}.py`
176 | })
177 | },
178 | {
179 | name: "palisn",
180 | lang: _ => "racket",
181 | langName: _ => "Racket",
182 | ...gitHubUrls({
183 | user: "palisn",
184 | repo: "advent-of-code",
185 | path: (day, part) => `${year}/day${pad(day + 1, 2)}/puzzle${part + 1}.rkt`
186 | })
187 | },
188 | {
189 | name: "xtay2",
190 | lang: _ => "java",
191 | langName: _ => "Java",
192 | ...gitHubUrls({
193 | user: "xtay2",
194 | repo: "AdventOfCode",
195 | path: (day, part) => `src/year${year}/day${pad(day + 1, 2)}/Task_${["A", "B"][part]}.java`
196 | })
197 | },
198 | {
199 | name: "JaGitJe",
200 | lang: _ => "haskell",
201 | langName: _ => "Haskell",
202 | ...gitHubUrls({
203 | user: "JaGitJe",
204 | repo: `adventofcode${shortYear}`,
205 | path: (day, part) => `src/Day${pad(day + 1, 2)}.hs`
206 | })
207 | },
208 | {
209 | name: "CoolCode2020",
210 | lang: _ => "python",
211 | langName: _ => "Python",
212 | ...gitHubUrls({
213 | user: "CoolCode2020",
214 | repo: "AOC",
215 | path: (day, part) => `/Tag${day + 1}/day${day + 1}.py`
216 | })
217 | },
218 | {
219 | name: "hype09",
220 | lang: _ => "fsharp",
221 | langName: _ => "F#",
222 | ...gitHubUrls({
223 | user: "hype09",
224 | repo: "aoc2024",
225 | branch: "master",
226 | path: (day, part) => `Day${pad(day + 1, 2)}/Part${pad(part + 1, 2)}.fs`
227 | })
228 | },
229 | {
230 | name: "UnDosTres",
231 | lang: _ => "python",
232 | langName: _ => "Python",
233 | ...gitHubUrls({
234 | user: "donmahallem",
235 | repo: `aoc${shortYear}`,
236 | path: (day, part) => `${pad(day + 1, 2)}/part_${part + 1}.py`
237 | })
238 | },
239 | {
240 | name: "Morsie (Hannes)",
241 | lang: _ => "python",
242 | langName: _ => "Python",
243 | ...gitHubUrls({
244 | user: "hnnsb",
245 | repo: `AdventOfCode${year}`,
246 | path: (day, part) => `${pad(day + 1, 2)}.py`
247 | })
248 | },
249 | {
250 | name: "Hendrik",
251 | lang: day => hendrick404Paths[day]?.lang.identifier,
252 | langName: day => hendrick404Paths[day]?.lang.name ?? "Unknown",
253 | langAnnotation: "Today: ",
254 | ...gitHubUrls({
255 | user: "hendrick404",
256 | repo: `advent-of-code-${year}`,
257 | branch: "main",
258 | path: (day, part) => hendrick404Paths[day]?.path ?? ((hendrick404Paths[day]?.paths ?? [])[part])
259 | })
260 | },
261 | {
262 | name: "Roman",
263 | lang: _ => "python",
264 | langName: _ => "Python",
265 | ...gitHubUrls({
266 | user: "romanhemens",
267 | repo: `advent_of_code2024`,
268 | path: (day, part) => `Day${day + 1}/${part === 0 ? "first" : "second"}.py`
269 | })
270 | },
271 | {
272 | name: "Sergej Gleithmann",
273 | lang: (day, part) => SGSolution(day, part)?.lang?.codemirror,
274 | langAnnotation: "Today: ",
275 | langName: (day, part) => SGSolution(day, part)?.lang?.name ?? "Unknown",
276 | encoding: (day, part) => SGSolution(day, part)?.encoding,
277 | ...gitHubUrls({
278 | user: "SergejGleithmann",
279 | repo: `aoc`,
280 | path: (day, part) => SGSolution(day, part)?.path
281 | })
282 | },
283 | {
284 | name: "mhu",
285 | lang: _ => "zig",
286 | langName: _ => "Zig",
287 | ...gitHubUrls({
288 | user: "marekhummel",
289 | repo: `advent-of-code`,
290 | path: (day, part) => `${year}/zig/solutions/day${pad(day + 1, 2)}.zig`
291 | })
292 | },
293 | {
294 | name: "Bennit",
295 | lang: _ => "python",
296 | langName: _ => "Python",
297 | ...gitHubUrls({
298 | user: "Bennit99",
299 | repo: `AdventOfCode`,
300 | path: (day, part) => `${year}/${day + 1}${["a", "b"][part]}.py`
301 | })
302 | }
303 | ];
304 |
305 | if (new Set(users.map(u => u.name)).size != users.length) {
306 | throw new Error("Users must have unique names!")
307 | }
308 |
309 | return users;
310 | }
311 |
--------------------------------------------------------------------------------
/src/users.js:
--------------------------------------------------------------------------------
1 | import { year, shortYear } from './constants.js';
2 | import { gitHubUrls, pad } from './utils.js';
3 |
4 | /** Loads the list of users. */
5 | export async function loadUsers() {
6 | // TODO handle error if necessary?
7 | // const fwcdPaths = await (await fetch(`https://raw.githubusercontent.com/fwcd/advent-of-code-${year}/main/paths.json`)).json().catch(() => ({}));
8 | const SGPaths = await (await fetch(`https://raw.githubusercontent.com/SergejGleithmann/aoc/main/${year}/paths.json`)).json().catch(() => ({}));
9 | // const kazumiPaths = await (await fetch(`https://raw.githubusercontent.com/Dormanil/Advent-of-Code/${year}/exceptionInfo.json`)).json().catch(() => ({}));
10 | // const magi3rPaths = await (await fetch(`https://raw.githubusercontent.com/Magi3r/AoC-${year}/main/paths.json`)).json().catch(() => ({}));
11 | // const hendrick404Paths = await (await fetch(`https://raw.githubusercontent.com/hendrick404/advent-of-code-${year}/main/paths.json`)).json().catch(() => ({}));
12 | const HappyHPaths = await (await fetch(`https://raw.githubusercontent.com/realHappyH/aoc/main/paths.json`)).json().catch(() => ({}));
13 |
14 | // const fwcdSolution = (day, part) => (fwcdPaths[day]?.parts ?? [])[part] ?? fwcdPaths[day];
15 | const SGSolution = (day, part) => (SGPaths[day]?.parts ?? [])[part] ?? SGPaths[day];
16 | // const magi3rSolution = (day, part) => (magi3rPaths[day]?.parts ?? [])[part] ?? magi3rPaths[day];
17 | const HappyHSolution = (day, part) => (HappyHPaths[day]?.parts ?? [])[part] ?? HappyHPaths[day];
18 |
19 | const users = [
20 | {
21 | name: "Alexander P",
22 | lang: _ => "clike",
23 | langName: _ => "C++",
24 | ...gitHubUrls({
25 | user: "Zeldacrafter",
26 | repo: "CompProg-Solutions",
27 | branch: "master",
28 | path: (day, part) => `AdventOfCode/${year}/${day + 1}/${part + 1}.cc`
29 | })
30 | },
31 | // {
32 | // name: "I3J03RN",
33 | // lang: _ => "clike",
34 | // langName: _ => "C++",
35 | // ...gitHubUrls({
36 | // user: "I3J03RN",
37 | // repo: "ProgrammingChallenges",
38 | // branch: "master",
39 | // path: day => `AoC/${year}/${day + 1}.cc`
40 | // })
41 | // },
42 | {
43 | name: "Melf",
44 | lang: _ => "haskell",
45 | langName: _ => "Haskell",
46 | ...gitHubUrls({
47 | user: "melfkammholz",
48 | repo: `aoc${shortYear}`,
49 | path: (day, part) => `Day${pad(day + 1, 2)}/${["A", "B"][part]}.hs`
50 | })
51 | },
52 | // {
53 | // name: "fwcd",
54 | // lang: (day, part) => fwcdSolution(day, part)?.lang?.codemirror,
55 | // langAnnotation: "Today: ",
56 | // langName: (day, part) => fwcdSolution(day, part)?.lang?.name ?? "Unknown",
57 | // encoding: (day, part) => fwcdSolution(day, part)?.encoding,
58 | // ...gitHubUrls({
59 | // user: "fwcd",
60 | // repo: `advent-of-code-${year}`,
61 | // path: (day, part) => fwcdSolution(day, part)?.path
62 | // })
63 | // },
64 | // {
65 | // name: "Yorik Hansen",
66 | // lang: _ => "python",
67 | // langName: _ => "Python",
68 | // ...gitHubUrls({
69 | // user: "YorikHansen",
70 | // repo: "AdventOfCode",
71 | // path: (day, part) => `${year}/day${pad(day + 1, 2)}/part${part + 1}.py`
72 | // })
73 | // },
74 | {
75 | name: "Skgland",
76 | lang: _ => "rust",
77 | langName: _ => "Rust",
78 | ...gitHubUrls({
79 | user: "Skgland",
80 | repo: "Advent-of-Code",
81 | path: day => `crates/year${year}/src/day${pad(day + 1, 2)}.rs`
82 | })
83 | },
84 | // {
85 | // name: "b3z",
86 | // lang: _ => "python",
87 | // langName: _ => "Python",
88 | // ...gitHubUrls({
89 | // user: "b3z",
90 | // repo: "aoc",
91 | // branch: "master",
92 | // path: (day, part) => `${year}/${pad(day + 1, 2)}/${part + 1}.py`
93 | // })
94 | // },
95 | {
96 | name: "H1tchhiker",
97 | lang: _ => "typescript",
98 | langName: _ => "TypeScript",
99 | ...gitHubUrls({
100 | user: "n00on",
101 | repo: "AdventOfCode",
102 | path: day => `${year}/day${pad(day + 1, 2)}.ts`
103 | })
104 | },
105 | {
106 | name: "H1ghBre4k3r",
107 | lang: _ => "rust",
108 | langName: _ => "Rust",
109 | ...gitHubUrls({
110 | user: "H1ghBre4k3r",
111 | repo: `aoc-${year}`,
112 | path: day => `src/day_${pad(day + 1, 2)}.rs`
113 | })
114 | },
115 | {
116 | name: "Zihark",
117 | lang: _ => "haskell",
118 | langName: _ => "Haskell",
119 | ...gitHubUrls({
120 | user: "Ziharrk",
121 | repo: `aoc${year}`,
122 | path: day => `src/Day${day + 1}.hs`
123 | })
124 | },
125 | // {
126 | // name: "maclement",
127 | // lang: _ => "haskell",
128 | // langName: _ => "Haskell",
129 | // ...gitHubUrls({
130 | // user: "maclement",
131 | // repo: `advent-of-code-${year}`,
132 | // path: day => `Haskell/Day${day + 1}/A.hs`
133 | // })
134 | // },
135 | // {
136 | // name: "Magi3r",
137 | // lang: (day, part) => magi3rSolution(day, part)?.lang?.codemirror,
138 | // langAnnotation: "Today: ",
139 | // langName: (day, part) => magi3rSolution(day, part)?.lang?.name ?? "Unknown",
140 | // encoding: (day, part) => magi3rSolution(day, part)?.encoding,
141 | // ...gitHubUrls({
142 | // user: "Magi3r",
143 | // repo: `AoC-${year}`,
144 | // path: (day, part) => magi3rSolution(day, part)?.path
145 | // })
146 | // },
147 | // {
148 | // name: "sebfisch",
149 | // lang: _ => "zig",
150 | // langName: _ => "Zig",
151 | // ...gitHubUrls({
152 | // user: "sebfisch",
153 | // repo: "AdventOfCode",
154 | // branch: "latest",
155 | // path: (day, part) => `year${year}/day${pad(day + 1, 2)}/task${part + 1}.zig`
156 | // })
157 | // },
158 | // {
159 | // name: "Kazumi",
160 | // lang: day => kazumiPaths[`${day + 1}`]?.lang ?? "csharp",
161 | // langAnnotation: "Today: ",
162 | // langName: day => kazumiPaths[`${day + 1}`]?.langName ?? "C#",
163 | // ...gitHubUrls({
164 | // user: "Dormanil",
165 | // repo: "Advent-of-Code",
166 | // branch: `${year}`,
167 | // path: day => `Dec${day + 1}/Program.${kazumiPaths[`${day + 1}`]?.extension ?? "cs"}`
168 | // })
169 | // },
170 | {
171 | name: "Sesquil",
172 | lang: _ => "python",
173 | langName: _ => "Python",
174 | ...gitHubUrls({
175 | user: "sesquil",
176 | repo: `aoc${shortYear}`,
177 | path: (day, part) => `day${pad(day + 1, 2)}/part_${part + 1}.py`
178 | })
179 | },
180 | {
181 | name: "palisn",
182 | lang: _ => "ua",
183 | langName: _ => "Uiua",
184 | ...gitHubUrls({
185 | user: "palisn",
186 | repo: "advent-of-code",
187 | path: (day, part) => `${year}/day${pad(day + 1, 2)}/puzzle${part + 1}.ua`
188 | })
189 | },
190 | // {
191 | // name: "xtay2",
192 | // lang: _ => "java",
193 | // langName: _ => "Java",
194 | // ...gitHubUrls({
195 | // user: "xtay2",
196 | // repo: "AdventOfCode",
197 | // path: (day, part) => `src/year${year}/day${pad(day + 1, 2)}/Task_${["A", "B"][part]}.java`
198 | // })
199 | // },
200 | // {
201 | // name: "JaGitJe",
202 | // lang: _ => "haskell",
203 | // langName: _ => "Haskell",
204 | // ...gitHubUrls({
205 | // user: "JaGitJe",
206 | // repo: `adventofcode${shortYear}`,
207 | // path: (day, part) => `src/Day${pad(day + 1, 2)}.hs`
208 | // })
209 | // },
210 | // {
211 | // name: "CoolCode2020",
212 | // lang: _ => "python",
213 | // langName: _ => "Python",
214 | // ...gitHubUrls({
215 | // user: "CoolCode2020",
216 | // repo: "AOC",
217 | // path: (day, part) => `/Tag${day + 1}/day${day + 1}.py`
218 | // })
219 | // },
220 | {
221 | name: "hype09",
222 | lang: _ => "fsharp",
223 | langName: _ => "F#",
224 | ...gitHubUrls({
225 | user: "hype09",
226 | repo: "aoc2025",
227 | branch: "master",
228 | path: (day, part) => `Day${pad(day + 1, 2)}/Part${pad(part + 1, 2)}.fs`
229 | })
230 | },
231 | {
232 | name: "UnDosTres",
233 | lang: _ => "python",
234 | langName: _ => "Python",
235 | ...gitHubUrls({
236 | user: "donmahallem",
237 | repo: `aoc`,
238 | path: (day, part) => `python/aoc${shortYear}/day${pad(day + 1, 2)}/part_${part + 1}.py`
239 | })
240 | },
241 | {
242 | name: "Morsie (Hannes)",
243 | lang: _ => "python",
244 | langName: _ => "Python",
245 | ...gitHubUrls({
246 | user: "hnnsb",
247 | repo: `AdventOfCode${year}`,
248 | path: (day, part) => `${pad(day + 1, 2)}.py`
249 | })
250 | },
251 | // {
252 | // name: "Hendrik",
253 | // lang: day => hendrick404Paths[day]?.lang.identifier,
254 | // langName: day => hendrick404Paths[day]?.lang.name ?? "Unknown",
255 | // langAnnotation: "Today: ",
256 | // ...gitHubUrls({
257 | // user: "hendrick404",
258 | // repo: `advent-of-code-${year}`,
259 | // branch: "main",
260 | // path: (day, part) => hendrick404Paths[day]?.path ?? ((hendrick404Paths[day]?.paths ?? [])[part])
261 | // })
262 | // },
263 | // {
264 | // name: "Roman",
265 | // lang: _ => "python",
266 | // langName: _ => "Python",
267 | // ...gitHubUrls({
268 | // user: "romanhemens",
269 | // repo: `advent_of_code2024`,
270 | // path: (day, part) => `Day${day + 1}/${part === 0 ? "first" : "second"}.py`
271 | // })
272 | // },
273 | {
274 | name: "Sergej Gleithmann",
275 | lang: (day, part) => SGSolution(day, part)?.lang?.codemirror,
276 | langAnnotation: "Today: ",
277 | langName: (day, part) => SGSolution(day, part)?.lang?.name ?? "Unknown",
278 | encoding: (day, part) => SGSolution(day, part)?.encoding,
279 | ...gitHubUrls({
280 | user: "SergejGleithmann",
281 | repo: `aoc`,
282 | path: (day, part) => SGSolution(day, part)?.path
283 | })
284 | },
285 | {
286 | name: "mhu",
287 | lang: _ => "elixir",
288 | langName: _ => "Elixir",
289 | ...gitHubUrls({
290 | user: "marekhummel",
291 | repo: `advent-of-code`,
292 | path: (day, part) => `${year}/elixir/solutions/day${pad(day + 1, 2)}.ex`
293 | })
294 | },
295 | // {
296 | // name: "Bennit",
297 | // lang: _ => "python",
298 | // langName: _ => "Python",
299 | // ...gitHubUrls({
300 | // user: "Bennit99",
301 | // repo: `AdventOfCode`,
302 | // path: (day, part) => `${year}/${day + 1}${["a", "b"][part]}.py`
303 | // })
304 | // },
305 | {
306 | name: "ggb",
307 | lang: _ => "clojure",
308 | langName: _ => "Clojure",
309 | ...gitHubUrls({
310 | user: "ggb",
311 | repo: "advent-of-code-2025",
312 | path: (day, part) => `src/ggb/day${day + 1}.clj`
313 | })
314 | },
315 | {
316 | name: "qr",
317 | lang: _ => "rust",
318 | langName: _ => "Rust",
319 | ...gitHubUrls({
320 | user: "QuantumRange",
321 | repo: "aoc25",
322 | branch: "master",
323 | path: (day, part) => `src/day${day + 1}${part + 1}.rs`
324 | })
325 | },
326 | {
327 | name: "Eddykasp",
328 | lang: _ => "python",
329 | langName: _ => "Python",
330 | ...gitHubUrls({
331 | user: "Eddykasp",
332 | repo: "AoC25",
333 | branch: "main",
334 | path: (day, part) => `day${pad(day + 1, 2)}/part${part + 1}.py`
335 | })
336 | },
337 | {
338 | name: "SturmEnte",
339 | lang: _ => "python",
340 | langName: _ => "Python",
341 | ...gitHubUrls({
342 | user: "SturmEnte",
343 | repo: "advent-of-code",
344 | branch: "main",
345 | path: (day, part) => `${year}/day ${day + 1}/part${part + 1}.py`
346 | })
347 | },
348 | {
349 | name: "YoEnte",
350 | lang: _ => "python",
351 | langName: _ => "Python",
352 | ...gitHubUrls({
353 | user: "YoEnte",
354 | repo: "adventofcode-solutions",
355 | branch: "master",
356 | path: (day, part) => `${year}/${pad(day + 1, 2)}/${['a', 'b'][part]}.py`
357 | })
358 | },
359 | {
360 | name: "HappyH",
361 | lang: (day, part) => HappyHSolution(day, part)?.lang?.codemirror,
362 | langAnnotation: "Today: ",
363 | langName: (day, part) => HappyHSolution(day, part)?.lang?.name ?? "Unknown",
364 | encoding: (day, part) => HappyHSolution(day, part)?.encoding,
365 | ...gitHubUrls({
366 | user: "realHappyH",
367 | repo: `aoc`,
368 | path: (day, part) => HappyHSolution(day, part)?.path[part]
369 | })
370 | },
371 | {
372 | name: "Rajib",
373 | lang: _ => "clike",
374 | langName: _ => "C++",
375 | ...gitHubUrls({
376 | user: "RajibTheKing",
377 | repo: "ACMProgramming",
378 | branch: "master",
379 | path: (day, part) => `AdventOfCode/${year}/Day_${pad(day + 1, 2)}/part${part + 1}.cpp`
380 | })
381 | },
382 | ];
383 |
384 | if (new Set(users.map(u => u.name)).size != users.length) {
385 | throw new Error("Users must have unique names!")
386 | }
387 |
388 | return users;
389 | }
390 |
--------------------------------------------------------------------------------