S26.shell脚本每日一练

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

猜你喜欢

转载自blog.csdn.net/qq_25599925/article/details/126772744