# Help me juice my avocados

In this challenge, I have a field of avocados which I'd like to juice as quickly and completely as possible. Can you write a program or function to help me work out how to juice all the avocados perfectly?

As input, you'll get the avocados as an mxm square grid, where m is an integer between 3 and 6. Each square contains exactly one avocado. Avocados have several stages of juiciness:

Stage 1: The avocado has not been juiced at all.
Stage 2: The avocado has been partially juiced.
Stage 3: The avocado has been completely juiced.
Stage 4: The avocado has exploded due to over-juicing.

When you use a juicing tool, the avocados in that juicing tool's area of effect move to the next stage. Exploding avocados have a lot of force and will destroy the entire avocado field, so make sure none of the avocados explode!

Here is an example of a grid of avocados. In these examples, I've used the coordinate 0,0 for the bottom-left corner, and the coordinate 2,2 for the top-right corner, although you can adjust the coordinate system to suit your language.

112
221
231


The goal is to make all the avocados perfectly juiced (i.e. stage 3). To achieve this you have three different juicing tools in your possession. Each juicing tool have a different area of effect, but they all increase the juiciness of affected avocados by 1.

Here are all the tools you have at your disposal. You use the juicers by specifying the first letter of the tool, then the coordinates which you want to juice. For example, to use the Slicer on square 5,2, you would output S 5,2.

Slicer: Juices the target coordinate and the avocado on either side.

112     112     112
221 --> XXX --> 332
231     231     231


Grater: Juices the target coordinate and the avocado above and below.

112     1X2     122
221 --> 2X1 --> 231 --> kaboom!
231     2X1     241


112     1X2     122
221 --> XXX --> 332
221     2X1     231


### Sample Inputs and Outputs

323
212
323

G 1,1
S 1,1

3312
3121
1213
2133

R 0,0
R 1,1
R 2,2
R 3,3

22322
22222
22222
33233
33333

G 0,3
G 1,3
G 2,2
G 3,3
G 4,3

222332
333221
222332
333222
222333
333222

S 1,5
S 1,3
S 1,1
S 4,5
S 4,3
S 4,1
G 5,4

• You don't seem to explicitly say this, but does the solution have to definitely take the fewest moves? Commented Mar 7, 2017 at 0:40
• This has ignored some constructive comments from the sandbox. Here's one: I suppose you should flexibly allow the user to choose their coordinate system (e.g., where the origin is, 0-indexed or 1-indexed). Commented Mar 7, 2017 at 1:20
• @Pavel thanks so much for not posting that as an answer or a question. Commented Mar 7, 2017 at 2:10
• I saw this question, and I was ready to downvote, VTC, and flag as spam. Instead, +1. Commented Mar 7, 2017 at 2:11
• @Pavel I was so tempted to make that the title... Commented Mar 7, 2017 at 2:35

## Mathematica — 350 bytes

Not a very short solution, but better than no solution at all, right?

t[x_]:=Flatten@Table[x/@{G,S,R},{i,n},{j,n}];""<>Cases[StringReplace[(First@Solve[(Table[G[i,j]+G[i-1,j]+G[i+1,j]+S[i,j]+S[i,j-1]+S[i,j+1]+R[i,j]+R[i-1,j]+R[i+1,j]+R[i,j-1]+R[i,j+1],{i,n=Length@#},{j,n}]/.(G|S|R)[___,0|n+1,___]->0)==3-#&&And@@t[#[i,j]>=0&],t[#[i,j]&],Integers])/.{(x_->m_):>ToString[m x]},{"["->" ","]"->"\n",", "->","}],Except@"0"]&


A more readable version (with extra spaces and indents and stuff):

t[x_] := Flatten@Table[x /@ {G, S, R}, {i, n}, {j, n}];
"" <> Cases[
StringReplace[(First@
Solve[(Table[
G[i, j] + G[i - 1, j] + G[i + 1, j] + S[i, j] +
S[i, j - 1] + S[i, j + 1] + R[i, j] + R[i - 1, j] +
R[i + 1, j] + R[i, j - 1] + R[i, j + 1], {i,
n = Length@#}, {j, n}] /. (G | S | R)[___,
0 | n + 1, ___] -> 0) == 3 - # &&
And @@ t[#[i, j] >= 0 &], t[#[i, j] &],
Integers]) /. {(x_ -> m_) :> ToString[m x]}, {"[" -> " ",
"]" -> "\n", ", " -> ","}], Except@"0"] &


Input is an array (e.g. {{3,2,3},{2,2,2},{3,2,3}}), output is a string (with a trailing newline — if this is unacceptable, enclose the function in StringDrop[...,-1] for an extra 15 bytes). I used the coordinate system that says (1,1) is the top-left corner, (n,n) is the bottom right (where n is the dimension of the matrix). Sometimes, if the solution requires doing the same operation multiple times, the output includes things like 3 G 2,2 (for "use the grater at (2,2) three times") — since you didn't say what to do in this case, I hope that's OK.

Explanation:

• Table[G[i,j]+G[i-1,j]+G[i+1,j]+S[i,j]+S[i,j-1]+S[i,j+1]+R[i,j]+R[i-1,j]+R[i+1,j]+R[i,j-1]+R[i,j+1],{i,n=Length@#},{j,n}] creates an array with the variables G[i,j] in each place that's affected by using the grater at (i,j), and similarly for S[i,j] and R[i,j]. These variables represent the number of times the tool is used at that position.
• .../.(G|S|R)[___,0|n+1,___]->0 removes the effects of using tools at positions outside the avocado field.
• ...==3-# compares this to the difference between the input and a field of perfectly juiced avocados.
• ...&&And@@t[#[i,j]>=0&] says the variables G[i,j], S[i,j], R[i,j] must be non-negative (you can't un-juice the avocados!), using the shorthand t[x_]:=Flatten@Table[x/@{G,S,R},{i,n},{j,n}].
• First@Solve[...,t[#[i,j]&],Integers] finds the first integer solution to our equations in terms of the variables G[i,j], S[i,j], R[i,j].
• /.{(x_->m_):>ToString[m x]} hides the variables that equal zero, while also putting the solution in a nice string form.
• StringReplace[...,{"["->" ","]"->"\n",", "->","}] turns strings like "2 G[1, 4]" into strings like "2 G 1,4", and adds a newline on the end.
• ""<>Cases[...,Except@"0"] removes all the leftover "0"s and joins all the strings together.

## Python3, 362 bytes

E=enumerate
M=[(0,1),(0,-1),(1,0),(-1,0)]
def f(a):
q=[({(x,y):u for x,r in E(a)for y,u in E(r)},[])]
while q:
m,j=q.pop(0)
if{3}=={*m.values()}:return j
for x,y in m:
for G,s in[('S',M[:2]),('G',M[2:]),('R',M)]:
if len(S:=[(x+X,y+Y)for X,Y in s+[(0,0)]if(C:=(x+X,y+Y))in m])==len(O:={C:m[C]+1for C in S if m[C]+1<=3}):q+=[({**m,**O},j+[(G,x,y)])]


Try it online!

The code above is a basic brute-force solution. However, it times out for the last test case, so below is an optimized solution (at the cost of 101 bytes) that solves all the test cases in a far more reasonable amount of time:

## Python3, 463 bytes

E=enumerate
M=[(0,1),(0,-1),(1,0),(-1,0)]
def f(a):
q=[({(x,y):u for x,r in E(a)for y,u in E(r)},[])]
while q:
m,j=q.pop(0)
if{3}=={*m.values()}:return j
D={'G':{},'S':{},'R':{}}
for x,y in m:
for G,s in[('S',M[:2]),('G',M[2:]),('R',M)]:
if len(S:=[(x+X,y+Y)for X,Y in s+[(0,0)]if(C:=(x+X,y+Y))in m])==len(O:={C:m[C]+1for C in S if m[C]+1<=3}):D[G][len(S)]=D[G].get(len(S),[])+[({**m,**O},j+[(G,x,y)])]
for i in D:
if D[i]:q+=D[i][max(D[i])]


Try it online!

Further optimizations could be added, including flood fills to check that a juicing process does not strand unjuiced avocados in a patch that can never be reached again.