-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 243c430
Showing
8 changed files
with
322 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |