您好,我正在执行以下编程练习:The Hunger Games - Foxes and Chickens。该语句是:

Story

Old MacDingle had a farm.

To be more precise, he had a free-range chicken farm.

But Old MacDingle also had a fox problem.

Foxes F eat chickens C

At night the only guaranteed "safe" chickens are in their cages [] (unless a fox has got into the cage with them!)
Kata Task

Given the initial configuration of foxes and chickens what will the farm look like the next morning after the hungry foxes have been feasting?
Examples
Ex1 Before

CCC[CCC]FCC[CCCCC]CFFFF[CCC]FFFF

After

...[CCC]F..[CCCCC].FFFF[CCC]FFFF

Ex2 Before

...[CCC]...[CCCFC].....[CCC]....

After

...[CCC]...[...F.].....[CCC]....

Ex3 Before

CCC[CCC]FCC[CCCFC]CFFFF[CCC]FFFF

After

...[CCC]F..[...F.].FFFF[CCC]FFFF

Notes

    Anything not a fox, a chicken, or a cage is just dirt .
    All cages are intact (not open-ended), and there are no cages inside other cages


我写了以下代码:

public class Dinglemouse {
  public static String hungryFoxes /*🦊🦊*/ (String farm) {
    System.out.println("farm: "+farm);
    int posCageStarted = -1;
    int posCageEnded = -1;

    //If there are not cages, and there are foxes, all chickens are cleared; otherwise we keep the farm as it is.
    if(!farm.contains("[") && !farm.contains("]")){
      if(farm.contains("F")){
        return farm.replace("C",".");
      }else{
        return farm;
      }
    }

    for(int i = 0; i < farm.length(); i++){
      System.out.println("i: "+i);
      char c = farm.charAt(i);
      if(c=='['){
        posCageStarted=i;
      }else if(c==']'){
        posCageEnded=i;
      }

      //If we are between cages ]...[
      if(posCageEnded>posCageStarted){
        System.out.println("posCageEnded: "+posCageEnded);
        System.out.println("posCageStarted: "+posCageStarted);
        String betweenCages = "";
        String ending = "";
        String starting = "";
        int nextCageStart;
        if(farm.substring(posCageEnded).contains("[")){
          nextCageStart = posCageEnded+farm.substring(posCageEnded).indexOf('[');
          betweenCages = farm.substring(posCageEnded+1,nextCageStart);
        }else{
          nextCageStart = farm.indexOf('[');
          ending = farm.substring(posCageEnded+1);
          starting = farm.substring(0,nextCageStart);
          betweenCages = ending+starting;
        }
          System.out.println("nextCageStart: "+nextCageStart);
          System.out.println("betweenCages: "+betweenCages);
        if(betweenCages.contains("F")){
          betweenCages = betweenCages.replace('C','.');
          System.out.println("betweenCages: "+betweenCages);
          if(nextCageStart>posCageEnded){
            farm = farm.substring(0,posCageEnded+1) + betweenCages + farm.substring(nextCageStart);
          }else{
            farm = betweenCages.substring(ending.length()) + farm.substring(farm.indexOf('['),posCageEnded+1)
                  + betweenCages.substring(0,ending.length());
          }
          System.out.println("new farm: "+farm);
        }
        i+=betweenCages.length();


      //If we are inside a cage [...]
      }else if(posCageStarted>posCageEnded){
          System.out.println("inside cage: ");
          System.out.println("posCageStarted: "+posCageStarted);
          System.out.println("posCageEnded: "+posCageEnded);
          int cageEnd = posCageStarted+1 + farm.substring(posCageStarted+1).indexOf(']');
          System.out.println("cageEnd: "+cageEnd);
          String insideCage = farm.substring(posCageStarted+1,cageEnd);
          System.out.println("insideCage: "+insideCage);
          if(insideCage.contains("F")){
            insideCage = insideCage.replace("C",".");
            farm = farm.substring(0,posCageStarted+1) + insideCage + farm.substring(cageEnd);
            System.out.println("new farm: "+farm);
          }
        i+=insideCage.length();
      }
    }
    System.out.println("\n\nWe return farm: "+farm);
    return farm;
  }

}


我很好奇,为什么随机测试会失败:

import org.junit.*;
import static org.junit.Assert.assertEquals;

public class ExampleTests {

  @Test
  public void ex1() {
    final String before = "CCC[CCC]FCC[CCCCC]CFFFF[CCC]FFFF";
    final String after  = "...[CCC]F..[CCCCC].FFFF[CCC]FFFF";
    assertEquals(after, Dinglemouse.hungryFoxes(before));
  }

  @Test
  public void ex2() {
    final String before = "...[CCC]...[CCCFC].....[CCC]....";
    final String after  = "...[CCC]...[...F.].....[CCC]....";
    assertEquals(after, Dinglemouse.hungryFoxes(before));
  }

  @Test
  public void ex3() {
    final String before = "CCC[CCC]FCC[CCCFC]CFFFF[CCC]FFFF";
    final String after  = "...[CCC]F..[...F.].FFFF[CCC]FFFF";
    assertEquals(after, Dinglemouse.hungryFoxes(before));
  }

  @Test
  public void noCagesTest(){
    final String before = "CCCCCF.CC..C..CC.CF.";
    final String after  = ".....F............F.";
    assertEquals(after, Dinglemouse.hungryFoxes(before));
  }

  @Test
  public void randomTest3(){
    final String before = ".C......C.F.[...F.]C..CC.....CC.CC[..CFCCC..CCCCCFC....CC...]C[.....C.....C...]";
    final String after  = "..........F.[...F.]...............[...F..........F..........].[.....C.....C...]";
    assertEquals(after, Dinglemouse.hungryFoxes(before));
  }

  @Test
  public void randomTest1(){
    final String before = "..CCCF....[.CC.CCC.CFFC...C.........C..C.CF..CC]CCCC....[.]";
    final String after  = ".....F....[.........FF....................F....]........[.]";
    assertEquals(after, Dinglemouse.hungryFoxes(before));
  }


}


如果我们密切注意对random1的测试,它会期望我们替代最终的Chickens。我的意思是以前的代码输出:

.....F....[.........FF....................F....]CCCC....[.]


它应该输出:

.....F....[.........FF....................F....]........[.]


此外,当我们执行randomTest3时,代码输出:

..........F.[...F.]C..CC.....CC.CC[...F..........F..........]C[.....C.....C...]


它应该输出:

..........F.[...F.]...............[...F..........F..........].[.....C.....C...]


这怎么可能?

最佳答案

到了晚上,唯一可以保证的“安全”鸡被关在笼子里[](除非狐狸和它们一起进入笼子!)


据我了解,如果没有笼子,那么所有的鸡都会死,不管是不是狐狸,所以

//If there are not cages, and there are foxes, all chickens are cleared; otherwise we keep the farm as it is.
if(!farm.contains("[") && !farm.contains("]")){
  if(farm.contains("F")){
     return farm.replace("C",".");
  }else{
    return farm;
  }
}


应该替换为

//If there are not cages all chickens are cleared
if(!farm.contains("[") && !farm.contains("]")){
  return farm.replace("C",".");
}


您的代码的另一个问题是当我们在笼子里或不在笼子里时,情况的检测很差。仅维护一个布尔变量isInsideCage,每次传递'['时将其设置为true,而每次传递']'时将其设置为false会更容易。

可以使用someIndex + farm.substring(someIndex).indexOf(']')代替farm.indexOf(']', someIndex)

但是,您的代码无法正常工作的原因是,您正在检查笼子之间是否存在狐狸以消灭鸡,而笼子外面的鸡无论如何都应该死亡。具体来说,您在if-branch //If we are between cages ]...[中包含以下行:

       if(betweenCages.contains("F")){


删除此检查为狐狸。

现在,您的代码正确删除了第一个笼子之前的所有鸡,因为posCageEndedposCageStarted均为-1,所以posCageStarted>posCageEndedposCageEnded>posCageStarted都不是,但是在第一个笼子之后,它将停止删除笼子外面的鸡,除非狐狸也在那里。

PS。在第2行的评论中投票给2张狐狸面孔:)

10-06 05:08