Skip to content

Instantly share code, notes, and snippets.

@t-katsushima
Created June 7, 2019 13:57
Show Gist options
  • Save t-katsushima/1c4987055fdc752564a54442ae67d5c8 to your computer and use it in GitHub Desktop.
Save t-katsushima/1c4987055fdc752564a54442ae67d5c8 to your computer and use it in GitHub Desktop.
function solve() {
// a / b
function modDiv(a, b, p) {
function repeatSquares(x, n) {
if (n === 0)
return 1
else if (n % 2 === 0)
return repeatSquares(x*x % p, n/2)
else
return (x * repeatSquares(x*x % p, n/2)) % p
}
const numer = a % p
const denom = repeatSquares(b, p-2)
return (numer * denom) % p
}
function rowReduction(mat, dim) {
const mod = 2
// 行の0化
for (let y=0; y < dim; y++) {
// swapフェーズ
if (mat[y][y] === 0) {
for (let k=y+1; k < dim; k++) {
if (mat[k][y] !== 0) {
tmp = mat[y].slice()
mat[y] = mat[k].slice()
mat[k] = tmp
break
}
}
}
const divisor = mat[y][y]
for (let x=0; x <= dim; x++)
mat[y][x] = modDiv(mat[y][x], divisor, mod)
for (let k=0; k < dim; k++) {
const coeff = mat[k][y]
if (k != y) {
for (let x=0; x <= dim; x++) {
mat[k][x] -= mat[y][x] * coeff
mat[k][x] %= mod
}
}
}
}
let res = []
for (let i=0; i < dim; i++) {
res.push(Math.round(mat[i][dim]))
}
return res;
}
function nyanToClockwise(nyan) {
return (Number(nyan.getAttribute("data-deg")) / (-90) + 4) % 4
}
const board = document.getElementsByClassName('nyan')
const nyans = Array.from(board).map(nyan => nyanToClockwise(nyan))
const elemNum = nyans.length
const side = Math.round(Math.sqrt(elemNum))
function inField(x, y) {
return 0 <= x && x < side && 0 <= y && y < side
}
function mk4Dir(x, y) {
return [[x-1, y], [x+1, y], [x, y-1], [x, y+1]];
}
// phase1
let equations1 = new Array(elemNum);
for (let i=0; i < elemNum; i++)
equations1[i] = new Array(elemNum+1).fill(0);
// write Equation
for (let i=0; i < elemNum; i++) {
equations1[i][i] += 1
for (const p of mk4Dir(i%side, Math.floor(i/side))) {
const [x, y] = p
if (inField(x, y))
equations1[i][y*side + x] -= 1
}
equations1[i][elemNum] = Math.abs(nyans[i] % 2)
}
let equations2 = JSON.parse(JSON.stringify(equations1))
const ans1 = rowReduction(equations1, elemNum).map(x => Math.abs(x))
// phase2
for (let i=0; i < elemNum; i++) {
if (ans1[i]) {
nyans[i] -= 1
for (const p of mk4Dir(i%side, Math.floor(i/side))) {
const [x, y] = p
if (inField(x, y))
nyans[y*side + x] += 1
}
}
}
nyans.forEach(nyan => ((nyan % 4) + 4) % 4)
console.log(nyans)
// write Equation
for (let i=0; i < elemNum; i++) {
equations2[i][elemNum] = nyans[i] / 2
}
const ans2 = rowReduction(equations2, elemNum).map(x => Math.abs(x))
const ans = []
for (let i=0; i < elemNum; i++)
for (let k=0; k < ans1[i] + ans2[i] * 2; k++)
ans.push(i)
for(var i = ans.length - 1; i > 0; i--){
var r = Math.floor(Math.random() * (i + 1));
var tmp = ans[i];
ans[i] = ans[r];
ans[r] = tmp;
}
for (let i = 0; i < ans.length; i++) {
setTimeout(() => board[ans[i]].click(), 10*i)
}
}
solve()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment