2015-05-02 3 views
4

Есть ли способ создать последовательность фибоначчи в APL с помощью однострочной линии, которая не требует циклов или управления потоком?Создайте серию фибоначчи без петли или управления потоком в APL

Я сделал это с помощью функции и условного теста, но я чувствую, что должен быть более элегантный, декларативный способ. example, что я нашел, что претензии на это на одной строке не работают на gnu-apl - кажется, что он на правильном пути, используя математическую математику, но мне тяжело идти дальше, t настроить его для правильной работы.

Я преследую APL как свой первый реальный язык программирования (мне нравятся символы. Я просто делаю.) Я сейчас использую Project Euler как способ лучше познакомиться.

+0

Почему это не работает на GNU-APL? Какие ошибки вы получаете? – bman

+0

@Baqer Mamouri - ↑ 0 1 ↓ ↑ + /. ×/N⊂2 2⍴1 1 1 0 где N равно 10 возвращает «1» –

+0

↑ 0 1 ↓ ↑ +. ×/N/⊂2 2⍴1 1 1 0 дает мне N-е число фибоначчи в Dyalog APL (с [] ML 3). Я могу «оживить» эту строку кода, сделав ее Dfn, т. Е. {↑ 0 1 ↓ ↑ +. ×/⍵/⊂2 2⍴1 1 1 0} ¨⍳20. Обратите внимание, что это работает в [] IO 1. Каждый оператор эффективно выполняет итерацию выражения над 1, 2, ... 20. – Lobachevsky

ответ

3

Мне тоже нравятся символы APL, а также его мощность программирования в массиве. Другие языки массива могут быть более мощными, например J, но им не хватает красоты символов APL и явного синтаксиса.

Я просто попытался пример вы ссылку в GNU APL и работает все в порядке:

 ↑0 1↓↑+.×/5/⊂2 2⍴1 1 1 0 
5 
     ↑0 1↓↑+.×/6/⊂2 2⍴1 1 1 0 
8 
     ↑0 1↓↑+.×/7/⊂2 2⍴1 1 1 0 
13 

Если вы не можете заставить его работать, убедитесь, что:

  • типа (или скопировать и вставить) точные символы, показанные в примере: в частности × - U + 00D7 MULTIPLICATION SIGN, а не X; U + 2374 APL FUNCTIONAL SYMBOL RHO, а не любой другой греческий Rho, и определенно не P; U + 2282 SUBSET OF; и так далее;
  • проверять некоторые цифры, отличные от 1 или 5, потому что они являются единственными числами, которые равны их числу Фибоначчи;
  • Если вы не ставите фактическое число вместо N, убедитесь, что вы правильно определили N, например N←7 в предыдущей строке.

Если вы все еще не можете заставить его работать, введите формулу один шаг в то время, начиная с правой стороны:

 2 2⍴1 1 1 0 
1 1 
1 0 
     ⊂2 2⍴1 1 1 0 
1 1 
1 0 
     7/⊂2 2⍴1 1 1 0 
1 1 1 1 1 1 1 1 1 1 1 1 1 1 
1 0 1 0 1 0 1 0 1 0 1 0 1 0 
     +.×/7/⊂2 2⍴1 1 1 0 
21 13 
13 8 
     ↑+.×/7/⊂2 2⍴1 1 1 0 
21 13 
13 8 
     0 1↓↑+.×/7/⊂2 2⍴1 1 1 0 
13 
8 
     ↑0 1↓↑+.×/7/⊂2 2⍴1 1 1 0 
13 

Что касается названия вопроса, я думаю, что эта матрица формула ногти он (! браво @mappo)

Если бы я был golfing, я бы, вероятно, использовать более короткий вариант, но это все:

 2⌷∊+.×/7/⊂∘.∨⍨1 0 
13 

Там, сюда м от 24 до 17 символов. Посмотрите, можете ли вы это выяснить :-)

GNU APL в порядке, хотя ему не хватает некоторых современных функций, но сохраните копию руководства Dyalog APL Programmer's Guide & Язык Ссылка удобна, поскольку это одна из самых полных ссылок на язык.

+0

Проблема была немой опечаткой - я использовал + /, когда мне просто хотелось +. Нарушение того, как это работает, очень полезно, tho! У меня есть Mac, и я не могу беспокоиться о том, чтобы запускать эмулятор только для этого (и ссылка на скачивание MicroAPL выглядит сломанной ...) –

+0

(Errr, «this» Я имел в виду «Dyalog») –

+0

Я использую [Wineskin] (http://wineskin.urgesoftware.com/) (графический интерфейс для Wine) для запуска приложений Windows на Mac без запуска всей ОС Windows. Версия Dialog работает свободно, как и многие другие утилиты. – Tobia

2

Другой способ сделать это будет использовать (относительно новый) оператор мощности. Это может или не может поддерживаться GNU APL, оно работает с Dyalog (я использую 13.1) и APN NGN.

Попробуйте

({⍵,+/¯2↑⍵} ⍣ 20) (1 1) 

Как и другие примеры, итерация скрыта, здесь с оператором питания.

Выражение

({⍵,+/¯2↑⍵} ⍣ 3) (1 1) 

делает

{⍵,+/¯2↑⍵} {⍵,+/¯2↑⍵} {⍵,+/¯2↑⍵} 1 1 

под одеялом.

1 1 - это начальное значение, и каждый последующий {⍵, +/¯2 ↑ ⍵} просто связывает сумму двух последних элементов.

+0

Нет umlauted star in Gnu APL, alack. Я слежу за вашими ответами APL, tho! Это очень классный способ программирования, и я рад видеть, что на SE есть сообщество APL, играющее на чартах! –

+0

@RISwampYankee GNU APL, похоже, приобрел этот оператор когда-то между тем, когда вы сделали свой комментарий, и теперь, поскольку этот фрагмент теперь работает по назначению! –

1

Вы используете Dyalog APL? В этом случае вы должны воспользоваться оператором power, как объяснялось предыдущим ответом (первый фрагмент кода в этом ответе, исходящий из книги Освоение Dyalog APL, стр. 416).

Другое решение с тем же оператором будет с матрицами:

(+.×⍣10)⍨ 2 2⍴1 1 1 0 

или как прямой функции:

{⊃(+.×⍣⍵)⍨2 2⍴1 1 1 0} 10 

Если вы не хотите использовать оператор power, вы все равно (код ниже проверен в соответствии с GNU APL 1.5):

{+.×/⍵⍴⊂2 2⍴1 1 1 0} 10 
+0

Нет, я использую GNU APL, который является языком APL2, который придерживается довольно близкого к стандарту. Это единственный APL, который я могу запустить на Mac, который, как представляется, поддерживается на постоянной основе. Dyalog заставляет меня хотеть купить RaspberryPi, так что я могу иметь специальную рабочую станцию ​​APL, чтобы возиться с ней, она довольно гладкая. –

+1

Привет, на вашем Mac вы также можете запустить NGN APL, который является современным, легким и отличным. Во всяком случае, я владею шестью RPi, и это действительно стоит покупать, если вы хотите использовать Dyalog APL (вы также сможете свободно использовать Mathematica по той же цене). С уважением. –

2

Хорошо, я думаю, я нашел способ, чтобы генерировать последовательность длины N (а не энного количества) в один (хотя и не очень красивая линия APL2):

+/¨(⊂0 0)⍉¨⊖¨(2/¨⍳N)↑¨⊂P←V∘.!V←⍳1+N←20 

Как я сказал: не так Симпатичная. Позвольте мне попытаться разбить его на идиомы:

Это треугольник Паскаля с 20 уровнями:

P←V∘.!V←⍳1+N←20 

Тогда мы возьмем N первый верхний левый-угловые квадраты:

(2/¨⍳N)↑¨⊂P 

Эта идиома возвращает главную диагональ матрицы:

(⊂0 0)⍉ 

Но мы хотим, а, nti-diagonal, поэтому перед этим мы будем использовать , чтобы перевернуть все квадраты.

Последний шаг состоит в том, чтобы суммировать все диафрагмы с +/.

+0

Метод использования Треугольника Паскаля исходит из [Википедии] (http://en.wikipedia.org/wiki/Fibonacci_number#Use_in_mathematics) – mappo

+0

Я забыл упомянуть, что он находится в начале 0. Также: назначение P не нужно. – mappo

+0

К сожалению, это не работает с GnuAPL - мы получаем доменную ошибку в ⍉, но выяснение, почему она не работает, будет образовательной. Это очень аккуратный подход, спасибо! –

0

Late к партии, но вот чистое решение, которое безопасно для Гну-APL, не используя оператор мощности, и немного тонкой настройки «нег-два взять» метод Лобачевского:

fib ← {{⍵, +/ ¯2↑ ⍵}/⌽ ⍳⍵} 

Основной трюк: изменяя список iota, так как сжатие читает его в обратном порядке.Выход образца:

 fib 10 
1 1 2 3 5 8 13 21 34 55 
+0

Я не думаю, что вы можете использовать монадическую функцию для оператора '/' в gnu apl, по крайней мере, не в последней версии svn, которую я имею. Игнорирование ⍺ легко, но '{{⍺⊢⍵, +/¯2 ↑ ⍵}/⌽⍳⍵}' должно делать все. Возможно, вы захотите поставить ''' спереди. – jxy

 Смежные вопросы

  • Нет связанных вопросов^_^