| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- === PT 1 ===
- ABC
- D@E
- FGH
- the condition 'A' indicates that there is a free space to the top left of a paper roll
- First attempt, but this actually checks for 3 or more free spaces, it should be 5
- A(B(C|D|E|F|G|H)
- C(D|E|F|G|H)
- D(E|F|G|H)
- E(F|G|H)
- F(G|H)
- GH)
- B(C(D|E|F|G|H)
- D(E|F|G|H)
- E(F|G|H)
- F(G|H)
- GH)
- C(D(E|F|G|H)
- E(F|G|H)
- F(G|H)
- GH)
- D(E(F|G|H)
- F(G|H)
- GH)
- E(F|G|H)
- GH)
- FGH
- Final pattern I settled on for checking if there are 5 or more empty spaces
- (A(B(C(D(E|F|G|H)
- E(F|G|H)
- F(G|H)|GH)
- D(E(F|G|H)
- F(G|H)|GH)
- E(F(G|H)|GH)
- FGH)
- C(D(E(F|G|H)
- F(G|H)|GH)
- E(F(G|H)|GH)
- FGH)
- D(E(F(G|H)|GH)
- FGH)
- EFGH)
- B(C(D(E(F|G|H)
- F(G|H)|GH)
- E(F(G|H)|GH)
- FGH)
- D(E(F(G|H)|GH)
- FGH)
- EFGH)
- C(D(E(F(G|H)|GH)
- FGH)
- EFGH)
- DEFGH)@
- Then I used these as the regex'es to check the conditions for the test input
- I found that for the large input I can only use lookaheads, no engine seems to support lookbehinds that far back
- I added the special cases for the 3 possible combinations of F, G and H since you can check those with a much shorter regex together
- New lines we are simply counting as characters, they are empty spaces after all, and then we are treating the input as a continous string.
- Looking 11 characters ahead then ends up looking at the character below, so we can use this to check all directions
- @:
- (?=(.|\n){12}@)(.|\n)
- F|G|H:
- (?=(.|\n){22,24}[^@])
- FGH:
- (?=(.|\n){22}[^@]{3})
- F(G|H)|GH:
- ->FH|FG|GH
- (?=(.|\n){22}[^@])(?=(.|\n){24}[^@])|(?=(.|\n){22,23}[^@]{2})
- A
- (?=[^@])
- B
- (?=(.|\n)[^@])
- C
- (?=(.|\n){2}[^@])
- D
- (?=(.|\n){11}[^@])
- E
- (?=(.|\n){13}[^@])
- F
- (?=(.|\n){22}[^@])
- G
- (?=(.|\n){23}[^@])
- H
- (?=(.|\n){24}[^@])
- \n:
- |
- space:
- (nothing)
- This constructs the following regex for the test input:
- ((?=[^@])((?=(.|\n)[^@])((?=(.|\n){2}[^@])((?=(.|\n){11}[^@])((?=(.|\n){13}[^@])|(?=(.|\n){22,24}[^@]))|(?=(.|\n){13}[^@])((?=(.|\n){22,24}[^@]))|(?=(.|\n){22}[^@])(?=(.|\n){24}[^@])|(?=(.|\n){22,23}[^@]{2}))|(?=(.|\n){11}[^@])((?=(.|\n){13}[^@])((?=(.|\n){22,24}[^@]))|(?=(.|\n){22}[^@])(?=(.|\n){24}[^@])|(?=(.|\n){22,23}[^@]{2}))|(?=(.|\n){13}[^@])((?=(.|\n){22}[^@])(?=(.|\n){24}[^@])|(?=(.|\n){22,23}[^@]{2}))|(?=(.|\n){22}[^@]{3}))|(?=(.|\n){2}[^@])((?=(.|\n){11}[^@])((?=(.|\n){13}[^@])((?=(.|\n){22,24}[^@]))|(?=(.|\n){22}[^@])(?=(.|\n){24}[^@])|(?=(.|\n){22,23}[^@]{2}))|(?=(.|\n){13}[^@])((?=(.|\n){22}[^@])(?=(.|\n){24}[^@])|(?=(.|\n){22,23}[^@]{2}))|(?=(.|\n){22}[^@]{3}))|(?=(.|\n){11}[^@])((?=(.|\n){13}[^@])((?=(.|\n){22}[^@])(?=(.|\n){24}[^@])|(?=(.|\n){22,23}[^@]{2}))|(?=(.|\n){22}[^@]{3}))|(?=(.|\n){13}[^@])(?=(.|\n){22}[^@]{3}))|(?=(.|\n)[^@])((?=(.|\n){2}[^@])((?=(.|\n){11}[^@])((?=(.|\n){13}[^@])((?=(.|\n){22,24}[^@]))|(?=(.|\n){22}[^@])(?=(.|\n){24}[^@])|(?=(.|\n){22,23}[^@]{2}))|(?=(.|\n){13}[^@])((?=(.|\n){22}[^@])(?=(.|\n){24}[^@])|(?=(.|\n){22,23}[^@]{2}))|(?=(.|\n){22}[^@]{3}))|(?=(.|\n){11}[^@])((?=(.|\n){13}[^@])((?=(.|\n){22}[^@])(?=(.|\n){24}[^@])|(?=(.|\n){22,23}[^@]{2}))|(?=(.|\n){22}[^@]{3}))|(?=(.|\n){13}[^@])(?=(.|\n){22}[^@]{3}))|(?=(.|\n){2}[^@])((?=(.|\n){11}[^@])((?=(.|\n){13}[^@])((?=(.|\n){22}[^@])(?=(.|\n){24}[^@])|(?=(.|\n){22,23}[^@]{2}))|(?=(.|\n){22}[^@]{3}))|(?=(.|\n){13}[^@])(?=(.|\n){22}[^@]{3}))|(?=(.|\n){11}[^@])(?=(.|\n){13}[^@])(?=(.|\n){22}[^@]{3}))(?=(.|\n){12}@)(.|\n)
- Replacing the numbers with the correct wrapping numbers for the real input gives this regex:
- (?:(?=[^@])(?:(?=(?:.|\n)[^@])(?:(?=(?:.|\n){2}[^@])(?:(?=(?:.|\n){141}[^@])(?:(?=(?:.|\n){143}[^@])|(?=(?:.|\n){282,284}[^@]))|(?=(?:.|\n){143}[^@])(?:(?=(?:.|\n){282,284}[^@]))|(?=(?:.|\n){282}[^@])(?=(?:.|\n){284}[^@])|(?=(?:.|\n){282,283}[^@]{2}))|(?=(?:.|\n){141}[^@])(?:(?=(?:.|\n){143}[^@])(?:(?=(?:.|\n){282,284}[^@]))|(?=(?:.|\n){282}[^@])(?=(?:.|\n){284}[^@])|(?=(?:.|\n){282,283}[^@]{2}))|(?=(?:.|\n){143}[^@])(?:(?=(?:.|\n){282}[^@])(?=(?:.|\n){284}[^@])|(?=(?:.|\n){282,283}[^@]{2}))|(?=(?:.|\n){282}[^@]{3}))|(?=(?:.|\n){2}[^@])(?:(?=(?:.|\n){141}[^@])(?:(?=(?:.|\n){143}[^@])(?:(?=(?:.|\n){282,284}[^@]))|(?=(?:.|\n){282}[^@])(?=(?:.|\n){284}[^@])|(?=(?:.|\n){282,283}[^@]{2}))|(?=(?:.|\n){143}[^@])(?:(?=(?:.|\n){282}[^@])(?=(?:.|\n){284}[^@])|(?=(?:.|\n){282,283}[^@]{2}))|(?=(?:.|\n){282}[^@]{3}))|(?=(?:.|\n){141}[^@])(?:(?=(?:.|\n){143}[^@])(?:(?=(?:.|\n){282}[^@])(?=(?:.|\n){284}[^@])|(?=(?:.|\n){282,283}[^@]{2}))|(?=(?:.|\n){282}[^@]{3}))|(?=(?:.|\n){143}[^@])(?=(?:.|\n){282}[^@]{3}))|(?=(?:.|\n)[^@])(?:(?=(?:.|\n){2}[^@])(?:(?=(?:.|\n){141}[^@])(?:(?=(?:.|\n){143}[^@])(?:(?=(?:.|\n){282,284}[^@]))|(?=(?:.|\n){282}[^@])(?=(?:.|\n){284}[^@])|(?=(?:.|\n){282,283}[^@]{2}))|(?=(?:.|\n){143}[^@])(?:(?=(?:.|\n){282}[^@])(?=(?:.|\n){284}[^@])|(?=(?:.|\n){282,283}[^@]{2}))|(?=(?:.|\n){282}[^@]{3}))|(?=(?:.|\n){141}[^@])(?:(?=(?:.|\n){143}[^@])(?:(?=(?:.|\n){282}[^@])(?=(?:.|\n){284}[^@])|(?=(?:.|\n){282,283}[^@]{2}))|(?=(?:.|\n){282}[^@]{3}))|(?=(?:.|\n){143}[^@])(?=(?:.|\n){282}[^@]{3}))|(?=(?:.|\n){2}[^@])(?:(?=(?:.|\n){141}[^@])(?:(?=(?:.|\n){143}[^@])(?:(?=(?:.|\n){282}[^@])(?=(?:.|\n){284}[^@])|(?=(?:.|\n){282,283}[^@]{2}))|(?=(?:.|\n){282}[^@]{3}))|(?=(?:.|\n){143}[^@])(?=(?:.|\n){282}[^@]{3}))|(?=(?:.|\n){141}[^@])(?=(?:.|\n){143}[^@])(?=(?:.|\n){282}[^@]{3}))(?=(?:.|\n){142}@)(?:.|\n)
- === PT 2 ===
- I decided to solve this using repeated application of a regex replacement. This required some rewriting of the pattern so that the caret would actually be consuming the paper roll that we would want to replace.
- The pattern for PT 1 consumes the character at position A. Luckily repeated application of the regex means we do not need to find all matches in a single pass like we did in PT 1, and we can rewrite the pattern as follows.
- We mostly had to add the consumption of both empty and occupied spaces in each step of the logic tree before the paper roll we are checking. So this means A, B, C and D. Fortunately this also means that A, B, C all use the same pattern of '.', with D being replaced with a wrap around + '.'. For checking the inverse of A, B, C and D we can simply check for '@'.
- This results in the following pattern:
- (.(.(.(D.(E|F|G|H)
- D@(E(F|G|H)
- F(G|H)|GH))
- @(D.(E(F|G|H)
- F(G|H)|GH)
- D@(E(F(G|H)|GH)
- FGH)))
- @(.(D.(E(F|G|H)
- F(G|H)|GH)
- D@(E(F(G|H)|GH)
- FGH))
- @(D.(E(F(G|H)|GH)
- FGH)
- D@EFGH)))
- @(.(.(D.(E(F|G|H)
- F(G|H)|GH)
- D@(E(F(G|H)|GH)
- FGH))
- @(D.(E(F(G|H)|GH)
- FGH)
- D@EFGH))
- @(.(D.(E(F(G|H)|GH)
- FGH)
- D@EFGH)
- @D.EFGH)))@
- We then replace '.' with [^@] because we also need to match new lines, and for the rest it is much of the same, except that the caret when performing the lookaheads is actually right before the center paper roll, meaning we can make some patterns shorter again.
- .:
- [^@]
- F|G|H:
- (?=(.|\n){10,12}[^@])
- FGH:
- (?=(.|\n){10}[^@]{3})
- F(G|H)|GH:
- ->FH|FG|GH
- (?=(.|\n){10}[^@])(?=(.|\n){12}[^@])|(?=(.|\n){10,11}[^@]{2})
- D
- (.|\n){8}
- E
- (?=@[^@])
- \n:
- |
- space:
- (nothing)
- This results in the following regex'es for the test and real input. They are actually shorter!
- ([^@]([^@]([^@]((.|\n){8}[^@]((?=@[^@])|(?=(.|\n){10,12}[^@]))|(.|\n){8}@((?=@[^@])((?=(.|\n){10,12}[^@]))|(?=(.|\n){10}[^@])(?=(.|\n){12}[^@])|(?=(.|\n){10,11}[^@]{2})))|@((.|\n){8}[^@]((?=@[^@])((?=(.|\n){10,12}[^@]))|(?=(.|\n){10}[^@])(?=(.|\n){12}[^@])|(?=(.|\n){10,11}[^@]{2}))|(.|\n){8}@((?=@[^@])((?=(.|\n){10}[^@])(?=(.|\n){12}[^@])|(?=(.|\n){10,11}[^@]{2}))|(?=(.|\n){10}[^@]{3}))))|@([^@]((.|\n){8}[^@]((?=@[^@])((?=(.|\n){10,12}[^@]))|(?=(.|\n){10}[^@])(?=(.|\n){12}[^@])|(?=(.|\n){10,11}[^@]{2}))|(.|\n){8}@((?=@[^@])((?=(.|\n){10}[^@])(?=(.|\n){12}[^@])|(?=(.|\n){10,11}[^@]{2}))|(?=(.|\n){10}[^@]{3})))|@((.|\n){8}[^@]((?=@[^@])((?=(.|\n){10}[^@])(?=(.|\n){12}[^@])|(?=(.|\n){10,11}[^@]{2}))|(?=(.|\n){10}[^@]{3}))|(.|\n){8}@(?=@[^@])(?=(.|\n){10}[^@]{3}))))|@([^@]([^@]((.|\n){8}[^@]((?=@[^@])((?=(.|\n){10,12}[^@]))|(?=(.|\n){10}[^@])(?=(.|\n){12}[^@])|(?=(.|\n){10,11}[^@]{2}))|(.|\n){8}@((?=@[^@])((?=(.|\n){10}[^@])(?=(.|\n){12}[^@])|(?=(.|\n){10,11}[^@]{2}))|(?=(.|\n){10}[^@]{3})))|@((.|\n){8}[^@]((?=@[^@])((?=(.|\n){10}[^@])(?=(.|\n){12}[^@])|(?=(.|\n){10,11}[^@]{2}))|(?=(.|\n){10}[^@]{3}))|(.|\n){8}@(?=@[^@])(?=(.|\n){10}[^@]{3})))|@([^@]((.|\n){8}[^@]((?=@[^@])((?=(.|\n){10}[^@])(?=(.|\n){12}[^@])|(?=(.|\n){10,11}[^@]{2}))|(?=(.|\n){10}[^@]{3}))|(.|\n){8}@(?=@[^@])(?=(.|\n){10}[^@]{3}))|@(.|\n){8}[^@](?=@[^@])(?=(.|\n){10}[^@]{3}))))@
- ([^@]([^@]([^@]((.|\n){138}[^@]((?=@[^@])|(?=(.|\n){140,142}[^@]))|(.|\n){138}@((?=@[^@])((?=(.|\n){140,142}[^@]))|(?=(.|\n){140}[^@])(?=(.|\n){142}[^@])|(?=(.|\n){140,141}[^@]{2})))|@((.|\n){138}[^@]((?=@[^@])((?=(.|\n){140,142}[^@]))|(?=(.|\n){140}[^@])(?=(.|\n){142}[^@])|(?=(.|\n){140,141}[^@]{2}))|(.|\n){138}@((?=@[^@])((?=(.|\n){140}[^@])(?=(.|\n){142}[^@])|(?=(.|\n){140,141}[^@]{2}))|(?=(.|\n){140}[^@]{3}))))|@([^@]((.|\n){138}[^@]((?=@[^@])((?=(.|\n){140,142}[^@]))|(?=(.|\n){140}[^@])(?=(.|\n){142}[^@])|(?=(.|\n){140,141}[^@]{2}))|(.|\n){138}@((?=@[^@])((?=(.|\n){140}[^@])(?=(.|\n){142}[^@])|(?=(.|\n){140,141}[^@]{2}))|(?=(.|\n){140}[^@]{3})))|@((.|\n){138}[^@]((?=@[^@])((?=(.|\n){140}[^@])(?=(.|\n){142}[^@])|(?=(.|\n){140,141}[^@]{2}))|(?=(.|\n){140}[^@]{3}))|(.|\n){138}@(?=@[^@])(?=(.|\n){140}[^@]{3}))))|@([^@]([^@]((.|\n){138}[^@]((?=@[^@])((?=(.|\n){140,142}[^@]))|(?=(.|\n){140}[^@])(?=(.|\n){142}[^@])|(?=(.|\n){140,141}[^@]{2}))|(.|\n){138}@((?=@[^@])((?=(.|\n){140}[^@])(?=(.|\n){142}[^@])|(?=(.|\n){140,141}[^@]{2}))|(?=(.|\n){140}[^@]{3})))|@((.|\n){138}[^@]((?=@[^@])((?=(.|\n){140}[^@])(?=(.|\n){142}[^@])|(?=(.|\n){140,141}[^@]{2}))|(?=(.|\n){140}[^@]{3}))|(.|\n){138}@(?=@[^@])(?=(.|\n){140}[^@]{3})))|@([^@]((.|\n){138}[^@]((?=@[^@])((?=(.|\n){140}[^@])(?=(.|\n){142}[^@])|(?=(.|\n){140,141}[^@]{2}))|(?=(.|\n){140}[^@]{3}))|(.|\n){138}@(?=@[^@])(?=(.|\n){140}[^@]{3}))|@(.|\n){138}[^@](?=@[^@])(?=(.|\n){140}[^@]{3}))))@
- Then using intellij* to replace this regex with '$1.' to remove a paper roll if there is enough space I got my results (after debugging found some bracket errors):
- total: 71
- left: 28
- removed: 43
- total: 12851
- left: 4105
- removed: 8746
- *: intellij was the first editor that could parse and run this regex, and allowed me to quickly mash the "replace all" button until no matches were left
|