C++. Пентамино. Решатель головоломки

Пентамино. Интересная конечно головоломка. На днях столкнулся с подобной задачкой. Есть 9 фигурок, каждая из которых представлена во входном файлике, причем своеобразной формы. Ниже парочка изображений этих фигурок






 Также после нахождения решений в виде таких же рисунков, нужно каждую из фигурок как-то отделить визуально, обычно в классическом пентамино для этого квадратные фигуры разукрашивают в разные цвета. Но в нашем случае фигурки необычные :) На выходе должен быть выходной файл с приведенными решениями пентамино! Как быть? С чего начать? Какую выбрать тактику? На первый взгляд непонятно с какого угла подойти к вопросу. Но для себя определил пару критериев, которых попробую придерживаться.

1. Необходимо фигуры перевести в цвет. Номер фигуры определяет цвет в виде числа(числовой цвет, числовая идентификация)


2. Каждая фигура определяется матрично (2ух мерно) размера m*n. Матричный каркас
 
3. У фигуры есть форма, а значит должна быть возможность симметричных поворотов определенных для  данной фигуры. Объектно-ориентированный подход
 
4. Метод сортировки - обход ладьей по часовой стрелке около первой фигуры (ближайшие ячейки, точки сопряжения) с переопределением матричного каркаса (подгонка)
5. Решением для двух фигур считается такая сортировка, при которой площадь сопряжения поверхностей двух фигур максимальна

Вперед и с песней :)

PHP5. Быстрая обработка csv файлов

Задача.
Есть основной файл и файлы шаблонов, причем все имеют расширение csv. Как можно быстро обработать файл на основе шаблонов?

В php5 есть специализированные функции str_getcsv(), fgetcsv() и fputcsv(), которые адаптированы для работы с такого рода файлами. Но можно обойтись и без этих функций. Во время такого рода манипуляций часто сталкивался с ошибками, которые необходимо учитывать - извлекаемые значения из массивов порой содержали неожиданные знаки табуляции, или строка состояла из символов в перемешку с NULL-символами... Поэтому обращение к шаблонам, разобранных на соответствующие массивы, сопровождались казусами, например - использование неопределенных массивов. Отсюда вывод - нужно использовать trim() как фильтр от таких "неожиданностей" и isset() - как подобие отлова исключительной ситуации с попыткой извлечения значения из массива по неопределенному индексу. В остальном все сработало неплохо :)

Пример (download).

<?php ## manipulation with csv-files (base of device tags)
/***********open source and target csv-files*****************************************
// 13010000.csv
$f = fopen("c:\\php\\scripts\\in\\devices.csv", "rb");
// pattern.csv
$pattern = fopen("c:\\php\\scripts\\templates\\pattern.csv", "rb");
// BTDevices_Adresses.csv
$btdevices = fopen("c:\\php\\scripts\\templates\\BTDevices_Adresses.csv", "rb");
// output.csv
$output = fopen("c:\\php\\scripts\\out\\output.csv", "wb");
//***********transfer data from file to string and clean all NULL************************
function transfer($file) {
 // read file to $hash from $buffer. Take max length of Double Integer
 while(($buffer = fgets($file, 64536)) !== FALSE) {
  $hash[] = $buffer;
 }
 // sort $hash and clean from '\0'
 for($k = 0; $k < count($hash); $k++) {
  // cleaned massive
  $strbox[$k] = " ";
  for($i = 0, $j = 0; $j < strlen($hash[$k]); $j++) {
   if($hash[$k][$j] == "\0") {
    continue;
   }
   else {
    $strbox[$k][$i] = $hash[$k][$j];
    $i++;
   }
  } 
 }

 // Clean buffer
 $buffer = NULL;

 return $strbox;
}
//**********transfer all files****************************************************
// device.csv
$box_f = transfer($f);
// pattern.csv
$box_patt = transfer($pattern);
// BTDevices_Adresses.csv
$box_btd = transfer($btdevices);
// create accessories arraies
//********$template_array  ********Array[:TEMPLATES][$i] = Signal Alias   ***********
// parse string into an array
for($i = 0; $i < count($box_patt); $i++) {
 $temp[] = explode(",", $box_patt[$i]);
}
// create Array[:TEMPLATES][$i] = Signal Alias
$template_array = Array();
for($col = 0; $col < count($temp[0]); $col++) {
 $template_name = NULL;
 $template_name = $temp[0][$col];
 for($str = 1; $str < count($temp); $str++) {
  $tem = NULL;
  $tem = $temp[$str][$col];
  $template_array[$template_name][] = $tem;
 }
}
//************************************************  $btd  ***********************   Array[:Tagname] = ShortDesc   *****************
// create Array[:Tagname] = ShortDesc
// ...немного схалтурил, так как нужно искать по индексам или иначе.
// Сие допустимо, так как структура файла - исходника нам известна
// parse string into an array. $i = 0 - header string have to miss
for($i = 1; $i < count($box_btd); $i++) {
 list(, $shortdesc,,,,,,, $tagname) = explode(",", $box_btd[$i]);
 $btd[$tagname] = $shortdesc;
 $shortdesc = NULL;
 $tagname = NULL;
}
//**********$engunits  ****************Array[:Tagname] = EngUnits   *****************
// create Array[:Tagname] = EngUnits
// ...немного схалтурил, так как нужно искать по индексам или иначе.
// Сие допустимо, так как структура файла - исходника нам известна
// parse string into an array. $i = 0 - header string have to miss
for($i = 1; $i < count($box_btd); $i++) {
 list(,,,, $engunit,,,, $tagname) = explode(",", $box_btd[$i]);
 $engunits[$tagname] = $engunit;
 $engunit = NULL;
 $tagname = NULL;
}
// create main array ($arr is base on input file)
//**********************$arr ****************************************************
// parse string into an array
for($i = 0; $i < count($box_f); $i++) {
 $arr[] = explode(",", $box_f[$i]);
}
print_r($arr);
//***********************processing $arr and rewrite needly values*********************
// for change values of $arr in loop we get array by ref
$count_row = 0;
foreach($arr as &$row) {
 foreach($row as $elem => $value) {

  // ':TEMPLATE'
  if((strpos($value, ':TEMPLATE')) !== false) {
  
   // reset array
   $signal_aliases = Array();
   // find template name of device
   list(,$templ) = explode("=", $value);
   $trimmed_templ = trim($templ);
   // defined signal aliases of find template
   // $template_array is array that content link :TEMPLATE -> Array(Template signal aliases)
   if(isset($template_array[$trimmed_templ])) {
    $signal_aliases = $template_array[$trimmed_templ];
   }  
  }
 
  // ':Tagname'
  if((strpos($value, ':Tagname')) !== false) {
  
   // initialization
   $index = 1;
   $stop = true;
   // reset array $tags
   $tags = Array();
   //
   while($stop) {
    $tag = trim($arr[$count_row + $index][$elem]);
    if($tag !== "") {
     $tags[] = $tag;
     $index++;
    }
    if($tag == "") {
     $stop = false;
    }
   }
  }
 
  // 'ShortDesc'
  if((strpos($value, 'ShortDesc')) !== false) {
   // initialization
   $position = $count_row + 1;
   $indexx = 0;
   while($indexx < count($tags)) {
    $tag_item = trim($tags[$indexx]);
    if(isset($btd[$tag_item])) {
     $short_desc = trim($btd[$tag_item]);
     $arr[$position + $indexx][$elem] = $short_desc;
    }
    $indexx++;
   }  
  }
 
  // 'Signal_alias.Desc'
  if((strpos($value, '.Desc')) !== false) {
 
   // find index field 'ShortDesc'
   list($item,) = explode(".", $value);
   $item = trim($item);
   //
   if(in_array($item, $signal_aliases)) {
  
    $pos = $count_row + 1;
    $indexxx = 0;
   
    while($indexxx < count($tags)) {
     $new_tag_item = trim($tags[$indexxx]);
     if(isset($btd[$new_tag_item])) {     
      $new_item = ". ".str_replace("_", " ", $item).".";
      $item_for_push = $btd[$new_tag_item].$new_item;
      $arr[$pos + $indexxx][$elem] = $item_for_push;
     }
     $indexxx++;
    }
   }  
  
  }
 }
 $count_row++;
}
//**************transfer from massive to string and write to output csv-file*****************
// for catch mini bug 'ая;'. It`s may be control symbols
$str = ltrim(implode(",", $arr[0]), "ая;");
fputs($output, $str);
// build output file
for($i = 1; $i < sizeof($arr); $i++) {
 $str = implode(",", $arr[$i]);
 fputs($output, $str);
}
//***********************close handles of source and target csv-files*********************
 
fclose($f);
fclose($pattern);
fclose($btdevices);
fclose($output);
?>

.htaccess. Правило перенаправления ссылок

Задача. Ссылки в адресной строке не должны быть вида http://mysite.ru/index.php?param=target, а должны выглядеть так http://mysite.ru/target.

Для реализации можно воспользоваться следующим способом. Необходимо создать .htaccess, где нужно прописать следующее правило, правило перенаправления. Соответственно, для ограничения поля влияния .htaccess, его нужно разместить в той директории, где нужно распространить сие правило (поддиректории также будут подподать в это поле влияния).

Я сделал так:

RewriteEngine on
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ http://mysite.ru/index.php?param=$1

php5. Debuging...

Иногда, для отлова своей же ошибки (!), приходится тратить много времени, казалось бы все хорошо, но почему-то все идет не так как мы того хотели бы. Что же мешает быстродействию отлова (debug)? Лень. Например, для того, чтобы понять, что же происходит, в определенных кусках кода проставляем команду вывода содержимого какой-нибудь переменной, бывает, нужно проставить таких меток более десятка, вот здесь и нужно проявить усидчивость, нужно их по-человечески прописать, чтобы при дальнейшем анализе было понятно, что идет не так!

MySQL Command Line Client. Not launch on WinOS

Если не запускается MySQL Command Line Client, нужно немного подкрутить в my.ini в блоке [mysql]: добавить строчечку вида character-sets-dir="C:/mysql5/share/charsets/". По-сути, здесь прописан путь до кодировок (используются правые "слэши")

PHP5. Обращение к переменным родительского класса. Два способа

Как можно получить доступ дочернего класса к переменным родительского класса?

Способ первый: необходимо несколько условий. 1 - переменные в родительском классе должны быть объявлены как protected, 2 - при объявлении дочернего конструктора, необходимо также объявить родительский конструктор, 3 - соответственно, обращаемся к переменной родительского класса как ко внутренней переменной $this->variable;

Способ второй: 1 - переменные в родительском классе могут быть закрытыми (private), 2 - необходимо создать методы, позволяющие получить доступ к переменным из дочернего класса, 3 - при объявлении дочернего конструктора, необходимо также объявить родительский конструктор, 4 - соответственно, обращаемся к переменной родительского класса через соответствующие методы parrent::getVariable();

Ниже приведен пример использования двух спобов обращения к переменным родительского класса.

<?php ##Обращение к переменным родительского класса. Два способа
// Родительский класс
class Item {
 // Для первого способа необходим уровень конфиденциальности - protected
 protected $name;
 private $code;
 // Консруктор родительского класса
 function __construct( $name = "Item", $code = 0 ) {
  $this->name = $name;
  $this->code = $code;
 }
 // Для второго способа создаем метод
 function getName() {
  return $this->name;
 }
 // Также создаем метод для второго метода
 function getCode() {
  return $this->code;
 }
}
// Дочерний класс
class PriceItem extends Item {
 private $temp;
 // Конструктор родительского класса
 function __construct( $name, $code, $temp = "temp" ) {
  // Обязательное объявление родительского конструктора
  parent::__construct( $name, $code );
  // Обращаемся к переменным родительского класса вторым способом - parent:getName() и getCode()
  $this->temp = "temp = ".$temp." name = ".parent::getName()." code = ".parent::getCode();
 }
 // Для вывода результата обращения к переменным родительского класса первым способом
 function getParentName() {
  return $this->name;
 }
 // Для вывода результата обращения к переменным родительского класса вторым способом
 function getIt() {
  return $this->temp;
 }
}
// Инстанцируем объект
$Item = new PriceItem(Name, 1616);
// Выводим результаты
print $Item->getIt();
print "<br />";
print $Item->getParentName();
?>