Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#!/bin/bash
instr() {
echo "применение: $0 <требуемый объём> <объём сосуда> <объём сосуда>"
exit
}
ravno0() {
echo "один из переданных параметров равен нулю"
echo "дайте задачу посложнее"
exit
}
ravny() {
echo "сосуды одного объёма"
echo "дайте задачу посложнее"
exit
}
nevozmozhno() {
echo "решения нет, ибо $1"
exit
}
state() {
echo "сейчас в первом сосуде: $n1, во втором сосуде: $n2"
}
itog() {
echo -n "шагов: $step "
state
}
n() { # наливаем в $1
local a1=$1
state
echo "наливаем в сосуд $a1"
eval n$a1=\$v$a1
set $((step++))
}
p() { # переливаем из $1 в $2
local vv a1=$1 a2=$2
state
echo "переливаем из сосуда $a1 в сосуд $a2"
eval vv=$((v$a2-n$a2>n$a1?n$a1:v$a2-n$a2))
eval n$a1=$((n$a1-vv))
eval n$a2=$((n$a2+vv))
set $((step++))
}
c() { # проверка, что объём чего-либо соответстует содержимому $v0
[ $n1 -eq $v0 -o $n2 -eq $v0 -o $((n2+n1)) -eq $v0 ]
}
v() { # выливаем содержимое $1
state
echo "выливаем содержимое сосуда $1"
eval n$1=0
set $((step++))
}
v1() { # выливаем содержимое $1
local a1=$1
eval v=$((v$a1-n$a1))
if [ $v -eq 0 ]; then
state
echo "выливаем содержимое сосуда $a1"
eval n$a1=0
set $((step++))
fi
}
pk() { # наливаем $1 раз в $2, переливаем $3 раз в $4, проверяем объём $5
local a1=$1 a2=$2 a3=$3 a4=$4
local k=$(($a1<$a3?$a3:$a1))
local vv
while [ $k -gt 0 ]; do
n $a2
c && return
p $a2 $a4
c && return
eval vv=$((v$a4-n$a4))
while [ $vv -eq 0 ]; do
v $a4
c && return
p $a2 $a4
c && return
eval vv=$((v$a4-n$a4))
done
set $((k--))
done
return
}
[ $# == 3 ] || instr
[ $1 != 0 -a $2 != 0 -a $3 != 0 ] || ravno0
[ $2 != $3 ] || ravny
v0=$1
if [ $2 -gt $3 ]; then
v1=$2
v2=$3
else
v1=$3
v2=$2
fi
echo "требуемый объём = $v0"
echo "объём первого сосуда = $v1"
echo "объём второго сосуда = $v2"
# v0 <= v1+v2
[ $((v1+v2)) -ge $v0 ] || nevozmozhno "требуемый объём превышает суммарный объём обоих сосудов"
# v0 == a*v1-b*v2 a<v1 b<v2
a=0
b=0
for ((i=1;i<v1;i++)); do
for ((j=0;j<v2;j++)); do
if [ $((i*v1-j*v2)) -eq $v0 ]; then
a=$i
b=$j
break 2
fi
done
done
# v0 == c*v2-d*v1 c<v2 d<v1
c=0
d=0
for ((i=1;i<v2;i++)); do
for ((j=0;j<v1;j++)); do
if [ $((i*v2-j*v1)) -eq $v0 ]; then
c=$i
d=$j
break 2
fi
done
done
n1=0
n2=0
step=0
if [ $a -gt 0 -o $b -gt 0 ]; then
echo a=$a b=$b
pk $a 1 $b 2 $v0
itog
else
if [ $c -gt 0 -o $d -gt 0 ]; then
echo c=$c d=$d
pk $c 2 $d 1 $v0
itog
else
if [ $((v1+v2)) -eq $v0 ]; then
n 1
n 2
itog
else
echo "к сожалению, решений не найдено"
fi
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.