Code for the Advent of Code event
aoc
advent-of-code
1lower_bound = 'a'\byte!
2upper_bound = 'z'\byte!
3
4is_valid = (pw) ->
5 -- Check if it contains a forbidden character
6 return false if pw\match'i' or pw\match'o' or pw\match'l'
7
8 -- Check for two pairs of different letters
9 first_pair = pw\match '((%w)%2)'
10
11 return false unless first_pair
12
13 local second_pair
14
15 for pair in pw\gmatch '((%w)%2)'
16 if pair != first_pair
17 second_pair = pair
18 break
19
20 return false unless second_pair
21
22 -- Check for "increasing straight of at least three letters"
23 bytes = [char\byte! for char in pw\gmatch '%w']
24
25 for i = 1, #bytes - 2
26 if bytes[i + 1] - bytes[i] == 1 and bytes[i + 2] - bytes[i] == 2
27 return true
28
29 return false
30
31get_next = (pw) ->
32 index = #pw
33 wrapped = true
34
35 while wrapped
36 byte = pw\sub(index, index)\byte!
37 local new_char
38
39 if byte == upper_bound
40 wrapped = true
41 new_char = 'a'
42 else
43 wrapped = false
44 new_char = string.char byte + 1
45
46 pw = pw\sub(1, index - 1) .. new_char .. pw\sub(index + 1)
47 index -= 1
48
49 pw
50
51{ :is_valid, :get_next }