Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
yeunhakim93 committed Dec 2, 2023
0 parents commit 243c430
Show file tree
Hide file tree
Showing 8 changed files with 322 additions and 0 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
REFERENCES

- H. Fredricksen and I. J. Kessler, "An algorithm for generating necklaces of beads in two colors," Discrete Mathematics 61 (1986) 181-188
- H. Fredricksen and J. Maiorana, "Necklaces of beads in k colors and k-ary de Bruijn sequences," Discrete Mathematics 23, No. 3 (1978) 207-210
- F. Ruskey, C. Savage, and T. Wang, "Generating Necklaces," Journal of Algorithms 13, No.3 (1992) 414-430
- J.Sawada, "Generating bracelets in constant amortized time,", Society for Industrial and Applied Mathematics 31, No.1 (2001) 259-268
- J.Davies, “Combinatorial Necklaces and Bracelets”, www.jasondavies.com/necklaces, Accessed 15 Nov. 2023
72 changes: 72 additions & 0 deletions generate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* REFERENCES
* [1] H. Fredricksen and I. J. Kessler, "An algorithm for generating necklaces of beads in two colors," Discrete Mathematics 61 (1986) 181-188
* [2] H. Fredricksen and J. Maiorana, "Necklaces of beads in k colors and k-ary de Bruijn sequences," Discrete Mathematics 23, No. 3 (1978) 207-210
* [3] F. Ruskey, C. Savage, and T. Wang, "Generating Necklaces," Journal of Algorithms 13, No.3 (1992) 414-430
* [4] J.Sawada, "Generating bracelets in constant amortized time,", Society for Industrial and Applied Mathematics 31, No.1 (2001) 259-268
* [5] J.Davies, “Combinatorial Necklaces and Bracelets”, www.jasondavies.com/necklaces, Accessed 15 Nov. 2023
*/

const BEADS_RADIUS = 5;
const BEADS_COLOR = ["red", "orange", "green", "blue", "purple"];

document.addEventListener("DOMContentLoaded", function (event) {
const length = document.querySelector(".length");
const kind = document.querySelector(".kind");
const type = document.querySelector(".type");
const generateButton = document.querySelector(".generate");
const result = document.querySelector(".result");
const resultNum = document.querySelector(".result-number");

generateButton.addEventListener("click", (event) => {
[result.innerHTML, resultNum.innerHTML] = generate(
length.value,
kind.value,
type.value
);
});
});

function getCoordinates(length) {
let angle = (Math.PI * 2) / length;
const angles = [];
const coordinates = [];
for (let i = 0; i < length; i++) {
angles.push(angle * i);
}
for (beadsAngle of angles) {
coordinates.push([Math.sin(beadsAngle), -Math.cos(beadsAngle)]);
}
return coordinates;
}

const generate = (length, kind, type) => {
const resultArr =
type === "0" ? getNecklaces(length, kind) : getBracelets(length, kind);

const beadsCoordinates = getCoordinates(length);
let drawing = "";
resultArr.forEach((uniqueOutcome, i) => {
drawing += `<svg width="100" height="100" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="-7.5 -7.5 15 15"
<defs>
</defs>
>
<circle cx="0" cy="0" r="5" stroke-width="0.2" stroke="silver"></circle>`;
uniqueOutcome.forEach((bead, j) => {
drawing += `<circle cx="${beadsCoordinates[j][0] * BEADS_RADIUS}" cy="${
beadsCoordinates[j][1] * BEADS_RADIUS
}" r="1" fill="url(#beadGradient${i}_${j}_${bead})"></circle>
<defs>
<radialGradient id="beadGradient${i}_${j}_${bead}" cx="40%" cy="40%" >
<stop offset="0%" style="stop-color: #ffffc6; stop-opacity: 1" />
<stop offset="100%" style="stop-color: ${
BEADS_COLOR[bead]
}; stop-opacity: 1" />
</radialGradient>
</defs>`;
});
drawing += `</svg>`;
});
return [drawing, "Number of unique arrangements: " + resultArr.length];
};
57 changes: 57 additions & 0 deletions getBracelets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
Joe Sawada,
Generating bracelets in constant amortized time,
Society for Industrial and Applied Mathematics,
Volume 31, Issue 1,
2001,
Pages 259-268,
https://epubs.siam.org/doi/10.1137/S0097539700377037
*/
function getBracelets(n, k) {
const a = [];
for (let i = 0; i < n; i++) a[i] = 0;

return generateBracelets(1, 1, 1, -1, 0, false);

function checkRev(t, i) {
for (let j = i + 1; j <= (t + 1) / 2; j++) {
if (a[j] < a[t - j + 1]) return 0;
if (a[j] > a[t - j + 1]) return -1;
}
return 1;
}

function generateBracelets(t, p, r, u, v, rs) {
let outcomes = [];
if (t - 1 > (n - r) / 2 + r) {
if (a[t - 1] > a[n - t + 2 + r]) rs = false;
else if (a[t - 1] < a[n - t + 2 + r]) rs = true;
}
if (t > n) {
if (!rs && n % p === 0) outcomes.push(a.slice(1));
} else {
a[t] = a[t - p];

if (a[t] === a[1]) v++;
else v = 0;

if (u === -1 && a[t - 1] !== a[1]) u = r = t - 2;
if (u === -1 || t !== n || a[n] !== a[1]) {
if (u === v) {
let rev = checkRev(t, u);
if (rev !== -1)
outcomes = outcomes.concat(
generateBracelets(t + 1, p, rev ? t : r, u, v, rev ? false : rs)
);
} else {
outcomes = outcomes.concat(generateBracelets(t + 1, p, r, u, v, rs));
}
}
for (let j = a[t - p] + 1; j < k; j++) {
a[t] = j;
outcomes = outcomes.concat(generateBracelets(t + 1, t, r, u, 0, rs));
}
}
return outcomes;
}
}
34 changes: 34 additions & 0 deletions getNecklaces.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
Frank Ruskey, Carla Savage, Terry Min Yih Wang,
Generating necklaces,
Journal of Algorithms,
Volume 13, Issue 3,
1992,
Pages 414-430,
ISSN 0196-6774,
https://doi.org/10.1016/0196-6774(92)90047-G.
*/
function getNecklaces(length, kind) {
const outcomes = [];
const a = [];
for (let i = 0; i <= length; i++) a[i] = 0;
outcomes.push(a.slice(1, length + 1));
let i = length;
do {
a[i] = a[i] + 1;
for (let j = 1; j <= length - i; j++) {
a[j + i] = a[j];
}

if (length % i === 0) {
outcomes.push(a.slice(1, length + 1));
}

i = length;
while (a[i] === kind - 1) {
i = i - 1;
}
} while (i !== 0);

return outcomes;
}
40 changes: 40 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Combinatorics - Necklaces</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>Combinatorics - Necklaces</h1>
<div class="body-wrapper">
<div class="inputs-container">
<label for="length">Length<input type="number" class="length" name="length" max="6" min="1" value="2"></input></label>
<label for="kind">Kind<input type="number" class="kind" name="kind" max="6" min="1" value="3"></input></label>
<label for="type">Type
<select class="type" name="type">
<option value="0" selected>Necklace</option>
<option value="1">Bracelet</option>
</select>
</label>
<button class="generate" name="generate">Generate</button>
</div>
<div class="result-number"></div>
<div class="result"></div>
</div>
<footer>
<ul>
<li>H. Fredricksen and I. J. Kessler, "An algorithm for generating necklaces of beads in two colors," Discrete Mathematics 61 (1986) 181-188</li>
<li>H. Fredricksen and J. Maiorana, "Necklaces of beads in k colors and k-ary de Bruijn sequences," Discrete Mathematics 23, No. 3 (1978) 207-210</li>
<li>F. Ruskey, C. Savage, and T. Wang, "Generating Necklaces," Journal of Algorithms 13, No.3 (1992) 414-430</li>
<li>J.Sawada, "Generating bracelets in constant amortized time,", Society for Industrial and Applied Mathematics 31, No.1 (2001) 259-268</li>
<li>J.Davies, “Combinatorial Necklaces and Bracelets”, www.jasondavies.com/necklaces, Accessed 15 Nov. 2023
</ul>
</footer>
</body>
<script src="getBracelets.js"></script>
<script src="getNecklaces.js"></script>
<script src="generate.js"></script>
</html>
22 changes: 22 additions & 0 deletions linearFinite.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
function linearFinite(n, k) {
result = [];
const beadsKinds = [];
for (let i = 0; i < n; i++) beadsKinds[i] = i;

function generate(availableBeads, prevBeads) {
if (availableBeads.length === 0) {
result.push(prevBeads);
return;
}

for (let i = 0; i < availableBeads.length; i++) {
const nextPermute = [...prevBeads, availableBeads[i]];
const beadsLeft = availableBeads.filter((_, index) => i !== index);
generate(beadsLeft, nextPermute);
}

return [];
}
generate(beadsKinds, "");
return result;
}
18 changes: 18 additions & 0 deletions linearInfinite.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
function linearInfinite(n, k) {
result = [];
const beadsKinds = [];
for (let i = 0; i < n; i++) beadsKinds[i] = i;

function generate(prevBeads) {
if (prevBeads.length === n) {
result.push(prevBeads);
return;
}
for (let i = 0; i < n; i++) {
const nextPermute = [...prevBeads, beadsKinds[i]];
generate(nextPermute);
}
}
generate("");
return result;
}
72 changes: 72 additions & 0 deletions style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
@import url("https://fonts.googleapis.com/css2?family=Dhurjati&family=Dosis:wght@300&family=Josefin+Slab:wght@300&display=swap");

input[type="number"],
select {
width: 50px;
padding: 6px 10px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
select {
width: 150px;
}
button {
background-color: #4caf50;
color: white;
padding: 6px 10px;
margin: 8px 0;
border: none;
border-radius: 4px;
cursor: pointer;
height: 32px;
}

button:hover {
background-color: #45a049;
}

.inputs-container {
display: flex;
gap: 10px;
align-items: flex-end;
justify-content: center;
}

.inputs-container > label {
display: flex;
flex-direction: column;
}

.result-number {
margin: 30px auto;
text-align: center;
font-size: 20px;
}

.body-wrapper {
max-width: 500px;
margin: auto;
}

footer {
margin-top: auto;
background-color: rgb(216, 216, 216);
color: gray;
}

body {
height: 100vh;
font-family: "Dosis", sans-serif;
display: flex;
flex-direction: column;
overflow: auto;
}

h1 {
margin-top: 50px;
text-align: center;
font-family: "Josefin Slab", serif;
}

0 comments on commit 243c430

Please sign in to comment.