中国青基会

查看完整版本: "谁养鱼"问题的shell代码

hew 2008-9-16 22:30

"谁养鱼"问题的shell代码

作者:ArchieYao

花了一天多时间用shell做出的"谁养鱼"求解程序,放上来让大家拍砖:) ,刚学shell,请大家多多指教
问题:
在一条街上,有5座房子,喷了5种颜色
每个房里住着不同国籍的人
每个人喝不同的饮料
抽不同的香烟
养不同的宠物
请问,谁养鱼?
提示:
1)、英国人住红色房子
2)、瑞典人养狗
3)、丹麦人喝茶
4)、绿色房子在白色房子左面
5)、绿色房子主人喝咖啡
6)、抽Pall Mall香烟的人养鸟
7)、黄色房子主人抽Dunhill
8)、住在中间房子的人喝牛奶
9)、挪威人住第一间房子
10)、抽Blends香烟的人住在养猫人的隔壁
11)、养马的人住在抽Dunhil香烟人的隔壁
12)、抽BlueMaster的人喝啤酒
13)、德国人抽prince香烟
14)、挪威人住蓝色房子隔壁
15)、抽Blends香烟人的有一个喝水的邻居

刚开始看到这个题,看目很吸引---"世界上有98%的人答不出来的题目",花了近两个小时去做完,再跑网上一看,原来这是世界上98%人都答得出来的题!其实这题是挺简单的,只是静不下心去思考,浮躁的年代...浮躁的心...
废话少说,上代码....[code]#!/bin/sh
#谁养鱼问题求解
#ArchieYao<[email]ArchieYao@126.com[/email]> 2008-01-11

#思路:
#把条件嵌入每个循环中,逐层过滤,最后没被过滤掉的就是结果
#就好比放五个漏斗,每个漏斗有不同的条件,当最后能漏出来的就是想要的东西

#大概处理流程:把排列次序放在room.tmp.range表中
#循环读取room.tmp.range表 ,调整属性位置->临时变量:如color=>color_temp
#根据属性位置和给出的提示条件过滤,保存到临时文件:如红房子住英国人,每读入一行颜色位置,过滤出英国位置和红色位置一致的行,结果->room.tmp.country
#每读一次就进入另一属性(color->country-drink->smoke->pet),直到最后


#初始化
color=("红" "黄" "蓝" "绿" "白")
country=("挪威" "英国" "丹麦" "德国" "瑞典")
drink=("水" "茶" "咖啡" "牛奶" "啤酒")
smoke=("Dunhill" "PallMall" "BlueMaster" "Blends" "prince")
pet=("马" "猫" "鱼" "狗" "鸟")

<<---
初始位置:0       | 1         | 2          | 3      | 4
         红      | 黄        | 蓝         | 绿     | 白
         挪威    | 英国      | 丹麦       | 德国   | 瑞典
         水      | 茶        | 咖啡       | 牛奶   | 啤酒
         Dunhill | PallMall  | BlueMaster | Blends | prince
         马      | 猫        | 鱼         | 狗     | 鸟
--

#--先生成五个数的位置全排列--
arrange()
{
#$1:str $2:pos $3:size
local m
local n
local a
local i
a=( `echo $1` )
m=$2
n=$3

if [[ $[m+1] -eq $n ]]
then
        echo ${a[@]}
fi
for ((i=$m;i<n;i++))
  do
#交换第m位和第i位数据
        t=${a[$m]}
        a[$m]=${a[$i]}
        a[$i]=$t
        temp=`echo ${a[@]}`
        arrange "$temp" $[m+1] $n
        #再交换回来,保持原有的排列顺序
        t=${a[$i]}
        a[$i]=${a[$m]}
        a[$m]=$t
  done
}
temp="0 1 2 3 4"
arrange "$temp" 0 5 >room.tmp.range
#--End 生成位置全排列--

#--开始逐层过滤求解--
`cat room.tmp.range|grep -e '^..2'|grep -e '3.4'>room.tmp.color`        #color蓝色房子2第二;绿色房子3在白色房子4左面 (注:1.所有的位置从0计起;2.本来蓝色房子在挪威人隔这条件是要放在里面过滤的,这里就偷懒放这里处理了)

#-----1.color-----
while read LINE
do
`cat room.tmp.range|grep -e '^0'>room.tmp.country`        #country 挪威人房子第一 挪威人0
`cat room.tmp.range|grep -e '^....3'>room.tmp.drink`        #drink第三间房子主人喝牛奶 牛奶3
`cat room.tmp.range>room.tmp.smoke`        #smoke
`cat room.tmp.range>room.tmp.pet`        #pet

arr=( $LINE )
#echo ${arr[@]}
#根据读入的数据调整房子颜色位置
for((colori=0;colori<5;colori++))
do
        pos=${arr[colori]}
        color_temp[$colori]=${color[$pos]}
        #
        case $pos in
        0) #英国人住红房子  位置0=红色 英国人位置=1
        `cat room.tmp.country|awk '{if($'$[colori+1]'==1)print}'>room.tmp.country1`         #注:awk中列数是中1开始的
        `mv room.tmp.country1 room.tmp.country`
        ;;
        3) #绿色房子主人喝咖啡 绿色房子=3 咖啡=2
        `cat room.tmp.drink|awk '{if($'$[colori+1]'==2)print}'>room.tmp.drink1`
        `mv room.tmp.drink1 room.tmp.drink`
        ;;
        1)
        #黄色房子主人抽Dunhill 黄色房子=1 Dunhill=0
        `cat room.tmp.smoke|awk '{if($'$[colori+1]'==0)print}'>room.tmp.smoke1`
        `mv room.tmp.smoke1 room.tmp.smoke`
        ;;
        esac
done
color_str=`echo ${color_temp[@]}`        
#echo "colorpos"${arr[@]}
#echo "color:"${color_temp[@]}
        #-----2.country-----
        while read LINE
        do
        arr=( $LINE )
        for((countryi=0;countryi<5;countryi++))
        do
                pos=${arr[countryi]}
                country_temp[$countryi]=${country[$pos]}
                case $pos in
                4)
                # 瑞典人养狗  瑞典人=4  狗=3
                `cat room.tmp.pet|awk '{if($'$[countryi+1]'==3)print}'>room.tmp.pet1`
                `mv room.tmp.pet1 room.tmp.pet`
                ;;
                2)
                #丹麦人喝茶 丹麦人=2 茶=1
                `cat room.tmp.drink|awk '{if($'$[countryi+1]'==1)print}'>room.tmp.drink1`
                `mv room.tmp.drink1 room.tmp.drink`
                ;;
                3)
                #德国人抽prince香烟 德国人=3 prince=4
                `cat room.tmp.smoke|awk '{if($'$[countryi+1]'==4)print}'>room.tmp.smoke1`
                `mv room.tmp.smoke1 room.tmp.smoke`
                ;;
                esac
        done
        country_str=`echo ${country_temp[@]}`        
        #echo "countrypos"${arr[@]}
        #echo "country:"${country_temp[@]}
                #-----3.drink-----
                while read LINE
                do
                arr=( $LINE )
                for((drinki=0;drinki<5;drinki++))
                do
                        pos=${arr[drinki]}
                        drink_temp[$drinki]=${drink[$pos]}
                        case $pos in
                        4)
                        #抽BlueMaster的人喝啤酒        啤酒=4        BlueMaster=2
                        `cat room.tmp.smoke|awk '{if($'$[drinki+1]'==2)print}'>room.tmp.smoke1`
                        `mv room.tmp.smoke1 room.tmp.smoke`
                        ;;
                        0)
                        #抽Blends香烟人的有一个喝水的邻居 水=0        隔壁Blends=3
                        if [ $drinki -gt 0 ]
                        then
                                `cat room.tmp.smoke|awk '{if($'$drinki'==3)print};'>>room.tmp.smoke1`
                        fi
                        if [ $[drinki+2] -le 5 ]
                        then
                                `cat room.tmp.smoke|awk '{if($'$[drinki+2]'==3)print};'>>room.tmp.smoke1`
                        fi
                        `sort room.tmp.smoke1|uniq>room.tmp.smoke`
                        `rm room.tmp.smoke1`
                        ;;
                        esac
                done
                drink_str=`echo ${drink_temp[@]}`        
                #echo "drinkpos"${arr[@]}
                #echo "drink:"${drink_temp[@]}
                        #-----4.smoke-----
                        while read LINE
                        do
                        arr=( $LINE )
                        for((smokei=0;smokei<5;smokei++))
                        do
                                pos=${arr[smokei]}
                                smoke_temp[$smokei]=${smoke[$pos]}
                                #echo "pos:"$pos
                                case $pos in
                                1)
                                #抽Pall Mall香烟的人养鸟 Pall Mall=1 鸟=4
                                `cat room.tmp.pet|awk '{if($'$[smokei+1]'==4)print}'>room.tmp.pet1`
                                `mv room.tmp.pet1 room.tmp.pet`
                                ;;
                                3)
                                #抽Blends香烟的人住在养猫人的隔壁 Blends=3 猫=1
                                if [ $smokei -gt 0 ]
                                then
                                        `cat room.tmp.pet|awk '{if($'$smokei'==1)print};'>>room.tmp.pet1`
                                fi
                                if [ $[smokei+2] -le 5 ]
                                then
                                         `cat room.tmp.pet|awk '{if($'$[smokei+2]'==1)print};'>>room.tmp.pet1`
                                fi
                                `sort room.tmp.pet1|uniq>room.tmp.pet`
                                `rm room.tmp.pet1`
                                ;;
                                0)
                                #养马的人住在抽Dunhil香烟人的隔壁 Dunhil=0 隔壁养马=0

                                if [ $smokei -gt 0 ]
                                then
                                        `cat room.tmp.pet|awk '{if($'$smokei'==0)print};'>>room.tmp.pet1`
                                fi
                                if [ $[smokei+2] -le 5 ]
                                then
                                         `cat room.tmp.pet|awk '{if($'$[smokei+2]'==0)print};'>>room.tmp.pet1`
                                fi
                                `sort room.tmp.pet1|uniq>room.tmp.pet`
                                `rm room.tmp.pet1`
                                ;;
                                esac
                        done
                        smoke_str=`echo ${smoke_temp[@]}`        
                        #echo "smoke:"${smoke_temp[@]}
                                #-----5.pet----
                                while read LINE
                                do
                                arr=( $LINE )
                                for((peti=0;peti<5;peti++))
                                do
                                        pos=${arr[peti]}
                                        pet_temp[$peti]=${pet[$pos]}
                                done
                                echo -e "房间:1 2 3 4 5\n"$color_str"\n"$country_str"\n"$drink_str"\n"$smoke_str
                                echo ${pet_temp[@]}
                                exit 0
                                done<room.tmp.pet
                                #-----nd 5.pet-----
                        done<room.tmp.smoke
                        #-----end 4.smoke-----
                done<room.tmp.drink
                #-----end 3.drink-----
        done<room.tmp.country
        #-----end 2.country----
done<room.tmp.color
#-----end 1.color-----
`rm room.tmp.*`
#-----------------------------------END----------------------------------[/code]
页: [1]
查看完整版本: "谁养鱼"问题的shell代码
Baidu