Принимает в качестве входных данных неотрицательное целое число, за которым следует символ новой строки, и выводит соответствующий факториал, за которым следует символ новой строки.
>>>>,----------[>>>>,----------]>>>>++<<<<<<<<[>++++++[<----
-->-]<-<<<<]>>>>[[>>+<<-]>>[<<+>+>-]<->+<[>>>>+<<<-<[-]]>[-]
>>]>[-<<<<<[<<<<]>>>>[[>>+<<-]>>[<<+>+>-]>>]>>>>[-[>+<-]+>>>
>]<<<<[<<<<]<<<<[<<<<]>>>>>[>>>[>>>>]>>>>[>>>>]<<<<[[>>>>+<<
<<-]<<<<]>>>>+<<<<<<<[<<<<]>>>>-[>>>[>>>>]>>>>[>>>>]<<<<[>>>
+<<<-]>>>[<<<+>>+>-]<-[>>+<<[-]]<<[<<<<]>>>>[>[>+<-]>[<<+>+>
-]<<[>>>+<<<-]>>>[<<<+>>+>-]<->+++++++++[-<[-[>>>>+<<<<-]]>>
>>[<<<<+>>>>-]<<<]<[>>+<<<<[-]>>[<<+>>-]]>>]<<<<[<<<<]<<<[<<
<<]>>>>-]>>>>]>>>[>[-]>>>]<<<<[>>+<<-]>>[<<+>+>-]<->+<[>-<[-
]]>[-<<-<<<<[>>+<<-]>>[<<+>+>-]<->+<[>-<[-]]>]<<[<<<<]<<<<-[
>>+<<-]>>[<<+>+>-]+<[>-<[-]]>[-<<++++++++++<<<<-[>>+<<-]>>[<
<+>+>-]+<[>-<[-]]>]<<[<<<<]>>>>[[>>+<<-]>>[<<+>+>-]<->+<[>>>
>+<<<-<[-]]>[-]>>]>]>>>[>>>>]<<<<[>+++++++[<+++++++>-]<--.<<
<<]++++++++++.
В отличие от ответа brainf * ck, опубликованного ранее, этот не переполняет любые области памяти. (Эта реализация помещает n! В одну ячейку памяти, фактически ограничивая ее до n менее 6 в соответствии со стандартными правилами bf.) Эта программа выведет n! для любого значения n, ограниченного только временем и памятью (или реализацией bf). Например, используя компилятор Урбана Мюллера на моей машине, для вычисления 1000 потребуется 12 секунд! Я думаю, что это довольно хорошо, учитывая, что программа может двигаться только влево / вправо и увеличиваться / уменьшаться на единицу.
Верьте или нет, это первая программа, написанная мной для BF; На это ушло около 10 часов, которые в основном были потрачены на отладку. К сожалению, я позже узнал, что Дэниел Б. Кристофани написал факториальный генератор , который просто выводит все более крупные факториалы, никогда не заканчивая:
>++++++++++>>>+>+[>>>+[-[<<<<<[+<<<<<]>>[[-]>[<<+>+>-]<[>+<-
]<[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>[-]>>>>+>+<
<<<<<-[>+<-]]]]]]]]]]]>[<+>-]+>>>>>]<<<<<[<<<<<]>>>>>>>[>>>>
>]++[-<<<<<]>>>>>>-]+>>>>>]<[>++<-]<<<<[<[>+<-]<<<<]>>[->[-]
++++++[<++++++++>-]>>>>]<<<<<[<[>+>+<<-]>.<<<<<]>.>>>>]
Его программа намного короче, но он практически профессиональный гольфист.
В простом примере, таком как это, нет ... но подумайте, был ли $ myVar
на самом деле чем-то более сложным, например, глубоким разыменованием ссылки на хэш или вызовом метода. Некоторые вещи интерполируются внутри строк (большинство ссылок на объекты делают), но вызовы методов - нет. Также массивы делают разные вещи при распечатке напрямую по сравнению с интерполяцией в строку.
PS. Добро пожаловать в Perl; пожалуйста, наслаждайтесь путешествием! :)
Там '
gotcha:
$owner = "John";
$item = "motorcycle".
print "This is $owner's $item.\n"; # Oops, parsed as $owner::s
, но приведенное выше можно безопасно записать как
print "This is ${owner}'s $item.\n";
Метод A должен быть:
$myVar = "value";
print 'Current value is ', $myVar, "\n";
Когда вы заключаете строку в одинарные кавычки, Perl не утруждает себя чтением всего этого целиком в поисках объектов для интерполяции, поэтому, если у вас есть длинная строка, которая не интерполяция не требуется, может быть быстрее использовать одинарные кавычки и добавлять динамические части, как указано выше.
Однако это микрооптимизация, которая на самом деле не имеет большого значения.
Другой случай использования метода A - это если строка содержит escape-символы, которые вы не хотите экранировать:
$myVar = 12000;
print 'Conversion from $US to $CND: ', $myVar,\n";
В этом случае вы не хотите, чтобы Perl искал переменные $ US
и $ CND
, вам просто нужно, чтобы в строке был знак доллара.
В В конце концов, это в основном вопрос стиля. Обычно я стараюсь избегать строк в двойных кавычках, если они мне не нужны.
, поскольку мы говорим об ошибках интерполяции, стоит упомянуть, что если вы используются строки в одинарных кавычках, чтобы избежать интерполяции, вам все равно нужно будет избегать косой черты в конце:
'c:\files\' #parse error
'c:\files\\' #correct
это потому, что последний символ первой строки выглядит как экранированная одинарная кавычка, а не как терминатор строки. также экранированная косая черта будет преобразована в одинарную косую черту в строках с одинарными кавычками
Есть несколько вещей, на которые следует обратить внимание при интерполяции, хотя, если вы знаете о их, вы никогда не сделаете их по ошибке.
Добавление имени переменной рядом с допустимым текстом идентификатора. Perl находит самое длинное допустимое имя переменной и не заботится о том, определено ли оно ранее. Вы можете выделить часть имени переменной фигурными скобками, чтобы быть явным:
my $p = 'p';
print "Mind your $ps and qs\n"; # $ps, not $p
print "Mind your ${p}s and qs"; # now its $p
Итак, в этом примере я забыл апостроф. Если я добавлю его, у меня возникнет другая проблема, поскольку апостроф раньше был разделителем пакетов, и он все еще работает. Фигурные скобки там тоже работают:
my $p = 'p';
print "Mind your $p's and q's\n"; # $p::s, not $p
print "Mind your ${p}'s and q's"; # now its $p
Perl также может интерполировать доступ к отдельным элементам к хешам и массивам, поэтому размещение символов индексации рядом с именем переменной может сделать что-то, чего вы не хотите:
print "The values are $string[$foo]\n"; That's the element at index $foo
print "The values are $string{$foo}\n"; That's the value for the key $foo
Если вам нужен адрес электронной почты в string, вы можете забыть, что Perl интерполирует массивы. Раньше Perl создавал фатальную ошибку, если только вы не экранировали @
:
print "Send me mail at joe@example.com\n"; # interpolates @example
print "Send me mail at joe\@example.com\n";
Поскольку Perl использует обратную косую черту для экранирования некоторых символов, вам нужно удвоить их, если вам нужен буквальный:
print "C:\real\tools\for\new\work"; # not what you might expect
print "C:\\real\\tools\\for\\new\\work"; # kinda ugly, but that's life
print "C:/real/tools/for/new/work"; # Windows still understands this
эти мелкие ошибки, Мне очень не хватает легкости, с которой я могу создавать строки в Perl, если мне приходится использовать другой язык.
Если вы обращаетесь к Perl, то вы ищете самый быстрый способ добиться своей цели. Более того, вас поощряют делать это так, как вы думаете (отсюда и девиз Perl: TMTOWTDI, есть больше, чем один способ сделать это). Следовательно: какой способ вам будет легче написать, какой способ вы, скорее всего, поймете, когда вернетесь к коду позже, - это именно то, как вы должны это делать (все остальные вещи, такие как получение желаемого результата, ).
Если вас беспокоит «безопасность», как вы предлагаете, узнайте о заражении , которое помогает защитить вас от потенциально вредоносных данных из внешнего мира.
(Вероятно, это вики сообщества.)
Единственная очевидная проблема, которая приходит мне в голову, - это интерполяция массивов. Сравните
print @arr, "\n";
с
print "@arr\n";
. Кроме того, иногда сложное разыменование не работает с интерполяцией, но это довольно редко.
Как сторонний наблюдатель Perl, который не знаком ни с какими редакторами, специфичными для Perl, и их возможностями выделения, я голосую за использование по возможности одинарные кавычки. Это проясняет читателю, что эта строка не содержит ничего, что можно было бы каким-либо образом интерполировать.
Интерполяция - отличный инструмент для упрощения и экономии времени. Но можно зайти слишком далеко.
Вы можете делать некоторые причудливые вещи с интерполяцией, если хотите.
@foo = 0..10;
print "$foo[2*3]"; # prints 6
А для увлекательной произвольной интерполяции вы можете использовать эту мерзость:
print "@{[ some_function_call('in list context') ]}";
Если вы действительно, действительно хотите сделать работают интерполированные вызовы функций, для этого есть модуль. См. Интерполяция . Он позволяет делать такие вещи, как это:
use Interpolation;
print "I like $eval{ what_I_like() };
sub what_like_like {
return 'pie';
}
И многое, многое другое.
Информацию об этом модуле можно найти в Identity.pm: очень забавный модуль и Интерполяция .
Определенно есть скрытые подводные камни - perl будет иметь дело с простые имена переменных и выражения типа
"$array[$subscript]"
и
"$hashref->{key}"
без каких-либо проблем. Однако по мере того, как ваши выражения становятся все более и более сложными, в конечном итоге perl не сможет определить, где заканчивается ваше выражение и начинается оставшаяся часть вашей строки.
В этой статье много кровавых деталей. Интерполяция переменных в Double -Котированные строки (первоначально здесь ,