воскресенье, 11 марта 2012 г.

Short Code

Есть такая задачка про n ферзей: на доске надо n×n надо расставить n ферзей, так чтобы ни один не был под боем.
Задача: написать на Mathematica самый компактный и легко читаемый код, решающий задачу в лоб и максимально использующий встроенные функции. Эффективность не важна — важна лаконичность. Вот пример решения в две строчки:

boardTest[board_] := Length[board] == Length@Union[board, SameTest -> (Equal @@ Abs[#1 - #2] &)]

findQueens[n_] := Module[{boards = Transpose[{Range[n], #}] & /@ Permutations[Range[n]]}, Select[boards, boardTest]]

Код для визуализации может быть любым. Например, определяем символы шахматных фигур:

nQeens = 5;
qSmb[0] = Style[FromCharacterCode[9813], FontFamily -> "Tahoma", FontSize -> 18, FontColor -> White];
qSmb[1] = Style[FromCharacterCode[9819], FontFamily -> "Tahoma", FontSize -> 18, FontColor -> Black];

После этого рисуем картинку:
colorFill[n_] := If[OddQ[n], Black, White]
whiteBoard[n_] := Table[{EdgeForm[Black], colorFill[i + j + 1], Rectangle[{i, j},
{i + 1, j + 1}]}, {i, 0, n - 1}, {j, 0, n - 1}]

queensBoard[pos_] := Text[qSmb[Mod[Total[#], 2]], # - {.5, .5}] & /@ pos; 

Graphics[{whiteBoard[nQueens], queensBoard[#]}, ImageSize -> 100] &/@ findQueens[nQueens]