デニス番号を生成する


69

この挑戦は、プログラミング言語のクイズの強盗の部分を獲得したPPCGユーザーデニスへのオマージュです。

見てみるとデニスのPPCGのプロフィールページ我々はいくつかの非常に印象的なものを見ることができます:

デニスのプロフィール

現在、彼の評価は6万8000を超えており、全体で2 になり、3位をほぼ3万回超えています。彼は最近、新しいモデレーターの選挙に勝ち、彼の名前の隣に輝く新しいダイヤモンドを得ました。しかし個人的には、デニスの最も興味深い部分は彼のPPCGユーザーID番号である12012です。

一見パリンドロームの12012ように見えますが、逆にすると同じ数字になりますが、少しずれています。それは回文になることができ、我々は最初の位置を入れ替えた場合と、それが回文になることができ、我々は最後のスワップ場合とを。また、数字の先頭のゼロが書き込まれないという規則に従って、最初の結果と結果を交換するか、どちらが別の回文です。2101212120211210021122112

デニス数を、回文自体ではなく、任意の2桁の少なくとも1組の位置を交換することで回文にすることができる正の整数として定義しましょう。デニス番号の順序は、パリンドローム(必ずしも区別されない)を作成するために交換できる数字の個別のペアの数です。

だからの順序は12012、その数字の3 3が異なる対である(12012、、)回文を生成するために周りに交換することができます。たまたま最小の3デニス数です。120121201212012

10は最小のデニス数で、順序1を持ちます。これは、10を切り替えると、回文である01aka 1が得られるためです。

数字の虚数の先行ゼロは、切り替え可能な数字としてカウントされません。たとえば、回文を取得するために最初の2桁に変更890808908て交換すること80908は無効です。8908デニス番号ではありません。

デニス以外の番号の順序は0であると言えます。

チャレンジ

正の整数Nを取り込んで、N番目に小さいデニス数とその順序を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

28
@Claudiuこれ OEISに追加されます。
-user48538

回答:


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ます。この質問のために私が行ったプルリクエストは次のとおり
isaacg1

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!yあるTrueリストの場合に限っxy(同じ長さを持つ必要があります)を正確に2つの場所で異なります。特に、xがの順列である場合yx!yそれが「スワップ」であるかどうかを判別します。

o nのデニス順序を見つけnます。の順列間のスワップをフィルタリングしx = show n、それらのスワップのうちパリンドロームである数をカウントします。このカウントを実行するリスト内包表記には追加のguard not (p x)があります。これは、最初に回文であった0場合nに戻ることを意味します。

snd (span (<'1') v)少しだけですdropWhileが、1バイト短いです。それはターン"01221""1221"

fリストから、インデックス(i, o i)場所o i > 0(つまりiとして、通常、ここではoff-by-oneエラーがあるでしょうデニス番号です。)(!!)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)

私のスワッピングコードが特に最適であるとは想像できませんが、これは私が手に入れた最高のものです。また、文字列と整数の間で変換する頻度が好きではありません...

各数字について、2桁のスワップがすべて回文であるかどうかのリストを作成します。これらの値の少なくとも1つが真であり、元の数が回文ではない場合、カウンターをデクリメントします。以来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つの要素が等しくなり、最後の2つの要素が結果として返されると終了します。


2

JavaScript(ES6)、229

いつものように、JavaScriptは組み合わせ論にふさわしくないことで輝いています(または、多分それは私の不適当さです...)。ここでは、指定された長さの2進数と2つだけが設定されたすべての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}'

数字が大きいほど遅くなります;)

Ungolfed再利用可能バージョン

{
    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!リターン"20"を呼び出すRuby機能を使用します。先行を無視するために正規表現を使用します0s。パリンドロームスイッチをチェックするために、文字列位置のすべてのペアを反復処理します。私はもともとこれを再帰関数と書いていましたが、スタックを破壊します。

774の出力は次のとおりです["12012", 3](引用符を削除するとさらに4バイトのコストがかかりますが、仕様では許可されていると思います)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.