生成丹尼斯数


69

这项挑战对PPCG用户Dennis赢得了The Programming Language Quiz的强盗部分表示敬意。

查看Dennis的PPCG个人资料页面,我们可以看到一些令人印象深刻的内容:

Dennis的个人资料

目前,他的声誉超过6.8 ,使他在销售代表中排名第二,以近3万的成绩超过了第三名。他最近赢得了我们的新主持人选举,并他的名字旁边得到了一颗闪亮的新钻石。但我个人认为,丹尼斯最有趣的部分是他的PPCG用户ID号:12012。

乍一看12012几乎像回文,反转时的数字相同,但差一点。它可以成为回文21012如果我们交换了第一的位置1,并2,它可以成为回文12021如果我们换最后12。同样,遵循不写数字前导零的约定,交换第一个10结果,02112或者2112换句话说,这是另一个回文。

让我们将Dennis数定义为一个正整数,它本身不是回文的,但是可以通过交换任意两个数字中的至少一对的位置而成为回文。丹尼斯数的顺序是可以交换以组成(不一定是不同的)回文数的不同数字对的数量。

这样的顺序12012是3,因为3个不同的对其位数(12012,,)可围绕交换以产生回文。碰巧是最小的3丹尼斯数。120121201212012

10是最小的丹尼斯数目和具有顺序1,因为绕切换10给出01又名1其是回文。

虚数前导零不算作可切换数字。例如,更改890808908并交换前两位以获得回文80908是无效的。8908不是丹尼斯数字。

非丹尼斯数字可以说是0阶。

挑战

编写一个程序或函数,该程序或函数采用正整数N并以某种合理的格式(例如或)打印或返回第N个最小的Dennis数及其顺序12012 3(12012, 3)

例如,12012第774个丹尼斯数774是,因此如果是程序的输入,则输出应类似于12012 3。(奇怪的是,774是另一个丹尼斯数字。)

以字节为单位的最短代码获胜。

以下是丹尼斯的前20个数字及其参考顺序:

N       Dennis  Order
1       10      1
2       20      1
3       30      1
4       40      1
5       50      1
6       60      1
7       70      1
8       80      1
9       90      1
10      100     1
11      110     2
12      112     1
13      113     1
14      114     1
15      115     1
16      116     1
17      117     1
18      118     1
19      119     1
20      122     1

这是直到N = 1000的相同列表。


31
这必须添加到OEIS
Claudiu 2015年

28
@Claudiu,这添加到OEIS。
user48538

Answers:


13

Pyth,44个字节

L/lf_ITs.e.e`sXXNkZYbN=N`b2,Je.f&!_I`ZyZQ0yJ

在线尝试:演示测试套件

Pyth中的一个愚蠢的小错误(?)破坏了41字节的解决方案。

说明:

L/lf_ITs.e.e`sXXNkZYbN=N`b2
L                             define a function y(b), which returns:
                      =N`b       assign the string representation of b to N
        .e             N         map each (k=Index, b=Value) of N to:
          .e         N             map each (Y=Index, Z=Value) of N to:
              XXNkZbN                switch the kth and Yth value in N
            `s                       get rid of leading zeros
       s                         combine these lists
   f_IT                          filter for palindromes
  l                              length
 /                        2      and divide by 2

,Je.f&!_I`ZyZQ0yJ
   .f        Q0     find the first input() numbers Z >= 0, which satisfy
      !_I`Z            Z is not a palindrom
     &                 and 
           yZ          y(Z) != 0
  e                 get the last number
 J                  and store in J
,J             yJ   print the pair [J, y(J)]

什么是“愚蠢的小虫子(?)”
CalculatorFeline

@CatsAreFluffy必须查找Github历史。它令人担忧.f。这是我因这个问题而提出的要求:github.com/isaacg1/pyth/pull/151
Jakube

42

CJam,45个字节

0{{)_s:C,2m*{~Ce\is_W%=},,2/:O!CCW%=|}g}ri*SO

在线尝试!

这个怎么运作

0          e# Push 0 (candidate).
{          e# Loop:
  {        e#   Loop:
    )_     e#     Increment the candidate and push a copy.
    s:C    e#     Cast to string and save in C.
    ,      e#     Get the length of C, i.e., the number of digits.
    2m*    e#     Push all pairs [i j] where 0 ≤ i,j < length(C).
    {      e#     Filter:
      ~    e#       Unwrap, pushing i and j on the stack.
      Ce\  e#       Swap the elements of C at those indices.
      is   e#       Cast to int, then to string, removing leading zeroes.
      _W%= e#       Copy, reverse and compare.
    },     e#     Keep the pairs for which = returned 1, i.e., palindromes.
    ,2/    e#     Count them and divide the count by 2 ([i j] ~ [j i]).
    :O     e#     Save the result (the order) in O.
    !      e#     Negate logically, so 0 -> 1.
    CCW%=  e#     Compare C with C reversed.
    |      e#     Compute the bitwise NOT of both Booleans.
           e#     This gives 0 iff O is 0 or C is a palindrome.
  }g       e#   Repeat the loop while the result is non-zero.
}ri*       e# Repeat the loop n times, where n is an integer read from STDIN.
           e# This leaves the last candidate (the n-th Dennis number) on the stack.
SO         e# Push a space and the order.

50
我已经达到了代表上限,但是我不得不发布第一个答案。
丹尼斯

1
啊。我该如何强迫自己以42个投票赞成一个评论?
NieDzejkob

我得到了第42次
投票

7

Haskell,174个字节

import Data.List
p x=x==reverse x
x!y=sum[1|(a,b)<-zip x y,a/=b]==2
o n|x<-show n=sum[1|v<-nub$permutations x,x!v,p$snd$span(<'1')v,not$p x]
f=([(x,o x)|x<-[-10..],o x>0]!!)

p 检查列表是否是回文。

x!yTrue当且仅当列表xy(应具有相同的长度)完全相同两个地方不同。具体来说,如果x是的排列y,则x!y确定它是否为“交换”。

o n找到的丹尼斯阶n。它过滤的排列之间的交换x = show n,然后计算这些交换中有多少是回文。执行此计数的列表理解有一个额外的后卫not (p x),这意味着0如果n从回文开始,它将返回。

snd (span (<'1') v)位仅dropWhile短一个字节。它变成"01221""1221"

f从一个(i, o i)位置o i > 0(即iDennis编号)列表中进行索引。这里通常会出现一个错误,因为(!!)从0开始计数,但问题从1开始计数。我设法通过从-10(开始搜索原来被我的程序视为丹尼斯数字!)从而将所有数字推入正确的位置。

f 774(12012,3)


6

Python 2,176

i=input()
n=9
c=lambda p:`p`[::-1]==`p`
while i:n+=1;x=`n`;R=range(len(x));r=[c(int(x[:s]+x[t]+x[s+1:t]+x[s]+x[t+1:]))for s in R for t in R[s+1:]];i-=any(r)^c(n)
print n,sum(r)

我无法想象我的交换代码特别理想,但这是我所能获得的最好的代码。我也不喜欢我在字符串和整数之间转换的频率...

对于每个数字,它都会创建一个列表,列出两位数字是否全部互换。当这些值中的至少一个为true且原始数字不是回文时,它将使计数器递减。由于0+True在python中计算1得出的最终列表的总和适用于丹尼斯数的顺序。


5

锈,390字节

fn d(mut i:u64)->(u64,i32){for n in 1..{let mut o=0;if n.to_string()==n.to_string().chars().rev().collect::<String>(){continue}let mut s=n.to_string().into_bytes();for a in 0..s.len(){for b in a+1..s.len(){s.swap(a,b);{let t=s.iter().skip_while(|&x|*x==48).collect::<Vec<&u8>>();if t.iter().cloned().rev().collect::<Vec<&u8>>()==t{o+=1}}s.swap(a,b);}}if o>0{i-=1;if i<1{return(n,o)}}}(0,0)}

新的Java?:/

取消评论并评论:

fn main() {
    let (num, order) = dennis_ungolfed(774);
    println!("{} {}", num, order);  //=> 12012 3
}

fn dennis_ungolfed(mut i: u64) -> (u64, i32) {
    for n in 1.. {
        let mut o = 0;  // the order of the Dennis number
        if n.to_string() == n.to_string().chars().rev().collect::<String>() {
            // already a palindrome
            continue
        }
        let mut s = n.to_string().into_bytes();  // so we can use swap()
        for a in 0..s.len() {  // iterate over every combination of (i, j)
            for b in a+1..s.len() {
                s.swap(a, b);
                // need to start a new block because we're borrowing s
                {
                    let t = s.iter().skip_while(|&x| *x == 48).collect::<Vec<&u8>>();
                    if t.iter().cloned().rev().collect::<Vec<&u8>>() == t { o += 1 }
                }
                s.swap(a, b);
            }
        }
        // is this a Dennis number (order at least 1)?
        if o > 0 {
            // if this is the i'th Dennis number, return
            i -= 1;
            if i == 0 { return (n, o) }
        }
    }
    (0, 0)  // grr this is necessary
}

4

果冻,33 个字节(无竞争)

ṚḌ=
=ċ0^2°;ḌÇ
DŒ!Qç@ÐfDL©Ṡ>ѵ#Ṫ,®

在线尝试!

这个怎么运作

DŒ!Qç@ÐfDL©Ṡ>ѵ#Ṫ,®  Main link. No arguments.

              µ      Combine the chain to the left into a link.
               #     Find; execute the chain with arguments k = 0, 1, 2, ...
                     until n values of k result in a truthy value, where n is an
                     integer read implicitly from STDIN. Return those n values.

D                      Decimal; convert k to the list of its digits in base 10.
 Œ!                    Generate all permutations of the digits.
   Q                   Unique; deduplicate the list of permutations.
      Ðf               Filter:
    ç@  D                Call the helper link on the second line with the
                         unpermuted digits (D) as left argument, and each
                         permutation as the right one.
                       Keep permutations for which ç returns a truthy value.
         L©            Compute the length (amount of kept permutations) and save
                       it in the register.
           Ṡ           Sign; yield 1 if the length is positive, and 0 otherwise.
            >Ṅ         Compare the sign with the result from the helper link on
                       the first line. This will return 1 if and only if the
                       length is positive and Ñ returns 0.
                Ṫ      Tail; extract the last value of k.
                 ,®    Pair it with the value in the register.


=ċ0^2°;ḌÇ              Helper link. Arguments: A, B (lists of digits)

=                      Compare the corresponding integers in A and B.
 ċ0                    Count the zeroes, i.e., the non-matching integers.
   ^2                  Bitwise XOR the amount with 2.
     °                 Convert to radians. This will yield 0 if exactly two
                       corresponding items of A and B are different ,and a
                       non-integral number otherwise.
      ;                Prepend the result to B.
       Ḍ               Convert the result from decimal to integer. Note that
                       leading zeroes in the argument won't alter the outcome.
        Ç              Call the helper link on the first line.


ṚḌ=                    Helper link. Argument: m (integer)

Ṛ                      Convert m to decimal and reverse the digits.
 Ḍ                     Convert back to integer.
  =                    Compare the result with m.

2

APL,87

2↓⎕{⍺(2⊃⍵+K⌊~A∧.=⌽A)X,K←+/{⍵∧.=⌽⍵}¨1↓∪,{⍕⍎Y⊣Y[⌽⍵]←⍵⊃¨⊂Y←A}¨∘.,⍨⍳⍴A←⍕X←1+3⊃⍵}⍣{=/2↑⍺}3⍴0

循环的主体返回一个由4个数字组成的向量:1)从输入中读取其左参数,2)到目前为止的丹尼斯数计数,3)X循环计数器的当前值,以及4)K计算为回文求和的顺序1次交换排列内。当前两个元素相等时终止,然后返回最后两个作为结果。


2

JavaScript(ES6),229

像往常一样,JavaScript因其对组合学的不熟练而大放异彩(或者,也许这是我的不熟练...)。在这里,我得到所有可能的交换位置,找到给定长度的所有二进制数,并且只设置了2个。

测试在Firefox中运行以下代码段(因为MSIE与EcmaScript 6的兼容性不强,而Chrome仍然缺少默认参数)

F=c=>(P=>{for(a=9;c;o&&--c)if(P(n=++a+'',o=0))for(i=1<<n.length;k=--i;[x,y,z]=q,u=n[x],v=n[y],!z&&u-v&&(m=[...n],m[x]=v,m[y]=u,P(+(m.join``))||++o))for(j=0,q=[];k&1?q.push(j):k;k>>=1)++j;})(x=>x-[...x+''].reverse().join``)||[a,o]

// TEST

function go(){ O.innerHTML=F(I.value)}


// Less Golfed
U=c=>{
  P=x=>x-[...x+''].reverse().join``; // return 0 if palindrome 
  
  for(a = 9; // start at 9 to get the first that is known == 10
      c; // loop while counter > 0
      o && --c // decrement only if a Dennis number found
      )
  {  
    o = 0; // reset order count
    ++a;
    if (P(a)) // if not palindrome
    {  
      n = a+''; // convert a to string
      for(i = 1 << n.length; --i; ) 
      {
        j = 0;
        q = [];
        for(k = i; k; k >>= 1)
        {
          if (k & 1) q.push(j); // if bit set, add bit position to q
          ++j;
        } 
        [x,y,z] = q; // position of first,second and third '1' (x,y must be present, z must be undefined)
        u = n[x], v = n[y]; // digits to swap (not valid if they are equal)
        if (!z && u - v) // fails if z>0 and if u==v or u or v are undefined
        {
          m=[...n]; // convert to array
          m[x] = v, m[y] = u; // swap digits
          m = +(m.join``); // from array to number (evenutally losing leading zeroes)
          if (!P(m)) // If palindrome ...
            ++o; // increase order count 
        }  
      }
    }
  }  
  return [a,o];
}

//////
go()
<input id=I value=774><button onclick="go()">-></button> <span id=O></span>


1

awk,199

{for(;++i&&d<$0;d+=o>0)for(o=j=_;j++<l=length(i);)for(k=j;k++<l;o+=v!=i&&+r~s){split(t=i,c,v=s=r=_);c[j]+=c[k]-(c[k]=c[j]);for(e in c){r=r c[e];s=s||c[e]?c[e]s:s;v=t?v t%10:v;t=int(t/10)}}print--i,o}

结构体

{
    for(;++i&&d<$0;d+=o>0)
        for(o=j=_;j++<l=length(i);)
            for(k=j;k++<l;o+=v!=i&&+r~s)
            {
                split(t=i,c,v=s=r=_);
                c[j]+=c[k]-(c[k]=c[j]);
                for(e in c)
                {
                    r=r c[e];
                    s=s||c[e]?c[e]s:s;
                    v=t?v t%10:v;
                    t=int(t/10)
                }
            }
    print--i,o
}

用法

echo如果需要,将其粘贴到控制台并替换数字

echo 20 | awk '{for(;++i&&d<$0;d+=o>0)for(o=j=_;j++<l=length(i);)for(k=j;k++<l;o+=v!=i&&+r~s){split(t=i,c,v=s=r=_);c[j]+=c[k]-(c[k]=c[j]);for(e in c){r=r c[e];s=s||c[e]?c[e]s:s;v=t?v t%10:v;t=int(t/10)}}print--i,o}'

数量增加时它会变慢;)

非高尔夫可重用版本

{
    dennisFound=0

    for(i=0; dennisFound<$0; )
    {
        i++
        order=0

        for(j=0; j++<length(i); )
        {
            for(k=j; k++<length(i); )
            {
                split(i, digit, "")
                digit[j]+=digit[k]-(digit[k]=digit[j]) # swap digits

                tmp=i
                iRev=iFlip=iFlipRev=""

                for(e in digit)
                {
                    if(tmp>0)                        # assemble reversed i
                        iRev=iRev tmp%10
                    tmp = int( tmp/10 )

                    iFlip=iFlip digit[e]             # assemble flipped i

                    if(iFlipRev>0 || digit[e]>0)     # assemble reversed flipped i
                        iFlipRev=digit[e] iFlipRev   # without leading zeros
                }
                if(iRev!=i && 0+iFlip==iFlipRev) order++  # i is not a palindrome,
            }                                             # but flipped i is
        }
        if(order>0) dennisFound++
    }
    print i, order
}

1

红宝石156

->i{s=?9
(o=0;(a=0...s.size).map{|x|a.map{|y|j=s+'';j[x],j[y]=j[y],j[x];x>y&&j[/[^0].*/]==$&.reverse&&o+=1}}
o<1||s==s.reverse||i-=1)while i>0&&s.next!;[s,o]}

在调用"19".next!返回时使用Ruby功能,"20"以避免必须来回转换类型;我们只是使用正则表达式忽略领导0s。遍历所有成对的弦位置,以检查回文开关。我最初将其编写为递归函数,但它破坏了堆栈。

774的输出是["12012", 3](删除引号会花费4个字节,但我认为规范允许这样做)。

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.