整数按其数字根排序


24

正整数的数字根(也是重复的数字和)是在每次迭代中使用前一次迭代的结果来计算数字总和的,通过对数字求和的迭代过程获得的(单个数字)值。该过程一直持续到达到一位数字为止。

例如,65536的数字根为7,因为6 + 5 + 5 + 3 + 6 = 252 + 5 = 7


对所有数字根进行排序没有多大意义,因为它只会以无限多个1 s开始。

取而代之的是,我们将创建所有单个数字整数及其数字根的列表,然后是所有两位数字及其数字根的列表,然后是三倍,四倍等等。

现在,对于这些列表中的每一个,我们将对其进行排序,以使所有数字根为1的整数首先出现,然后所有数字根为2的整数出现,依此类推。排序将是稳定的,因此具有一定数字根的整数列表在排序后应按升序排列。

最后,我们将这些列表连接成一个序列。此序列将从所有个位数开始,然后是所有两位数(按其数字根排序),然后是所有三位数,依此类推。


挑战:

以一个整数n作为输入,并按上述顺序输出第n个数字。您可以选择列表是0索引还是1索引。

该序列如下所示:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 19, 28, 37, 46, 55, 64, 73, 82, 91, 11, 20, 29 ... 
72, 81, 90, 99, 100, 109, 118, ... 
981, 990, 999, 1000, 1009, 1018, 1027, ...

测试用例:

测试用例为1索引。

   n   f(n)  
   9      9
  10     10
  11     19
  40     13
  41     22
  42     31
  43     40
  44     49
  45     58
 600    105
 601    114
 602    123
 603    132
 604    141
 605    150
4050   1453
4051   1462
4052   1471
4053   1480
4054   1489
4055   1498

易于复制:

n =    9, 10, 11, 40, 41, 42, 43, 44, 45, 600, 601, 602, 603, 604, 605, 4050, 4051, 4052, 4053, 4054, 4055, 
f(n) = 9, 10, 19, 13, 22, 31, 40, 49, 58, 105, 114, 123, 132, 141, 150, 1453, 1462, 1471, 1480, 1489, 1498

说明:

  • 您可能不会输出全部n个第一元素。您只能输出第n个。
  • 从理论上讲,该代码必须适用于所有最大为10 ^ 9的整数,但是对于大于999的输入,如果它在TIO(或具有时间限制的其他解释器)上超时,则可以。
  • 鼓励解释。

这是,因此每种语言中最短的代码胜出!即使您想使用的语言短于其他解决方案,也不要气other其他解决方案!


2
有趣的提示:尚未在OEIS中使用
apnorton

Answers:


16

Python 2中78个 60 52 46 45字节

-6个字节,感谢GB
-1个字节感谢Jakob

n=input()
b=10**~-len(`n`)
print~-b+n/b+n%b*9

在线尝试!

最终达到一个封闭的形式,以1为索引。


Python 2,78个字节

0索引。

d=10;k=1
exec'\nk+=9\nif k>d+7:k=d;d*=10\nif k>=d:k-=d/10*9-1'*input()
print k

在线尝试!


2
我希望看到的解决方案不能创建整个序列。做得好:-)
Stewie Griffin

您是如何得出封闭式解决方案的?(编辑:维基百科上似乎有一种解释)
sevko

@sevko 78-byter是我最初的解决方案(此处有点古板的变体)。这已经可以在不计算任何多维数据集根的情况下起作用,而是根据我在序列中观察到的规则通过逐个编号生成序列号。基于这种迭代计算,可以计算出每个表达式执行了多少次。
ovs

@sevko在WolframAlpha帮助下,能够构造一个封闭的表格。最初,使用封闭形式的程序要长得多(〜95个字节),但是随着打高尔夫球和WolframAlpha的出现,程序恢复到当前形式。
ovs

4

Python 3,80个字节

f=lambda i,k=1:k>i and sorted(range(k//10,k),key=lambda n:n%-9)[i-k]or f(i,k*10)

在线尝试!

1个索引。这是我在Python 3中能做到的最好的(好吧,除了78-byter,这是下面我的Python 2解决方案的移植;不过我认为这要得多)。Python 2完整程序在此特定挑战中具有优势,因为input()需要将其转换为intPython 3(+5字节),exec是函数而不是语句(+2字节),并且/如果其参数为int中的整数,则默认情况下执行整数除法Py 2(+1字节),因此这绝对比移植ovs的答案要

怎么运行的

设定

f=lambda i,k=1:k>i and ... or f(i,k*10)

这定义了一个递归函数f,该函数采用一个整数参数i和另一个参数k(默认值为1)。虽然ķ≤我,函数˚F返回F(I,10K) ,乘以ķ10每次直到它变成大于

目标范围和正确的索引编制

...range(k//10,k)...[i-k]

经过这组运算后,我们剩下i,初始输入和变量k,它代表比i大10的最小幂。这样,我们就可以生成(整数)范围[floor(k / 10),k),该范围基本上包括以下所有整数:

  • 大于或等于10的最高幂小于或等于i
  • 小于k,比i大10的最小幂

由于我们忽略了小于x = floor(k / 10)的整数,因此我们必须移动索引,以便解决缺失的数字。一种明显的方法是从i中减去它们的计数x,以便我们索引到列表中(排序后将在下面进行描述),因此具有ix。但是,由于该列表包含9k / 10个项目,并且在索引-y的列表中为某个正y索引会从Python的末尾产生y th个元素,因此这仅等效于使用ik进行索引,因此节省了4个字节。

按数字根对每个进行排序

sorted(...,key=lambda n:n%-9)

数字根函数的公式为1 +((n-1)mod 9)(请参阅此Wikipedia文章Congruence公式部分)。由于1将这种方式加入到他们每个人,它排序时是多余的,所以我们留下了(N-1)MOD 9。在RHS上给定负数时,Python 运算符的工作方式非常方便,因为我们可以使用n pymod -9来保存另一个字节。%


Python 2,72个字节

灵感来自Chas Brown的陈述

lambda i:sorted(range(1,10**len(`i`)),key=lambda n:(len(`n`),n%-9))[i-1]

在线尝试!



4

果冻 15 14 10  9 字节

D,Ḣ$‘Ḍḅ9’

在线尝试!

怎么样?

使用ovs在其Python回答中创建的封闭式解决方案的修订版...

ovs暴露的公式是:9 *(n%b)+(n / b)+ b-1其中b = 10 floor(log(n,10))

现在,如果cn的小数位数,则b-1c-1十进制的9。
这等于十进制c-1值(例如111*9=999)的9倍。

此外N / B是一家领先的数字Ññ%B是的位数为十进制数的其余部分。

可以将b * x + y之类的公式实现为[x,y]从基b的转换
(即b ^ 1 * x + b ^ 0 * y = b * x + y

这样,我们可以取一个数字n(例如7045),将其拆分为前导数字和尾随数字,将前导数字放在末尾([[0,4,5],7]),在第一个项目的所有数字上加一个,以适应b-1[[1,5,6],7])将其从十进制列表转换为整数([156,7]),并将其从基数九(1411)转换为整数。

在下面的实现中,当满足b-1[[0,4,5],8])时,我们在两个项目的所有数字上加一个,从十进制列表转换为整数([156,8]),从基数九转换(1412),然后减去此过程添加的一位(1411)。

D,Ḣ$‘Ḍḅ9’ - Link: positive integer, n    e.g. 4091
D         - to base ten                       [4, 0, 9, 1]
   $      - last two links as a monad:
  Ḣ       -   head (modifies the list too)    4
 ,        -   pair (the modified list) with   [[0, 9, 1], 4]
    ‘     - increment (vectorises)            [[1, 10, 2], 5]
     Ḍ    - from base ten (vectorises)        [202, 5] (since 1*10^2+10*10^1+2*10^0 = 100+100+2 = 202)  
      ḅ9  - convert from base 9               1823 (since 202*9^1 + 5*9^0 = 202*9 + 6*9 = 1818 + 5 = 1823)
        ’ - decrement                         1822

前一个14个字节:

æċ⁵DL,’%9ƊƲÞị@

在线尝试!

通过对这些自然数进行排序,然后在输入的索引中找到该值,从而将列表构建到输入之上的下一个10的[digitalRoot, digitCount]


3

Haskell94 88字节

([n|x<-[0..],i<-[1..9],n<-[10^x..10^(x+1)-1],until(<10)(sum.map(read.pure).show)n==i]!!)

在线尝试!0索引。

说明:

列表推导将序列生成为无限列表,我们在其中使用!!以下索引:

  • x 比当前位数少一位,并从无限列表中得出 [0,1,2,3, ...]
  • i在从1到的范围内进行迭代,9并用于按数字根排序
  • nx+1数字迭代所有数字
  • until(<10)(sum.map(read.pure).show)计算数字根(有关详细信息,请参见此处
  • n如果其数字根等于,则添加到列表i

2

视网膜,65字节

.
9
.+
*
L$`
$`
O$`_(_{9})*(_*)
$2
_+
$.&
N$`
$.&
"$+L`^|\d+"^~G`

在线尝试!1个索引。说明:

.
9
.+
*
L$`
$`

建立一个_从0到下一个10的幂(不包括在内)的s 行的列表。

O$`_(_{9})*(_*)
$2

将它们按数字根顺序排序。

_+
$.&

从一元转换为十进制。

N$`
$.&

按长度顺序对它们进行排序。

"$+L`^|\d+"^~G`

提取nth元素。


2

Pyth 36 31 25 24 23  22字节

1个索引。

@o%tN9rFK^LThBlt`Q-QhK

测试套件!

工作方式(已过时)

@smo%tN9dcU^TKhs.lQT^LTSK – Full program. Q = input.
             Khs.lQT      – Take floor(log10(Q))+1 and store it in K.
          U^T             – Generate [0 ... T^K).
         c                – Cut at locations...
                    ^LTSK – Of the powers of 10 less than K.
  m     d                 – Map over those.
   o  N                   – Sort them by...
    %t 9                  – Themselves decremented, modulo 9.
@s                        – Flatten the result and retrieve the Q'th entry.

2

05AB1E19 11字节

我的Python回答的端口。

-6个字节(!),感谢Kevin Cruijssen

g<°©‰`9*®O<

在线尝试!

Code           Explanation            Stack
               implicit input         [n]
g              length                 [len(n)]
 <             decrement              [len(n)-1]
  °            10 ** a                [10**(len(n) - 1)]
   ©           store value            [10**(len(n) - 1)]
    ‰          divmod                 [[n // 10**(len(n) - 1), n % 10**(len(n) - 1)]]
     `         push items to stack    [n // 10**(len(n) - 1), n % 10**(len(n) - 1)]
      9*       multiply by 9          [n // 10**(len(n) - 1), n % 10**(len(n) - 1) * 9]
        ®      retrieve value         [n // 10**(len(n) - 1), n % 10**(len(n) - 1) * 9, 10**(len(n) - 1)]
         O     sum the stack          [n // 10**(len(n) - 1) + n % 10**(len(n) - 1) * 9 + 10**(len(n) - 1)]
          <    decrement              [n // 10**(len(n) - 1) + n % 10**(len(n) - 1) * 9 + 10**(len(n) - 1) - 1]
               implicit output

您击败了我,正在研究一个答案,它是您的Python答案的一部分。;)13个字节:g<°©÷¹®%9*®O<。在这里,我将为此发布解释
凯文·克鲁伊森

1
@KevinCruijssen非常感谢。该寄存器似乎非常有用。我能够使用divmod将其降低两个字节。
ovs


1

Perl 6的 68  58个字节

{({|(10**$++..^10**++$).sort({({.comb.sum}…*==*).tail})}…*)[$_]}

0开始测试

{sort({.chars,({.comb.sum}…*==*).tail},^10**.chars)[$_]}

1开始测试

展开:

{  # bare block lambda with implicit parameter $_

  sort(
    {
      .chars,         # sort by the length first

      (  # generate sequence to find digital sum

        { .comb.sum } # one round of digital sum
         * == *      # stop when the digital sum matches itself (1..9)

      ).tail          # get the last value
    },

    ^                 # Range up to (and excluding)
      10 ** .chars    # the next power of 10

  )[ $_ ] # index into the sequence
}



1

K4,38个字节

解:

-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\:

例子:

q)k)-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\:40
13
q)k)-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\:601
114
q)k)-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\:4051
1462

说明:

当我用尽内存构建了1到1e9的数字根时,乔纳森·艾伦(Jonathan Allan)解决方案的移植。

-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\: / the solution
                                  10\: / convert to base 10
                                1+     / add 1
                              x:       / save as x
                             #         / take from x
                     (      )          / do together
                          #x           / count x
                        c:             / save as c
                      1+               / add 1
                   1_                  / drop the first
                  _                    / cut at these indices
           ( ;   )                     / 2-item list
              c-1                      / length - 1
            0                          / .. zero
      10/:'                            / convert each from base 10
   9/:                                 / convert from base 9
-1+                                    / subtract 1

奖金:

ovs解决方案的翻译更简单,但时间更长:

-1+b+/1 9*(_%;.q.mod).\:x,b:10 xexp#1_$x:

明确指出:“理论上,代码必须适用于所有最大10 ^ 9的整数”。看来这不是...?
Stewie Griffin

嗯 然后,我将使用奖励答案之一,因为我将用尽内存来尝试计算最多10e6,更不用说10e9了。稍后将修复。
streetster


0

J,24个字节

(]/:([:+/[:".&>":)^:_"0)

默认表达式被包裹在括号中,表示应单独对待它,而不应将其视为随后的任何表达式(如自变量)的一部分。

短语“] /:”按数字的总和“ + /”对原始数组“]”进行排序(升序“ /:”)

". &> ":

将数字转换为带有'“:'的字符向量,然后应用其反数”“。-字符到数字-应用于每个“&>”项目。因此,65536->'65536'-> 6 5 5 3 6。

表达式结尾附近的幂连词“ ^:”将我们刚刚说明的代码(在左侧)应用了指定的次数。在这种情况下,指定的次数是无穷大的“ _”,这意味着将继续应用直到结果停止更改。

最后的“ 0”表示将左侧的整个表达式应用于右侧的每个标量(0维)项,这将是我们要对其应用数值的数组。


您如何创建输入列表?我正在用K写一个解决方案,但答案的一半是生成列表...
streetster

我假设列表是从外部输入的。我看不到在哪里创建列表是问题的一部分。
DevonMcC

以正整数n作为输入,并按照上述顺序输出第n个数字。” 您必须创建序列(或找到一种避免产生序列的方法-参见其他答案)。
streetster

0

灵药,239字节

q=:math
e=Enum
r=fn x,f->cond do
x<10->x
1->f.(e.sum(Integer.digits x),f)end end
fn p->e.at(e.at(Stream.unfold({0,[0]},fn {a,c}->{c,{a+1,c++e.sort(trunc(q.pow 10,a)..trunc(q.pow 10,a+1)-1,&r.(&1,r)<=r.(&2,r))}}end),1+trunc q.log10 p),p)end

在线尝试!

解释传入(缓慢)!我认为它不会比这更短,但是我总是愿意提出建议


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.