51.汉诺塔(又称河内塔)问题是源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘,利用函数,实现N片盘的汉诺塔的移动步骤
[root@centos8 ~]# cat hanoi.sh
#!/bin/bash
#
#**********************************************************************************************
#Author: Raymond
#QQ: 88563128
#Date: 2021-10-21
#FileName: hanoi.sh
#URL: raymond.blog.csdn.net
#Description: The test script
#Copyright (C): 2021 All rights reserved
#**********************************************************************************************
hanoi(){
local tmp=$1
if [ $tmp -eq 1 ] ;then
let i++
echo "step:$i move $2--->$4" #move A to C
else
hanoi $[$1-1] $2 $4 $3 # move the n-1 plate to B
let i++
echo "step:$i move $2--->$4" #move the bigest plate to C
hanoi $[$1-1] $3 $2 $4 #move the n-1 plate to C
fi
}
trap 'echo Ctrl+C is not work ,Please type q or quit to exit' 2
while : ;do
read -p "please input a number:" tmp
declare -i i=0
if [[ $tmp =~ ^[Qq]([Uu][Ii][Tt])?$ ]] ;then
break
elif [[ $tmp =~ ^[0-9]+$ ]] ;then
hanoi $tmp A B C
else
echo "Error:please input a positive number!"
fi
unset tmp
done
[root@centos8 ~]# bash hanoi.sh
please input a number:5
step:1 move A--->C
step:2 move A--->B
step:3 move C--->B
step:4 move A--->C
step:5 move B--->A
step:6 move B--->C
step:7 move A--->C
step:8 move A--->B
step:9 move C--->B
step:10 move C--->A
step:11 move B--->A
step:12 move C--->B
step:13 move A--->C
step:14 move A--->B
step:15 move C--->B
step:16 move A--->C
step:17 move B--->A
step:18 move B--->C
step:19 move A--->C
step:20 move B--->A
step:21 move C--->B
step:22 move C--->A
step:23 move B--->A
step:24 move B--->C
step:25 move A--->C
step:26 move A--->B
step:27 move C--->B
step:28 move A--->C
step:29 move B--->A
step:30 move B--->C
step:31 move A--->C
please input a number:q
[root@centos8 ~]# cat hanoi_tower_1.1.sh
#!/bin/bash
##################################################################
#Auther: CaiJingshui Zhaowenguang
#
#Descript: Hanoi Tower
#
#Contact: [email protected] [email protected]
##################################################################
#*******************************************************#
# 变量声明 #
#*******************************************************#
#用于保存生成的所有的盘子
declare -ax han_disk
#用于保存生成的整根立柱和底座
declare -ax han_pillar
#用于保存立柱的每一节
declare -x pillar_part
#用于移动盘子的临时变量
declare -x tmp
#声明用于表示显示立柱的变量
declare -ax A
#设置移动延迟时间
declare -x times
#*******************************************************#
# 函数声明 #
#*******************************************************#
#生成盘子
disk(){
local num=$1 color='\033[1;44m' colorend='\033[0m'
for i in `seq 1 $num`;do
local blank="" disk=""
for k in `seq 1 $[num+1-i]`;do
blank+=" "
done
for l in `eval echo {
1..$i}`;do
disk+="IIII"
done
han_disk[i]="$blank$color$disk$colorend"
done
}
#生成柱子
pillar ()
{
local radius=$1
local color='\033[1;43m' colorend='\033[0m'
local base=""
#立柱的每一节
for n in `seq 1 $radius`;do
pillar_part+=" "
[ $n -eq $radius ] && pillar_part+=" "
done
pillar_part+="${color}@@${colorend}"
#组装成立柱
for m in `seq 1 $[num+2]`;do
[ $m -eq 1 ] && han_pillar[m]="" && continue
han_pillar[m]="$pillar_part"
done
#底座
for o in `seq 1 $[radius+1]`;do
base+='@@@@'
done
#将底座安装到立柱的下面
han_pillar[$[num+3]]="$color$base$colorend"
}
#清除柱子空间的内容
clean_pillar(){
echo -ne "\033[0H"
local blank
for i in `seq 1 $[num+1]`;do
blank+=' '
done
for i in `seq 1 $[num+3]`;do
echo -e "\033[${1}G$blank"
done
echo -ne "\033[0H"
}
#打印柱子;需要一个参数 1 2 或 3,指明第几根柱子
printA(){
if [ $1 -eq 1 ] ;then
colume=0
elif [ $1 -eq 2 ];then
colume=$[(num+1)*4]
else
colume=$[(num+1)*8]
fi
clean_pillar $colume
for i in `seq 0 $[num+3]`;do
echo -e "\033[${colume}G${A[$1$i]}"
done
#for j in "${A[@]}";do
# echo -e "$j"
#done
}
#初始化柱子并打印
init_pillar()
{
for i in 1 2 3;do
for j in `seq 0 $[num+3]`;do
A[$i$j]=${han_pillar[$[j+1]]}
done
if [ $i -eq 1 ]; then
for i in `seq 1 $num`;do
A[1$[i+1]]=${han_disk[$i]}
done
fi
done
printA 1
printA 2
printA 3
}
#将盘子往上移动
moveup(){
local num_tmp
while : ; do
sleep $times
for i in `seq 0 $[num+2]`;do
echo ${A[$1$i]}|grep -E "II" > /dev/null
if [ $? -eq 0 ];then
tmp=${A[$1$i]}
num_tmp=$i
A[$1$[i-1]]=$tmp
A[$1$i]=$pillar_part
break
elif [ $? -ne 0 -a $i -eq $[num+2] ];then
break 2
fi
done
if [ "${A[${1}0]}" != "" ]; then
A[${1}0]=""
printA $1
break
fi
printA $1
done
}
#将盘子往下放;需要一个参数 说明是哪个柱子
movedown(){
local num_tmp
while : ; do
#sleep $times
for i in `seq 1 $[num+1]`;do
echo ${A[$1$i]}|grep -E "II" > /dev/null
if [ $? -ne 0 ];then
A[$1$i]=$tmp
A[$1$[i-1]]=$pillar_part
if [ $i -eq 1 ]; then
A[20]=""
A[$1$[i-1]]=""
printA 2 #刷新B柱
fi
else
break 2
fi
sleep $times
printA $1
done
if [[ "${A[$1$[num+1]]}" == *I* ]]; then
break
fi
done
}
#汉诺塔盘片移动函数
move()
{
local disknum=$1
local yuan=$2
local linshi=$3
local mubiao=$4
if [ $disknum -eq 1 ]; then
#echo "$yuan => $mubiao"
moveup $yuan
movedown $mubiao
else
move $[disknum-1] $yuan $mubiao $linshi
#echo "$yuan => $mubiao"
moveup $yuan
movedown $mubiao
move $[disknum-1] $linshi $yuan $mubiao
fi
}
#捕捉 Ctrl+c 信息
kill_han(){
echo -e "\033[?25h"
#kill -9 $pidnum
echo -e "\033[3B"
print_Auther
exit
}
#打印作者信息
print_Auther(){
cat <<EOF
#################################################################
# Auther: CaiJingshui Zhaowenguang Liuteng #
# #
# Contact: [email protected] [email protected] #
#################################################################
此程序每次刷新都是一根柱子的范围。由于时间原因,我们不再改进
如果各位网友有兴趣,可以完善(只刷新变化了的部分。)
EOF
}
#*******************************************************#
# 主程序 #
#*******************************************************#
trap "kill_han" 2
trap "kill_han" 9
#输入盘子的数量
while : ;do
read -p "请输入一个正整数(注意屏幕宽度限制):" num
[[ $num =~ ^[0-9]*[1-9]+$ ]] && break
echo -e "\033[1;31m输入的不是正整数\033[0m"
done
#输入盘子移动的速度
while : ;do
read -p "请输入盘子的移动速度:" times
[[ "$times" =~ ^[0-9]*\.?[0-9]+$ ]] && break
echo -e "\033[1;31m输入的不是数字\033[0m"
done
#隐藏光标
echo -ne "\033[?25l"
#生成柱子的高度
#height=$[num+2] 此变量已经废弃
#生成柱子数组
pillar $num
#生成盘子数组
disk $num
#主程序
clear
#播放背景音乐
#( play back_music.wav &> /dev/null )
#pidnum=`pidof play`
pid=$!
init_pillar
move $num 1 2 3
#撤销变量
unset han_disk
unset han_pillar
unset pillar_part
unset tmp
unset A
unset times
#将光标移动到汉诺塔下面的第三行
echo -e "\033[3B"
#打印作者信息
print_Auther
#恢复光标
echo -e "\033[?25h"
#kill -9 $pidnum
52.创建linux回收站
[root@rocky8 ~]# vim rm.sh
#!/bin/bash
#
#**********************************************************************************************
#Author: Raymond
#QQ: 88563128
#Date: 2021-10-22
#FileName: rm.sh
#URL: raymond.blog.csdn.net
#Description: The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
DIR=`mktemp -d /tmp/trash-$(date +%F_%H-%M-%S)XXXXXX`
mv $* $DIR
echo $* is move tu $DIR
[root@rocky8 ~]# alias rm='~/rm.sh'
[root@rocky8 ~]# chmod +x rm.sh
[root@rocky8 ~]# rm finish.log
finish.log is move tu /tmp/trash-2021-10-22_15-16-52VxVPyy
[root@rocky8 ~]# ll /tmp/trash-2021-10-22_15-16-52VxVPyy/
total 4
-rw-r--r-- 1 root root 7 Oct 22 15:07 finish.log