此为《算法的兴趣》读书笔记,我用javascript从新完成算法。
敝人鄙见
此题作者完成得过于庞杂,我将初始状况定义为:[3,3,0,0,true],释义:顺次示意,彼岸僧人数目、彼岸妖怪数目、彼岸僧人数目、彼岸妖怪数目、船在彼岸否。有了以上定义,完全可以将这个题目算作与上一章桶等分水谁人题目是一样的题目,两岸是两个“桶”,僧人和妖怪是”水”,”水”在两个”桶“中返来倒,末了悉数倒到彼岸谁人桶中。
题目形貌
有三个僧人和三个妖怪要应用唯一的一条小船过河,这条小船一次只能载两个人,同时,无论是在河的两岸照样在船上,只需妖怪的数目大于僧人的数目,妖怪们就会将僧人吃掉。如今须要挑选一种过河的部署,保证僧人和妖怪都能过河且僧人不能被妖怪吃掉。
变量定义
var states = [[3,3,0,0,true]]; //初值,递次为:当地僧人、妖怪;对岸僧人、妖怪、船在彼岸
var IsLocal = true; //是不是在彼岸,是为真,在对岸为假
检测搭船部署是不是可行(倒水要领合理?)
function CanTakeDumpAction(curr,local,from,to){
//检测船上,僧人数目大于即是妖怪或许僧人为零且总数为1或2
if((from >= to || from === 0 && to > 0) && (from + to <= 2) && (from + to > 0)){
if(local){ //彼岸与彼岸是差别的
//船过岸后,两岸都要满足要么僧人为0,要么僧人数目大于即是妖怪
if((curr[0] >= from && curr[1] >= to && (curr[0] - from == 0 || curr[0] - from >= curr[1] - to)) && (curr[2] + from == 0 || curr[2] + from >= curr[3] + to)){
return true;
}
}else{
if((curr[2] >= from && curr[3] >= to && (curr[2] - from == 0 || curr[2] - from >= curr[3] - to)) && (curr[0] + from == 0 || curr[0] + from >= curr[1] + to)){
return true;
}
}
}
return false;
}
船到岸后(过河)操纵(倒水)
function DumpWater(curr,local,from,to){
var next = curr.slice();
if(local){ //彼岸与彼岸有差别的操纵
next[0] -= from;
next[1] -= to;
next[2] += from;
next[3] += to;
}else{
next[0] += from;
next[1] += to;
next[2] -= from;
next[3] -= to;
}
next[4] = !local //船到对岸
return next;
}
检测状况是不是涌现过
这个函数是保证不会进入死循环。
function IsStateExist(state){
for(var i = 0; i < states.length; i++){
if(state[0] == states[i][0] && state[1] == states[i][1] && state[2] == states[i][2] && state[3] == states[i][3] && state[4] == states[i][4]){
return true;
}
}
return false;
}
状况搜刮主函数
(function SearchState(states,local){
var curr = states[states.length - 1]; //取初始状况
if(curr[2] == 3 && curr[3] == 3){ //找到解
var rs = ''
states.forEach(function(al){
rs += al.join(',') + ' -> ';
});
console.log(rs.substr(0,rs.length - 4))
}
for(var i = 0; i < 3; i++){ //i示意搭船的僧人数目,0~2
for(var j = 0; j < 3; j++){ //j示意搭船的妖怪数目,0~2
if(CanTakeDumpAction(curr,local,i,j)){ //搭船部署合理
var next = DumpWater(curr,local,i,j); //过河
if(!IsStateExist(next)){
states.push(next);
SearchState(states,!local);
states.pop();
}
}
}
}
})(states,IsLocal);
四组效果
3,3,0,0,true -> 3,1,0,2,false -> 3,2,0,1,true -> 3,0,0,3,false -> 3,1,0,2,true -> 1,1,2,2,false -> 2,2,1,1,true -> 0,2,3,1,false -> 0,3,3,0,true -> 0,1,3,2,false -> 0,2,3,1,true -> 0,0,3,3,false
3,3,0,0,true -> 3,1,0,2,false -> 3,2,0,1,true -> 3,0,0,3,false -> 3,1,0,2,true -> 1,1,2,2,false -> 2,2,1,1,true -> 0,2,3,1,false -> 0,3,3,0,true -> 0,1,3,2,false -> 1,1,2,2,true -> 0,0,3,3,false
3,3,0,0,true -> 2,2,1,1,false -> 3,2,0,1,true -> 3,0,0,3,false -> 3,1,0,2,true -> 1,1,2,2,false -> 2,2,1,1,true -> 0,2,3,1,false -> 0,3,3,0,true -> 0,1,3,2,false -> 0,2,3,1,true -> 0,0,3,3,false
3,3,0,0,true -> 2,2,1,1,false -> 3,2,0,1,true -> 3,0,0,3,false -> 3,1,0,2,true -> 1,1,2,2,false -> 2,2,1,1,true -> 0,2,3,1,false -> 0,3,3,0,true -> 0,1,3,2,false -> 1,1,2,2,true -> 0,0,3,3,false