Grime is based on Boolean grammars. The basic idea is to construct rectangular patterns from smaller components, and check whether they are found in the input matrix. So far, Grime only supports rectangular matches, and solves at least 1011 problems more or less elegantly.
EDIT3: Implemented size constraints, and added the Nether portals problem.
EDIT: options Options can nowalso be specified within the grammar, by inserting them before any line and adding a comma , (see below for examples).
- Any character escaped with
\matches any1x1rectangle containing that character. .matches any single character.$matches a1x1rectangle outside the character matrix._matches any rectangle of zero width or height.- The pre-defined character groups are
digit,uppercase,lowercase,alphabetic, alphanumeric, andsymbol. - New character classes can be defined by the syntax
[a-prt-w,d-gu]. The letters on the left are included, and those on the right are excluded, so this matches exactly the lettersabchijklmnoprtvw. If the left side is empty, it is taken to contain all characters. The comma can be omitted if the right side is empty. The characters[],-\must be escaped with\. - An unescaped uppercase letter is a nonterminal, and matches the expression it is assigned.
- If
PandQare expressions, thenPQis just their horizontal concatenation, andP/Qis their vertical concatenation, withPon top. P+is one or morePs aligned horizontally, andP/+is the same aligned vertically.- The Boolean operations are denoted
P|Q,P&QandP!. P?is shorthand forP|_,P*forP+|_, andP/*forP/+|_.P#matches any rectangle that contains a match ofP.P{a-b,c-d}, whereabcdare nonnegative integers, is a size constraint onP. IfPis a character class, then the expression matches anymxnrectangle containing only those characters, provided thatmis betweenaandbinclusive, andnis betweencanddinclusive. In other cases, the expression matches any rectangle that has the correct size and thatPalso matches. Ifaorcare omitted, they are taken to be0, and ifbordare omitted, they are infinite. If the hyphen betweenaandbis omitted, then we use the same number for both ends of the interval. If the entirec-dpart is omitted, both axes are constrained. To clarify,{-b}is equivalent to{0-b,0-b}, and{a-,c}is equivalent to{a-infinity,c-c}.
Faster matching. Currently, the interpreter does not take into account the fact that, for example,
.can only match1x1rectangles. Until it finds a match, it tries all rectangles of all sizes in order, instantly failing for each of them.Operations to constrain the size of expressions. Nether portals is very hard without it.
Rotation and reflection operations, for the word search and glider challenges.
Non-rectangular matches using contexts, which would be helpful in the Boggle board challenge. For example,
Pv(Q>R)meansPwith bottom context (Qwith right contextR). It would match the L-shaped patternsPPP PPP QQQRRRR QQQRRRR QQQRRRR
dd+/(dd+)/+d{2-}
This is simple: two or more rowsa rectangle of two or more digits of size at least 2x2.
A=[[,qQ]
B=AAAA
B/B/B/B{4}
I think I forgot to put this here earlier, even though it was veryThis is almost as simple even withoutas the character classes.
Anyway, herefirst one; now we have two nonterminals Aa more restricted size and B (basically just for shortening the grammar).
A matches any character that is not q or Q, which is achieved by a newly implementedcustom character class.
B is just four As in a row, and the toplevel nonterminal is four Bs on top of each other.
Nether Portals
.\X+./\X/+\.{2-22,3-22}\X/+/.\X+.
With the size restriction operator, this one's not that hard.
The middle part \.{2-22,3-22} matches any rectangle of . of the correct sizes, and then we just add columns of Xs on both sides, and tack rows of Xs with ignored ends on the top and bottom of that.
S=[#_]
B=SSS+
(\#\#|\#/\#|\_\_|\_/\_)#!&B/B/B/+&[#_]{3-}
I'm using S and B as auxiliary nonterminals to make the grammar shorter.
TheThe right-hand side B/B/B/+[#_]{3-} matches any 3x3 or larger rectangle of #s and _s, while the left-hand side guarantees that it does not contain two adjacent #s or _s.
Note the character class in the definition of S.
This is basically the same as above, except that we can match any non-empty rectangle, but need to use the e flag for entire input verification.