%anpassbar: für jeden:
%Zeichen, die als Platzhalter dienen:
char('0',_).
char('.',_).
char(X,Num):-number_chars(Num,[X]).
%festcodierte Blockgrößen: board(Seitenlänge,Zeilen im Block,Spalten im Block)
board(6,2,3).
board(8,2,4).
board(9,3,3).
board(12,3,4).
board(16,4,4).
board(25,5,5).
board(X,_,_):- \+member(X,[6,8,9,12,16,25]),write('Unbekannte Sudoku Größe, bitte die Aufteilung des Feldes\n'),
write('in Blocks(wieviele Zeilen/Spalten im Block sind) vornehemen!\n'),
write('In: processfile.pl, ab Zeile 7'),fail.
%anpassbar: nicht für jeden ;-)
:-use_module(library(lists)).
processfile(File,Cells,Domain,Lines,Rows,Blocks):-open(File,read,Stream),
(reader(Stream,Cells)->close(Stream);close(Stream)),
check(Cells,Domain),lines(Cells,Lines),rows(Lines,Rows),
blocks(Cells,Blocks).
check(Cells,Size):-length(Cells,Len),Size is ceiling(sqrt(Len)),board(Size,_,_),!.
reader(Stream,[]):- peek_char(Stream,end_of_file),!.
reader(Stream,[Cell|Cells]):- get_char(Stream,Char),get_cell(Char,Cell),reader(Stream,Cells),!.
reader(Stream,T):-reader(Stream,T),!.
get_cell(Char,Cell):-
Char\='\n',char(Char,Cell).
/*Konstruiere Spalten
Parameter: +Input,-Result; Zeilenlänge muss =Zeilenanzahl */
rows(Lines,Res):-length(Lines,RowSize),rows(Lines,0,RowSize,Res),!.
rows(_,Size,Size,[]).
rows(Lines,Count,Size,[Row|Rows]):- NewCount is Count+1 ,
row(Lines,NewCount,Row),
rows(Lines,NewCount,Size,Rows).
row([],_,[]).
row([Line|Lines],Nth,[E|Row]):- nth1(Nth,Line,E),row(Lines,Nth,Row).
/*Konstruiere aus Raw Data Zeilen
Parameter: +Input,-List of Lines,Inputgröße sollte X*X sein, wobei X ganzzahlig ist*/
lines([],[],_).
lines(Data,[Line|Lines],Len):- line(Data,0,Len,Line,Tail),lines(Tail,Lines,Len).
lines(Data,Lines):- line_len(Data,LineLen),
lines(Data,Lines,LineLen),!.
line(Tail,Size,Size,[],Tail).
line([E|Data],Count,Size,[E|Line],Tail):-NewCount is Count+1,
line(Data,NewCount,Size,Line,Tail).
line_len(Cells,LineLen):-length(Cells,Len),LineLen is (ceiling(sqrt(Len))).
blocks(Cells,Blocks):-line_len(Cells,Len),board(Len,LnNum,RowNum),
TotalBlocks is ceiling((Len*Len)/(LnNum*RowNum)),
blocks(Cells,TotalBlocks,Len,Blocks),!.
blocks(_,0,_,[]).
blocks(Cells,Count,Len,[Block|Blocks]):-block(Cells,0,Count,Len,Block),NewCount is Count-1,
blocks(Cells,NewCount,Len,Blocks),!.
block([],_,_,_,[]).
block([Cell|Cells],Count,Num,Len,[Cell|Block]):- board(Len,LnNum,RowNum),
VBlocks is ceiling(Len/LnNum),
BlockNum is ceiling(floor(Count/Len+1)/LnNum)
+ (ceiling((mod(Count,Len)+1)/RowNum)*VBlocks)-VBlocks,
NewCount is Count+1,BlockNum is Num,
block(Cells,NewCount,Num,Len,Block),!.
block([_|Cells],Count,Num,Len,Block):- NewCount is Count+1,
block(Cells,NewCount,Num,Len,Block),!.