자바 스크립트 (ES6) 361 (376-15) 372
(아마도 골프는 조금 더 할 수 있습니다)
함수로서 첫 번째 매개 변수는 자릿수 문자열이고 두 번째 매개 변수는 그룹 수입니다.
처음 발견 된 솔루션에서 멈추는 순진한 재귀 검색입니다 (20 보너스 없음).
더 큰 입력에서 성능을 확인하려면 테스트 케이스가 더 필요합니다.
F=(g,n,l=g.length,i=w=Math.sqrt(l),o=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(g=h,-1,n,1))?h.map((c,p)=>o+=c!=':'?g[p]+c:'')&&o:'None'
Ungolfed & Explained
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, // init value to return is 0
h = String.fromCharCode(97+k); // group letter from group
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 elements
// 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 cells adiacent to current group 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 returns 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)
// to 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 returns 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 grid 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';
}
FireFox / FireBug 콘솔에서 테스트
F("156790809",3)
산출 1c5c6b7a9c0b8a0a9b
F("156790819",3)
산출 None
6b
아닌 격리 된 것을 의미한다고 생각 합니다0b
.