রুবি ফ্যাক্টরিয়াল ফাংশন


89

আমি পাগল হয়ে যাচ্ছি: ফ্যাকটোরিয়ালটির জন্য রুবি ফাংশনটি কোথায়? না, আমার টিউটোরিয়াল বাস্তবায়ন দরকার নেই, আমি কেবল লাইব্রেরি থেকে ফাংশন চাই। এটা ম্যাথে নেই!

আমি সন্দেহ করতে শুরু করছি, এটি কি একটি স্ট্যান্ডার্ড লাইব্রেরি ফাংশন?


63
আমি এটির মতো করি6.downto(1).inject(:*)
মার্চকে

43
@মেকেড: বা (1..6).inject(:*)যা কিছুটা বেশি সংঘাতযুক্ত ।
sepp2k

8
আপনি কেন সেখানে এক হওয়ার আশা করবেন?
রাষ্ট্রপতি জেমস কে পোলক

4
আমি ভাবছি যে রুবির জন্য গণিত এবং বিজ্ঞানের পাঠাগারগুলির স্ট্যাটাসটি কী।
অ্যান্ড্রু গ্রিম

4
ইনজেকশন ব্যবহার করে প্রদত্ত উদাহরণগুলিতে কেবল একটি নোট। (1..num).inject(:*)ক্ষেত্রে যেখানে ব্যর্থ num == 0(1..(num.zero? ? 1 : num)).inject(:*)0 কেসের জন্য সঠিক উত্তর দেয় এবং nilনেতিবাচক পরামিতিগুলির জন্য ফিরে আসে ।
যোগ

উত্তর:


136

স্ট্যান্ডার্ড লাইব্রেরিতে কোনও ফ্যাক্টরিয়াল ফাংশন নেই।


7
রুবির Math.gammaপদ্ধতি রয়েছে, যেমন স্ট্যাকওভারফ্লো.com
ডোরিয়ান

4
কি পাগল যুক্তি! আমাদের (এন -১) আছে! ফাংশন এবং সরল এন নেই! !!!
আলেকজান্ডার গর্গ


77

এটি স্ট্যান্ডার্ড লাইব্রেরিতে নেই তবে আপনি পূর্ণসংখ্যার শ্রেণিটি প্রসারিত করতে পারেন।

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

সুস্পষ্ট পারফরম্যান্স কারণে এনবি আইট্রেটিভ ফ্যাক্টরিয়াল একটি ভাল পছন্দ।


8
তিনি স্পষ্টভাবে বলেছিলেন, তিনি কোনও বাস্তবায়ন চান না।
sepp2k

117
সে নাও পারে; তবে লোকেরা "রুবি ফ্যাক্টরিয়াল" অনুসন্ধান করতে পারে।
পিয়েরে-আন্তোইন লাফায়েট


পুনরাবৃত্ত সংস্করণটি কি আসলেই ধীর? এটি রুবি পুচ্ছ-পুনরাবৃত্তি অপ্টিমাইজেশন করে কিনা তার উপর নির্ভর করে।
লেকস লিন্ডসে

24

Http://rosettacode.org/wiki/Factorial# রবি থেকে নির্লজ্জভাবে আঁকড়ে ধরা হয়েছে , আমার ব্যক্তিগত প্রিয়

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

>> 400.fact
=> 64034522846623895262347970319503005850702583026002959458684445942802397169186831436278478647463264676294350575035856810848298162883517435228961988646802997937341654150838162426461942352307046244325015114448670890662773914918117331955996440709549671345290477020322434911210797593280795101545372667251627877890009349763765710326350331533965349868386831339352024373788157786791506311858702618270169819740062983025308591298346162272304558339520759611505302236086810433297255194852674432232438669948422404232599805551610635942376961399231917134063858996537970147827206606320217379472010321356624613809077942304597360699567595836096158715129913822286578579549361617654480453222007825818400848436415591229454275384803558374518022675900061399560145595206127211192918105032491008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

রোজটা কোডে তালিকাভুক্ত রূপগুলির মধ্যে এই প্রয়োগটি দ্রুততম হিসাবে ঘটে to

আপডেট # 1

|| 1শূন্য কেস পরিচালনা করতে যোগ করা হয়েছে।

আপডেট # 2

মার্ক থমাসকে ধন্যবাদ এবং প্রশংসা সহ , এখানে এমন একটি সংস্করণ দেওয়া হয়েছে যা কিছুটা দক্ষ, মার্জিত এবং অস্পষ্ট:

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

4
হেক মানে কি ?! হ্যাঁ এটি দ্রুত তবে এটির খুব অযৌক্তিকভাবে যদিও
নিককোলো মি।

4
এটি 0 এর জন্যও ভুল! - এর মতো কিছু হওয়া উচিত: যদি স্ব <= 1; 1; অন্য; (1.. নিজেই) .ড্রেস (: *); শেষ
টারমো

9
@ অ্যালেন - ভাষাটি বুঝতে না পারলে দোষ দেবেন না। এর সহজ অর্থ হল, 1 ব্যাপ্তিকে নিজের দিকে নিয়ে যান, তারপরে এটি থেকে প্রথম উপাদানটি (1) সরান (অর্থাত্‍ এটি কার্যকরী প্রোগ্রামিংয়ের মানে হ্রাস করে)। তারপরে যা বাকি আছে তার প্রথম উপাদানটি মুছে ফেলুন (২) এবং তাদের একসাথে গুণ করুন (: *)। এখন যা বাকি আছে তা থেকে প্রথম উপাদানটি সরিয়ে ফেলুন (3) এবং চলমান মোটের সাথে এটিকে গুণ করুন। কিছুই বাকি না হওয়া পর্যন্ত চালিয়ে যান (যেমন আপনি পুরো ব্যাপ্তিটি পরিচালনা করেছেন)। যদি ব্যর্থতা হ্রাস করে (কারণ অ্যারেটি 0 এর ক্ষেত্রে খালি) তবে কেবল যাইহোক 1 তে ফিরে আসুন।
SDJMcHattie

তুমিও প্রাথমিক মান নির্দিষ্ট করে শূন্য ক্ষেত্রে সব ব্যবস্থা করতে সক্ষম reduce: (1..self).reduce(1,:*)
মার্ক থমাস

4
আসলে আপনি ব্যবহার করতে পারেন (2..self).reduce(1,:*), যদি মাইক্রো-দক্ষতা আপনার জিনিস হয় :)
মার্ক থমাস


14

আপনি Math.gammaপূর্ণসংখ্যার পরামিতিগুলির জন্য ফাংশনরিলে ফোঁড়া ফাংশনটি ব্যবহার করতে পারেন ।


4
দস্তাবেজগুলি থেকে: "নোট করুন যে গামা (এন) পূর্ণসংখ্যার ক্ষেত্রে (n-1) হিসাবে একই (n) 0 তবে গামা (এন) ভাসমান ফেরত দেয় এবং একটি অনুমান হতে পারে"। যদি কেউ এটি বিবেচনায় নেয় তবে এটি কাজ করে, তবে হ্রাস সমাধানটি আরও অনেকগুলি সোজা সামনে বলে মনে হয়।
মাইকেল কোহল

এর জন্য ধন্যবাদ! আমার অন্ত্রে যখনই সম্ভব কাস্টম-লিখিত হ্রাস উপর স্ট্যান্ডার্ড লাইব্রেরি ব্যবহার করতে বলে। প্রোফাইলিং অন্যথায় পরামর্শ দিতে পারে।
ডেভিড জে

4
দ্রষ্টব্য: এটি এর হে (1) এবং জন্য সুনির্দিষ্ট 0..22: এমআরআই রুবি আসলে ঐ মানের জন্য একটি লুকআপ (দেখুন সঞ্চালিত static const double fact_table[]মধ্যে উৎস )। এর বাইরেও এটি একটি আনুমানিক। 23!, উদাহরণস্বরূপ, 56-বিট ম্যান্টিসার প্রয়োজন যা তিনি আইইইই 754 ডাবল ব্যবহার করেছেন যা 53-বিট ম্যান্টিসাস ব্যবহার করে যথাযথভাবে উপস্থাপন করা অসম্ভব।
fny

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

উদাহরণ

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

এর সাথে কী হয়েছে class Integer ; def ! ; (1..self).inject(:*) ; end ; end?
আলেক্সেই মাতিউশকিন

@ মুদাসোবওয়া আমার পছন্দ হয়েছে, আমি সরলতার জন্য রিফেক্টর করেছি।
জেসনলনহার্ড

4
আমি শ্রদ্ধার সাথে পরামর্শ দিচ্ছি যে মিথ্যাবাদী কোনও ব্যক্তি আপনাকে অনেক বন্ধু নাও বানিয়ে তুলতে সত্যের মান ফিরিয়ে দেওয়ার জন্য সমস্ত রুবি অবজেক্টের সাথে অন্তর্ভুক্ত একটি উদাহরণ পদ্ধতি ওভাররাইড করা উচিত।
MatzFan

এটা তোলে অস্বীকার অপারেটর করতে যখন অন্য কিছু পরিণত সত্যিই বিপজ্জনক হতে পারে aহতে হবে Integerক্ষেত্রে !a... এমনটি অস্তিত্ব একটি বাগ যা খুবই বলা কঠিন হতে পারে। যদি aএরকম একটি বড় সংখ্যক হিসাবে ঘটে থাকে 357264543তবে প্রসেসরটি একটি বড় লুপের মধ্যে চলে যাচ্ছে এবং লোকেরা ভাবতে পারে যে কেন প্রোগ্রামটি হঠাৎ ধীর হয়ে যায়
অবিচ্ছিন্নতা

এই উত্তরটি ব্যবহারের ব্যবহারিক উদাহরণের চেয়ে ভাগ করে নেওয়া কেবল একটি দুর্দান্ত জিনিস ছিল।
জেসনলনহার্ড


6

আমি শুধু আমার নিজের লিখেছি:

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


3

ব্যবহার Math.gamma.floorকরা একটি আনুমানিক উত্পাদনের সহজ উপায় এবং তারপরে এটিকে সঠিক সংখ্যার ফলাফলের দিকে ফিরিয়ে আনা হয়। সমস্ত পূর্ণসংখ্যার জন্য কাজ করা উচিত, যদি প্রয়োজন হয় একটি ইনপুট চেক অন্তর্ভুক্ত।


6
সংশোধন: n = 22এটি সঠিক উত্তর দেওয়া বন্ধ করার পরে এবং আনুমানিক উত্পাদন করে।
আয়র্ক

2

যারা আমাদের অংশগ্রহণে অংশ নিয়েছিল এবং তাদের সময় ব্যয় করেছিল তাদের প্রতি শ্রদ্ধার সাথে আমি এখানে তালিকাভুক্ত সমাধানগুলির আমার বেঞ্চমার্কগুলি ভাগ করতে চাই share পরম:

পুনরাবৃত্তি = 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)

এন = 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)

4
লক্ষণীয় যে দ্রুততমটি Math.gamma(n+1)কেবলমাত্র n> 22 এর জন্যই আনুমানিক, সুতরাং সমস্ত ব্যবহারের ক্ষেত্রে এটি উপযুক্ত নাও হতে পারে।
নীল স্লেটার

1

এটি করার জন্য অন্য একটি উপায়, যদিও এটি সত্যিই প্রয়োজনীয় নয়।

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

1

আপনি সম্ভবত একটি রুবি বৈশিষ্ট্য অনুরোধ দরকারী পাবেন। এটিতে একটি অনিয়ন্ত্রিত প্যাচ রয়েছে যা একটি ডেমো বাশ স্ক্রিপ্ট অন্তর্ভুক্ত করে । একটি নিষ্পাপ লুপ এবং ব্যাচের উপস্থাপিত সমাধানের মধ্যে গতির পার্থক্যটি আক্ষরিকভাবে 100x (শতগুণ) হতে পারে। খাঁটি রুবিতে সব লিখেছেন।


1

এখানে আমার সংস্করণটি পরিষ্কার হিসাবে মনে হচ্ছে যদিও এটি পরিষ্কার নয়।

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

এটি ছিল আমার আইআরবি পরীক্ষার লাইন যা প্রতিটি পদক্ষেপ দেখিয়েছিল।

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

0
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

0

এবং এখনও অন্য উপায় (=

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)

0

এটি করার আরও একটি উপায়:

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

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

fact(6) => 720

0

এই সঠিক কাজের জন্য অন্তর্নির্মিত পুনরাবৃত্তি রয়েছে কেন, কেন স্ট্যান্ডার্ড লাইব্রেরির একটি ফ্যাক্টরিয়াল পদ্ধতি প্রয়োজন? একে বলা হয় upto

এই সমস্ত উত্তরগুলির মতো আপনার পুনরাবৃত্তি ব্যবহার করার দরকার নেই।

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

বরং অন্তর্নির্মিত পুনরুক্তিটি ফ্যাকটোরিয়াল গণনা করতে ব্যবহার করা যেতে পারে:

factorial = 1
1.upto(10) {|x| factorial *= x }
factorial
 => 3628800
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.