package com.tryer;
import java.util.ArrayList;
import java.util.List;
/*假定老鼠是孕育周期是这样:
a、小老鼠出生后2个月性成熟,可以开始孕育
b、孕育周期是1个月,然后马上可以继续孕育
c、性衰退期是1年,也就是说一只老鼠最多只能生12窝
d、一窝老鼠10只,雌雄平均
e、生命周期是2年,
问,有一对刚出生的小老鼠,半年后有多少,一年后有多少,三年后有多少
//1 2
//2 2
//3 2+10
//4 2+10
//5 2+10+10
//6 2+10+10+50
//7 2+10+10+50+10
*/
/**生命周期*/
enum Cycle {
/** 新生老鼠 */
newleft,
/** 成熟老鼠 */
mature,
/** 孕育老鼠 */
breed,
/** 老年老鼠 */
old,
/** 死亡老鼠 */
del
}
public class MonuseGame{
// 老鼠集合
public List<Mouse> mouseList = new ArrayList<>();
private int delMonuse=0;//死亡老鼠数量
public void exec(int month) {
for (int i = 1; i <= month; i++) {
//新生老鼠存放
List<Mouse> newmouseList = new ArrayList<Mouse>();
//死亡老鼠存放
List<Mouse> templist= new ArrayList<Mouse>();
for (Mouse mouse : mouseList) {
mouse.setAgeMonth(mouse.getAgeMonth() + 1);
if (mouse.getCycle() == Cycle.mature) {
if (mouse.getAgeMonth() >= 3) {
mouse.setCycle(Cycle.breed); //①
mouse.setBreedMonth(mouse.getBreedMonth()+1);
}
}
//①处如果执行,说明该老鼠是3个月及以上月份的老鼠,孕育完成了,可生产。so,此处用if 不用else if
if (mouse.getCycle() == Cycle.breed) {
if (mouse.getAgeMonth() >= 12) {
mouse.setCycle(Cycle.old);
} else {
if (mouse.getSex() == 0 && mouse.getBreedMonth() >= MonuseFactory.breedCycle) {
this.doMature(newmouseList);// 生老鼠
mouse.setBreedMonth(0);
} else if(mouse.getSex() == 0 && mouse.getBreedMonth() < MonuseFactory.breedCycle){
mouse.setBreedMonth(mouse.getBreedMonth()+1);
}
}
} else if (mouse.getCycle() == Cycle.newleft) {
if (mouse.getAgeMonth() >= 2) {
mouse.setCycle(Cycle.mature);
}
} else if (mouse.getCycle() == Cycle.old) {
if (mouse.getAgeMonth() >= 24) {
mouse.setCycle(Cycle.del);
}
}else if(mouse.getCycle()==Cycle.del){
templist.add(mouse);
}
}
/**
* 不移除死亡的老鼠,发现用6G内存启动都跑29个月老鼠的数量,5分钟没反应,然后内存溢出
*/
//升天了的老鼠,还是别占地儿了,记个数就行了~\(≧▽≦)/~
for (Mouse mouse : templist) {
mouseList.remove(mouse);
mouse=null;
delMonuse++;
}
templist = new ArrayList<Mouse>();// 释放内存
System.out.println("已有老鼠数量:"+mouseList.size());
System.out.println("新增老鼠数量:"+newmouseList.size());
mouseList.addAll(newmouseList);
newmouseList = null;// 释放内存
}
}
// 生10只老鼠
private void doMature(final List<Mouse> list) {
for (int i = 0; i < 10; i++) {
try {
list.add(MonuseFactory.getMouse());// 生老鼠
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MonuseGame t = new MonuseGame();
//初始两只新老鼠
t.mouseList.add(MonuseFactory.getMouse());
t.mouseList.add(MonuseFactory.getMouse());
t.exec(6);// 28个月
/**
* 28个月
总共老鼠:75236290
小老鼠:54108750
成熟老鼠:10287500
可育老鼠:10809050
老老鼠:30990
母老鼠:37618145
死亡老鼠:12
*
*
* 29个月
* 总共老鼠:144800280
小老鼠:105482750
成熟老鼠:18190000
可育老鼠:21061550
老老鼠:65980
母老鼠:72400151
*/
long count = t.mouseList.stream()
.filter(u -> (u.getCycle() != Cycle.del)).count();
long newcount = t.mouseList.stream()
.filter(u -> (u.getCycle() == Cycle.newleft)).count();
long maturecount = t.mouseList.stream()
.filter(u -> (u.getCycle() == Cycle.mature)).count();
long breedcount = t.mouseList.stream()
.filter(u -> (u.getCycle() == Cycle.breed)).count();
long oldcount = t.mouseList.stream()
.filter(u -> (u.getCycle() == Cycle.old)).count();
long moCount = t.mouseList.stream()
.filter(u ->u.getSex()==0).count();
/*********************java8以下版本 */
// long count = 0L;
// long newcount = 0L;
// long maturecount = 0L;
// long breedcount = 0L;
// long oldcount = 0L;
// long moCount = 0L;
//
// for (Mouse u : t.mouseList) {
// if (u.getCycle() != Cycle.del) {
// count++;
// }
// if (u.getCycle() == Cycle.newleft) {
// newcount++;
// }
// if (u.getCycle() == Cycle.mature) {
// maturecount++;
// }
// if (u.getCycle() == Cycle.breed) {
// breedcount++;
// }
// if (u.getCycle() == Cycle.old) {
// oldcount++;
// }
// if (u.getSex() == 0) {
// moCount++;
// }
// }
System.out.println("总共老鼠:"+count);
System.out.println("小老鼠:"+newcount);
System.out.println("成熟老鼠:"+maturecount);
System.out.println("可育老鼠:"+breedcount);
System.out.println("老老鼠:"+oldcount);
System.out.println("母老鼠:"+moCount);
System.out.println("死亡老鼠:"+t.delMonuse);
}
}
class MonuseFactory {
private static int sumMonse = 0;// 总共老鼠数量
public final static int breedCycle = 1;// 孕育周期
public synchronized static Mouse getMouse() {
Mouse m = new Mouse(sumMonse);
sumMonse++;
return m;
}
}
class Mouse {
private int ageMonth = 0;// 月龄
private Cycle cycle = Cycle.newleft;// 所处生命周期
private int sex;//性别 0:雌 1:雄
private int breedMonth =0;//当前老鼠如果是孕育期的雌老鼠,小鼠的孕期
//控制雌雄老鼠数量相同
public Mouse(int i){
if(i%2==0){
this.sex=0;
}else{
this.sex=1;
}
}
public int getBreedMonth() {
return breedMonth;
}
public void setBreedMonth(int breedMonth) {
this.breedMonth = breedMonth;
}
public int getSex() {
return sex;
}
public int getAgeMonth() {
return ageMonth;
}
public void setAgeMonth(int ageMonth) {
this.ageMonth = ageMonth;
}
public Cycle getCycle() {
return cycle;
}
public void setCycle(Cycle cycle) {
this.cycle = cycle;
}
}
启用6G内存运行:
内存溢出了:
调试发现已产生的数量并没有超过int的最大值,不是越界导致。
最后3年老鼠的数量还是没有算出来。
近日,又看到这个,一时间来了兴致又重新思考了一番,最后还是解决了问题:
public class MonuseGame2 {
//老鼠每個月生命週期对应的数量
Long[] temp = new Long[]{
2L, 0L,//成长期2个月,初始化第一个2只老鼠
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,//成熟孕育期
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L};//老年期
LinkedList<Long> leftMonse = new LinkedList(Arrays.asList(temp));
Long del = 0L;//死亡老鼠数量
public void exec(int month) {
for (int i = 1; i < month; i++) {
//进行一轮生长:将老年期的最后一个月的老鼠数量加入死亡老鼠数量中,并移出老鼠生命周期
del += leftMonse.getLast();
leftMonse.removeLast();
leftMonse.addFirst(0L);//在第一行插入,使老鼠“生长”一个月
//孕育周期是一个月,所以隔月生老鼠
// if(i%2==0){
Long sumMatureMonuse = 0L;
for (int j = 2; j < 14; j++) {//将生命周期在2个月以上14个月以下的老鼠总数算出
if((j-2)%2==1){//孕育周期是一个月,所以隔月生老鼠
sumMatureMonuse += leftMonse.get(j);
}
}
//新生的老鼠等于总数除以2得到母老鼠数量,每只母老鼠生10只
leftMonse.set(0, sumMatureMonuse / 2 * 10);
// }
}
long count = 0L;
long newcount = 0L;
long maturecount = 0L;
long oldcount = 0L;
for (int i = 0; i < leftMonse.size(); i++) {
count += leftMonse.get(i);
if (i < 2) {
newcount += leftMonse.get(i);
} else if (i >= 2 && i < 14) {
maturecount += leftMonse.get(i);
} else if (i > 14) {
oldcount += leftMonse.get(i);
}
}
System.out.println("总共老鼠:" + count);
System.out.println("小老鼠:" + newcount);
System.out.println("成熟可育老鼠:" + maturecount);
System.out.println("老老鼠:" + oldcount);
System.out.println("母老鼠:" + count / 2);
System.out.println("死亡老鼠:" + del);
}
public static void main(String[] args) {
MonuseGame2 mg = new MonuseGame2();
mg.exec(36);
}
}