Путь шепелявости решить Fibonnaci

Да! Вы можете определенно использовать Fabric для таких приложений. Однако в соответствии с лицензией на ресурсы , связанной с этим документом, ресурсы (шрифты и значки) могут использоваться только в том случае, если приложение каким-либо образом подключается к службе Microsoft. Это может быть так же просто, как размещение приложения в качестве веб-приложения Azure.

Вот связанная цитата из этого комментария GitHub , которая немного расширяется:

Ресурсы Fabric (шрифты, значки и логотипы продуктов) являются частью бренда Microsoft и могут использоваться только в приложениях & amp; услуги, в том числе коммерческие, которые связаны с продуктами Microsoft. К ним относятся надстройки для Office , веб-части для SharePoint и другие расширения для продуктов Microsoft. Это относится к использованию ресурсов в самом коде приложения, а также к любым проектам, созданным инструментарием.

Однако весь код Fabric (JS, CSS и т. Д.) Имеет лицензию MIT и может использоваться в коммерческих продуктах сторонних производителей. Существует даже первоклассная поддержка Selawik , открытого альтернативного пользовательского интерфейса Segoe с открытым исходным кодом. Тем не менее, сегодня нет замены шрифту иконки.

blockquote>

Чтобы отказаться от этих ресурсов, вы можете заменить значки по умолчанию Fabric на что-то вроде Font Awesome, например:

import { registerIcons } from '@uifabric/styling';
import FontAwesomeIcon from '@fortawesome/react-fontawesome';

registerIcons({
  icons: {
    'check-square': ,
    ...etc
  }
});

Чтобы отказаться от пользовательского интерфейса Segoe, вы можете использовать команду create Пользовательская тема, которая заменяет defaultFontStyle другим шрифтом. Вот CodePen, иллюстрирующий это: https://codepen.io/jahnp/pen/pYMyZM

11
задан Rainer Joswig 22 January 2015 в 16:42
поделиться

12 ответов

http://fare.tunes.org/files/fun/fibonacci.lisp имеет обход через решения fibonacci, постепенно улучшая время и выполнение памяти реализации.

15
ответ дан 3 December 2019 в 01:16
поделиться
(defun fib (x &optional (y 0) (z 1))
           (if (< x z)
               nil
               (append (list z) (fib x z (+ y z)))))

CL-USER> (reduce #'+ (remove-if-not #'evenp (fib 1000000)))
0
ответ дан 3 December 2019 в 01:16
поделиться

Посмотрите и видео и текст, расположенный в: http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/

0
ответ дан 3 December 2019 в 01:16
поделиться

Мое понимание "духа шепелявости" состоит в том, чтобы отсоединить себя от любого зафиксированного, догматичного, stuckup идея духа шепелявости, и использовать конструкцию шепелявости, которая наиболее тесно отражает структуру вычисления, требуемого решить Вашу проблему. Например,

(defun euler2 (&optional (n 4000000))
  (do ((i 1 j)
       (j 2 (+ i j))
       (k 0))
      ((<= n i) k)
    (when (evenp i) (incf k i))))

Если Вы настаиваете на рекурсии, вот иначе:

(defun euler2 (&optional (n 4000000))
  (labels ((fn (i j k) 
             (if (<= n i) k (fn j (+ i j) (if (oddp i) k (+ k i))))))
    (fn 1 2 0)))
1
ответ дан 3 December 2019 в 01:16
поделиться

Чтобы подробно остановиться на ответе Danio, статья по http://fare.tunes.org/files/fun/fibonacci.lisp представляет два способа сделать код выполненным быстрее. Используя прямую рекурсию (последний вызов или не) O (2^n) и очень медленный. Трудность состоит в том, что каждое значение вычисляется много раз. Необходимо сделать вещи по-другому. Эти две рекомендации:

  1. Используйте итерационный подход.
(defun bubble-fib (n)
  (declare (optimize (speed 3) (safety 0) (debug 0)))
  (check-type n fixnum)
  (loop repeat n
  with p = 0 with q = 1
  do (psetq p q
        q (+ p q))
  finally (return p)))
  1. Используйте Memoization. Это означает помнить, что значения видят прежде и вспоминание их вместо того, чтобы повторно вычислить их. Статья предоставляет пакет CL, который сделает это, а также некоторый код, чтобы сделать это самостоятельно.
1
ответ дан 3 December 2019 в 01:16
поделиться

Простой, эффективный способ создать список чисел Фибоначчи:

(defun fibs (n &optional (a 1) (b 1))
  (loop repeat n 
        collect (shiftf a b (+ a b))))

(shiftf) берет любое количество мест и наконец значения. Каждое место установлено на значение следующей переменной с последней переменной, принимающей значение, которое прибывает после него. Это возвращает значение первого места. Другими словами, это смещает все значения, оставленные одним.

Однако Вам не нужен полный список (Вам только нужно выравнивание), и Вам не нужен список вообще (Вам только нужна сумма), таким образом, это может работаться в функцию непосредственно. Каждое третье число Фибоначчи даже, таким образом...

(defun euler-2 (limit &optional (a 1) (b 1))
  (loop for x upfrom 1
        until (> a limit)
        if (zerop (mod x 3)) 
           sum a
        do (shiftf a b (+ a b))))
1
ответ дан 3 December 2019 в 01:16
поделиться

Способ решить это состоит в том, чтобы работать вверх дном, генерируя каждый термин Fibonnaci один за другим, и добавляя его к сумме, если это даже, и останавливающийся, после того как мы добираемся до 4 миллионов порогов. Мой LISP ржав, таким образом, здесь это находится в psuedocode:

one_prior = 1
two_prior = 1
curr = 2
sum = 0
while curr < 4000000000
  if curr % 2 == 0
    sum = sum + curr
  two_prior = one_prior
  one_prior = curr
  curr = one_prior + two_prior
3
ответ дан 3 December 2019 в 01:16
поделиться

ответ danio поможет значительно с вопросами о производительности.

Вот короткий критик Вашего стиля:

 (defun fib(i)
   (if (= i 1) ;//Could rewrite this as a case statement
     1
     (if (= i 2)
       1
       (+ (fib (- i 1)) (fib (- i 2)))
     )
   )
 )

Осуществите рефакторинг вложил IFS в COND.

Не помещайте круглые скобки на строку собой.

 (defun solve(i)
   (let ((f (fib i))) ;//Store result in local variable
     (print f) ;//For debugging
     (if (

Using ZEROP is clearer.

         (+ f (solve (+ i 1))) ;//add number
         (solve (+ i 1)) ;//Don't

Why do you put those // in? A semicolon followed by a space is enough.

) ) ) ) (print (solve 1))

Вы продержались, оператор печати делает меня немного подозрительным. Вы запускаете эту программу из файла или из REPL? Если Вы делаете первого затем, необходимо рассмотреть выполнение последнего. Если Вы делаете последнего, можно просто сказать (решите 1) получить результат.

2
ответ дан 3 December 2019 в 01:16
поделиться
(let ((a 1) (b 1))
  (flet ((nextfib ()
           (prog1 a
             (psetf a b b (+ a b)))))
    (loop for fib = (nextfib)
          while (<= fib 4000000)
          when (evenp fib)
            sum fib)))

Выше определяет функциональный NEXTFIB, который генерирует следующее число Фибоначчи для каждого вызова. ЦИКЛ суммирует даже результаты до предела 4000000.

PROG1 возвращает значение первого из его подвыражений. PSETF устанавливает a и b в 'параллели'.

Это - общий шаблон. Существует функция генератора, и каждый неоднократно называет ее, фильтрует результаты и комбинирует их.

4
ответ дан 3 December 2019 в 01:16
поделиться

Используйте хвостовую рекурсию вместо наивной рекурсии. Большинство реализаций Lisp должно выполнить tailcall-оптимизацию; больше никакого предела глубины рекурсии.

Кроме того, попытайтесь думать о вещах с точки зрения списков и абстрактных операций, которые Вы могли выполнить в тех списках. Две из более соответствующих операций для рассмотрения:

Относительно других ресурсов Lisp:

ОБНОВЛЕНИЕ: рекурсивная схема хвоста fib функция:

(define (fib n)
  (fib-tr n 1 0))

(define (fib-tr n next result)
  (cond ((= n 0) result)
        (else (fib-tr (- n 1) (+ next result) next))))
6
ответ дан 3 December 2019 в 01:16
поделиться

Memoization является способом кэшировать результаты к функции, постараться не повторно вычислять посреднические результаты много раз. Memoization в основном имеет в виду в первый раз, когда Вы вызываете функцию с некоторым args, вычисляете ответ и возвращаете его, и кэш тот ответ; для последующих вызовов к функции с теми теми же args просто возвратите кэшируемое значение.

В Lisp можно легко использовать функции высшего порядка и макрос к прозрачно memoize функция. Clojure имеет memoize как включенная стандартная функция. Также взгляд на страницу 65 На Lisp для реализации языка Common LISP memoize. Здесь это находится в Clojure:

(defn fib-naive [i]
  (if (or (= i 1) (= i 2))
    1
    (+ (fib-naive (- i 1)) (fib-naive (- i 2)))))

(def fib-memo
     (memoize (fn [i]
                (if (or (= i 1) (= i 2))
                  1
                  (+ (fib-memo (- i 1)) (fib-memo (- i 2)))))))

user> (time (fib-naive 30))
"Elapsed time: 455.857987 msecs"
832040
user> (time (fib-memo 30))
"Elapsed time: 0.415264 msecs"
832040
user> 

Это может все еще вызвать переполнение стека при вызове его на большом целом числе. например, сразу выполнение (fib 10000) унесет стек, потому что он все еще должен рекурсивно вызвать очень глубоко (однажды). Но если Вы главный кэш сначала, это больше не должно рекурсивно вызывать глубоко, и этого можно избежать. Просто делая это сначала (в Clojure):

(dorun (map fib-memo (range 1 10000)))

будет достаточно, чтобы затем позволить Вам сделать (fib 10000) без проблем.

(Определенный предмет вычисления Чисел Фибоначчи недавно подошел в списке рассылки Clojure. Существует решение там на основе чисел Lucas, которые я не понимаю в малейшем, но которые, предположительно, в 40 раз быстрее, чем наивный алгоритм.)

9
ответ дан 3 December 2019 в 01:16
поделиться

В дополнение ко всем полезным ответам следующие формулы могут обеспечить еще больше эффективности - вычисление Fn в O (Журнал (n)) вместо O (2^n). Это должно быть вместе с memoization и является прочной базой для решения проблемы:

F(2*n) = F(n)^2 + F(n-1)^2

F(2*n + 1) = ( 2*F(n-1) + F(n) )   *   F(n)
2
ответ дан 3 December 2019 в 01:16
поделиться