转自
http://www.iteye.com/topic/257039同学帮他侄儿问我一个问题:
资源:
1、小明的钱可以购买50瓶汽水。
2、老板搞促销,两个空汽水瓶子可以换一瓶汽水。
问:小明最多能喝多少瓶汽水?
开始还楞了一下, 现在的小学题目还真不简单。不过马上给出答案:
先是50瓶,然后用50个空瓶换来25瓶,喝完后用25个空瓶换12瓶再多个空瓶,
喝完后用13个空瓶换6瓶,然后是7个空瓶换3瓶,然后是4个空瓶换2瓶,
然后是2个空瓶换1瓶,最后问老板借1个空瓶,再用2个空瓶换1瓶,
剩下来那个空瓶还给老板。所以喝到50+25+12+6+3+2+1+1=100
不过最近在学习规则引擎, 于是就想到了怎么用规则引擎来实现。
我的想法是:
1: 假设汽水一元一瓶, 则小明最初有50元。
2: 如果兜里有超过一元钱, 则买一瓶汽水喝, 此时:
钱减少一元,同时拥有的空瓶增加一个。
3: 如果拥有至少两个空瓶, 则两个空瓶卖给老板, 兜里的钱加一。
根据如上想法, 有了如下规则引擎的实现的实现(Drool):
java文件SodaWater.java:
- package org.drools.examples;
-
- import java.io.InputStreamReader;
- import java.io.Reader;
-
- import org.drools.FactHandle;
- import org.drools.RuleBase;
- import org.drools.RuleBaseFactory;
- import org.drools.StatefulSession;
- import org.drools.WorkingMemory;
- import org.drools.compiler.PackageBuilder;
- import org.drools.rule.Package;
-
- public class SodaWater
- {
- public static final void main(String[] args) throws Exception {
- final PackageBuilder builder = new PackageBuilder();
- builder.addPackageFromDrl( new InputStreamReader( SodaWater.class.getResourceAsStream( "SodaWater.drl" ) ) );
-
- final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
- ruleBase.addPackage( builder.getPackage() );
-
- final StatefulSession session = ruleBase.newStatefulSession();
-
- Customer customer = new Customer( "XiaoMing", 50);
- session.insert(customer);
- session.fireAllRules();
- }
-
- public static class Customer
- {
- private String name;
-
- private int money;
-
- private int drinkSum;
-
- private int blankCup;
-
- public Customer(String name, int money)
- {
- this.name = name;
- this.money = money;
- this.drinkSum = 0;
- this.blankCup = 0;
- }
-
- public int getMoney()
- {
- return money;
- }
-
- public void setMoney(int money)
- {
- this.money = money;
- }
-
- public int getBlankCup()
- {
- return blankCup;
- }
-
- public void setBlankCup(int blankCup)
- {
- this.blankCup = blankCup;
- }
-
- public int getDrinkSum()
- {
- return drinkSum;
- }
-
- public void setDrinkSum(int drinkSum)
- {
- this.drinkSum = drinkSum;
- }
-
- public String getName()
- {
- return name;
- }
-
- public void setName(String name)
- {
- this.name = name;
- }
-
- }
- }
package org.drools.examples;
import java.io.InputStreamReader;
import java.io.Reader;
import org.drools.FactHandle;
import org.drools.RuleBase;
import org.drools.RuleBaseFactory;
import org.drools.StatefulSession;
import org.drools.WorkingMemory;
import org.drools.compiler.PackageBuilder;
import org.drools.rule.Package;
public class SodaWater
{
public static final void main(String[] args) throws Exception {
final PackageBuilder builder = new PackageBuilder();
builder.addPackageFromDrl( new InputStreamReader( SodaWater.class.getResourceAsStream( "SodaWater.drl" ) ) );
final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
ruleBase.addPackage( builder.getPackage() );
final StatefulSession session = ruleBase.newStatefulSession();
Customer customer = new Customer( "XiaoMing", 50);
session.insert(customer);
session.fireAllRules();
}
public static class Customer
{
private String name;
private int money;
private int drinkSum;
private int blankCup;
public Customer(String name, int money)
{
this.name = name;
this.money = money;
this.drinkSum = 0;
this.blankCup = 0;
}
public int getMoney()
{
return money;
}
public void setMoney(int money)
{
this.money = money;
}
public int getBlankCup()
{
return blankCup;
}
public void setBlankCup(int blankCup)
{
this.blankCup = blankCup;
}
public int getDrinkSum()
{
return drinkSum;
}
public void setDrinkSum(int drinkSum)
{
this.drinkSum = drinkSum;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
}
rule文件:
- package org.drools.examples
-
- dialect "mvel"
-
- import org.drools.examples.SodaWater.Customer
-
-
- rule "buy a soda water and drink"
- when
- $c : Customer(money > 0, $m:money, $b:blankCup, $d:drinkSum)
- then
- $c.money = $m - 1;
- $c.blankCup = $b + 1;
- $c.drinkSum = $d + 1;
- System.out.println( "Customer " + $c.name + " now buy a soda water and drink: money=" + $c.money + " and blankCup=" + $c.blankCup);
- update($c);
- end
-
- rule "sale blank cup and get money"
- when
- $c : Customer(blankCup > 1, $b:blankCup, $m:money )
- then
- $c.blankCup = $b - 2;
- $c.money = $m + 1;
- System.out.println("Customer " + $c.name + " now sale 2 cups and get money: money=" + $c.money + ", blankCup=" + $c.blankCup);
- update($c);
- end
-
- rule "finish drink"
- no-loop true
- dialect "java"
- when
- $c : Customer(blankCup < 2, money == 0)
- then
- System.out.println( "Customer " + $c.getName() + " finished drink, and drink number is " + $c.getDrinkSum() + " blankCup=" + $c.getBlankCup());
- end
package org.drools.examples
dialect "mvel"
import org.drools.examples.SodaWater.Customer
rule "buy a soda water and drink"
when
$c : Customer(money > 0, $m:money, $b:blankCup, $d:drinkSum)
then
$c.money = $m - 1;
$c.blankCup = $b + 1;
$c.drinkSum = $d + 1;
System.out.println( "Customer " + $c.name + " now buy a soda water and drink: money=" + $c.money + " and blankCup=" + $c.blankCup);
update($c);
end
rule "sale blank cup and get money"
when
$c : Customer(blankCup > 1, $b:blankCup, $m:money )
then
$c.blankCup = $b - 2;
$c.money = $m + 1;
System.out.println("Customer " + $c.name + " now sale 2 cups and get money: money=" + $c.money + ", blankCup=" + $c.blankCup);
update($c);
end
rule "finish drink"
no-loop true
dialect "java"
when
$c : Customer(blankCup < 2, money == 0)
then
System.out.println( "Customer " + $c.getName() + " finished drink, and drink number is " + $c.getDrinkSum() + " blankCup=" + $c.getBlankCup());
end
运行结果如下:
Customer XiaoMing now buy a soda water and drink: money=49 and blankCup=1
Customer XiaoMing now buy a soda water and drink: money=48 and blankCup=2
Customer XiaoMing now sale 2 cups and get money: money=49, blankCup=0
Customer XiaoMing now buy a soda water and drink: money=48 and blankCup=1
Customer XiaoMing now buy a soda water and drink: money=47 and blankCup=2
...
Customer XiaoMing now buy a soda water and drink: money=1 and blankCup=1
Customer XiaoMing now buy a soda water and drink: money=0 and blankCup=2
Customer XiaoMing now sale 2 cups and get money: money=1, blankCup=0
Customer XiaoMing now buy a soda water and drink: money=0 and blankCup=1
Customer XiaoMing finished drink, and drink number is 99 blankCup=1
不过小明最后手上还有最后一个瓶子, 计算机只能到此了。
向老板借一个瓶子换一瓶汽水,喝完在还一个空瓶子,估计就是人类智慧来。
此程序需要drools的jar包,具体可见:
http://lcllcl987.iteye.com/blog/254381
看看大家还有什么好的算法。