The River
Table of Contents
Ce document est disponible sur ma page personnelle
1 Exercice CodinGame: THE RIVER I. par ng201
1.1 Approche de l'exercice
La comprehension de cet exercice ainsi que sa résolution n'a pas été difficile pour moi. En effet, je savais déjà comment récupérer uniquement le certains chiffre d'un nombre en utilisant le modulo de 10. Ainsi, l'unique difficulté de l'exercice était donc de déterminer à quel moment, deux rivières de nombres se rejoignent.
1.2 Résolution de l'exercice
1.2.1 Concaténation
- Solution personnelle
La première tâche à laquelle je me suis attelé a été de créer une fonction prenant en argument un nombre renvoyant la concaténation de tous les chiffres de de ce nombre. J'ai donc procèdé en ajoutant le modulo 10 du nombre dans une variable puis en divisant le nombre par 10 et ce jusqu'à ce que le nombre soit nul.
Code de la fonction correspondante:
1: int cat(int input) 2: { 3: int cat = 0; 4: do{ 5: cat += input % 10; 6: input /= 10; 7: }while(input > 0); 8: return cat; 9: }
- Solutions remarquable
Ce fonctionnement par appel de fonction a aussi été utilisé par Alain-Delpuch. Cependant la fonction qu'il propose est bien plus courte puisqu'il utilise une fonction qui s'exécute de fçon récursive en utilisant le même système de modulo et de division par 10 que j'ai utilisé.
Code de la fonction de Alain-Delpuch
1: int 2: s(int n) { 3: return n ? n % 10 + s( n / 10 ) : 0 ; 4: }
1.2.2 Fonction principale
- Solution personnelle
En se qui concerne la fonction principale, j'ajoute la concaténation du plus petit des deux nombres à ce même nombre et ce jusqu'a ce que les deux nombres soit égaux. Puis, j'affiche l'un des deux nombres, qui à ce stade, sont égaux.
Code de la fonction principale
1: int main() 2: { 3: int nb1, nb2 = 0; 4: scanf("%d", &nb1); 5: scanf("%d", &nb2); 6: 7: while(nb1 != nb2){ 8: if(nb1 < nb2){ 9: nb1 += cat(nb1); 10: } 11: else{ 12: nb2 += cat(nb2); 13: } 14: } 15: 16: printf("%d\n", nb1); 17: 18: return 0; 19: }
- Autres solutions
En ce qui concerne la fonction principale des autres utilisateurs ayant utilisé un appel de fonction, elle est assez similaire à mon programme principal. En revanche d'autres n'ont utilisé qu'une seule fonction qui calcul donc le nombre suivant de la rivière dans cette même fonction ce qui peut créer un manque de visibilité dans la lecture du programme. Notons également que plutôt que de changer la valeur du plus petit des deux nombre, xerneas02 propose de toujours modifier la valeur de la première variable et inverse donc la valeur des deux variables si la première variable est supérieur à la deuxième.
Code de la fonction principale de xerneas02
1: int main() 2: { 3: int r_1, r_2, i, somme; 4: scanf("%d %d", &r_1, &r_2); 5: while(r_1 != r_2){ 6: if(r_1 > r_2){ 7: r_1 += r_2; 8: r_2 = r_1 - r_2; 9: r_1 -= r_2; 10: } 11: somme = 0; 12: 13: for(i = 10; i <= r_1*10 ; i=i*10) 14: somme += (int)((r_1%i)/(i/10)); 15: 16: r_1 += somme; 17: } 18: printf("%d", r_1); 19: return 0; 20: }
1.3 Code complet
1: #include <stdio.h> 2: 3: int cat(int input) 4: { 5: int cat = 0; 6: do{ 7: cat += input % 10; 8: input /= 10; 9: }while(input > 0); 10: return cat; 11: } 12: 13: int main() 14: { 15: int nb1, nb2 = 0; 16: scanf("%d", &nb1); 17: scanf("%d", &nb2); 18: 19: while(nb1 != nb2){ 20: if(nb1 < nb2){ 21: nb1 += cat(nb1); 22: } 23: else{ 24: nb2 += cat(nb2); 25: } 26: } 27: 28: printf("%d\n", nb1); 29: 30: return 0; 31: }
2 Exercice CodinGame: THE RIVER II. par ng201
2.1 Approche de l'exercice
La compréhension de cette exercice a été d'autant plus simple qu'il s'appuis sur le même principe que l'exercice THE RIVER I. J'ai donc pu réutiliser la même fonction de concaténation que dans THE RIVER I pour déterminer s'il existe un nombre qui par ajout de sa propre concaténation est égal à un autre.
2.2 Résolution de l'exercice
2.2.1 Concaténation (même fonction que pour THE RIVER I)
2.2.2 Fonction principale
- Solution personnelle
En se qui concerne la fonction principale, je regarde s'il existe un nombre a entre le nombre nb donné par l'utilisateur et 0 tel que la somme de a et de sa concaténation est égale à nb.
Code de la fonction principale
1: int main() 2: { 3: int nb; 4: bool search = true; 5: scanf("%d", &nb); 6: for(int i = nb - 1; i > 0 && search; i--){ 7: if(cat(nb - i) + nb - i == nb){ 8: search = false; 9: } 10: } 11: printf(search ? "NO" : "YES"); 12: 13: return 0; 14: }
Notons que cette fonction pourrait être optimisé en déterminant une seuil tel que tous les nombres inférieurs à ce seuil ai un nombre suivant dans leur rivière strictement inférieur au nombre donné par l'utilisateur. Ce seuil remplacerait donc la limite de 0 que j'ai défini dans la boucle for et qui éviterait des vérification inutiles.
- Autres solutions
drFailer propose de définir un seuil inférieur de 0.75 fois le nombre donné par l'utilisateur, ce qui permet de réduire le nombre de vérifications éffectué mais qui je pense peut encore être affiné.
Code de la fonction principale de de drFailer
1: int main() 2: { 3: int nb; 4: bool search = true; 5: scanf("%d", &nb); 6: for(int i = nb - 1; i > 0 && search; i--){ 7: if(cat(nb - i) + nb - i == nb){ 8: search = false; 9: } 10: } 11: printf(search ? "NO" : "YES"); 12: 13: return 0; 14: }
2.3 Code complet
1: #include <stdlib.h> 2: #include <stdio.h> 3: #include <stdbool.h> 4: 5: int cat(int input) 6: { 7: int cat = 0; 8: do{ 9: cat += input % 10; 10: input /= 10; 11: }while(input > 0); 12: return cat; 13: } 14: 15: int main() 16: { 17: int nb; 18: bool search = true; 19: scanf("%d", &nb); 20: for(int i = nb - 1; i > 0 && search; i--){ 21: if(cat(nb - i) + nb - i == nb){ 22: search = false; 23: } 24: } 25: printf(search ? "NO" : "YES"); 26: 27: return 0; 28: }