Функциональная функция Ruby

Я схожу с ума: где функция Ruby для факториала? Нет, мне не нужны учебники, я просто хочу, чтобы функция из библиотеки. Это не в Math!

Я начинаю сомневаться, это стандартная библиотечная функция?

Ответ 1

В стандартной библиотеке нет факториальной функции.

Ответ 2

Как это лучше

(1..n).inject(:*) || 1

Ответ 3

Это не в стандартной библиотеке, но вы можете расширить класс Integer.

class Integer
  def factorial_recursive
    self <= 1 ? 1 : self * (self - 1).factorial
  end
  def factorial_iterative
    f = 1; for i in 1..self; f *= i; end; f
  end
  alias :factorial :factorial_iterative
end

N.B. Итеративный фактор - лучший выбор для очевидных причин производительности.

Ответ 4

Бесстыдно взято с http://rosettacode.org/wiki/Factorial#Ruby, мой личный фаворит

class Integer
  def fact
    (1..self).reduce(:*) || 1
  end
end

>> 400.fact
=> 64034522846623895262347970319503005850702583026002959458684445942802397169186831436278478647463264676294350575035856810848298162883517435228961988646802997937341654150838162426461942352307046244325015114448670890662773914918117331955996440709549671345290477020322434911210797593280795101545372667251627877890009349763765710326350331533965349868386831339352024373788157786791506311858702618270169819740062983025308591298346162272304558339520759611505302236086810433297255194852674432232438669948422404232599805551610635942376961399231917134063858996537970147827206606320217379472010321356624613809077942304597360699567595836096158715129913822286578579549361617654480453222007825818400848436415591229454275384803558374518022675900061399560145595206127211192918105032491008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Эта реализация также оказывается самой быстрой среди вариантов, перечисленных в Rosetta Code.

обновление № 1

Добавлено || 1 || 1 для обработки нулевого случая.

обновление № 2

С благодарностью и благодарностью Марку Томасу, вот версия, которая немного более эффективна, элегантна и неясна:

class Integer
  def fact
    (2..self).reduce(1,:*)
  end
end

Ответ 5

Вы также можете использовать функцию Math.gamma, которая сводится к factorial для целочисленных параметров.

Ответ 6

class Integer
  def !
    (1..self).inject(:*)
  end
end

примеры

!3  # => 6
!4  # => 24

Ответ 7

В математике factorial of n это просто gamma function of n+1
(см.: http://en.wikipedia.org/wiki/Gamma_function)

В Ruby есть Math.gamma() поэтому просто используйте Math.gamma(n+1) и при желании Math.gamma(n+1) его к целому числу.

Ответ 8

Я бы сделал

(1..n).inject(1, :*)

Ответ 9

Я просто написал свой собственный:

def fact(n)
  if n<= 1
    1
  else
    n * fact( n - 1 )
  end
end

Кроме того, вы можете определить падающий факториал:

def fall_fact(n,k)
  if k <= 0
    1
  else
    n*fall_fact(n - 1, k - 1)
  end
end

Ответ 10

Использование Math.gamma.floor - это простой способ получить приближение, а затем округлить его до правильного целочисленного результата. Должны работать для всех целых чисел, при необходимости включать проверку ввода.

Ответ 11

Просто вызовите эту функцию

def factorial(n=0)
  (1..n).inject(:*)
end

примеры

factorial(3)
factorial(11)

Ответ 12

Еще один способ сделать это, хотя это действительно не нужно.

class Factorial
   attr_reader :num
   def initialize(num)
      @num = num
   end

   def find_factorial
      (1..num).inject(:*) || 1
   end
end

number = Factorial.new(8).find_factorial
puts number

Ответ 13

Вероятно, вы найдете удобный запрос Ruby . Он содержит нетривиальный патч который включает demo Bash script. Разница в скорости между наивным циклом и решением, представленным в партии, может быть буквально 100x (сто раз). Написано все в чистом Ruby.

Ответ 14

class Integer
  def factorial
    return self < 0 ? false : self==0 ? 1 : self.downto(1).inject(:*)
    #Not sure what other libraries say, but my understanding is that factorial of 
    #anything less than 0 does not exist.
  end
end

Ответ 15

И еще один способ (=

def factorial(number)
  number = number.to_i
  number_range = (number).downto(1).to_a
  factorial = number_range.inject(:*)
  puts "The factorial of #{number} is #{factorial}"
end
factorial(#number)

Ответ 16

Вот моя версия кажется мне понятной, хотя она не такая чистая.

def factorial(num)
    step = 0
    (num - 1).times do (step += 1 ;num *= step) end
    return num
end

Это моя линия тестирования irb, которая показывала каждый шаг.

num = 8;step = 0;(num - 1).times do (step += 1 ;num *= step; puts num) end;num

Ответ 17

Еще один способ сделать это:

# fact(n) => Computes the Factorial of "n" = n!

def fact(n) (1..n).inject(1) {|r,i| r*i }end

fact(6) => 720

Ответ 18

Зачем стандартной библиотеке нужен метод факториала, если для этой цели есть встроенный итератор? Это называется upto.

Нет, вам не нужно использовать рекурсию, как показывают все эти другие ответы.

def fact(n)
  n == 0 ? 1 : n * fact(n - 1)
end  

Скорее, встроенный итератор upto может использоваться для вычисления факториалов:

factorial = 1
1.upto(10) {|x| factorial *= x }
factorial
 => 3628800

Ответ 19

С большим уважением ко всем, кто принимал участие и потратил свое время, чтобы помочь нам, я хотел бы поделиться своими оценками решений, перечисленных здесь. Params:

итерации = 1000

n = 6

                                     user     system      total        real
Math.gamma(n+1)                   0.000383   0.000106   0.000489 (  0.000487)
(1..n).inject(:*) || 1            0.003986   0.000000   0.003986 (  0.003987)
(1..n).reduce(1, :*)              0.003926   0.000000   0.003926 (  0.004023)
1.upto(n) {|x| factorial *= x }   0.003748   0.011734   0.015482 (  0.022795)

Для n = 10

  user     system      total        real
0.000378   0.000102   0.000480 (  0.000477)
0.004469   0.000007   0.004476 (  0.004491)
0.004532   0.000024   0.004556 (  0.005119)
0.027720   0.011211   0.038931 (  0.058309)