找到 3x3 打孔的所有组合

2024-03-26

我参加了一个嘉年华,在每个地点,他们都会用特殊的打孔器标记您的节目。打孔器是一个 3x3 空间的网格。在每个空间中,要么有一根大头针刺破你的纸,要么没有。这让我想知道你可以用这个工具制作多少种不同的图案。我的第一个想法是:2^9 = 512,但是所有 9 个空格都是无针的,这并不是真正的一拳,所以真的是:511。

然后复杂性让我震惊。特别是因为工作人员在打孔时并不那么小心,所以这些看起来都是一样的:

x..  .x.  ...  etc.
.x.  x..  .x.
...  ...  ..x

问题:如何编写测试来考虑旋转和移位?


迄今为止的勤奋和想法:

  • 二进制感觉像是这个方程的一个明显的部分
  • 找到独特的模式后,将其存储在内存中,以便将来的模式可以针对它进行测试
  • 有 4 种旋转可能性。
    Edit:我所说的“旋转”是指你可以采用任何形状并将其旋转 90 度。考虑左上角的一个点的图案。您可以将其旋转 90 度,然后将点置于右上角。再次执行此操作,它位于右下角。再次,它位于左下角。使用纯 2^9 计算,有 4 种不同的组合。然而,对于这个问题,这些正是我试图清除的重复项。
  • 对于每次旋转,有 25 种方法使 3x3 网格重叠:

重叠:

/ = the spaces in the new one to test
\ = the spaces in a verified unique one

1               2               25
/ / / . . . .   . / / / . . .   . . . . . . .
/ / / . . . .   . / / / . . .   . . . . . . .
/ / X \ \ . .   . / X X \ . .   . . \ \ \ . .
. . \ \ \ . .   . . \ \ \ . .   . . \ \ \ . .
. . \ \ \ . .   . . \ \ \ . .   . . \ \ X / /
. . . . . . .   . . . . . . .   . . . . / / /
. . . . . . .   . . . . . . .   . . . . / / /
  • 如果任一图案包含不在重叠区域中的引脚,则不需要测试重叠。按位与可以在这里提供帮助。
  • 如果将 2 个模式的每个位置都放入字符串中,则只需检查是否相等
  • 能否将前两种想法结合起来以提高效率?

我们只需要考虑在第一行和第一列有冲孔的图案。如果第一行为空,则模式可以上移。如果第一列为空,则模式可以向左移动。无论哪种情况,我们都可以得出我们确实考虑的类似模式。

对于这些模式,我们需要检查旋转后的版本是否相同。为此,我们应用最多三个 90 度旋转,可能会向左移动以删除前导空列(第一行永远不为空)并查找具有最低数值的模式。

然后我们可以将该值添加到哈希集中,该哈希集将仅保留唯一值。

不包括空模式,因为它的所有行都是空的。

为了实现这一点,我们将模式编码为连续位:

012
345
678

我们需要的操作大多非常简单:

Test for an empty row:    (n & 7) == 0     // bits 0,1,2 not set
Test for an empty column: (n & 73) == 0    // bits 0,3,6 not set
Shift pattern up:         n -> (n >> 3)
Shift pattern left:       n -> (n >> 1)

最棘手的部分是旋转,这实际上只是重新排列所有位:

n -> ((n & 1) << 2) + ((n & 2) << 4) + ((n & 4) << 6)
   + ((n & 8) >> 2) + (n & 16) + ((n & 32) << 2)
   + ((n & 64) >> 6) + ((n & 128) >> 4) + ((n & 256) >> 2);

In C#:

public static int Count3x3() {
    HashSet<int> patterns = new HashSet<int>();
    for (int i = 0; i < 512; i++) {
        if ((i & 7) == 0 || (i & 73) == 0)
            continue;
        int nLowest = i;
        int n = i;
        do {
            nLowest = Math.Min(nLowest, n);
            n = ((n & 1) << 2) + ((n & 2) << 4) + ((n & 4) << 6)
                + ((n & 8) >> 2) + (n & 16) + ((n & 32) << 2)
                + ((n & 64) >> 6) + ((n & 128) >> 4) + ((n & 256) >> 2);
            while ((n & 73) == 0)
                n >>= 1;
        } while (n != i);
        patterns.Add(nLowest);
    }
    return patterns.Count;
}

这个函数返回116。在我的机器上花费的时间是0.023ms。

EDIT:通过使用 4 个观察结果,您可以获得额外 7 倍的改进:

  1. 我们可以使用简单的访问数组来代替哈希集。如果以前见过某种模式,我们就不会计算它。这也消除了跟踪内循环中“最低”模式的需要。如果访问了一个模式,那么它的最低旋转模式也会被访问。
  2. 如果我们没有 180 度旋转对称性,那么第三次旋转将不会产生原始图案。第四次旋转总是会发生,所以没有必要。
  3. 旋转表达式可以稍微简化。

因此,如果我们应用这些观察结果并展开内部 do 循环,我们会得到以下结果:

static int Rotate(int n) {
    n = ((n & (1+32)) << 2) + ((n & 2) << 4) + ((n & 4) << 6)
        + ((n & (8+256)) >> 2) + (n & 16)
        + ((n & 64) >> 6) + ((n & 128) >> 4);
    while ((n & 73) == 0) 
        n >>= 1;
    return n;
}
public static int Count3x3_3() {
    bool[] visited = new bool[512];
    int count = 0, r;
    for (int i = 0; i < 512; i++) {
        if (visited[i])
            continue;
        if ((i & 7) == 0 || (i & 73) == 0)
            continue;
        count++;
        if ((r = Rotate(i)) == i) continue;
        visited[r] = true;
        if ((r = Rotate(r)) == i) continue;
        visited[r] = true;
        visited[Rotate(r)] = true;
    }
    return count;
}

在同一台机器上运行时间约为 3μs。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

找到 3x3 打孔的所有组合 的相关文章

  • 在 C 中打印字符串的所有排列

    我正在学习回溯和递归 并且我陷入了打印字符串所有排列的算法 我用以下方法解决了它贝尔算法 http programminggeeks com bell algorithm for permutation 用于排列 但我无法理解递归方法 我在
  • 如何在代码生成过程中简化包含变量的 C 风格算术表达式?

    我正在尝试优化编译器中的表达式求值 算术表达式都是C风格的 并且它们可以包含变量 我希望尽可能简化表达 例如 3 100 A B 100 3 100可以简化为409 300 A B 主要取决于分配律 结合律和交换律 我遇到的主要困难是如何将
  • 如何检查一个盒子是否适合另一个盒子(允许任何旋转)

    假设我有两个盒子 每个盒子都是一个长方体 http en wikipedia org wiki Rectangular cuboid aka长方体 我需要编写一个函数来决定盒子是否具有尺寸 一 二 三 可以装入具有尺寸的盒子中 甲 乙 丙
  • 如何选择部分密集数据集的均匀分布子集?

    P是一个 n d 矩阵 持有nd 维样本 P某些地区的密度是其他地区的几倍 我想选择一个子集P其中任意样本对之间的距离大于d0 并且我需要将其传播到整个区域 所有样本都具有相同的优先级 无需优化任何内容 例如覆盖面积或成对距离之和 这是执行
  • 修改排列算法以防止重复打印输出的策略

    我一直在审查实践算法 目前正在研究一种我非常喜欢的排列算法 void permute char set int begin int end int range end begin if range 1 cout lt lt set lt l
  • 如何找到最长的回文子序列(不是它的长度)

    我想找出字符串中最长的回文子序列 我到处都找到了找出子序列长度的算法 并声明该算法也可以扩展以返回子序列 但我没有找到如何实现的 有人能解释一下我怎样才能得到序列吗 既然你提到了链接最长回文子序列 http www geeksforgeek
  • 以一定角度遍历二维数组

    通常我们按行或列遍历数组 但这里我想以角度遍历它 我会尝试解释我的意思 因此 假设角度是 45 度 那么它会搜索为 0 0 then 0 1 1 0 then 0 2 1 1 2 0 等等 抱歉 无法上传图像 因为我是新用户 不允许这样做
  • 交换两个向量之间的值,使两个向量的 max_element 之和最小

    这是 Codechef 的问题 但请耐心等待 https www codechef com ZCOPRAC problems ZCO16001 https www codechef com ZCOPRAC problems ZCO16001
  • 两个非嵌套循环的大 O 表示法

    对于两个非嵌套的 for 循环 大 O 表示法是什么 Example for int i 0 i
  • 在无向图中查找强连通分量

    我想在无向图中找到强连接的组件 即如果我从节点开始A然后我会回到节点A并且每条边都被恰好访问一次 对于有向图可以使用Tarjan算法来寻找强连通分量 但是对于无向图怎么办 我认为您错过了强连通分量的含义 强连接组件 如果所有顶点对之间都存在
  • 如何计算两个ip之间的主机数量? C#

    我有两个ip 1 1 1 1 1 2 4 4 4 4 显然这只是一个例子 这是一个动态计算器 如果子网掩码不相关 我如何计算所述 ip 之间的主机数量 要计算 理论 IP 地址的数量 您需要将每个 IP 地址转换为其 32 位整数格式 这实
  • 加密成本高,解密成本低

    我希望该用户 攻击者加密数据并发送给服务器 现在我想要一种与标准算法完全相反的算法 使用快 难以解密 即很难使用服务器发送的密钥来加密密码等数据 以防止随机攻击 但很容易解密这样服务器在验证用户时消耗的时间非常少 但是对于攻击者来说 每次使
  • 反转二进制网络

    如何反转二元方程 以便找到哪些输入将产生给定的输出 Example Inputs i0 through i8 Outputs o0 through o8 Operators XOR AND 二元方程 1 i0 1 i1 0 i2 1 i3
  • Java:如何实现3和?

    我正在研究 3 Sum 来自己实现它 并遇到了以下规则的实现 给定一个由 n 个整数组成的数组 S S 中是否存在满足 a b c 0 的元素 a b c 查找数组中所有总和为零的唯一三元组 注意 三元组 a b c 中的元素必须按非降序排
  • Exposé 布局算法

    我正在制作一些项目 其布局类似于 Mac OS X 在 Expos 中对窗口所做的操作 它适应项目的长宽比和可用区域的长宽比 基本上 可用区域分为行和列 每个单元格 行和列的交集 中放置一个项目 这些项目必须保持其纵横比 此处width h
  • 从日志文件中获取前 100 个 URL

    我的一位朋友在接受采访时被问到以下问题 谁能告诉我如何解决它 我们有一个相当大的日志文件 大约 5GB 日志文件的每一行都包含一个用户在我们网站上访问过的 URL 我们想要找出用户访问最多的 100 个 URL 怎么做 如果我们有超过 10
  • 如何查找给定字符串中仅出现一次的第一个字符[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 在 O(n) 时间内找到 n x n 矩阵中的局部最小值

    所以 这不是我的家庭作业问题 而是取自 coursera 算法和数据结构课程的未评分作业 现已完成 You are given an n by n grid of distinct numbers A number is a local m
  • 检索受“rowspan”影响的行的列索引的最有效方法是什么?

    考虑下表 table thead tr th th th A th th B th th C th tr thead tbody tr th 1 th td Apples td td Oranges td td Pears td tr tb
  • 删除队列中的最后一个元素

    我需要删除队列的最后一个元素 我唯一可以使用的操作是 Peek 获取第一个元素而不删除它 Enqueue element 向队列末尾插入一个元素 Dequeue 删除第一个元素 IsEmpty true 或 false 队列是否为空 而且我

随机推荐

  • 如何挂钩异步 Backbone 事件来显示 HTML

    我想做的是调用数据库 然后以 HTML 形式显示结果 我一切正常 数据从数据库返回得很好 除了我无法弄清楚如何显示数据 我知道fetch 是异步的 但我不确定如何将其连接到我的集合视图中 这是我的骨干 function window App
  • 列出以特定字符开头的文件

    我有一个文件夹 其中包含以下名称的文件 5 45name Rdata and 15 45name Rdata 我只想列出以 5 开头的那些 在上面的示例中这意味着我想排除 15 45name Rdata Using list files p
  • silverlight DataGrid 中的复选框行为异常

    我在用checkbox in an itemtemplate中的列Silverlight 5 数据网格 我面临着一个奇怪的问题 当我选择多个时checkbox然后上下滚动网格 选择会转移到其他checkbox 我在代码中修复了这个问题 我在
  • Flutter/Dart 数量处理能力

    我是 Flutter 的新手 我想做一个输入量大的计算器 考虑每个数字 30 40 位 有人可以帮助我如何做到这一点吗 就像在 android 中我使用 BigDecimal 一样 Flutter 中的替代方案是什么 您可以使用decima
  • 根据传入的字符串设置枚举值

    我有许多需要枚举的设置方法 这些基于传入对象属性 有一种方法可以避免硬编码 10 种不同的 case 语句 而不是编写一堆这样的语句 有没有办法创建可重用的方法 Side class declared as public final enu
  • iOS / FCM - 如何使用有效负载中的图像名称将 XCAsset 文件夹中的图像显示为通知附件?

    我正在为通过 FCM 发送的天气应用程序开发丰富通知 首先 我想通知您 我的通知已通过 APNS 和 FCM 成功发送和接收 我在用Pusher https github com noodlewerk NWPusher and Postma
  • 用 jQuery 动态替换 img src 属性

    我正在尝试使用 jQuery 替换给定源的 img 源 例如 当图像源为 smith gif 时 替换为 johnson gif 如果 williams gif 替换为 Brown gif 等 编辑 图像是从 XML 中按随机顺序检索的 每
  • Kotlin 喜欢 Javascript 中的作用域函数(let、also、apply、run)吗?

    是否可以在 Javascript Typescript 中创建类似 Kotlin 的作用域函数 有没有图书馆可以做到这一点 参考 https kotlinlang org docs reference scope functions htm
  • 在 iframe 中访问 TinyMCE 当前输入

    我正在使用 TinyMCE 并且尝试将用户当前输入的内容输出到 TinyMCE 编辑器下方的 div 中 我希望用户看到帖子的渲染效果如何 我正在使用的脚本是这样的 我已将相应的 div 放置在视图中的开始表单中 div div 然而 当我
  • sIFR 还是 FLIR?

    我最近遇到了面部提升术 这是 sIFR 的替代方案 我想知道那些同时拥有 sIFR 和 FLIR 经验的人是否可以介绍一下他们使用 FLIR 的经验 对于那些还没有了解 FLIR 工作原理的人来说 FLIR 的工作原理是使用 JavaScr
  • 不同的交易必须保证选择不同的项目;避免争论

    作为注册新用户的一部分 我们从预编译列表 表 中为它们分配资源 在本例中为 Solr 核心 如果 5 个用户注册 则必须为他们分配 5 个不同的核心 如果用户成功注册 分配即为最终分配 请参阅下面的描述 但在现实世界中 同时注册新用户竞争同
  • 如何在表单提交时打开新窗口

    我有一个提交表单 并希望它在用户提交表单时打开一个新窗口 以便我可以在分析中跟踪它 这是我正在使用的代码
  • QWidgets可以添加到QWindow中吗?

    现在推荐使用QWindow进行OpenGL绘图 是否可以向此窗口添加小部件 如果是这样 怎么办 如果没有 我应该如何使用 Qt5 将小部件添加到 OpenGL 程序中 应用程序通常会使用QWidget or QQuickView对于它的 U
  • Laravel Auth::user() 关系

    我试图通过 Auth user 函数获取我的用户角色关系 我以前曾这样做过 但由于某种原因它不起作用 Auth user gt role 这将返回尝试从非对象获取属性的错误 在我的用户模型中我有这个 public function role
  • Flask-SQLAlchemy 和 Flask-Restless 不获取孙子

    Problem 我正在 Flask Flask SQLAlchemy 和 Flask Restless 上构建一个应用程序 我使用 Restless 生成了一个用于父子孙关系的 API 我的孩子上的 GET 将正确获取孙子 但父母上的 GE
  • 如何减少部署时的 Docker 映像大小?

    所以我刚刚创建了一个非常基本的 Node 应用程序 我想练习将其放入docker容器中并部署到另一台服务器上 我正在使用这里的步骤 https nodejs org en docs guides nodejs docker webapp h
  • 跳过 FlatFileParseException 或 Spring Batch 中的特定异常

    您好 我需要读取 n 个 平面文件 在文件读取期间 如果从读取器收到 FileParseException 则停止当前文件读取并安全退出并处理下一个文件并继续作业执行 目前我有这个 xml 配置 但我不想这样做 因为我没有真正的跳过限制计数
  • 春云|假装 Hytrix |首次调用超时

    我有一项服务使用了 3 个假客户端 每次启动应用程序时 我都会在第一次调用任何假客户端时收到 TimeoutException 在一切稳定之前 我必须至少触发每个假客户端一次 在网上查了一下 问题是 feign 或 hystrix 内部的某
  • 通过隧道颠覆

    对于工作 我在一个封闭的网络中工作 我们设置了一些只能从我们的网络内部访问的 IP 地址 不过 有一个盒子 我们可以通过 SSH 进入并通过隧道到达我们各自的开发者盒子 我知道我可以通过使用以下方式从我们的开发者盒子获得流量 Lssh 的参
  • 找到 3x3 打孔的所有组合

    我参加了一个嘉年华 在每个地点 他们都会用特殊的打孔器标记您的节目 打孔器是一个 3x3 空间的网格 在每个空间中 要么有一根大头针刺破你的纸 要么没有 这让我想知道你可以用这个工具制作多少种不同的图案 我的第一个想法是 2 9 512 但