Пример обзора кода Java (makeChocolate в codingbat)

проблема здесь в кодировании bat java заставила меня немного растянуться:

проблема:

мы хотим сделать пакет килограммов шоколада цели. У нас есть маленькие бары (1 кило каждый) и большие бары (5 кило каждый). Верните количество маленьких баров для использования, предполагая, что мы всегда используем большие бары перед маленькими барами. Верните -1, если это невозможно сделать.

makeChocolate(4, 1, 9) → 4 makeChocolate(4, 1, 10) → -1 makeChocolate(4, 1, 7) → 2

http://codingbat.com/prob/p191363

Я мог бы придумать это как решение, я не уверен, что это лучший способ, который хотели бы рассмотреть энтузиасты, приветствуется! Я набрал это без какого-либо компилятора или чего-либо еще, поэтому извините меня за отступы:

ЛЮБЫЕ ЛУЧШИЕ ОТВЕТЫ БУДУТ ОЦЕНЕНЫ:

public int makeChocolate(int small, int big, int goal) {
  if(goal<5&&small>=goal)
  {
    return goal;
  }

  if(goal<5&&small<goal)
  {
    return -1;
  }

  if(goal>=5)
  {
    if(5*big>goal)
    {
      int temp=goal/5;
      if(goal-temp*5<=small)
      {
        return goal-temp*5;
      }
      if(goal-temp*5>small)
      {
        return -1;
      }
    }

    if(5*big<goal)
    {
      if(small<(goal-5*big))
      {
        return -1;
      }
      if(small>=(goal-5*big))
      {
        return goal-5*big;
      }
    }
  }
  return 0;    
}

16 ответов


private final int BIG_SIZE = 5;

public int makeChocolate(int small, int big, int goal) {
    int s = goal - Math.min(big, goal / BIG_SIZE ) * BIG_SIZE ;
    return (s <= small) ? s : -1;
}

объяснение:

goal / BIG_SIZE вычисляет общее количество требуемых больших баров. Конечно, это может быть больше, чем у нас, так Math.min(big, goal / BIG_SIZE) ограничит это число до big (количество больших баров у нас).

если мы теперь умножим это число на размер большого бара (5 килограммов) и вычтем это из goal, мы получаем количество килограммов, оставшихся для заполнения небольшими барами (s).

вторая строка просто проверяет, достаточно ли у нас маленьких палка. Если да,s является результатом, если нет, мы не можем сделать этот шоколад (-1).


private final int BIG_SIZE = 5;

public int makeChocolate(int small, int big, int goal) {
   // 1
   while (goal >= BIG_SIZE && big >= 1) {goal -=BIG_SIZE; big -= 1;}
   // 2
   return goal <= small ? goal : -1;
}

Я думаю, что это четкое решение:

  1. используйте все большие конфеты
  2. проверьте, есть ли у нас достаточно маленький шоколад и возвращаемое значение

вот простое решение, использующее только булеву логику и простую математику. Как только случаи отказа цели обнаружены, проблема проще для того чтобы разрешить.

public int makeChocolate(int small, int big, int goal) {
    big *= 5;
    if (big + small < goal || small < goal%5)
        return -1;  //goal can not be met
    small = goal - big;    //use big bars first
    return small < 0 ? (big+small)%5 : small;
}

вот мое решение, использующее цикл while (вместо рекурсивного вызова метода):

public int makeChocolate(int small, int big, int goal) {
  while (goal >=5 && big>0) {
    goal -= 5; 
    big--;     
  }
  if (goal<=small) {
    return goal; 
  }
  else return -1;
}

1.Вычитайте 5, пока остальное не будет между 0 и 4, включительно.

2.Остановите вычитание, если количество больших баров исчезло.

3.проверьте, достаточно ли маленьких баров для завершения цели.

4.возвращение остальных, в противном случае -1


public int makeChocolate(int small, int big, int goal) {
     int nbSmallNeeded;
     int nbBigNeeded = Math.abs(goal/5);
     if(big >= nbBigNeeded){
      nbSmallNeeded= goal - nbBigNeeded*5;
     }
     else {
      nbSmallNeeded = goal - 5*big;
     }
     return small >= nbSmallNeeded? nbSmallNeeded: -1; 
}

private final int BIG_SIZE = 5;

public int makeChocolate(int small, int big, int goal) 
{
    if(big > 0 && goal >= BIG_SIZE )
      return makeChocolate(small, --big, goal-BIG_SIZE);

    return (small >= goal ? goal : -1);
}

краткое описание:

пока мы все еще можем использовать большой шоколад (i.e #big > 0 & & goal > BIG_SIZE), метод вызова рекурсивно отбрасывает одну большую плитку шоколада и цель BIG_SIZE.

Как только мы больше не можем использовать большой, просто проверьте, достаточно ли маленьких, чтобы покрыть оставшуюся цель.


public int makeChocolate(int small, int big, int goal) 
{
  int b=big*5;
  if(b>0 && b+small>=goal && goal%5<=small || small>=goal)
  {
    while(goal>=5 && b>0)
    {
     goal-=5;
     b-=5;
    }
    return goal;
  }
  return -1;
}

"Если", чтобы проверить, достаточно ли больших и маленьких конфет, и "в то время как", чтобы избавиться от правильного количества больших конфет


public int makeChocolate(int small, int big, int goal) {

//fail number 1 -- not enough chocolate to reach the goal.
if(goal > big*5 +small) return -1;

//fail number 2 -- not enough small ones to fill the remaining.  
if(goal%5 > small) return -1;

//fail number 3 -- not enough big ones
if(goal - big*5 >=5) return goal-big*5;

return goal%5;
}

Я считаю, что codingbat пытается решить проблему без использования какой-либо формы циклов, как и в предыдущем упражнении MakeBrics. Его стратегия состоит в том, чтобы найти простые способы проверки на провал. Простой способ взглянуть на это-увидеть это как процесс скрининга.

Fail 1 - нет смысла пытаться вычислить, сколько нам нужно, если у нас недостаточно шоколада Для начала. Это требует времени и неэффективно.

Fail 2-мы проверяем, если есть достаточно маленьких оголенных, чтобы заполнить оставшееся пространство. Если это не так, завершите операцию, так как нет смысла вычислять дальше.

Fail 3-в случае, когда у нас недостаточно больших, чтобы слепо полагаться на операцию модуля внизу, если она предполагает бесконечные большие, поэтому она дает только отдых, нам нужно только проверить, сколько у нас есть больших. Поскольку fail #1 прошел, мы знаем, что у нас достаточно шоколада, чтобы заполнить заказ, поэтому все, что нам нужно сделать, это суммируйте большие, а затем вычитайте это из цели,которая оставляет нам правильный ответ малых.


public int makeChocolate(int small, int big, int goal) {
  int goalDiv = goal / 5;
  int goalRem = goal % 5;

  // Equal or more big bars, and small bars available
  if (goalDiv <= big && goalRem <= small)
    return goalRem;

  // Not enough big bars, but more than goal when combined with small bar  
  if (goalDiv > big && (big * 5 + small >= goal))
    return goal - (big * 5);

  return -1;
}

public int makeChocolate(int small, int big, int goal) {
  if(goal  > (big * 5))
  {
    if( (goal - 5 * big) <= small ) return goal - 5 * big;
  }
  else 
  {
    if(goal % 5 <= small) return goal % 5;
  }
  return -1;
}

вот мой код:

public int makeChocolate(int small, int big, int goal) {

    goal=goal-big*5;

    while(goal<0){
      goal+=5;
    }

    if(small>=goal){
      return goal;
    }
    else{
      return -1;
    }

}

public int makeChocolate(int small, int big, int goal) {
    if(goal/5 <= big)
        goal = goal - (goal/5)*5;
    else
        goal = goal - big*5;
    if(goal <= small)
        return goal;
  return -1;
}

public int makeChocolate(int small, int big, int goal) {
  int bigs = big*5;
  while(bigs > goal) {
    big--;
    bigs = big*5;
  }
  int compare = goal - bigs;
  if(small >= compare) return compare;
  if(small < compare) return -1;
  return small;
}

    public int makeChocolate(int small, int big, int goal) {

int big_amount = 0;

 for (int x = 1; x * 5 <= goal; x++){
    if (big > big_amount)
     big_amount++;
 }

  if (goal - big_amount*5 > small)
    return -1;
  else
    return goal - big_amount*5;
}

public int makeChocolate(int small, int big, int goal) {
    // Condtion When Fails
    if (goal > 5 * big + small || goal % 5 > small) {
        return -1;
    }

    if (goal > 5 * big) {
        return (goal - 5 * big);
    } else {
        return (goal % 5);

    }

}

public int makeChocolate(int small, int big, int goal) {
 if(goal>small+big*5) return -1;
 if(goal%5 > small) return -1;
 if(big*5 > goal){
   return goal%5;
 }
 return goal- big*5;
}