数字多样性


16

正整数可以以整数为底表示1 <= b < inf

转换为该基数时,它具有一些不同的数字。

基数中的任何正整数都1具有1不同的数字。

base中大多数正整数2都有2不同的数字,2^n - 1只有形式为的例外1

因此,可以用1唯一数字表示的整数基中的第一个正整数是1,可以用2不同数字表示的第一个正整数是2

我们可以说,1是与数字多样性的第一个整数1,并2与数字多样性的第一个整数2

挑战:

给定一个正整数,则n返回其数字分集为的第一个正整数(以10为基数*)n

*如果您的语言仅支持特定的基础(例如,一元或二进制),则可以以该基础输出。

理论上,您的算法必须适用于任何正整数输入:它可能会失败,因为语言整数的精度对于输出而言太小;但可能不会失败,因为仅定义了基本转换。

测试用例

input  output
   1     1
   2     2
   3     11
   4     75
   5     694
   6     8345
   7     123717
  17     49030176097150555672
  20     5271200265927977839335179
  35     31553934355853606735562426636407089783813301667210139
  63     3625251781415299613726919161860178255907794200133329465833974783321623703779312895623049180230543882191649073441
 257     87678437238928144977867204156371666030574491195943247606217411725999221158137320290311206746021269051905957869964398955543865645836750532964676103309118517901711628268617642190891105089936701834562621017362909185346834491214407969530898724148629372941508591337423558645926764610261822387781382563338079572769909101879401794746607730261119588219922573912353523976018472514396317057486257150092160745928604277707892487794747938484196105308022626085969393774316283689089561353458798878282422725100360693093282006215082783023264045094700028196975508236300153490495688610733745982183150355962887110565055971546946484175232

这是,以字节为单位的最短解决方案。

OEIS:A049363-也是基数n中最小的全景数字。

Answers:


11

果冻,4 字节

ṖaWḅ

在线尝试!验证所有测试用例

怎么运行的

ṖaWḅ  Main link. Argument: n

Ṗ     Pop; yield [1, 2, 3, ..., n-1].
  W   Wrap; yield [n].
 a    Logical AND; yield [n, 2, 3, ..., n-1].
   ḅ  Convert the result from base n to integer.

我忘了地方价值可能溢出,击败了我的糟糕7 :)
乔纳森·艾伦

我希望在codegolf上每个用户都有一个rep vs字节使用图表。也许是使用的总字节数与当前代表数的关系图。
菲利普·哈格隆德16-10-14

花了我一些时间弄清楚为什么这行得通...精巧地完成了!
格雷格·马丁

9

Python,40个字节

f=lambda n,k=1:n*(n<k+2)or-~f(n,k+1)*n-k

Ideone上进行测试

怎么运行的

与一些Ñ不同位数必须清楚地在碱来表示b≥Ñ。由于我们的目标是尽量减少数量,b也应尽可能的小,所以B =ñ是合乎逻辑的选择。

这样我们就可以安排数字0,...,n-1来创建尽可能小的数字,这意味着必须将最高有效数字保持尽可能小。由于第一位数字在规范表示中不能为0,因此最小数字为
(1)(0)(2)...(n-2)(n-1)n = n n-1 + 2n n-3 +…+(n-2)n +(n-1),其中f递归计算。


6

Python 2,54 46字节

这是非常非常 非常的快速,迭代的解决方案。

n=r=input();k=2
while k<n:r=r*n+k;k+=1
print r

在线尝试

没有递归,因此适用于大量输入。结果如下n = 17000(需要1-2秒):

http://pastebin.com/UZjgvUSW


输入17000需要多长时间?在我的机器上需要26秒,与果冻的0.9秒相比,它似乎很慢……
丹尼斯

类似但以其他方式减少了三个字节:lambda n:n**~-n+sum(i*n**(n+~i)for i in range(2,n))
Jonathan Allan

2
46字节和很多:快n=r=input();k=2\nwhile k<n:r=r*n+k;k+=1\nprint r
丹尼斯

是的,令人惊讶的是while循环比Python中的理解要快得多。
乔纳森·艾伦

@JonathanAllan那不是原因。计算能力非常慢,而循环仅使用乘法和加法。
丹尼斯

5

JavaScript(ES6),29个字节

f=(b,n=b)=>n>2?f(b,--n)*b+n:b

5

J,9个字节

#.],2}.i.

基于@Dennis 方法

用法

   f =: #.],2}.i.
   (,.f"0) >: i. 7
1      1
2      2
3     11
4     75
5    694
6   8345
7 123717
   f 17x
49030176097150555672

说明

#.],2}.i.  Input: n
       i.  Get range, [0, 1, ..., n-1]
    2}.    Drop the first 2 values, [2, 3, ...., n-1]
  ]        Get n
   ,       Prepend it, [n, 2, 3, ..., n-1]
#.         Convert that to decimal from a list of base-n digits and return

有一个基于使用置换索引的替代解决方案。给定输入n,创建数字列表[0, 1, ..., n],并使用索引n!查找置换,并将其转换为以n为基数的列表。J中对应的解决方案为12个字节

#.]{.!A.i.,]  Input: n
        i.    Make range [0, 1, ..., n-1]
           ]  Get n
          ,   Join, makes [0, 1, ..., n-1, n]
     !        Factorial of n
      A.      Permutation index using n! into [0, 1, ..., n]
  ]           Get n
   {.         Take the first n values of that permutation
              (This is to handle the case when n = 1)
#.            Convert that to decimal from a list of base-n digits and return

构造起来会更短[1,0,2,3,...,n-1]吗?
乔纳森·艾伦

1
@JonathanAllan我找不到方法,但是我确实注意到那些方法的排列索引为(n -1)!
2016年

4

Ruby,37 35 34字节

->n{s=n;(2...n).map{|d|s=s*n+d};s}

给定的答案n采用10234...(n-1)base 的形式n。使用n=10作为一个例子:

开始于n10

乘以n并加2:102

相互加n并加3:1023

等等。

编辑:似乎使用地图更短。

编辑2:感谢您的提示,m-chrzan!


(2...n)将短一个字节。
m-chrzan

3

CJam,9个字节

ri__,2>+b

在线尝试!

说明

ri   e# Read input N.
__   e# Make two copies.
,    e# Turn last copy into range [0 1 2 ... N-1].
2>   e# Discard up to two leading values.
+    e# Prepend a copy of N.
b    e# Treat as base-N digits.

3

CJam(9字节)

qi_,X2$tb

在线演示

解剖

显然,与数字多样性的最小数量n由基地转换发现 [1 0 2 3 ... n-1]的基础n。但是,请注意,内置的基本转换不需要数字在range内0 .. n-1

qi    e# Read integer from stdin
_,    e# Duplicate and built array [0 1 ... n-1]
X2$t  e# Set value at index 1 to n
b     e# Base conversion

请注意,在特殊情况下,n = 1我们1 [0] 1 1 tb给出的1 [0 1] b1


3

Haskell,31个字节

f n=foldl((+).(*n))n[2..n-1]

使用霍纳方法通过折叠将列表转换[n,2,3,...,n-1]为基数n在OEIS页面上提供的高尔夫版本较少。

感谢妮米的3个字节!


我不太了解Haskell,折叠是否要求将函数命名为(f?)才是有效的高尔夫解决方案?(只是f稍后在代码中未引用)
Jonathan Allan

@JonathanAllan Haskell中的lambda函数形式为\n->fold1...,只要命名即可。您可以编写一个无点函数,其中输入变量没有通过组合子函数来命名,但是在这里有3个引用会很糟糕n
xnor

太好了,谢谢您的解释。Haskell语法使我有些困惑。
乔纳森·艾伦

您可以使用foldl并开始于nf n=foldl((+).(*n))n[2..n-1]
nimi

3

05AB1E,9个字节

DL¦¨v¹*y+

在线尝试!

说明

n = 4 例如使用。

D           # duplicate input
            # STACK: 4, 4
 L          # range(1, a)
            # STACK: 4, [1,2,3,4]
  ¦¨        # remove first and last element of list
            # STACK: 4, [2,3]
    v       # for each y in list
     ¹*     # multiply current stack with input
       y+   # and add y
            # STACK, first pass: 4*4+2 = 18
            # STACK, second pass: 18*4+3 = 75

2

C ++- 181 55

打算使用<numeric>以下方式发布真正的酷解决方案:

#import <vector>
#import <numeric>
using namespace std;int f(int n){vector<int> v(n+1);iota(v.begin(),v.end(),0);swap(v[0],v[1]);return accumulate(v.begin(),v.end()-1,0,[n](int r,int a){return r*n+a;});}

然后我意识到这是方式更容易:

int g(int n){int r=n,j=2;for(;j<n;)r=r*n+j++;return r;}

2

Perl 6的 34个31  30字节

翻译自OEIS页面上的Haskell示例。

{(1,0,|(2..^$^n)).reduce: $n×*+*}        # 34
{(1,0,|(2..^$^n)).reduce: $n* *+*}       # 34

{reduce $^n×*+*,1,0,|(2..^$n)}           # 31
{[[&($^n×*+*)]] 1,0,|(2..^$n)}           # 31

{reduce $_×*+*,1,0,|(2..^$_)}            # 30
  • [&(…)]变成就地中缀运算符
  • […]上述转弯中所示的缀运算成倍(左边或右边取决于操作关联)

展开:

{
  reduce

    # declare the blocks only parameter 「$n」 ( the 「^」 twigil )
    # declare a WhateverCode lambda that takes two args 「*」
    $^n × * + *

    # a list that always contains at least (1,0)
    1, 0,
    # with a range slipped in
    |(
      2 ..^ $n # range from 2 up-to and excluding 「$n」
               # it is empty if $n <= 2
    )
}

用法:

my &code = {reduce $_×*+*,1,0,|(2..^$_)}

say code 1; # 1
say code 2; # 2
say code 3; # 11
say code 4; # 75
say code 7; # 123717

# let's see how long it takes to calculate a largish value:

my $start-time = now;
$_ = code 17000;
my $calc-time = now;
$_ = ~$_; # 25189207981120412047...86380901260421982999
my $display-time = now;

say "It takes only { $calc-time - $start-time } seconds to calculate 17000";
say "but { $display-time - $calc-time } seconds to stringify"

# It takes only 1.06527824 seconds to calculate 17000
# but 5.3929017 seconds to stringify

2

Brain-Flak84 76字节

感谢Wheat Wizard打高尔夫球8个字节

(({})<>){(({}[()]))}{}(<{}{}>)((())){{}({<({}[()])><>({})<>}{}{})([][()])}{}

在线尝试!

说明

该程序从推压值0n-1堆栈替换顶部0110。然后,它乘以堆栈的顶部n并在其下方加上一个值,直到堆栈上只剩下一个值。

从本质上讲,它会找到n包含n不同数字的基数最小的数字(对于n> 1,它始终是形式1023...(n-1))。然后,它根据给定的数字和基数来计算数字。

带注释的代码

(({})<>)       # Pushes a copy of n to the right stack and switches to right stack
{(({}[()]))}{} # While the top of the stack != 0 copy the top of the stack-1
               #   and push it
(<{}{}>)       # Discard the top two values (0 and 1 for n > 1) and push 0
((()))         # Push 1 twice (second time so that the loop is works properly)
{{}            # Loop while stack height > 1
  (            #   Push...
    {<({}[()])><>({})<>}{} # The top value of the stack * n
    {}         #     Plus the value below the top of the stack
  )            #   End push
([][()])}{}    # End loop

您可以替换{}{}(()(<()>))([][()])(<{}{}>)([(())][])救四个字节
后摇滚Garf亨特

然后,您可以将其替换为(<{}{}>)((()))以节省更多的四个字节
发布Rock Garf Hunter,2016年



1

PHP,78字节

for(;$i<$a=$argn;)$s=bcadd($s,bcmul($i<2?1-$i:$i,bcpow($a,$a-1-$i++)));echo$s;

在线版本

60字节只能在测试用例中达到n = 16的精度

对于n = 144 INF

n = 145 NAN

for(;$j<$a=$argn;)$t+=($j<2?1-$j:$j)*$a**($a-1-$j++);echo$t;


0

JavaScript(ES6),39个字节

不使用 =>

function f(b,n){throw f(b,n>2?--n:1)*b}

欢迎来到PPCG!
斯蒂芬
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.