2009-06-28 4 views
8

mi sono imbattuto in questo problema in javabat (http://www.javabat.com/prob/p183562):Un problema pratica java

Vogliamo fare una fila di mattoni che è lunga obiettivo pollici. Abbiamo un numero di piccoli mattoni (1 pollice ciascuno) e grandi mattoni (5 pollici ciascuno). Restituisce vero se è possibile effettuare l'obiettivo con scegliendo tra i mattoni indicati. Questo è un po 'più difficile di quanto sembri e può essere fatto senza alcun loop.

makeBricks (3, 1, 8) → veri
makeBricks (3, 1, 9) → falsi
makeBricks (3, 2, 10) → vero

sono arrivato fino a questa soluzione :

public boolean makeBricks(int small, int big, int goal) { 
    if (goal > small + big * 5) 
     return false; 
    else if (goal % 5 == 0) 
     return goal/5 <= big; 
    else 
     return goal % 5 <= small; 
} 

Questo ha superato il test. Ma ho trovato un contro-esempio: makeBricks (10, 0, 10) -> true. La mia logica tornerà falsa. Come dovrei risolvere la mia logica? O c'è un modo migliore per farlo?

+0

Questo è naturalmente ... uno dei problemi di pratica su un sito di apprendimento Java e Python ... codingbat.com –

risposta

17

Penso che si possa semplicemente rimuovere il secondo test. Vorrei provare questo:

public boolean makeBricks(int small, int big, int goal) { 
    if (goal > small + big * 5) 
     return false; 
    else 
     return goal % 5 <= small; 
} 
9

La tua logica non è corretta. Questo dovrebbe farlo:

public boolean makeBricks(int small, int big, int goal) { 
    if (goal < 0 || big < 0 || small < 0) { 
    throw new IllegalArgumentException(); 
    } else if (goal > big * 5 + small) { 
    return false; 
    } else if (goal % 5 <= small) { 
    return true; 
    } else { 
    return false; 
    } 
} 

è sufficiente. Questo può essere semplificata per:

public boolean makeBricks(int small, int big, int goal) { 
    if (goal < 0 || big < 0 || small < 0) { 
    throw new IllegalArgumentException(); 
    } else { 
    return goal <= big * 5 + small && goal % 5 <= small; 
    } 
} 

Naturalmente, il test di integrità in porta negativo, piccolo o grande non è indispensabile ma consigliato. Senza questi controlli, il risultato può essere semplicemente ottenuto da:

public boolean makeBricks(int small, int big, int goal) { 
    return goal <= big * 5 + small && goal % 5 <= small; 
} 
+0

Io non la penso così - per esempio, la tua logica produrrebbe vero per makeBricks (0, 5, 4), dove non puoi realmente fare un quattro pollici linea di meta usando solo un mattone da cinque pollici. – Tim

+14

Ehm, no, non lo farebbe. L'obiettivo <= grande * 5 + piccolo? Sì. Ma l'obiettivo% 5 è 4. Piccolo è 0, quindi restituisce falso. Si prega di provare prima di dichiarare erroneamente che è sbagliato. – cletus

1

è tornare falso perché il secondo controllo è solo confrontandola con la big, che nel tuo esempio contatore che hai zero.

quindi 2 < = 0 è falso.

Ecco un buon modo per farlo:

return (Math.min(goal/5,big)*5 + small) >= goal; 

In questo modo si è sicuri di utilizzare solo il maggior numero di grandi mattoni di cui hai bisogno, ma non di più, garantendo che l'unico modo per raggiungere l'obiettivo è se hai abbastanza mattoni piccoli.

3

Il secondo test è del tutto inutile. Il primo controlla che tu abbia abbastanza lunghezza totale, e tutto va bene.

Ma la seconda nuovamente controlla se hai abbastanza lunghezza totale (obiettivo ritorno/5 < = grande;) ma ignora la lunghezza aggiunto da piccoli mattoni. Il problema è che stai verificando se si tratta di un multiplo di 5, e automaticamente assumendo che tu stia per utilizzare solo mattoni di grandi dimensioni, se lo è. In realtà, potresti usare cinque piccoli mattoni invece. (o, come nel tuo esempio, 10 mattoncini piccoli.) L'ultimo controllo è corretto, verificando se hai una granularità sufficiente per ottenere la giusta lunghezza, assumendo che tu abbia abbastanza lunghezza.

1

Ho provato alcuni altri scenari: "makeBricks (8, 1, 13)" "makeBricks (1, 2, 6)" dove non hai abbastanza o troppi mattoni grandi, ma ne hai bisogno. Per tenere conto di entrambe le possibilità Si avrebbe bisogno di qualcosa di simile a:

public boolean makeBricks(int small, int big, int goal) { 
    /* Not enough bricks to make the goal so don't bother */ 
    if (goal > small + big * 5) 
    return false; 

    /* How many big bricks can we use */ 
    int bigBricksToUse = Math.min(big, (goal/5)); 

    /* If we use that many bigs, do we have enough small */ 
    return goal - (bigBricksToUse * 5) <= small; 
} 
1

Ecco un altro problema pratica ho pensato di che è abbastanza simile a questo problema, solo pensato che avrei posto e vedere se funziona per le persone:

viene fornito un SO INT a partire dalla reputazione e una reputazione di obiettivo SO int. Superiore a quella di partenza. Rispondi solo alle domande in modo che tu possa guadagnare solo da 10 o 15. puoi anche votare meno così puoi perdere anche la reputazione di 1. cosa è la quantità minima di reputazione che si dovrebbe perdere per raggiungere la reputazione bersaglio?

esempio: si parte da 715 e si desidera raggiungere 888. la risposta è 2.

per aumentare la sfida modificare le interi per anela e non utilizzare un ciclo.

1

Ecco la mia risposta originale; non ha funzionato per gli altri test, ma al momento non sono riuscito a capire come non fosse (ancora non ci riesco), e la risposta corretta mi fa incazzare perché anche se si verifica fa schifo funziona davvero perché una certa affermazione è dannatamente falsa. Rant rant rant, ben alcun modo qui:

 
public boolean makeBricks(int small, int big, int goal) {

if(goal<=((big*5)+small) && goal%(big*5)<=small){ return true; } return false; }

Risposta corretta qui, anche se può succhiare:

 
public boolean makeBricks(int small, int big, int goal) {

if(goal<=((big*5)+small) && goal%5<=small){ return true; } return false; }

se piccolo è> = il resto, dovrebbe essere vero, e sempre lo sarà, e se non lo è, allora non può essere vero. Perché la mia strada non funziona, e in questo modo funziona nella sua imperfezione? Sì, l'affermazione precedente (obiettivo < = ((grande * 5) + piccolo) interrompe tutte le istanze in cui non funziona, ma ho fatto quella dichiarazione generale per cancellare che tutto ciò che non è uguale alla somma totale di pollici è falso, non per quello scopo, l'ho derivato dal vecchio problema di matematica in ogni argomento matematico che ho avuto finora, che viene suddiviso in una forma più semplice a questo: w = (ax + bx) dove w = intero a = un numero (in questo caso 5) valore un'operazione più grande del numero rappresentato da b (in questo caso 1) e x è il LCF tra i due valori trovati (in questo caso 1 di nuovo) più adeguatamente da questo problema algebrico geometrico un angolo è 36 gradi più di due volte il suo angolo supplementare (x = 2 (180-x) +36; x = 396-2x; 3x = 396; x = 132). Normalmente viene fornito un suggerimento sull'ammontare di un gruppo, non solo sulle variabili. E cosa c'è di sbagliato nel mio, dov'è l'istanza in cui non funziona?

0

Questa è la mia risposta.

private static boolean makeBricks (int small, int big, int goal) { 

    return ((big * 5 + small) >= goal) && (goal % big <= small); 
} 
+0

Benvenuti in Stack Overflow! Prenderesti in considerazione l'aggiunta di alcune narrative per spiegare perché questo codice funziona e cosa ne fa una risposta alla domanda? –

+0

Questa soluzione fallisce quando ci sono più mattoncini grandi del necessario e ha anche un'eccezione '/ per zero' per' makeBricks (20, 0, 19) ' – dansalmo

+0

' return! (Big * 5 + small piccolo); 'funziona – dansalmo

0
private boolean makeBricks (int small, int big, int goal) { 
    return !(big*5 + small < goal || small < goal%5); 
} 

usa solo operatori booleani per verificare l'assenza di entrambi i casi di insufficienza !(fail || fail). L'ovvio, non abbastanza mattoni per rendere l'obiettivo big*5 + small < goal. Il meno ovvio, non abbastanza piccoli mattoni quando l'obiettivo non è un multiplo pari di 5 small < goal%5.

0

Mattoni public class {

public boolean checkMethod(int small, int big, int goal) { 
    if (goal <= small + big * 5 && goal >= big * 5) { 
     return true; 
    } else 
     return false; 
} 

public static void main(String args[]) { 
    Bricks brick = new Bricks(); 
    System.out.println(brick.checkMethod(10, 0, 10)); 
} 

}

0
private boolean makeBricks(int small, int big, int goal) 
{ 
    if (goal < 0 || big < 0 || small < 0) 
    { 
     throw new IllegalArgumentException(); 
    } 
    else return goal - (5 * big + small) <= 0; 
} 

è questo. Ecco come è fatto.

0

ecco la soluzione perfetta:

public static boolean makeBricks(int small, int big, int goal) { 

    int totalInches = small + big*5; 
    if(totalInches < goal){ 
     return false; 
    } 

    int bigInches= big*5; 
    int smallRequired = goal %5; 

    if(smallRequired > small && bigInches != goal){ 
     return false; 
    }else if(smallRequired <=small){ 
     if(bigInches >= goal || smallRequired + bigInches == goal || small +bigInches ==goal 
       || small+ bigInches == goal){ 
      return true; 
     }if(bigInches + small > goal){ 
      if(small > goal-bigInches){ 
       return true; 
      } 
     } 

    } 
    return false; 
} 
0

Probabilmente nessuno soluzione perfetta, ma forse un po 'più comprensibile rispetto a quelli precedenti:

public boolean makeBricks(int small, int big, int goal) { 
    //not testing for invalid input - no invalid input from codingbat.com (in this case) 

    int obviousDemandSmall = goal%5; 
    if (obviousDemandSmall>small) return false; 

    boolean needSmallToMakeUpForBig = (goal/5>big) ? true : false; 
    if (!needSmallToMakeUpForBig) return true; 

    int superfluousSmallFromFirstGlance = small-obviousDemandSmall; 
    int extraSmallCanMakeThisManyBig = superfluousSmallFromFirstGlance/5; 
    int missingBig = goal/5-big; 
    if (extraSmallCanMakeThisManyBig>=missingBig) return true; 

    return false; 
} 
0
if (goal < 0 || big < 0 || small < 0) { 
      throw new IllegalArgumentException(); 
     } else { 
      int reqBig = goal/5; 
      int reqSamll = goal % 5; 

      if (reqBig <= big && reqSamll <= small) 
       return true; 
      else if (reqBig > big) { 
       int remainingLen = goal - (big * 5); 
       if (remainingLen <= small) 
        return true; 
       else 
        return false; 
      } else 
       return false; 
     } 
+1

Soluzione perfetta senza looping. Mi dà la soluzione di successo in tutti i miei casi di test. –

0

Inoltre si può provare questo:

public boolean makeBricks(int small, int big, int goal) { 
return goal - big * 5 <= small 
     && goal % 5 <= small; 
}