Skip to content

Commit 962c24d

Browse files
2015 --> Day19
1 parent 32ee165 commit 962c24d

File tree

3 files changed

+227
-1
lines changed

3 files changed

+227
-1
lines changed

2015/Day19/input.txt

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
Al => ThF
2+
Al => ThRnFAr
3+
B => BCa
4+
B => TiB
5+
B => TiRnFAr
6+
Ca => CaCa
7+
Ca => PB
8+
Ca => PRnFAr
9+
Ca => SiRnFYFAr
10+
Ca => SiRnMgAr
11+
Ca => SiTh
12+
F => CaF
13+
F => PMg
14+
F => SiAl
15+
H => CRnAlAr
16+
H => CRnFYFYFAr
17+
H => CRnFYMgAr
18+
H => CRnMgYFAr
19+
H => HCa
20+
H => NRnFYFAr
21+
H => NRnMgAr
22+
H => NTh
23+
H => OB
24+
H => ORnFAr
25+
Mg => BF
26+
Mg => TiMg
27+
N => CRnFAr
28+
N => HSi
29+
O => CRnFYFAr
30+
O => CRnMgAr
31+
O => HP
32+
O => NRnFAr
33+
O => OTi
34+
P => CaP
35+
P => PTi
36+
P => SiRnFAr
37+
Si => CaSi
38+
Th => ThCa
39+
Ti => BP
40+
Ti => TiTi
41+
e => HF
42+
e => NAl
43+
e => OMg
44+
45+
CRnCaCaCaSiRnBPTiMgArSiRnSiRnMgArSiRnCaFArTiTiBSiThFYCaFArCaCaSiThCaPBSiThSiThCaCaPTiRnPBSiThRnFArArCaCaSiThCaSiThSiRnMgArCaPTiBPRnFArSiThCaSiRnFArBCaSiRnCaPRnFArPMgYCaFArCaPTiTiTiBPBSiThCaPTiBPBSiRnFArBPBSiRnCaFArBPRnSiRnFArRnSiRnBFArCaFArCaCaCaSiThSiThCaCaPBPTiTiRnFArCaPTiBSiAlArPBCaCaCaCaCaSiRnMgArCaSiThFArThCaSiThCaSiRnCaFYCaSiRnFYFArFArCaSiRnFYFArCaSiRnBPMgArSiThPRnFArCaSiRnFArTiRnSiRnFYFArCaSiRnBFArCaSiRnTiMgArSiThCaSiThCaFArPRnFArSiRnFArTiTiTiTiBCaCaSiRnCaCaFYFArSiThCaPTiBPTiBCaSiThSiRnMgArCaF

2015/Day19/main.cpp

+181
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/*
2+
L'entrée représente une grammaire, un peu comme dans l'algorithme CYK (Cocke-Younger-Kasami)
3+
À la fin, une chaîne de caractères est fournie sur laquelle nous allons travailler.
4+
5+
Dans la Partie 1, l'objectif est de compter le nombre de combinaisons possibles sur la chaîne d'entrée en fonction de
6+
la grammaire.
7+
Exemple avec la chaîne "HOH":
8+
9+
La grammaire de l'entrée:
10+
e => H
11+
e => O
12+
H => HO
13+
H => OH
14+
O => HH
15+
16+
Il y a 5 combinaisons possibles après une modification de la chaîne d'origine, dont 4 uniques :
17+
HOOH (H => HO sur le premier H)
18+
HOHO (H => HO sur le second H)
19+
OHOH (H => OH sur le premier H)
20+
HOOH (H => OH sur le second H)
21+
HHHH (O => HH sur le premier O)
22+
23+
Dans la Partie 2, l'objectif est de compter le nombre d'étapes nécessaires en partant de la chaîne "e" pour arriver à
24+
la chaîne d'entrée.
25+
26+
Par exemple, en reprenant la grammaire d'entrée ci-dessus, il nous faudrait 3 étapes en partant de "e" pour arriver à
27+
"HOH":
28+
[e => O] => O
29+
[O => HH] => HH
30+
[H => HO] => HOH
31+
*/
32+
#include <algorithm>
33+
#include <fstream>
34+
#include <iostream>
35+
#include <map>
36+
#include <set>
37+
#include <string>
38+
#include <vector>
39+
40+
#include <Utils/MeasureExecutionTime.cpp>
41+
#include <Utils/SplitString.cpp>
42+
43+
using namespace std;
44+
45+
map<string, vector<string>> mapReplacements;
46+
string input;
47+
48+
int parseInput()
49+
{
50+
MEASURE_FUNCTION_EXECUTION_TIME
51+
string filename = "input.txt";
52+
ifstream file(filename);
53+
54+
if (!file.is_open())
55+
{
56+
cerr << "Erreur : impossible d'ouvrir le fichier " << filename;
57+
return 1;
58+
}
59+
string line;
60+
while (getline(file, line))
61+
{
62+
if (line == "")
63+
{
64+
getline(file, input);
65+
continue;
66+
}
67+
vector<string> splitedInput = splitString(line, " => ");
68+
mapReplacements[splitedInput[0]].push_back(splitedInput[1]);
69+
}
70+
file.close();
71+
return 0;
72+
}
73+
74+
int processP1()
75+
{
76+
MEASURE_FUNCTION_EXECUTION_TIME
77+
78+
// Utiliser un ensemble pour stocker les chaînes uniques résultant des remplacements
79+
set<string> uniqueString;
80+
81+
// Parcourir les remplacements dans la mapReplacements
82+
for (auto &it : mapReplacements)
83+
{
84+
// Trouver la première occurrence de la clé dans la chaîne d'entrée
85+
for (string s : it.second)
86+
{
87+
// Trouver la première occurrence de la clé dans la chaîne d'entrée
88+
size_t pos = input.find(it.first);
89+
90+
// Effectuer les remplacements dans la chaîne d'entrée
91+
while (pos != string::npos)
92+
{
93+
string newString = input.substr(0, pos) + s + input.substr(pos + it.first.size());
94+
95+
// Insérer la nouvelle chaîne dans l'ensemble pour garantir l'unicité
96+
uniqueString.insert(newString);
97+
98+
// Trouver la prochaine occurrence de la clé dans la chaîne d'entrée
99+
pos = input.find(it.first, pos + 1);
100+
}
101+
}
102+
}
103+
104+
return uniqueString.size();
105+
}
106+
vector<string> alreadySee;
107+
108+
// Effectue un parcours récursif pour atteindre la molécule cible "e" à partir de la molécule actuelle.
109+
// Le paramètre 'count' représente le nombre d'étapes effectuées.
110+
int backtrack(string molecule, int count)
111+
{
112+
// Vérifier si la molécule a déjà été traitée pour éviter une boucle infinie
113+
if (find(alreadySee.begin(), alreadySee.end(), molecule) != alreadySee.end())
114+
{
115+
return -1;
116+
}
117+
// Vérifier si la molécule est la cible finale "e"
118+
if (molecule == "e")
119+
{
120+
return count;
121+
}
122+
123+
// Ajouter la molécule actuelle à la liste des molécules déjà vues
124+
alreadySee.push_back(molecule);
125+
126+
// Parcourir les remplacements possibles dans la mapReplacements
127+
for (auto &it : mapReplacements)
128+
{
129+
// Parcourir les chaînes de remplacement associées à la clé actuelle
130+
for (string s : it.second)
131+
{
132+
// Trouver la première occurrence de la chaîne de remplacement dans la molécule
133+
size_t pos = molecule.find(s);
134+
135+
// Effectuer les remplacements dans la molécule
136+
while (pos != string::npos)
137+
{
138+
string newString = molecule.substr(0, pos) + it.first + molecule.substr(pos + s.size());
139+
140+
// Récursivement appeler backtrack avec la nouvelle molécule et le compte mis à jour
141+
int value = backtrack(newString, count + 1);
142+
143+
// Si une solution est trouvée, la retourner
144+
if (value != -1)
145+
{
146+
return value;
147+
}
148+
149+
// Trouver la prochaine occurrence de la chaîne de remplacement dans la molécule
150+
pos = molecule.find(s, pos + 1);
151+
}
152+
}
153+
}
154+
155+
// Aucune solution trouvée, retourner -1
156+
return -1;
157+
}
158+
159+
int processP2()
160+
{
161+
MEASURE_FUNCTION_EXECUTION_TIME
162+
163+
// Appeler la fonction backtrack pour effectuer le parcours récursif
164+
return backtrack(input, 0);
165+
}
166+
167+
int main()
168+
{
169+
if (parseInput() == 1)
170+
{
171+
return 1;
172+
}
173+
174+
int part1 = processP1();
175+
int part2 = processP2();
176+
177+
cout << "\nPart1: " << part1 << '\n';
178+
cout << "Part2: " << part2 << '\n';
179+
180+
return 0;
181+
}

readme.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ All the exercices I solved on [Advent of code](https://adventofcode.com/)
6868
| [Day 16: Aunt Sue](https://adventofcode.com/2015/day/16) | :heavy_check_mark: Completed | [C++](https://github.com/SlicedPotatoes/Advent_of_code/blob/main/2015/Day16/main.cpp) |
6969
| [Day 17: No Such Thing as Too Much](https://adventofcode.com/2015/day/17) | :heavy_check_mark: Completed | [C++](https://github.com/SlicedPotatoes/Advent_of_code/blob/main/2015/Day17/main.cpp) |
7070
| [Day 18: Like a GIF For Your Yard](https://adventofcode.com/2015/day/18) | :heavy_check_mark: Completed | [C++](https://github.com/SlicedPotatoes/Advent_of_code/blob/main/2015/Day18/main.cpp) |
71-
| [Day 19: Medicine for Rudolph](https://adventofcode.com/2015/day/19) | :x: Not Completed | [C++]() |
71+
| [Day 19: Medicine for Rudolph](https://adventofcode.com/2015/day/19) | :heavy_check_mark: Completed | [C++](https://github.com/SlicedPotatoes/Advent_of_code/blob/main/2015/Day19/main.cpp) |
7272
| [Day 20: Infinite Elves and Infinite Houses](https://adventofcode.com/2015/day/20) | :x: Not Completed | [C++]() |
7373
| [Day 21: RPG Simulator 20XX](https://adventofcode.com/2015/day/21) | :x: Not Completed | [C++]() |
7474
| [Day 22: Wizard Simulator 20XX](https://adventofcode.com/2015/day/22) | :x: Not Completed | [C++]() |

0 commit comments

Comments
 (0)