Cette semaine, c'est Kevin qui vous propose un #KataOfTheWeek : Formule de Luhn
Briefing du Kata : L'algorithme procède en trois étapes.
- L'algorithme multiplie par deux un chiffre sur deux, en commençant par l'avant dernier et en se déplaçant de droite à gauche. Si un chiffre qui est multiplié par deux est plus grand que neuf (comme c'est le cas par exemple pour 8 qui devient 16), alors il faut le ramener à un chiffre entre 1 et 9. Pour cela, il y a 2 manières de faire (pour un résultat identique) :
- Soit les chiffres composant le doublement sont additionnés (pour le chiffre 8: on obtient d'abord 16 en le multipliant par 2 puis 7 en sommant les chiffres composant le résultat : 1+6).
- Soit on lui soustrait 9 (pour le chiffre 8 : on obtient 16 en le multipliant par 2 puis 7 en soustrayant 9 au résultat).
- La somme de tous les chiffres obtenus est effectuée.
- Le résultat est divisé par 10. Si le reste de la division est égal à zéro, alors le nombre original est valide.
Saurez-vous résoudre le problème ?
Bon courage !
Et voici une solution proposée par l'auteur en JavaScript :
private static int getMinimumCodeSmellsGap(Map<Integer, Integer> enemies, List<Integer> weights) {
int halfNumberOfWeight = weights.stream().mapToInt(x -> x).sum() / 2;
// L(i, j) <-> if it is possible to have a side with weight j, considering
// only the developers in the first i couples of enemies
boolean[][] L = new boolean[enemies.size() + 1][halfNumberOfWeight + 1];
// initialize to false
for (int i = 0; i <= enemies.size(); i++) {
for (int j = 0; j <= halfNumberOfWeight; j++) {
L[i][j] = false;
}
}
// L(0, 0) = true
// L(0, j) = false for j != 0
L[0][0] = true;
// L(i+1, j) = L(i, j-w[k]) or L(i, j), where k is one of the developers
// concerned by the (i+1)-th enemy
int jWeight = 0; // How many enemies have been explored
for (Map.Entry<Integer, Integer> rivalry : enemies.entrySet()) {
for (int j = 0; j <= halfNumberOfWeight; j++) {
if (rivalry.getValue() != -1) {
if (j - weights.get(rivalry.getKey()) >= 0) {
L[jWeight + 1][j] = L[jWeight][j - weights.get(rivalry.getKey())]
|| L[jWeight + 1][j];
}
if (j - weights.get(rivalry.getValue()) >= 0) {
L[jWeight + 1][j] = L[jWeight][j - weights.get(rivalry.getValue())]
|| L[jWeight + 1][j];
}
} else {
if (j - weights.get(rivalry.getKey()) >= 0) {
L[jWeight + 1][j] = L[jWeight][j - weights.get(rivalry.getKey())]
|| L[jWeight][j];
} else
L[jWeight + 1][j] = L[jWeight][j];
}
}
jWeight++;
}
int maxNumberOfWeight = halfNumberOfWeight;
while ((maxNumberOfWeight >= 0) && (!L[enemies.size()][maxNumberOfWeight])) {
maxNumberOfWeight--;
}
return 2 * (halfNumberOfWeight - maxNumberOfWeight);
}
Votre équipe TakiVeille