aoc-2015/jour11/jour11.lua

125 lines
3.9 KiB
Lua
Raw Normal View History

2021-03-24 17:14:50 +00:00
-- Calcule le mot suivant
-- @param mot string : le mot à incrémenter
-- @return string : le mot incrémenté
-- exemple : abcz -> abda
2021-03-24 16:41:37 +00:00
local function suivant(mot)
local len = mot:len()
local ret = mot:sub(1, len - 1)
if mot:sub(len, len) == 'z' then
2021-03-24 17:14:50 +00:00
-- utilisé si abzz par ex. sappelle récursivment pour trouver acaa
ret = suivant(ret) .. 'a'
2021-03-24 16:41:37 +00:00
else
2021-03-24 17:14:50 +00:00
ret = ret .. string.char(mot:sub(len, len):byte() + 1)
2021-03-24 16:41:37 +00:00
end
return ret
end
2021-03-24 17:14:50 +00:00
-- Détecte sil existe une suite de 3 lettres consécutives
-- @param mot string : mot où il faut vérifier sil y a une suite
-- @return bool : true sil y a une suite, false sinon
-- exemple : uabcie -> true; abecud -> false
2021-03-24 16:41:37 +00:00
local function suite(mot)
local ret = false
local pred = nil
local i = 1
local c = nil
2021-03-24 17:14:50 +00:00
-- lorsquon trouve la première lettre, on met ret à true et pred à c
-- si on trouve la troisième lettre, on met pred à nil.
-- si ret est à true et pred à nil, on a trouvé une suite de 3 lettres
while not (ret and pred == nil) and i <= #mot do
2021-03-24 16:41:37 +00:00
c = mot:sub(i, i)
2021-03-24 17:14:50 +00:00
-- première itération
2021-03-24 16:41:37 +00:00
if pred == nil then
pred = c
elseif pred ~= nil then
2021-03-24 17:14:50 +00:00
if pred:byte() == (c:byte() - 1) then
-- si le pred est bien prédecesseur de c, on vérifie ret
-- pour modifier ensuite pred en conséquence (nil si fin)
2021-03-24 16:41:37 +00:00
if ret then
pred = nil
else
pred = c
ret = true
end
else
ret = false
pred = c
end
end
i = i + 1
end
2021-03-24 17:14:50 +00:00
return (ret and pred == nil) and true or false
2021-03-24 16:41:37 +00:00
end
2021-03-24 17:14:50 +00:00
-- Cherche le nombre de double dans un mot
-- @param mot string : mot à vérifier
-- @return int : le nombre de double présent
-- exemple : aaabc -> 1; aacaauxxii -> 4
2021-03-24 16:41:37 +00:00
local function double(mot)
local ret = 0
local pred = nil
for c in mot:gmatch(".") do
2021-03-24 17:14:50 +00:00
-- pred ~= obligatoire car on ne peut pas comparer un char avec un nil
2021-03-24 16:41:37 +00:00
if pred ~= nil and pred == c then
ret = ret + 1
pred = nil
else
pred = c
end
end
return ret
end
2021-03-24 17:14:50 +00:00
-- incrémente le mot selon le mauvais caractère
-- @param mot string : le mot à modifier
-- @param char string : le caractère à trouver et incrémenter
-- @return string : le mot modifié ou non
-- exemple : avec char = i
-- abcidd -> abcjaa; abcde -> abcde
2021-03-24 16:41:37 +00:00
local function badChar(mot, char)
local ret = mot
local tmp = mot:find(char)
if tmp ~= nil then
if tmp == 1 then
2021-03-24 17:14:50 +00:00
ret = string.char(ret:sub(tmp, tmp):byte() + 1) .. string.rep('a', #ret - tmp)
2021-03-24 16:41:37 +00:00
elseif tmp == ret:len() then
2021-03-24 17:14:50 +00:00
ret = ret:sub(1, tmp-1) .. string.char(ret:sub(tmp, tmp):byte() + 1)
2021-03-24 16:41:37 +00:00
else
2021-03-24 17:14:50 +00:00
ret = ret:sub(1, tmp - 1) .. string.char(ret:sub(tmp, tmp):byte() + 1) .. string.rep('a', #ret - tmp)
2021-03-24 16:41:37 +00:00
end
end
return ret
end
2021-03-24 17:19:49 +00:00
-- Trouve le mot de passe correspondant aux critères suivants :
-- * une suite de 3 lettres consécutives au moins
-- * pas de lettre i, l ou o
-- * 2 pairs de lettres distinctes (aaa ne compte que pour une paire)
-- @param mot string : le mot à vérifier et modifier
-- @return string : le nouveau mot de passe
local function findPass(mot)
local fin = false
local ret = mot
while not fin do
ret = badChar(ret, 'i')
ret = badChar(ret, 'l')
ret = badChar(ret, 'o')
if suite(ret) and double(ret) >= 2 then
fin = true
else
ret = suivant(ret)
end
2021-03-24 16:41:37 +00:00
end
2021-03-24 17:19:49 +00:00
return ret
2021-03-24 16:41:37 +00:00
end
2021-03-24 17:19:49 +00:00
myInput = "cqjxjnds"
print("Traitement première partie…")
myInput = findPass(myInput)
print("Le nouveau mot de passe est : " .. myInput)
2021-03-24 17:21:22 +00:00
print("Traitement deuxième partie…")
myInput = findPass(suivant(myInput))
print("Le nouveau mot de passe est : " .. myInput)