gpt4 book ai didi

ruby-on-rails - 如何查找范围是否包含在范围数组中?

转载 作者:数据小太阳 更新时间:2023-10-29 07:45:51 25 4
gpt4 key购买 nike

例子

business_hours['monday'] = [800..1200, 1300..1700]
business_hours['tuesday'] = [900..1100, 1300..1700]

...

例如,我有一堆事件占据了其中的一些间隔

event = { start_at: somedatetime, end_at: somedatetime }

遍历从某个日期到某个日期的事件,我创建了另一个数组

busy_hours['monday'] = [800..830, 1400..1415]

...

现在我的挑战是

  • 创建一个包含 business_hours 减去 busy_hours 的 available_hours 数组

available_hours = business_hours - busy_hours

  • 给定一个特定的持续时间,比如 30 分钟,找出 available_hours 中有哪些时间段可用。在上面的示例中,这样的方法将返回

available_slots['monday'] = [830..900, 845..915, 900..930, 等等]

并不是说它会以 15 分钟的增量检查指定持续时间的时段的 available_hours。

感谢您的帮助!

最佳答案

我认为这是位域的工作。不幸的是,这个解决方案将依赖于魔数(Magic Number)、转换助手和相当多的二进制逻辑,所以它不会很漂亮。但它会工作并且非常有效。

这就是我处理问题的方式:

将您的每一天分成合理的时间间隔。我将按照您的示例并将每个 15 分钟的时间 block 视为一个时间 block (主要是因为它使示例保持简单)。然后将您每小时的可用性表示为十六进制数字。

例子:

  • 0xF = 0x1111 => 整个小时可用。
  • 0xC = 0x1100 => 在前半个小时可用。

将其中的 24 个串在一起代表一天。如果您可以确定不会在范围之外发生任何事件,则可以更少。该示例继续假设 24 小时。

从这一点开始,为了便于阅读,我将长十六进制数字拆分为单词假设一天从 00:00 到 23:59 business_hours['monday'] = 0x0000 0000 FFFF 0FFF F000 0000

要获得 busy_hours,您可以以类似的格式存储事件,并将它们全部放在一起。

示例:

event_a = 0x0000 0000 00F0 0000 0000 0000 # 10:00 - 11:00 
event_b = 0x0000 0000 0000 07F8 0000 0000 # 13:15 - 15:15

busy_hours = event_a & event_b

从 busy_hours 和 business_hours 你可以得到空闲时间:

available_hours = business_hours & (busy_hours ^ 0xFFFF FFFF FFFF FFFF FFFF FFFF)

xor(^) 本质上是将 busy_hours 转换为 not_busy_hours。 Anding (&) not_busy_hours 与 business_hours 为我们提供了当天的可用时间。

该方案还使得比较许多人的可用时间变得简单。

all_available_hours = person_a_available_hours & person_b_available_hours & person_c_available_hours

然后找到适合可用时间的时间段。你需要做这样的事情:将您的时间长度转换为与小时类似的十六进制数字,其中这些数字代表时隙将覆盖的该小时的所有时间 block 。接下来右移数字,这样就没有尾随的 0。

例子胜于解释:0x1 => 15 分钟,0x3 => 半小时,0x7 => 45 分钟,0xF => 整小时,... 0xFF => 2 小时等

完成后,您可以执行以下操作:

acceptable_times =[]
(0 .. 24 * 4 - (#of time chunks time slot)).each do |i|
acceptable_times.unshift(time_slot_in_hex) if available_hours & (time_slot_in_hex << i) == time_slot_in_hex << i
end

范围的高端有点乱。所以让我们多看看它。我们不想移动太多次,否则我们可能会在频谱的早期开始出现误报。

24 * 4 一天中的 24 小时,每个小时由 4 位表示。- (#of time chunks in time slot) 在我们正在寻找的时间段中,每 15 分钟减去 1 个检查。这个值可以通过 (Math.log(time_slot_in_hex)/Math.log(2)).floor + 1

找到

从一天结束时开始,检查每个时间段,在每次迭代中提前一个时间 block (在本例中为 15 分钟)。如果时间段可用,则将其添加到可接受时间的开始。因此,当流程完成时,acceptable_times 按发生顺序排序。

很酷的是,这个实现允许合并时间段,这样您的与会者可以在他们一天中有一个忙碌的时期,将您正在寻找的时间段平分,休息一下,否则他们可能很忙。

由您编写在范围数组(即:[800..1200, 1300..1700])和十六进制表示之间进行转换的辅助函数。最好的方法是将行为封装在对象中并使用自定义访问器方法。然后使用相同的对象来表示日期、事件、繁忙时间等。唯一没有内置到该方案中的是如何安排事件,以便它们可以跨越日期的边界。

关于ruby-on-rails - 如何查找范围是否包含在范围数组中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1609267/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com