运行平台
选数
// 导入可视化库 {
const { Tracer, Array1DTracer, LogTracer, Layout, VerticalLayout } = require('algorithm-visualizer');
// }
const N = 4, K = 3; //从包含4个元素的集合中选出3个数
let ans = 0 //方案数
const board =[3, 7, 12, 19]; //创建包含4个元素的一维数组
const chosen = [-1, -1, -1, -1]; //创建一维数组,初始为-1
// 定义跟踪器 {
const boardTracer = new Array1DTracer('集合'); //集合,一维数组
const chosenTracer = new Array1DTracer('选中元素'); //选中元素,一维数组
const logger = new LogTracer('枚举过程');
Layout.setRoot(new VerticalLayout([boardTracer, chosenTracer, logger ]));
boardTracer.set(board);
chosenTracer.set(chosen);
logger.println(`选数: 从${N}个元素中选出${K}个元素`);
Tracer.delay();
// }
function validState(sum) {
if(sum <= 1) return false;
for (let i = 2; i <= sum / i; i ++)
if(sum % i === 0) return false;
return true;
}
function dfs(t, last, sum) {
if (t >= K) {
let res = validState(sum)
if(res) ans ++;
// logger {
logger.println(`所选${K}个数的和为${sum}`);
if(res) logger.println(`${sum}是质数, 已找到${ans}组方案`);
else logger.println(`${sum}不是质数`);
logger.println('------------------------------------------------------------------');
// }
return;
}
for(let i = last + 1; i < N; i ++) {
// visualize {
logger.println(`第${t + 1}个数选择${board[i]}`);
boardTracer.select(i);
Tracer.delay();
chosenTracer.patch(t, board[i])
Tracer.delay();
// }
dfs(t + 1, i, sum + board[i])
// visualize {
boardTracer.deselect(i);
Tracer.delay();
chosenTracer.patch(t, -1)
chosenTracer.depatch(t)
Tracer.delay();
// }
}
}
// logger {
logger.println('开始执行');
// }
dfs(0, -1, 0);
// logger {
logger.println(`完成,一共有${ans}组答案`);
// }
八皇后 Checker Challenge
[USACO1.5] 八皇后 Checker Challenge
// import visualization libraries {
const { Tracer, Array2DTracer, Array1DTracer, LogTracer, Randomize, Layout, VerticalLayout } = require('algorithm-visualizer');
// }
function filledArray(length, value) {
return Array(...Array(length)).map(Number.prototype.valueOf, value);
}
const N = 6; //配置棋盘大小和初始状态
const board = (function createArray(N) {
const result = [];
for (let i = 0; i < N; i++) {
result[i] = filledArray(N, 0);
}
return result;
}(N));
const queens = filledArray(N, -1);
const c = Randomize.Array1D({ N: N, value: () => Randomize.Integer({ min: 0, max: 0 }) }); //列状态
const u = Randomize.Array1D({ N: 2 * N, value: () => Randomize.Integer({ min: 0, max: 0 }) }); //对角线\状态
const v = Randomize.Array1D({ N: 2 * N, value: () => Randomize.Integer({ min: 0, max: 0 }) }); //对角线/状态
// define tracer variables {
const boardTracer = new Array2DTracer('棋盘');
const queenTracer = new Array1DTracer('皇后所在行');
const logger = new LogTracer('算法过程');
Layout.setRoot(new VerticalLayout([boardTracer, queenTracer, logger]));
boardTracer.set(board);
queenTracer.set(queens);
logger.println(`N皇后问题: ${N} X ${N}的棋盘放置 ${N} 个皇后`);
Tracer.delay();
// }
let ans = 0
function dfs(x) {
if (x >= N) {
ans ++;
// logger {
logger.println(`递归到底. 所有皇后放置成功,第 ${ans} 组解为: [${queens.join(', ')}]`);
logger.println('------------------------------------------------------------------');
// }
return;
}
for(let y = 0; y < N; y ++)
{
if(c[y] === 0 && u[x + y] === 0 && v[y - x + N] === 0)
{
// logger {
logger.println(`将第 ${x} 行的皇后放到第 ${y} 列`);
boardTracer.select(x, y);
Tracer.delay();
queenTracer.patch(x, y);
Tracer.delay();
// }
c[y] = u[x + y] = v[y - x + N] = 1;
queens[x] = y;
dfs(x + 1);
c[y] = u[x + y] = v[y - x + N] = 0;
// logger {
boardTracer.deselect(x, y);
Tracer.delay();
queenTracer.patch(x, -1);
queenTracer.depatch(x, -1);
Tracer.delay();
// }
}
}
}
// logger {
logger.println('开始执行');
// }
dfs(0);
// logger {
logger.println(`完成,一共有${ans}组解`);
// }
Lake Counting S
// import visualization libraries {
const {Tracer, Array2DTracer, LogTracer, Layout, VerticalLayout } = require('algorithm-visualizer');
// }
const n = 10, m = 12;
const G = [
['W','.','.','.','.','.','.','.','.','W','W','.'],
['.','W','W','W','.','.','.','.','.','W','W','W'],
['.','.','.','.','W','W','.','.','.','W','W','.'],
['.','.','.','.','.','.','.','.','.','W','W','.'],
['.','.','.','.','.','.','.','.','.','W','.','.'],
['.','.','W','.','.','.','.','.','.','W','.','.'],
['.','W','.','W','.','.','.','.','.','W','W','.'],
['W','.','W','.','W','.','.','.','.','.','W','.'],
['.','W','.','W','.','.','.','.','.','.','W','.'],
['.','.','W','.','.','.','.','.','.','.','W','.'],
];
// define tracer variables {
const tracer = new Array2DTracer("Lake Counting S");
const logger = new LogTracer('广度优先搜索');
Layout.setRoot(new VerticalLayout([tracer, logger]));
tracer.set(G);
Tracer.delay();
// }
const dx = [-1, -1, 0, 1, 1, 1, 0, -1];
const dy = [0, 1, 1, 1, 0, -1, -1, -1];
function bfs(x, y) {
const Q = [];
let node = [x, y]
Q.push(node)
tracer.patch(x, y, '.');
Tracer.delay();
while(Q.length > 0)
{
const node = Q.shift(); // dequeue
x = node[0], y = node[1];
for(let i = 0; i < 8; i ++)
{
let a = x + dx[i], b = y + dy[i];
if(a < 0 || a >= n || b < 0 || b >= m) continue;
if(G[a][b] == '.') continue;
G[a][b] = '.';
Q.push([a, b]);
// visualize {
tracer.patch(a, b, '.');
Tracer.delay();
// }
}
}
}
// logger {
logger.println('开始执行');
// }
let ans = 0;
for(let i = 0; i < n; i ++)
for(let j = 0; j < m; j ++)
if(G[i][j] == 'W')
{
// logger {
logger.println(`开始搜索${i}行${j}列开始的连通块`);
// }
ans ++;
bfs(i, j);
// logger {
logger.println(`${i}行${j}列开始的连通块搜索结束`);
// }
}
// logger {
logger.println(`搜索完成,一共找到${ans}个水坑`);
// }