#JavaScript (ES6) 372361 (387376-15) 372
(SurelyMaybe can still be golfed a little more)
F=(g,n,l=g.length,i=w=Math.sqrt(l))=>(
s=h='',[for(c of g)(s-=-c,h+=--i?c:(i=w,c+':'))],s/=n,g=ho=s=h='',
R=(g,p,k,j=l/n,t=s/n,v=0,h=String.fromCharCode(97+k))=>
(
t-=g[p],
!(t<0)&&
(
g=[...g],g[p]=h,
S=f=>g.some((c,p)=>c<':'&&f(p)),
--j?S(p=>(g[p+1]==h|g[p-1]==h|g[p+w+1]==h|g[p-w-1]==h)&&(?v=R(g,p,k,j,t)):0)
:t?0:k?S(p=>v=R(g,p,k-1)):v=g
),v
),
)=>([for(c of g)(s-=-c,h+=--i?c:(i=w,c+':'))],h=R(hg=h,-1,n,1),o='',
h)?h.map((c,p)=>o+=c!=':'?g[p]+c:'')&&o:'None'
)
F=(g,n)=>
{
var l = g.length, // string size, group size is l/n
w = Math.sqrt(l), // width of grid
s,i,h,o;
// Build a new string in h, adding rows delimiters that will act as boundary markers
// At the same time calculate the total sum of all digits
h='', // Init string
s = 0, // Init sum
i = w, // Init running counter for delimiters
[for(c of g)(
s -= -c, // compute sum using minus to avoid string concatenation
h += --i ? c : (i=w, c+':') // add current char + delimiter when needed
)];
// Recursive search
// Paramaters:
// g : current grid array, during search used digits are replaced with group letters
// p : current position
// k : current group id (start at n, decreaseing)
// j : current group size, start at l/n decreasing, at 0 goto next group id
// t : current group sum value, start at s/n decreasing
var R=(g,p,k,j,t)=>
{
var v = 0, // intiinit value to return is 0
h = String.fromCharCode(97+k); // group letter from group if
t-=g[p]; // subtract current digit
if (t<0) // exceed the sum value, return 0 to stop search and backtrak
return 0;
g=[...g]; // build a new array from orginal parameter
g[p] = h; // mark current position
// Utility function to scan grid array
// call worker function f only for digit elemenselements
// skipping group markers, row delimieters and out of grid values (that are undefined)
// Using .some will return ealry if f returns truthy
var S=f=>g.some((c,p)=>c<':'&&f(p));
if (--j) // decrement current group size, if 0 then group completed
{ // if not 0
// Scan grid to find cellecells adiacent to current grouogroup and call R for each
S( p => {
if (g[p+1]==h|g[p-1]==h|g[p+w+1]==h|g[p-w-1]==h) // check if adiacent to a mark valued h
{
return v=R(g,p,k,j,t) // set v value and returnreturns it
}
})
// here v could be 0 or a full grid
}
else
{
// special case: at first call, t is be NaN because p -1 (outside the grid)
// tpto start a full grid serach
if (t) // check if current reached 0
return 0; // if not, return 0 to stop search and backtrak
if (k) // check if current group completed
{
// if not at last group, recursive call to R to check next group
S( p => {
// exec the call for each valid cell still in grid
// params j and t start again at init values
return v=R(g,p,k-1,l/n,s/n) // set value v and returnreturns it
})
// here v could be 0 or a full grid
}
else
{
return g; // all groups checked, search OK, return grid with all groups marked
}
}
return v
};
g = h; // set g = h, so g has the row boundaries and all the digits
h=R(h,-1,n,1); // first call with position -1 to and group size 1 to start a full girdgrid search
if (h) // h is the grid with group marked if search ok, else h is 0
{
o = ''; // init output string
// build output string merging the group marks in h and the original digits in g
h.map( (c,p) => o += c>':' ? g[p]+c: '') // cut delimiter ':'
return o;
}
return 'None';
}