用Ruby计算组合的算法

背景 (Background)

When I learned to code, I hadn’t slept in a math classroom in 14 years.

当我学会编码的时候,我已经有14年没睡在数学教室了。

I studied philosophy and taught courses on Symbolic Logic. I can talk about deductive proofs for days, but when people pull out a f of n’s… x²… [insert Greek letter] — I nod along, but trust me, I have no idea what’s happening.

我学习了哲学,并教授了符号逻辑课程。 我可以谈论几天的演绎证明,但是当人们拿出n的 f x²… [插入希腊字母]时—我一直点头,但请相信我,我不知道发生了什么事。

For this reason, I got a huge boost of empowerment when I figured out an algorithm question asking, “How can you determine the mathematical combination (nCr) of two numbers?”

出于这个原因,当我想到一个算法问题:“如何确定两个数字的数学组合(nCr)?”时,我的能力得到了极大的提升。

If you’re like ‘what the…?’, then hell yeah, you are me a day ago. Let’s go!

如果您想说“什么……?”,那么,是的,您是前一天。 我们走吧!

这肉 (The Meat)

Defining the Problem

定义问题

I’ll try my best to explain a combination:

我会尽力解释一个组合

Image for post

Imagine you’re losing a high stakes poker game. You have sweat on your neck as a couple Mafia grunts stare daggers at you. As the big one cracks his knuckles, you think “It’s a shame I never learned to count cards. But maybe start now?”

想象一下,您正在输掉高额桌扑克游戏。 一对黑手党的咕star声凝视着匕首,您的脖子上流汗了。 当大个子打断他的指关节时,您会认为“这是我从未学过数数卡的可耻之处。 但是也许现在开始?”

Your mind is racing. You start thinking, how do I start? How many possible hands are there in the deck? Well, there are 52 cards. You get 5 distinct cards in each hand, and they can come in any order. Let’s see, some quick math in your head and…

你的想法在加速。 您开始思考,我该如何开始? 甲板上有几只手? 好,有52张卡片。 您每手有5张不同的卡,它们可以按任何顺序排列。 让我们来看看,您的脑子里有了一些快速数学运算……

Image for post

Yeah, the answer is not obvious. But, you’re attempting a combination. A combination is when you have a collection of items and you want to find all the possible selections from that collection — for example, every possible hand from a deck of cards.

是的,答案并不明显。 但是,您正在尝试组合。 组合是指您拥有一个项目集合,并且想要从该集合中找到所有可能的选择-例如,一副纸牌中的每只可能的手。

By the way, the answer is 2,598,960. Each hand has a 1/2,598,960th chance of being drawn. With numbers that big, it’s good we can train a computer to solve the problem.

顺便说一句,答案是2,598,960。 每只手都有1 / 2,598,960的被抽中机会。 有了这么大的数字,我们可以训练一台计算机来解决问题,这是很好的。

Solution

The mathematical formula for finding a combination between two terms looks like this:

查找两个术语之间的组合的数学公式如下所示:

Image for post

The Ruby version looks like this:

Ruby版本如下所示:

Image for post

Explanation

说明

Okay, let’s break this down. The math works like this:

好吧,让我们分解一下。 数学原理如下:

  1. On top, we have n!. First, we find the factorial of our collection.

    最重要的是,我们有n! 。 首先,我们找到集合的阶乘。

  2. Next, we subtract our selection from the collection and find the factorial of that or(n — r)!.

    接下来,我们从集合中减去我们的选择,然后找到那个或(n — r)!的阶乘(n — r)!

  3. Find the factorial of our selection r! and multiply by the result of step 2.

    找到我们选择的阶乘r! 并乘以步骤2的结果。

  4. Finally, divide step 1 — n! — by the result of step 3 — r!(n-r)!.

    最后,划分步骤1- n! -通过第3步的结果r!(nr)!

Let’s translate this to Ruby

让我们将其翻译成Ruby

  1. Ruby does not have a method for finding a factorial so we have to write one. I found a couple of nice one-liners here and here.

    Ruby没有找到阶乘的方法,因此我们必须编写一个。 我在这里这里找到了两个不错的单线客。

def factorial(num)
(1..num).inject(1) { |prod, i| prod * i }
end

A factorial is the product of an integer and all the integers below it. So, if we wanted to know the factorial of 3 or3!, we calculate 1 * 2 * 3 and get 6.

阶乘是整数和其下所有整数的乘积。 因此,如果我们想知道3或3!的阶乘3! ,我们计算出1 * 2 * 3并得到6

Abstracting this with Ruby, inject will be a useful method. inject among other things, can take an array of numbers and apply a block reducing them to a single number. (That’s why inject is aliased as reduce).

使用Ruby对此进行抽象, inject将是一种有用的方法。 除其他外, inject可以采用数字数组并应用一个将其减少为单个数字的块。 (这就是为什么inject被别名为reduce的原因)。

In this case, our array is the range of numbers from 1 to our target. We iterate through the array multiplying each number to a parameter initially set to 1, and return the result.

在这种情况下,我们的数组是从1到目标的数字范围。 我们遍历数组,将每个数字乘以一个初始设置为1的参数,然后返回结果。

2. With our factorial method written, we can find the combination in one line.

2.通过编写阶乘方法,我们可以在一行中找到组合。

def get_combination(num1, num2)
factorial(num1) / (factorial(num2) * factorial(num1 - num2))
end

Here we are simply following the mathematical steps outlined earlier. We find the factorial of our collection, and divide it by the factorial of our set multiplied by the result of a factorial of the result of our collection minus our set. Got it?

在这里,我们仅遵循前面概述的数学步骤。 我们找到集合的阶乘,然后将其除以集合的阶乘乘以集合结果减去我们的集合的阶乘的结果。 得到它了?

Thanks for reading. Hope this helps someone!

谢谢阅读。 希望这对某人有帮助!

翻译自: https://medium.com/weekly-webtips/algorithms-calculating-combination-with-ruby-2784f6ddce4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值