Преобразовать из int в шестнадцатеричную строку, чтобы проверить, содержит ли она слово - PullRequest
0 голосов
/ 10 апреля 2020

мы выполняем следующее упражнение по программированию: Смерть от кофе .

Основная задача - преобразовать целые числа в шестнадцатеричные и добавить значения. Мы написали следующий код:

public class Dinglemouse {

  public static int[] coffeeLimits /*☕*/ (final int year, final int month, final int day) {
    System.out.println("year: "+year);
    System.out.println("month: "+month);
    System.out.println("day: "+day);

    long healthNumber = Long.parseLong(String.valueOf(year)+String.valueOf(month)+String.valueOf(day));
    System.out.println("healthNumber: "+healthNumber);

    long cafe = Long.valueOf("CAFE",16);
    long decaf = Long.valueOf("DECAF",16);

    int cafeLimit = getLimit(cafe, healthNumber);
    System.out.println("\ncafeLimit: "+cafeLimit);
    int decafLimit = getLimit(decaf, healthNumber);
    System.out.println("\ndecafLimit: "+decafLimit);

    return new int []{cafeLimit, decafLimit};
  }

  public static int getLimit(long coffee, long healthNumber){
    int limit=0;
    while(limit<=5000 && !Long.toHexString(healthNumber).contains("dead")){
      limit++;
      healthNumber+=coffee;
      System.out.println("new healthNumber: "+Long.toHexString(healthNumber));
    }
    return limit>5000 ? 0 : limit;    
  }

}

Интересно, почему код проходит следующие тесты, кроме exJohn:

import org.junit.Test;
import static org.junit.Assert.*;
import java.util.*;

public class Tests {

  // Show returned limits
  private static int[] show(final int y, final int m, final int d, final int[] result) {
    System.out.println(String.format("%4d%02d%02d -> ",y,m,d)+Arrays.toString(result));
    return result;
  }

  @Test
  public void exJohn() {
    final int y=1950, m=1, d=19;
    assertArrayEquals(new int[]{2645,1162}, show(y,m,d,Dinglemouse.coffeeLimits(y,m,d)));
  }

  @Test
  public void exSusan() {
    final int y=1965, m=12, d=11;
    assertArrayEquals(new int[]{111,0}, show(y,m,d,Dinglemouse.coffeeLimits(y,m,d)));
  }

  @Test
  public void exElizabeth() {
    final int y=1964, m=11, d=28;
    assertArrayEquals(new int[]{0,11}, show(y,m,d,Dinglemouse.coffeeLimits(y,m,d)));
  }

  @Test
  public void exPeter() {
    final int y=1965, m=9, d=4;
    assertArrayEquals(new int[]{0,0}, show(y,m,d,Dinglemouse.coffeeLimits(y,m,d)));
  }

}

Мы напечатали то, что получаем внутри l oop getLimit и мы видим, что последний номер HealthNumber, выводимый для предела кафе, равен:

...
new healthNumber: 2dc4cbb
new healthNumber: 2dd17b9
new healthNumber: 2dde2b7
new healthNumber: 2deadb5

cafeLimit: 889

А для предела без кофеина мы имеем:

...
new healthNumber: 10ff8a241
new healthNumber: 110068ef0
new healthNumber: 110147b9f
new healthNumber: 11022684e

decafLimit: 0

Итак, результат нашего кода: [889 , 0]

Когда это должно быть: [2645, 1162]

Мы думали, что это может быть вызвано переполнением int, поэтому мы изменили все переменные на long, однако программа ведет себя одинаково.

Мы прочитали:

1 Ответ

0 голосов
/ 10 апреля 2020

Ваша строка кода

long healthNumber = Long.parseLong(String.valueOf(year)+String.valueOf(month)+String.valueOf(day));

"съедает" ведущие нули в день и месяц, вы можете заменить ее на что-то вроде

long healthNumber = year*10000+month*100+day;

, чтобы она работала как положено.

...