562,"NULL" 586, 585, 564, 565,"hbEdATkPa\f=K>ybkKYh9P`[W4EJ[jxTwz4Dgjk[8hmsoL=^lTQwbQ=KaDoX]fDA0o=P[>Vd8sNSHviD[ydbS>eiISmL;^Q94;nI50ku]Eca_9RNsV636D_7BlN^;Osry0EPwAaGbYLVE;=qz?QsbFDm=1R82oEgC7teBrc9gZ_kqxD3b>U4DcVt^Uyzztt^qn]Slijt" 593, 594, 595, 597, 598, 596, 800, 801, 566,0 567,"," 588,"." 589, 568,"""" 570, 571, 569,0 592,0 599,1000 560,0 561,0 590,0 637,0 577,0 578,0 579,0 580,0 581,0 582,0 572,70 #****GENERATED STATEMENTS START**** #****GENERATED STATEMENTS FINISH**** cubename = 'Sudoku'; rows = 'sudoku rows'; columns = 'sudoku columns'; grid = 'grid'; group = 'Finance'; #difficulty level: 20 to 23 empty pairs = easy (i.e. 40 to 46 empty cells) pairs = 20; CubeDestroy(cubename); DimensionDestroy(rows); DimensionDestroy(columns); DimensionDestroy(grid); If(DimensionExists(grid) = 0); DimensionCreate(grid); DimensionCreate(rows); DimensionCreate(columns); CubeCreate(cubename, rows, columns, grid); #CubeCreate('}ElementSecurity_'|cubename, rows, columns, grid); CubeCreate('}CellSecurity_'|cubename, rows, columns, grid, '}Groups'); DimensionElementInsert('grid','','input','N'); DimensionElementInsert('grid','','solution','N'); #rows labeled 1 to 9 c = 49; while(c < 58); DimensionElementInsert(rows, '', char(c),'N'); c = c + 1; end; #columns labeled 1 to 9 c = 49; while(c < 58); DimensionElementInsert(columns, '', char(c),'N'); c = c + 1; end; #create default view #ViewCreate(cubename,'Default'); endif; #override any cell locks in place CubeLockOverride(1); #clean up #view created will contain all elements by default, perfect to totally wipe out a cube ViewCreate(cubename,'All'); ViewZeroOut(cubename,'All'); ViewDestroy(cubename,'All'); CubeLockOverride(0); ViewCreate(cubename,'Default'); ViewRowDimensionSet(cubename, 'Default', rows, 1); ViewColumnDimensionSet(cubename, 'Default', columns, 1); ViewTitleDimensionSet(cubename, 'Default', grid); #force creation of }ElementAttributes_ rows cube #so that we can set the elements format later on AttrInsert(rows,'','Format','S'); 573,3 #****GENERATED STATEMENTS START**** #****GENERATED STATEMENTS FINISH**** 574,3 #****GENERATED STATEMENTS START**** #****GENERATED STATEMENTS FINISH**** 575,148 #****GENERATED STATEMENTS START**** #****GENERATED STATEMENTS FINISH**** #disable logging for that cube, it is about to get a lot of heat CubeSetLogChanges(cubename,0); #must be executed in Epilog because elements have been freshly inserted in Prolog magic = 123456789; #set all rows format to display as integers i = 1; while(i <= 9); ATTRPUTS('b:0 F|0|','sudoku rows',NumberToString(i),'Format'); i = i + 1; end; #allow one preset group to use the sudoku cube CellPutS('WRITE','}CubeSecurity', cubename, group); CellPutS('READ','}DimensionSecurity', rows, group); CellPutS('READ','}DimensionSecurity', columns, group); CellPutS('READ','}DimensionSecurity', grid, group); #forbid that group to read the solution grid ElementSecurityPut('None', grid, 'solution', group); #init grid, put all possibilities 123456789 in all cells r = 1; while(r <= 9); c = 1; while(c <= 9); CellPutN(magic, cubename, NumberToString(r), NumberToString(c),'input'); c = c + 1; end; r = r + 1; end; #generate grid r = 1; while(r <= 9); c = 1; while(c <= 9); candidate = 0; while(candidate = 0); candidate = round(8*rand)+1; remains = CellGetN(cubename, NumberToString(r), NumberToString(c),'input'); If( StringToNumber(SUBST(NumberToStringEx(remains,'000000000','',''),candidate,1)) <1); candidate = 0; Endif; end; remains = remains - candidate * 10 ^ (9 - candidate); CellPutN(remains,cubename, NumberToString(r), NumberToString(c),'input'); CellPutN(candidate,cubename, NumberToString(r), NumberToString(c),'solution'); #check that candidate validates the 3 sudoku constraints duplicate = -3; #unique on row x = 1; while(x <= 9); If( CellGetN(cubename, NumberToString(r), NumberToString(x),'solution') = candidate ); duplicate = duplicate + 1; Endif; x = x + 1; end; #unique on column x = 1; while(x <= 9); If( CellGetN(cubename, NumberToString(x), NumberToString(c),'solution') = candidate ); duplicate = duplicate + 1; Endif; x = x + 1; end; #unique in block x = 1; while( x <= 3); y = 1; while( y <= 3); If( CellGetN(cubename, NumberToString(3*int((r-1)/3)+x), NumberToString(3*int((c-1)/3)+y),'solution') = candidate ); duplicate = duplicate + 1; Endif; y = y + 1; end; x = x + 1; end; #show how the grid gets populated #asciioutput(logit,NumberToString(r),NumberToString(c),NumberToString(candidate),NumberToString(remains),NumberToString(duplicate)); #valid candidate If(duplicate = 0); #remove candidate from remaining possibilities #move down the grid c = c + 1; Else; #must try other candidate #all candidates exhausted? If(remains = 0); #backtrack the whole row #reinitialiase row x = 1; while(x <= 9); CellPutN(0,cubename, NumberToString(r), NumberToString(x),'solution'); CellPutN(magic,cubename, NumberToString(r), NumberToString(x),'input'); x = x + 1; end; #return to 1st cell on the row c = 1; Endif; Endif; end; r = r + 1; end; #copy solution to input #use relative proportional spread? r = 1; while(r <= 9); c = 1; while(c <= 9); CellPutN(CellGetN(cubename, NumberToString(r), NumberToString(c),'solution') , cubename, NumberToString(r), NumberToString(c),'input'); #lock elements to read only by default CellPutS('READ','}CellSecurity_'|cubename,NumberToString(r),NumberToString(c),'input',group); c = c + 1; end; r = r + 1; end; #randomly empty symmetrical pairs to create the puzzle from the solution (20 to 23 pairs = easy) while( pairs > 0); r = round(8*rand)+1; c = round(8*rand)+1; If(CellGetN(cubename, NumberToString(r), NumberToString(c),'input') <> 0); CellPutN(0,cubename, NumberToString(r), NumberToString(c),'input'); CellPutN(0,cubename, NumberToString(10 - r), NumberToString(10 - c),'input'); #unlock empty cells CellPutS('WRITE','}CellSecurity_'|cubename,NumberToString(r),NumberToString(c),'input',group); CellPutS('WRITE','}CellSecurity_'|cubename,NumberToString(10 - r),NumberToString(10 - c),'input',group); pairs = pairs - 1; Endif; end; #careful in some cases securityrefresh might have an impact on server, taking lots of time to refresh SecurityRefresh; #force security refresh on cube by reloading it CubeUnload(cubename); 576,CubeAction=1511€DataAction=1503€CubeLogChanges=0€ 638,1 804,0 900, 901, 902, 903, 906, 907, 908, 904,0 905,0 909,0 910,0 911, 912, 913, 914, 915, 916,