比提供的解决方案更快地获取排列索引和索引处的排列

2023-12-02

多亏了这个answer,这是我如何获取排列索引和索引处的排列:

import time


def get_Cl(distinct):
    Cl = []
    for i in range(1, distinct + 1):  # i is distincct
        c = [0] * i + [1, 0]
        C = [c]
        for l in range(2, distinct + 1):
            c = [
                    c[d] * d + c[d + 1] * (distinct - d)
                    for d in range(i + 1)
                ] + [0]
            C.append(c)
        Cl.append(C)
    return Cl


def item_index(item, distinct, n_symbols, Cl):
    length = len(item)
    offset = 0
    seen = set()
    for i, di in enumerate(item):
        for d in range(n_symbols):
            if d == di:
                break
            if d in seen:
                # test = Cl[distinct][length - 1 - i][len(seen)]
                offset += Cl[distinct][length - 1 - i][len(seen)]
            else:
                offset += Cl[distinct][length - 1 - i][len(seen) + 1]
        seen.add(di)
    return offset


def item_at(idx, length, distinct, n_symbols, Cl):
    seen = [0] * n_symbols
    prefix = [0] * length
    used = 0
    for i in range(length):
        for d in range(n_symbols):
            if seen[d] != 0:
                branch_count = Cl[distinct][length - 1 - i][used]
            else:
                branch_count = Cl[distinct][length - 1 - i][used + 1]
            if branch_count <= idx:
                idx -= branch_count
            else:
                prefix[i] = d
                if seen[d] == 0:
                    used += 1
                seen[d] = 1
                break
    return prefix


if __name__ == "__main__":
    start_time = time.time()
    Cl = get_Cl(512)
    end_time = time.time()
    print(f'{(end_time - start_time)} seconds for Cl')
    start_time = time.time()
    item = item_at(idx=432, length=512, distinct=350, n_symbols=512, Cl=Cl)
    end_time = time.time()
    print(f'{(end_time - start_time)} seconds for item_at')
    print(item)
    start_time = time.time()
    print(item_index(item=item, distinct=350, n_symbols=512, Cl=Cl))
    end_time = time.time()
    print(f'{(end_time - start_time)} seconds for item_index')
356.3069865703583 seconds for Cl
2.5428783893585205 seconds for item_at  
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 351, 458]  
432
0.025868892669677734 seconds for item_index

它工作得很好,除非数字变大,然后它会变得非常慢。想知道是否可以改进这段代码this答案是计算所有排列的同一慢速函数的改进版本?

我得到的原因Cl在单独的一行中是对于固定的distinct将会有数千个电话item_at and item_index, 所以Cl是一样的如果distinct是相同的,因此不需要为每个调用它item_at or item_index.

Update:答案的测试结果

0.008994340896606445 seconds for item_at
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 347, 348, 344, 345, 346, 349]
432
0.006995677947998047 seconds for item_index

在这个答案中,我将演示两个可以用来提高速度的修改item_at and item_index.

在开始之前,让我们初始化 Cl 表,以处理调用distinct=200

def get_Cl(length, distinct):
      i = distinct
      c = [0] * i + [1, 0]
      C = [c]
      for l in range(2, length+1):
          c = [
                  c[d] * d + c[d + 1] * (i - d)
                  for d in range(i + 1)
              ] + [0]
          C.append(c)
      return C;

Cl = {200:get_Cl(300, 200)}

修改为item_index

请注意,内循环item_index只是递增offset由不依赖的值d in seen但不在d本身。如果我们提前知道多少次d in seenTrue。因此,让我们以跟踪之前看到的值的数量的方式重写代码d在一个数组中seen_before[d].

import numpy as np
def item_index_bs(item, distinct, n_symbols, Cl):
    length = len(item)
    offset = 0
    seen = set()
    seen_before = np.zeros(n_symbols, dtype=np.uint64)
    for i, di in enumerate(item):
        offset += Cl[distinct][length - 1 - i][len(seen)] * int(seen_before[di]) \
           + Cl[distinct][length - 1 - i][len(seen) + 1] * int(di - seen_before[di]);
        if di not in seen:
            seen.add(di)
            seen_before[di+1:] += 1;

    return offset

这可以通过以下方式进行测试

pp = item_at(256, 300, 200, 300, Cl)
item_index_factored(pp, 200, 300, Cl) # 1.8ms
item_index(pp, 200, 300, Cl) # 5.39ms

修改为item_at

For the item_at我们不能简单地对术语进行分组,如下所示item_index,但我们可以跳过一些迭代,比如说idx减少了a如果该项目被看到,否则它会减少b,因此最多减少max(a,b)至少需要idx//max(a,b)找到要使用的数字。然后我们通过乘法进行更新a and b通过它们各自的系数。

def item_at_skip(idx, length, distinct, n_symbols, Cl):
    seen = [0] * n_symbols;
    prefix = [0] * length
    used = 0
    for i in range(length):
        a = Cl[distinct][length - 1 - i][used];
        b = Cl[distinct][length - 1 - i][used + 1]
        c = idx // max(a,b) # d will be at least c
        ac = sum(seen[:c]) # the number of time a is subtracted
        idx -= a * ac + b * (c - ac);
        for d in range(c, n_symbols):
            if seen[d] != 0:
                branch_count = a
            else:
                branch_count = b
            if branch_count <= idx:
                idx -= branch_count
            else:
                prefix[i] = d
                if seen[d] == 0:
                    used += 1
                    seen[d] = 1
                break
    return prefix
assert item_at_skip(10**200, 300, 200, 300, Cl) == item_at(10**200, 300, 200, 300, Cl)
item_at_skip(10**200, 300, 200, 300, Cl) # 3.16ms
item_at(10**200, 300, 200, 300, Cl) # 6.25ms
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

比提供的解决方案更快地获取排列索引和索引处的排列 的相关文章

  • Gunicorn 工作人员无论如何都会超时

    我正在尝试通过gunicorn运行一个简单的烧瓶应用程序 但是无论我做什么 我的工作人员都会超时 无论是否有针对应用程序的活动 工作人员在我设置任何内容后总是会超时timeout值到 是什么导致它们超时 当我发出请求时 请求成功通过 但工作
  • 为什么 dataclasses.astuple 返回类属性的深层副本?

    在下面的代码中astuple函数正在执行数据类的类属性的深层复制 为什么它不能产生与函数相同的结果my tuple import copy import dataclasses dataclasses dataclass class Dem
  • 在 Python 中将列表元素作为单独的项目返回

    Stackoverflow 的朋友们大家好 我有一个计算列表的函数 我想单独返回列表的每个元素 如下所示 接收此返回的函数旨在处理未定义数量的参数 def foo my list 1 2 3 4 return 1 2 3 4 列表中的元素数
  • 如何实现n个元素的查找和插入操作的动态二分查找

    这个想法是使用多个数组 每个长度为 2 k 根据 n 的二进制表示来存储 n 个元素 每个数组都是排序的 不同的数组没有以任何方式排序 在上述数据结构中 SEARCH是通过对每个数组进行一系列二分查找来进行的 INSERT 是通过一系列相同
  • python multiprocessing 设置生成进程等待

    是否可以生成一些进程并将生成进程设置为等待生成的进程完成 下面是我用过的一个例子 import multiprocessing import time import sys def daemon p multiprocessing curr
  • 在 Django Admin 中调整字段大小

    在管理上添加或编辑条目时 Django 倾向于填充水平空间 但在某些情况下 当编辑 8 个字符宽的日期字段或 6 或 8 个字符的 CharField 时 这确实是一种空间浪费 字符宽 然后编辑框最多可容纳 15 或 20 个字符 我如何告
  • 矩形函数的数值傅里叶变换

    本文的目的是通过一个众所周知的分析傅里叶变换示例来正确理解 Python 或 Matlab 上的数值傅里叶变换 为此 我选择矩形函数 这里报告了它的解析表达式及其傅立叶变换https en wikipedia org wiki Rectan
  • Python 内置的 super() 是否违反了 DRY?

    显然这是有原因的 但我没有足够的经验来认识到这一点 这是Python中给出的例子docs http docs python org 2 library functions html super class C B def method se
  • 使用 python/numpy 重塑数组

    我想重塑以下数组 gt gt gt test array 11 12 13 14 21 22 23 24 31 32 33 34 41 42 43 44 为了得到 gt gt gt test2 array 11 12 21 22 13 14
  • 使用 Python Oauthlib 通过服务帐户验证 Google API

    我不想使用适用于 Python 的 Google API 客户端库 但仍想使用 Python 访问 Google APIOauthlib https github com idan oauthlib 创建服务帐户后谷歌开发者控制台 http
  • 无法导入 langchain.agents.load_tools

    我正在尝试使用 LangChain Agents 但无法导入 load tools 版本 langchain 0 0 27 我尝试过这些 from langchain agents import initialize agent from
  • pandas - 包含时间序列数据的堆积条形图

    我正在尝试使用时间序列数据在 pandas 中创建堆积条形图 DATE TYPE VOL 0 2010 01 01 Heavy 932 612903 1 2010 01 01 Light 370 612903 2 2010 01 01 Me
  • 将 Matlab 的 datenum 格式转换为 Python

    我刚刚开始从 Matlab 迁移到 Python 2 7 在读取 mat 文件时遇到一些问题 时间信息以 Matlab 的日期数字格式存储 对于那些不熟悉它的人 日期序列号将日历日期表示为自固定基准日期以来已经过去的天数 在 MATLAB
  • 如何使用 Python 3 检查目录是否包含文件

    我到处寻找这个答案但找不到 我正在尝试编写一个脚本来搜索特定的子文件夹 然后检查它是否包含任何文件 如果包含 则写出该文件夹的路径 我已经弄清楚了子文件夹搜索部分 但检查文件却难倒了我 我发现了有关如何检查文件夹是否为空的多个建议 并且我尝
  • Spider 必须返回 Request、BaseItem、dict 或 None,已“设置”

    我正在尝试从以下位置下载所有产品的图像 我的蜘蛛看起来像 from shopclues items import ImgData import scrapy class multipleImages scrapy Spider name m
  • 如何使用 AWS Lambda Python 读取 AWS S3 存储的 Word 文档(.doc 和 .docx)文件内容?

    我的场景是 我尝试使用 python 实现从 Aws Lambda 读取 AWS 存储的 S3 word 文档 doc 和 docx 文件内容 下面的代码是我使用的 我的问题是我可以获取文件名 但无法读取内容 def lambda hand
  • 制作一份 Python 文档的 PDF 文件

    Python 官方网站提供 PDF 文档下载 但它们是按章节分隔的 我下载了源代码并构建了 PDF 文档 这些文档也是单独的 PDF 我怎么能够从源代码中的 Makefile 构建一个 PDF 文件 我认为这样阅读起来会更方便 如果连接单独
  • 等待子进程使用 os.system

    我用了很多os system在 for 循环内调用创建后台进程 如何等待所有后台进程结束 os wait告诉我没有子进程 ps 我使用的是Solaris 这是我的代码 usr bin python import subprocess imp
  • 如何使用 PrimaryKeyRelatedField 更新多对多关系上的类别

    Django Rest 框架有一个主键相关字段 http www django rest framework org api guide relations primarykeyrelatedfield其中列出了我的 IDmany to m
  • python 对浮点数进行不正确的舍入

    gt gt gt a 0 3135 gt gt gt print 3f a 0 314 gt gt gt a 0 3125 gt gt gt print 3f a 0 312 gt gt gt 我期待 0 313 而不是 0 312 有没有

随机推荐

  • 调试代码时 Ninject 出现无源可用错误

    我已经使用NuGet安装了最新版本的Ninject v2 2 1 4 然后我创建了自己的 NinjectDependencyResolver 归功于亚当 弗里曼和史蒂夫 桑德森 public class NinjectDependencyR
  • 第一次运行flutter时报错:没有找到pubspec.yaml文件

    我试着跟随Get Stated here https flutter io setup windows And got gt flutter run Error No pubspec yaml file found This command
  • Firebase 数据库规范化

    所以我制作了一个简单的应用程序 一个三轮车巡逻应用程序 您可以通过登录并填写表格来举报鲁莽的三轮车司机 在我们的城市这里没有任何问题 报告表格包含 created at description lat lng plateNumber 到目前
  • 用于按行“连接 If”的 VBA 用户定义函数

    我有一些关于是否为特定站点执行特定 服务 例如鸟类调查 的数据 每项服务都有 是 或 否 E G A 列包含站点名称 例如 A B C D 和 E A1 中标题为 站点名称 A2 中标题为 A 依此类推 B 列 B1 中包含 鸟类调查 然后
  • 捕获分段违规并继续生活

    我正在编写一个程序来检查它自己的地址空间 具体来说 我关心所有 malloc 的数据块 如果有一些系统调用来获取它们的列表 那就太棒了 对于我的应用程序 我不能使用 LD PRELOAD wrap 或任何额外的命令行选项 如果有办法做到这一
  • 使 arraylist 上的 select -unique 返回 arraylist 而不是字符串

    我在下面的类中有三个数组列表 我想让它们保持独特 但是 如果数组列表中只有一项 字符串 并且您使用 select unique 或任何其他方法来实现此目的 它将返回字符串而不是字符串列表 用 包围它也不起作用 因为这会将其转换为数组而不是数
  • Android内存泄漏,没有静态变量

    我是一名初级 Android 开发人员 作为一个实践项目 我正在尝试制作一个可以拍照 将其保存到外部存储并在 ImageView 中显示的活动 几乎一切似乎都正常 但是 我似乎有内存泄漏 当屏幕方向改变时 我相信活动会被破坏 然后重新创建
  • 存储过程中的账本报告逻辑

    我有一个名为 患者分类帐报告 的存储过程 我需要在其中显示患者的日常交易详细信息和余额金额 我正在为您提供以下代码中的一个采样数据 这些数据是如何插入到我的临时表中的sp create table Patient ledger PATIEN
  • Python 是否有相当于部分类的东西?

    使用 新 样式类 我使用的是 python 3 2 有没有办法将一个类拆分为多个文件 我有一个大类 从面向对象设计的角度来看 考虑到耦合等 它实际上应该是一个类 但是为了便于编辑类 最好将其拆分为几个文件 如果您的问题确实只是在编辑器中处理
  • “gcloud builds 提交...”有什么作用?

    我想知道什么gcloud 构建提交做 就我而言 我正在运行GCloud运行教程 The 官方文档指出它提交构建 这不是一个特别有用的信息 有人可以提供更多背景信息吗 什么是build 一个图像 jar 文件 这个 构建 被提交到哪里 提交
  • 更改 PHP 中包含内容的相对链接路径

    我的服务器根目录下有一个 PHP 文件 索引 php 哪个include的 DIR main php 现在 DIR main php 具有到许多附近文件的相对链接 所有相关链接均已损坏 我可以通过任何方式更改相对 URL 基本路径对于链接
  • 在Python 3中使用MagicMethods计算欧几里德距离

    我有一个为我计算欧几里德距离的代码 class Point A point in two dimensional space def init self x y self x x self y y def eq self other ret
  • 使用两个 android spinner,一个依赖于另一个

    我已经浏览了很多代码并试图找出我做错了什么 但我不及格并且浪费时间 这会很简单 但我无法弄清楚 我正在开发一个 Android 应用程序 需要在一项活动中放置 2 个旋转器 第二个微调器将根据第一个微调器中选择的条目进行填充 听起来很简单吧
  • Android 中的 Webview 能够运行 php

    我正在开发一个具有 Web 视图的 Android 应用程序 我还需要加载 html jquery js 和 php 现在我可以加载 html jquery css javascript 但我的问题是我无法在离线的 Web 视图中加载 ph
  • 为什么在构造函数上创建新线程是不好的做法? [复制]

    这个问题在这里已经有答案了 可能的重复 Java 为什么不在构造函数中启动线程 如何终止 我习惯了跑步FindBugs在我的代码上 以便发现错误或不良做法 今天它抱怨我在类构造函数中启动一个线程 真的是一件坏事吗 你能解释一下为什么吗 如果
  • 如何在 Windows 中获取每个进程的磁盘活动

    我需要提取给定进程的磁盘统计信息 我可以获取列出的进程并获取总体信息 例如使用 WMI 和 PerformanceCounters 列出的 CPU 和内存 但信息都是捆绑在一起的 有什么方法可以提取每个进程的这些数据 有点像 Windows
  • 获取当前位置 Android Kotlin

    我尝试在我的应用程序中使用 GM API 获取当前位置 使用 Android Studio 但是 如果我单击触发 getLocation 函数的按钮 我总是会进入 catch 块 但我不知道为什么 我的移动设备已连接以进行测试 这是 get
  • Typescript - 键入以检查字符串是否仅包含特定字符

    如何对我们知道仅包含某些值的字符串进行类型检查 例子 const binary 1010000101000 我们知道 用十进制表示的二进制值只能是 1 和 0 为了进行更好的类型检查 对于这些类型的值来说 什么是好的类型定义 type Bi
  • 将 Argparse 与 Google Admin API 结合使用

    我正在使用 Google 的 Python API 来提取审核信息 但我无法让 argparse 的父组参数 这似乎是 API 访问所必需的 和我自己的参数 例如传递日期 一起工作 Code import pprint import sys
  • 比提供的解决方案更快地获取排列索引和索引处的排列

    多亏了这个answer 这是我如何获取排列索引和索引处的排列 import time def get Cl distinct Cl for i in range 1 distinct 1 i is distincct c 0 i 1 0 C