Алгоритм, чтобы проверить, есть ли определенные буквы, ограниченные [клетки] и заменить их? - PullRequest
1 голос
/ 25 февраля 2020

Здравствуйте, я делаю следующее упражнение по программированию: Голодные игры - лисы и цыплята . Утверждение таково:

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, он ожидает от нас замены конечных цыплят. Я имею в виду предыдущий код:

.....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...]

Как это возможно?

1 Ответ

0 голосов
/ 25 февраля 2020

Ночью единственные гарантированные "безопасные" цыплята находятся в их клетках [] (если только лиса не попала с ними в клетку!)

Насколько я понимаю, если есть нет клеток, тогда вся курица d ie в любом случае, лиса или нет, поэтому

//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")){

Снимите эту проверку для лисы.

Прямо сейчас ваш код правильно удаляет всю курицу перед первой клеткой, потому что тогда и posCageEnded и posCageStarted равны -1, поэтому ни posCageStarted>posCageEnded, ни posCageEnded>posCageStarted, но после первой клетки она останавливается убирая курицу за пределы клетки, если там нет и лисы.

PS. Голосуйте за 2 лисы в комментарии к строке 2:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...