데니스 번호 생성


69

이 과제는 The Programming Language Quiz 의 강도를 얻은 PPCG 사용자 Dennis 에게 경의를 표합니다 .

보면 데니스 'PPCG 프로필 페이지 것은 우리는 꽤 인상적인 물건을 볼 수 있습니다 :

데니스의 프로필

그는 현재 6 만 8 이상의 명성을 가지고 있으며 전체적으로 2 위를 차지하며 거의 3 만 명을 넘어 섰습니다. 그는 최근 에 새로운 중재자를위한 우리의 선거에서 승리했고 그의 이름 옆에 반짝이는 새로운 다이아몬드를 얻었 습니다. 그러나 개인적으로 Dennis의 가장 흥미로운 부분은 PPCG 사용자 ID 번호 인 12012라고 생각합니다.

언뜻보기에는 12012거의 회문 처럼 보이지만 , 반대로 뒤집어도 같은 숫자이지만 약간은 다릅니다. 21012첫 번째 1와 의 위치를 ​​바꾸면 회문이 될 수 있고 2, 12021마지막 1과를 바꾸면 회문이 될 수 있습니다 2. 또한, 숫자 앞에 0이 기록되지 대회, 첫 스와핑 다음 10결과 02112또는 오히려 2112다른 회문 인을.

Dennis 숫자 를 회문 자체는 아니지만 양수의 정수로 정의하고 두 자리 중 적어도 한 쌍의 위치를 ​​바꾸어 회문으로 만들 수 있습니다. 데니스 수 의 순서 는 서로 구별되는 숫자 쌍의 수로, 반드시 별개의 회문을 만들기 위해 바꿀 수 있습니다.

따라서 순서가 12012그 자리 3/3 보낸 구별 쌍 인 ( 12012, , )을 생성 회문 주위 교환 될 수있다. 가장 작은 차수 3 Dennis 번호가됩니다.120121201212012

10최소 데니스 번호이고 주위 스위칭 때문에 순서 1을 보유 1하고하기 001일명 1회문된다.

숫자의 가상 선행 0은 전환 가능한 숫자로 계산되지 않습니다. 예를 들어, 변화 890808908하고, 회문을 얻기 위해 처음 2 자리 숫자를 교환하는 것은 80908올바르지 않습니다. 8908데니스 번호가 아닙니다.

데니스가 아닌 숫자는 순서가 0이라고 할 수 있습니다.

도전

제 N 최소 데니스 번호를 양의 정수 N과 인쇄물에 걸리거나 반환하는 함수 작성 프로그램이나 그 순서에 따라 같은 어떤 적당한 형식 12012 3또는 (12012, 3).

예를 들어, 12012774 번째 Dennis 숫자이므로 774프로그램에 입력하면 출력은 다음과 같아야 12012 3합니다. 흥미롭게도 774는 또 다른 데니스 번호입니다.

바이트 단위의 가장 짧은 코드가 이깁니다.

다음은 첫 20 개의 Dennis 번호와 참조 순서입니다.

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이다. 이 질문으로 인해 내가 요청한 내용은 다음과 같습니다. 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
이미 담당자 한도를 쳤지 만 첫 번째 답변 게시 해야했습니다 .
Dennis

1
어. 42 개의 업 보트로 의견을 올리려면 어떻게해야합니까?
NieDzejkob

나는 42 번째 공의를 얻었다 : P
mackycheese21

7

하스켈, 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리스트 IFF에 xy(동일한 길이를 가져야한다)는 정확히 두 장소에서 다르다. 즉,이 경우 x의 순열이고 y, x!y그것은 "스왑"인지 여부를 판정한다.

o n의 Dennis 순서를 찾습니다 n. 의 순열 중 스왑을 필터링 x = show n한 다음이 스왑 중 회문 수를 계산합니다. 이 계산을 수행하는 목록 이해에는 추가 가드가 있으며 not (p x), 이는 회문으로 시작 하면 반환 0됩니다 n.

snd (span (<'1') v)비트는 그냥 dropWhile하지만 한 바이트 짧은; 그것은 회전 "01221""1221".

f목록에서 인덱스 (i, o i)경우 o i > 0(즉, i일반적으로이 같이 여기 off-by-one 오류 일 것 데니스 번호입니다.) (!!)0부터 카운트하지만 문제는 (1)에서 카운트는 내가에서 검색을 시작하여이 문제를 해결하기 위해 관리 -10(이 내 프로그램에서 Dennis 번호로 간주되었습니다!) 모든 숫자를 올바른 지점으로 밀어 넣습니다.

f 774입니다 (12012,3).


6

파이썬 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파이썬에서 평가 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)}

새로운 자바? : /

Ungolfed 및 댓글 :

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

루프의 본문은 1) 입력에서 읽은 왼쪽 인수 , 2) 지금까지 Dennis 숫자의 개수, 3) X루프 카운터 의 현재 값 및 4) K회 문의 합으로 계산 된 순서 1- 스왑 순열 내에서 처음 두 요소가 같으면 마지막 두 요소가 결과로 반환됩니다.


2

자바 스크립트 (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

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 바이트가 더 필요하지만 사양에서 허용한다고 생각합니다).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.