Еще в прошлом веке университетский товарищ посоветовал мне почитать книгу о том, как программировать игры. Ни автора, ни названия я не помню, но очень хорошо запомнил, что простыми вычислениями можно запрограммировать полет мухи вокруг лампочки, а еще несколькими строками сделать траекторию ее полета такой, что возникнет впечатление, что муха летает осмысленно.
На прошлой неделе я купил книгу создателя Wolfram|Alpha Стивена Вольфрама A New Kind of Science. Книга, конечно, объемная (1200 страниц), и всю ее я еще не прочитал, но основная мысль заключается в том, что большинство, если не все, явлений в природе возможно запрограммировать последовательностью простых вычислений.
Тот рассказ о программировании полета мухи — а я его тогда проверил на C++ — я всегда помню и стараюсь пользоваться простыми расчетами, если это возможно.
Лингвистические задачи, для которых Perl обычно очень удобен, часто можно свести к набору простейших подзадач. Вот пример того, как я генерирую фразы-подсказки поисковых запросов к конвертеру валют.
Первым делом нужно задать набор грамматик, по которым следует формировать случайные фразы:
my @grammars = (
'RateWordNoun CurrencyNameGenitiveA',
'RateWordAdjective CurrencyNameNominativeA',
'HowMuchCurrencyNameWithValueA',
'Value CurrencyCodeA ConvertWord CurrencyCodeB',
'CurrencyNameWithValueA ConvertWord
CurrencyNamePluralLocativeB'
);
Каждое слово в строке отдельной грамматики — вызов одноименной функции; каждая из них тоже простейшая:
sub RateWordNoun {
return $rateWordNoun[int rand scalar @rateWordNoun];
}
sub RateWordAdjective {
return $rateWordAdjective[int rand scalar @rateWordAdjective];
}
Эти функции используют небольшой набор слов:
my @rateWordNoun = ('курс');
my @rateWordAdjective = ('сколько стоит', 'почем');
Однако это не мешает делать и сколь угодно длинные списки:
my @currencyCode = qw(
RUR EUR USD JPY CHF GBP UAH KZT CAD
AUD BYR DKK ISK NOK SEK CNY TRY SGD ILS
);
my @currencyNameNominative =
('рубль', 'евро', 'доллар США', 'японская иена',
'швейцарский франк', 'фунт стерлингов',
'украинская гривна', 'казахстанский тенге',
'канадский доллар', 'австралийский доллар',
'белорусский рубль', 'датская крона',
'исландская крона', 'норвежская крона',
'шведская крона', 'китайский юань',
'турецкая лира', 'сингапурский доллар', 'шекель');
Собственно, остается написать функцию, которая выбирает случайную грамматику и строит случайную фразу по заданным правилам.
sub random {
my $template = $grammars[int rand scalar @grammars];
$template =~ s{(\w)\b}{$1()}g;
$template =~ s{([AB]\b)\(\)}{(\$$1)}g;
$template =~ s{\s+}{ . ' ' . }g;
return eval $template;
}
Блюдо готово.
курс швейцарского франка
сколько стоят 2 шведские кроны
курс японской иены
29 UAH в TRY
15 сингапурских долларов в норвежских кронах
почем турецкая лира
сколько стоят 36 евро
почем шекель
8 CHF в SEK
51 китайский юань в белорусских рублях
360 EUR в AUD
82 шекеля в рублях
600 долларов США в австралийских долларах