Факториальные Алгоритмы на различных языках

В моем случае я хотел добавить метод с пользовательским swift-объектом в качестве параметра типа, а имя, которое я дал переменной в параметре, было точно таким же, как имя класса пользовательского объекта

Проблемы были примерно такими:

func moveBlob(**blob** : blob){
    ...code
}

Часть жирным шрифтом вызывала ошибку необъявленного типа

64
задан 13 revs, 4 users 100% 21 September 2014 в 15:40
поделиться

129 ответов

Приведенный ниже код не совсем понятен, однако, если учесть, что возвращаемое значение ограничено значением n < 34 для uint32, < 65 uint64 до того, как нам не хватит места для возвращаемого значения с uint, жесткое кодирование 33 значений не так уж и безумно :)

public static int Factorial(int n)
{
    switch (n)
    {
        case 1:
            return 1;
        case 2:
            return 2;
        case 3:
            return 6;
        case 4:
            return 24;
        default:
            throw new Exception("Sorry, I can only count to 4");
    }

}
5
ответ дан 5 revs 24 November 2019 в 15:33
поделиться

C/C++ : Процедурный

unsigned long factorial(int n)
{
    unsigned long factorial = 1;
    int i;

    for (i = 2; i <= n; i++)
        factorial *= i;

    return factorial;
}

PHP: Процедурный

function factorial($n)
{
    for ($factorial = 1, $i = 2; $i <= $n; $i++)
        $factorial *= $i;

    return $factorial;
}

@Niyaz: Вы не определили тип возврата для функции

5
ответ дан 4 revs 24 November 2019 в 15:33
поделиться

Проблема с большинством из вышеперечисленных заключается в том, что они будут работать с точностью около 25! (12! С 32-битными значениями) или просто переполнение. Вот реализация c # для преодоления этих ограничений!

class Number
{
  public Number ()
  {
    m_number = "0";
  }

  public Number (string value)
  {
    m_number = value;
  }

  public int this [int column]
  {
    get
    {
      return column < m_number.Length ? m_number [m_number.Length - column - 1] - '0' : 0;
    }
  }

  public static implicit operator Number (string rhs)
  {
    return new Number (rhs);
  }

  public static bool operator == (Number lhs, Number rhs)
  {
    return lhs.m_number == rhs.m_number;
  }

  public static bool operator != (Number lhs, Number rhs)
  {
    return lhs.m_number != rhs.m_number;
  }

  public override bool Equals (object obj)
  {
     return this == (Number) obj;
  }

  public override int GetHashCode ()
  {
    return m_number.GetHashCode ();
  }

  public static Number operator + (Number lhs, Number rhs)
  {
    StringBuilder
      result = new StringBuilder (new string ('0', lhs.m_number.Length + rhs.m_number.Length));

    int
      carry = 0;

    for (int i = 0 ; i < result.Length ; ++i)
    {
      int
        sum = carry + lhs [i] + rhs [i],
        units = sum % 10;

      carry = sum / 10;

      result [result.Length - i - 1] = (char) ('0' + units);
    }

    return TrimLeadingZeros (result);
  }

  public static Number operator * (Number lhs, Number rhs)
  {
    StringBuilder
      result = new StringBuilder (new string ('0', lhs.m_number.Length + rhs.m_number.Length));

    for (int multiplier_index = rhs.m_number.Length - 1 ; multiplier_index >= 0 ; --multiplier_index)
    {
      int
        multiplier = rhs.m_number [multiplier_index] - '0',
        column = result.Length - rhs.m_number.Length + multiplier_index;

      for (int i = lhs.m_number.Length - 1 ; i >= 0 ; --i, --column)
      {
        int
          product = (lhs.m_number [i] - '0') * multiplier,
          units = product % 10,
          tens = product / 10,
          hundreds = 0,
          unit_sum = result [column] - '0' + units;

        if (unit_sum > 9)
        {
          unit_sum -= 10;
          ++tens;
        }

        result [column] = (char) ('0' + unit_sum);

        int
          tens_sum = result [column - 1] - '0' + tens;

        if (tens_sum > 9)
        {
          tens_sum -= 10;
          ++hundreds;
        }

        result [column - 1] = (char) ('0' + tens_sum);

        if (hundreds > 0)
        {
          int
            hundreds_sum = result [column - 2] - '0' + hundreds;

          result [column - 2] = (char) ('0' + hundreds_sum);
        }
      }
    }

    return TrimLeadingZeros (result);
  }

  public override string ToString ()
  {
    return m_number;
  }

  static string TrimLeadingZeros (StringBuilder number)
  {
    while (number [0] == '0' && number.Length > 1)
    {
      number.Remove (0, 1);
    }

    return number.ToString ();
  }

  string
    m_number;
}

static void Main (string [] args)
{
  Number
    a = new Number ("1"),
    b = new Number (args [0]),
    one = new Number ("1");

  for (Number c = new Number ("1") ; c != b ; )
  {
    c = c + one;
    a = a * c;
  }

  Console.WriteLine (string.Format ("{0}! = {1}", new object [] { b, a }));
}

FWIW: 10000! более 35500 символов.

Skizz

5
ответ дан Skizz 24 November 2019 в 15:33
поделиться

Лямбда-исчисление

Ввод и вывод является церковными цифрами (т.е. натуральное число k \f n. f^k n; так 3 = \f n. f (f (f n)))

(\x. x x) (\y f. f (y y f)) (\y n. n (\x y z. z) (\x y. x) (\f n. f n) (\f. n (y (\f m. n (\g h. h (g f)) (\x. m) (\x. x)) f)))
5
ответ дан 2 revs, 2 users 83% 24 November 2019 в 15:33
поделиться

Рубин: функциональный

def factorial(n)
    return 1 if n == 1
    n * factorial(n -1)
end
4
ответ дан krujos 24 November 2019 в 15:33
поделиться

Простые решения являются лучшими:

#include <stdexcept>;

long fact(long f)
{
    static long fact [] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 1932053504, 1278945280, 2004310016, 2004189184 };
    static long max     = sizeof(fact)/sizeof(long);

    if ((f < 0) || (f >= max))
    {   throw std::range_error("Factorial Range Error");
    }

    return fact[f];
}
2
ответ дан Martin York 24 November 2019 в 15:33
поделиться

Название языка: ChucK

Moog moog => dac;
4.0 => moog.gain;

for (0 => int i; i < 8; i++) {
    <<< factorial(i) >>>;
}

fun int factorial(int n) {
    1 => int result;
    if (n != 0) {
        n * factorial(n - 1) => result;
    }

    Std.mtof(result % 128) => moog.freq;
    0.25::second => now;

    return result;
}

И это звучит как это . Не очень интересно, но, эй, это просто факториальная функция!

2
ответ дан Paul Reiners 24 November 2019 в 15:33
поделиться

Схема: функциональная - хвост рекурсивный

(define (factorial n)
  (define (fac-times n acc)
    (if (= n 0)
        acc
        (fac-times (- n 1) (* acc n))))
  (if (< n 0)
      (display "Wrong argument!")
      (fac-times n 1)))
2
ответ дан grom 24 November 2019 в 15:33
поделиться

Visual Basic: Linq

<Extension()> _
Public Function Product(ByVal xs As IEnumerable(Of Integer)) As Integer
    Return xs.Aggregate(1, Function(a, b) a * b)
End Function

Public Function Fact(ByVal n As Integer) As Integer
    Return Aggregate x In Enumerable.Range(1, n) Into Product()
End Function

Здесь показано, как использовать ключевое слово Aggregate в VB. C # не может этого сделать (хотя C #, конечно, может вызывать метод расширения напрямую).

2
ответ дан Konrad Rudolph 24 November 2019 в 15:33
поделиться

два из многих решений Mathematica (хотя! встроено и эффективен):

(* returns pure function *)
(FixedPoint[(If[#[[2]]>1,{#[[1]]*#[[2]],#[[2]]-1},#])&,{1,n}][[1]])&

(* not using built-in, returns pure function, don't use: might build 1..n list *)
(Times @@ Range[#])&
2
ответ дан 3 revs 24 November 2019 в 15:33
поделиться

C:

Редактировать: На самом деле C ++, я думаю, из-за объявления переменной в цикле for.

 int factorial(int x) {
      int product = 1;

      for (int i = x; i > 0; i--) {
           product *= i;
      }

      return product;
 }
2
ответ дан Jeremy Ruten 24 November 2019 в 15:33
поделиться

Perl 6: процедурный

sub factorial ( int $n ){

  my $result = 1;

  loop ( ; $n > 0; $n-- ){

    $result *= $n;

  }

  return $result;
}
2
ответ дан Brad Gilbert 24 November 2019 в 15:33
поделиться

Python: функциональная, рекурсивная однострочная с использованием логической оценки короткого замыкания.

    factorial = lambda n: ((n <= 1) and 1) or factorial(n-1) * n
3
ответ дан 3 revs 24 November 2019 в 15:33
поделиться

Сценарий Java: Творческий метод с помощью "вопрос об интервью" подсчет битов fnc.

function nu(x)
{
  var r=0
  while( x ) {
    x &= x-1
    r++
  }
  return r
}

function fac(n)
{
  var r= Math.pow(2,n-nu(n))

  for ( var i=3 ; i <= n ; i+= 2 )
    r *= Math.pow(i,Math.floor(Math.log(n/i)/Math.LN2)+1)
  return r
}

Работы до 21! тогда Chrome переключается на экспоненциальное представление. Вдохновение благодарит отсутствие сна и Knuth, и "конкретной математики al".

3
ответ дан 4 revs 24 November 2019 в 15:33
поделиться

Scala

Факториал может быть определен функционально как:

def fact(n: Int): BigInt = 1 to n reduceLeft(_*_)

или более традиционно как

def fact(n: Int): BigInt = if (n == 0) 1 else fact(n-1) * n

, и мы можем сделать! допустимый метод для Ints:

object extendBuiltins extends Application {

  class Factorizer(n: Int) {
    def ! = 1 to n reduceLeft(_*_)
  }

  implicit def int2fact(n: Int) = new Factorizer(n)

  println("10! = " + (10!))
}
3
ответ дан 3 revs, 2 users 79% 24 November 2019 в 15:33
поделиться

Brainfuck: с поддержкой bignum!

Принимает в качестве входных данных неотрицательное целое число, за которым следует символ новой строки, и выводит соответствующий факториал, за которым следует символ новой строки.

>>>>,----------[>>>>,----------]>>>>++<<<<<<<<[>++++++[<----
-->-]<-<<<<]>>>>[[>>+<<-]>>[<<+>+>-]<->+<[>>>>+<<<-<[-]]>[-]
>>]>[-<<<<<[<<<<]>>>>[[>>+<<-]>>[<<+>+>-]>>]>>>>[-[>+<-]+>>>
>]<<<<[<<<<]<<<<[<<<<]>>>>>[>>>[>>>>]>>>>[>>>>]<<<<[[>>>>+<<
<<-]<<<<]>>>>+<<<<<<<[<<<<]>>>>-[>>>[>>>>]>>>>[>>>>]<<<<[>>>
+<<<-]>>>[<<<+>>+>-]<-[>>+<<[-]]<<[<<<<]>>>>[>[>+<-]>[<<+>+>
-]<<[>>>+<<<-]>>>[<<<+>>+>-]<->+++++++++[-<[-[>>>>+<<<<-]]>>
>>[<<<<+>>>>-]<<<]<[>>+<<<<[-]>>[<<+>>-]]>>]<<<<[<<<<]<<<[<<
<<]>>>>-]>>>>]>>>[>[-]>>>]<<<<[>>+<<-]>>[<<+>+>-]<->+<[>-<[-
]]>[-<<-<<<<[>>+<<-]>>[<<+>+>-]<->+<[>-<[-]]>]<<[<<<<]<<<<-[
>>+<<-]>>[<<+>+>-]+<[>-<[-]]>[-<<++++++++++<<<<-[>>+<<-]>>[<
<+>+>-]+<[>-<[-]]>]<<[<<<<]>>>>[[>>+<<-]>>[<<+>+>-]<->+<[>>>
>+<<<-<[-]]>[-]>>]>]>>>[>>>>]<<<<[>+++++++[<+++++++>-]<--.<<
<<]++++++++++.

В отличие от ответа brainf * ck, опубликованного ранее, этот не переполняет любые области памяти. (Эта реализация помещает n! В одну ячейку памяти, фактически ограничивая ее до n менее 6 в соответствии со стандартными правилами bf.) Эта программа выведет n! для любого значения n, ограниченного только временем и памятью (или реализацией bf). Например, используя компилятор Урбана Мюллера на моей машине, для вычисления 1000 потребуется 12 секунд! Я думаю, что это довольно хорошо, учитывая, что программа может двигаться только влево / вправо и увеличиваться / уменьшаться на единицу.

Верьте или нет, это первая программа, написанная мной для BF; На это ушло около 10 часов, которые в основном были потрачены на отладку. К сожалению, я позже узнал, что Дэниел Б. Кристофани написал факториальный генератор , который просто выводит все более крупные факториалы, никогда не заканчивая:

>++++++++++>>>+>+[>>>+[-[<<<<<[+<<<<<]>>[[-]>[<<+>+>-]<[>+<-
]<[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>[-]>>>>+>+<
<<<<<-[>+<-]]]]]]]]]]]>[<+>-]+>>>>>]<<<<<[<<<<<]>>>>>>>[>>>>
>]++[-<<<<<]>>>>>>-]+>>>>>]<[>++<-]<<<<[<[>+<-]<<<<]>>[->[-]
++++++[<++++++++>-]>>>>]<<<<<[<[>+>+<<-]>.<<<<<]>.>>>>]

Его программа намного короче, но он практически профессиональный гольфист.

3
ответ дан 2 revs 24 November 2019 в 15:33
поделиться

Время компиляции в C ++

template<unsigned i>
struct factorial
{ static const unsigned value = i * factorial<i-1>::value; };

template<>
struct factorial<0>
{ static const unsigned value = 1; };

Использовать в коде как:

Factorial<5>::value
3
ответ дан Chris Jefferson 24 November 2019 в 15:33
поделиться

Forth (рекурсивно):

: factorial ( n -- n )
    dup 1 > if
        dup 1 - recurse *
    else
        drop 1
     then
;
3
ответ дан Anonymous 24 November 2019 в 15:33
поделиться

PostScript: хвост, рекурсивный

/fact0 { dup 2 lt { pop } { 2 copy mul 3 1 roll 1 sub exch pop fact0 } ifelse } def
/fact { 1 exch fact0 } def
3
ответ дан plinth 24 November 2019 в 15:33
поделиться

Delphi

facts: array[2..12] of integer;

function TForm1.calculate(f: integer): integer;
begin
    if f = 1 then
      Result := f
    else if f > High(facts) then
      Result := High(Integer)
    else if (facts[f] > 0) then
      Result := facts[f]
    else begin
      facts[f] := f * Calculate(f-1);
      Result := facts[f];
    end;
end;

initialize

  for i := Low(facts) to High(facts) do
    facts[i] := 0;

После первого вычисления факториала, большего или равного требуемому значению, этот алгоритм просто возвращает факториал за постоянное время O (1).

Следует учитывать, что только int32 может содержать до 12!

3
ответ дан 2 revs, 2 users 98% 24 November 2019 в 15:33
поделиться
#Language: T-SQL
#Style: Recursive, divide and conquer

Просто для удовольствия - в T-SQL используется рекурсивный метод «разделяй и властвуй». Да, рекурсивно - в SQL без переполнения стека.

create function factorial(@b int=1, @e int) returns float as begin
  return case when @b>=@e then @e else 
      convert(float,dbo.factorial(@b,convert(int,@b+(@e-@b)/2)))
    * convert(float,dbo.factorial(convert(int,@b+1+(@e-@b)/2),@e)) end
end

называйте это так:

print dbo.factorial(1,170) -- the 1 being the starting number
3
ответ дан 5 revs 24 November 2019 в 15:33
поделиться

Агда 2: функционально, зависимо типизированный.

data Nat = zero | suc (m::Nat)

add (m::Nat) (n::Nat) :: Nat
 = case m of
     (zero ) -> n
     (suc p) -> suc (add p n)

mul (m::Nat) (n::Nat)::Nat
   = case m of
      (zero ) -> zero
      (suc p) -> add n (mul p n)

factorial (n::Nat)::Nat 
 = case n of
    (zero ) -> suc zero
    (suc p) -> mul n (factorial p)
3
ответ дан 2 revs 24 November 2019 в 15:33
поделиться

Lua

function factorial (n)
  if (n <= 1) then return 1 end
  return n*factorial(n-1)
end

И вот является переполнением стека, пойманным в дикой природе:

> print (factorial(234132))
stdin:3: stack overflow
stack traceback:
    stdin:3: in function 'factorial'
    stdin:3: in function 'factorial'
    stdin:3: in function 'factorial'
    stdin:3: in function 'factorial'
    stdin:3: in function 'factorial'
    stdin:3: in function 'factorial'
    stdin:3: in function 'factorial'
    stdin:3: in function 'factorial'
    stdin:3: in function 'factorial'
    stdin:3: in function 'factorial'
    ...
    stdin:3: in function 'factorial'
    stdin:3: in function 'factorial'
    stdin:3: in function 'factorial'
    stdin:3: in function 'factorial'
    stdin:3: in function 'factorial'
    stdin:3: in function 'factorial'
    stdin:3: in function 'factorial'
    stdin:3: in function 'factorial'
    stdin:1: in main chunk
    [C]: ?
3
ответ дан Jon Ericson 24 November 2019 в 15:33
поделиться

Nemerle: функциональный

def fact(n) {
    | 0 => 1
    | x => x * fact(x-1)
}
3
ответ дан Cody Brocious 24 November 2019 в 15:33
поделиться

Mathematica : использование чисто рекурсивных функций

(If[#>1,# #0[#-1],1])&
3
ответ дан John with waffle 24 November 2019 в 15:33
поделиться

Haskell

factorial n = product [1..n]
4
ответ дан 2 revs, 2 users 75%SMYD JOEL 24 November 2019 в 15:33
поделиться

Clojure

Хвост-рекурсивный

(defn fact 
  ([n] (fact n 1))
  ([n acc] (if (= n 0) 
               acc 
               (recur (- n 1) (* acc n)))))

Короткий и простой

 (defn fact [n] (apply * (range 1 (+ n 1))))
4
ответ дан Brian Carper 24 November 2019 в 15:33
поделиться

Ничто не с такой скоростью, как удар & до н.э :

function fac { seq $1 | paste -sd* | bc; }  
$ fac 42
1405006117752879898543142606244511569936384000000000
$
4
ответ дан Johannes Schaub - litb 24 November 2019 в 15:33
поделиться

Значок

Рекурсивная функция

procedure factorial(n)
  return (0<n) * factorial(n-1) | 1
end

я обманул немного отрицательных сторон разрешения для возврата 1. Если Вы хотите, чтобы он перестал работать, учитывая отрицательный аргумент, это немного менее кратко:

  return (0<n) * factorial(n-1) | (n=0 & 1)

Тогда

write(factorial(3))
write(factorial(-1))
write(factorial(20))

печать

6
2432902008176640000

Повторяющийся генератор

procedure factorials()
  local f,n
  f := 1; n := 0
  repeat suspend f *:= (n +:= 1)
end

Тогда

every write(factorials() \ 5)

печать

1
2
6
24
120

Для понимания этого: оценка направлена на цель и отслеживает в обратном порядке при отказе. Нет никакого булева типа и бинарных операторов, которые возвратили бы булевскую переменную на других языках, или перестать работать или возвратить их второй аргумент - за исключением |, который в контексте единственного значения возвращает его первый аргумент, если он успешно выполняется, иначе пробует его второй аргумент. (в контексте нескольких-значений это возвращается, его первый аргумент тогда его второй аргумент)

suspend похож yield на других языках, за исключением того, что генератор явно не называют многократно для возврата его результатов. Вместо этого every спрашивает его аргумент в пользу всех значений, но ничего не возвращает по умолчанию; это полезно с побочными эффектами (в этом вводе-выводе случая).

\ пределы количество значений, возвращенных генератором, который в случае [1 111] было бы бесконечно.

4
ответ дан 3 revs 24 November 2019 в 15:33
поделиться

Agda2

Это Agda2, использующий очень хороший синтаксис Agda2.

module fac where

data Nat : Set where        -- Peano numbers
  zero : Nat
  suc : Nat -> Nat
{-# BUILTIN NATURAL Nat #-}
{-# BUILTIN SUC suc #-}
{-# BUILTIN ZERO zero #-}

infixl 10 _+_               -- Addition over Peano numbers
_+_ : Nat -> Nat -> Nat
zero + n    = n
(suc n) + m = suc (n + m)

infixl 20 _*_               -- Multiplication over Peano numbers
_*_ : Nat -> Nat -> Nat
zero * n = zero
n * zero = zero
(suc n) * (suc m) = suc n + (suc n * m)

_! : Nat -> Nat             -- Factorial function, syntax: "x !"
zero ! = suc zero
(suc n) ! = (suc n) * (n !)
3
ответ дан 24 November 2019 в 15:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: