-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
142 lines (122 loc) · 3.78 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
L'entrée représente l'ancien mot de passe du Père Noël qui a expiré.
De nouvelles contraintes ont été mises en place pour avoir un mot de passe "robuste":
- Le mot de passe doit contenir au moins une suite croissante de trois lettres.
- Les lettres "i", "o" et "l" sont interdites.
- Le mot de passe doit contenir au moins 2 paires de lettres qui ne se chevauchent pas.
Pour la partie 1, il faut retrouver le mot de passe suivant en l'incrémentant et qu'il respecte les nouvelles
contraintes.
L'incrémentation du mot de passe revient à le considérer comme des nombres : aay --> aaz --> aba --> etc.
Pour la partie 2, le nouveau mot de passe a encore expiré, il faut encore le trouver.
*/
#include <algorithm>
#include <cmath>
#include <fstream>
#include <iostream>
#include <string>
#include <Utils/MeasureExecutionTime.cpp>
using namespace std;
const int BASE = 26;
const int PASSWORD_SIZE = 8;
string input;
int parseInput()
{
MEASURE_FUNCTION_EXECUTION_TIME
string filename = "input.txt";
ifstream file(filename);
if (!file.is_open())
{
cerr << "Erreur : impossible d'ouvrir le fichier " << filename;
return 1;
}
getline(file, input);
file.close();
return 0;
}
// Convertit le mot de passe en nombre décimal en considérant que celui-ci est en base 26.
long long passwordToNumber(const string &s)
{
long long n = 0;
for (int i = 0; i < PASSWORD_SIZE; i++)
{
int charValue = s[i] - 'a';
n += charValue * pow(BASE, PASSWORD_SIZE - i - 1);
}
return n;
}
// Convertit un nombre décimal en mot de passe en considérant que le mot de passe est en base 26.
// Le mot de passe résultant est ajusté à la taille PASSWORD_SIZE.
string numberToPassword(long long n)
{
string s = "";
while (n != 0)
{
int remainder = n % BASE;
n = (n - remainder) / BASE;
s += 'a' + (remainder);
}
while (s.size() != PASSWORD_SIZE)
{
s += 'a';
}
reverse(s.begin(), s.end());
return s;
}
// Vérifie la validité d'un mot de passe selon les critères spécifiés.
bool passwordIsValid(string &s)
{
bool valid = false;
int countPair = 0;
int lastCharInPair = -2;
// Parcours du mot de passe
for (int i = 0; i < PASSWORD_SIZE; i++)
{
// Vérification de la présence d'une suite croissante de trois lettres
if (i < PASSWORD_SIZE - 2)
{
if (s[i] + 2 == s[i + 1] + 1 && s[i + 2] == s[i] + 2)
{
valid = true;
}
}
// Vérification de la présence d'au moins 2 paires de lettres qui ne se chevauchent pas
if (i < PASSWORD_SIZE - 1 && lastCharInPair != i - 1 && s[i] == s[i + 1])
{
countPair++;
lastCharInPair = i;
}
// Vérification de l'interdiction des lettres 'i', 'l' et 'o'
if (s[i] == 'i' || s[i] == 'l' || s[i] == 'o')
{
return false;
}
}
// Le mot de passe est valide s'il satisfait toutes les conditions
return valid && countPair >= 2;
}
// Génère un nouveau mot de passe conforme à partir d'un mot de passe initial non valide.
string process(string s)
{
MEASURE_FUNCTION_EXECUTION_TIME
long long value = passwordToNumber(s);
// Tant que le mot de passe n'est pas valide, on incrémente la valeur et on génère un nouveau mot de passe
while (!passwordIsValid(s))
{
value++;
s = numberToPassword(value);
}
return s;
}
int main()
{
if (parseInput() == 1)
{
return 1;
}
string part1 = process(input);
string s = numberToPassword(passwordToNumber(part1) + 1);
string part2 = process(s);
cout << "\nPart1: " << part1 << '\n';
cout << "Part2: " << part2 << '\n';
return 0;
}