Tạo số Dennis


69

Thử thách này là một sự tôn vinh đối với người dùng Dennis của PPCG vì đã chiến thắng phần của Kẻ cướp trong Bài kiểm tra ngôn ngữ lập trình .

Nhìn vào trang hồ sơ PPCG của Dennis, chúng ta có thể thấy một số nội dung khá ấn tượng:

Hồ sơ của Dennis

Anh ta hiện có hơn sáu mươi tám ngàn danh tiếng, khiến anh ta đứng thứ hai về tổng thể , vượt qua vị trí thứ ba gần ba mươi ngàn. Gần đây anh ấy đã thắng cuộc bầu cử của chúng tôi cho một người điều hành mới và một viên kim cương mới sáng bóng bên cạnh tên của anh ấy. Nhưng cá nhân tôi nghĩ phần thú vị nhất về Dennis là số ID người dùng PPCG của anh ấy: 12012.

Thoạt nhìn 12012gần trông giống như một palindrome , một số mà đọc giống nhau khi đảo ngược, nhưng đó là một chút đi. Nó có thể trở thành bảng màu 21012nếu chúng ta trao đổi vị trí của vị trí đầu tiên 12, và nó có thể trở thành bảng màu 12021nếu chúng ta trao đổi vị trí cuối cùng 12. Ngoài ra, theo quy ước rằng các số 0 đứng đầu trong một số không được viết, hoán đổi đầu tiên 10kết quả trong 02112hoặc đúng hơn 2112là một palindrom khác.

Chúng ta hãy định nghĩa một số Dennis là một số nguyên dương không phải là chính nó nhưng có thể được tạo thành một bảng màu bằng cách hoán đổi vị trí của ít nhất một cặp của hai chữ số bất kỳ. Thứ tự của một số Dennis là số lượng các cặp chữ số riêng biệt có thể được hoán đổi để tạo thành một bảng màu (không nhất thiết phải khác biệt).

Vì vậy, theo thứ tự 12012là 3 từ 3 cặp khác biệt của các chữ số của nó ( 12012, , ) có thể được hoán đổi xung quanh để tạo ra palindromes. xảy ra là số nhỏ nhất 3 số Dennis.120121201212012

10là số Dennis nhỏ nhất và có thứ tự 1 vì chuyển đổi xung quanh 10cho 01aka 1đó là một bảng màu.

Các số 0 đứng đầu tưởng tượng của một số không được tính là các chữ số có thể chuyển đổi. Ví dụ, thay đổi 8908đến 08908và trao đổi hai chữ số đầu tiên để có được những palindrome 80908không hợp lệ. 8908không phải là số Dennis.

Các số không phải Dennis có thể được cho là có số 0.

Thử thách

Viết chương trình hoặc hàm lấy số nguyên dương N và in hoặc trả về số Dennis nhỏ nhất thứ N cùng với thứ tự của nó theo một số định dạng hợp lý như 12012 3hoặc (12012, 3).

Ví dụ, 12012là số Dennis thứ 774 vì vậy nếu 774là đầu vào cho chương trình của bạn, thì đầu ra phải giống như vậy 12012 3. (Thật kỳ lạ, 774 là một số Dennis khác.)

Mã ngắn nhất tính bằng byte thắng.

Dưới đây là 20 số Dennis đầu tiên và đơn đặt hàng của họ để tham khảo:

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

Đây là danh sách tương tự lên tới N = 1000.


31
Điều này đã được thêm vào OEIS
Claudiu

28
@Claudiu này được thêm vào OEIS.
dùng48538

Câu trả lời:


13

Bình thường, 44 byte

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

Dùng thử trực tuyến: Trình diễn hoặc Test Suite

Một lỗi nhỏ ngu ngốc (?) Trong Pyth đã phá hỏng giải pháp 41 byte.

Giải trình:

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)]

Và đây là 'lỗi nhỏ ngu ngốc (?)'
CalculatorFeline

@CatsAreFluffy Đã tìm kiếm lịch sử Github. Nó quan tâm .f. Đây là yêu cầu kéo mà tôi đã thực hiện vì câu hỏi này: github.com/isaacg1/pyth/pull/151
Jakube

42

CJam, 45 byte

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

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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
Tôi đã đạt đến giới hạn rồi, nhưng tôi phải đăng câu trả lời đầu tiên.
Dennis

1
Ừ Làm thế nào để tôi buộc bản thân phải đưa ra một nhận xét với 42 upvote?
NieDzejkob

Tôi đã nhận được upvote thứ 42: P
mackycheese21

7

Haskell, 174 byte

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 kiểm tra xem một danh sách là một palindrom.

x!yTruecác danh sách xy(nên có cùng độ dài) khác nhau ở chính xác hai nơi. Cụ thể, nếu xlà hoán vị của y, x!yxác định xem đó có phải là "hoán đổi" hay không.

o ntìm thấy thứ tự Dennis của n. Nó lọc các giao dịch hoán đổi giữa các hoán vị của x = show n, và sau đó đếm xem có bao nhiêu trong số các giao dịch hoán đổi đó là palindromes. Việc hiểu danh sách thực hiện số này có thêm một người bảo vệ not (p x), có nghĩa là nó sẽ trở lại 0nếu nlà một bảng màu bắt đầu.

Các snd (span (<'1') v)bit chỉ là dropWhilenhưng ngắn hơn một byte; nó quay "01221"vào "1221".

flập chỉ mục từ một danh sách trong (i, o i)đó o i > 0(ví dụ ilà số Dennis.) Thông thường sẽ có một lỗi xảy ra ở đây, vì (!!)được tính từ 0 nhưng vấn đề được tính từ 1. Tôi đã khắc phục điều này bằng cách bắt đầu tìm kiếm từ -10(mà hóa ra được coi là một số Dennis bởi chương trình của tôi!) do đó đẩy tất cả các số vào đúng điểm.

f 774(12012,3).


6

Con trăn 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)

Tôi không thể tưởng tượng rằng mã hoán đổi của tôi đặc biệt tối ưu, nhưng đây là mã tốt nhất tôi có thể nhận được. Tôi cũng không thích tần suất tôi chuyển đổi giữa chuỗi và số nguyên ...

Đối với mỗi số, nó tạo ra một danh sách cho dù tất cả các giao dịch hoán đổi của hai chữ số là palindromes. Nó làm giảm bộ đếm khi có ít nhất một trong các giá trị này là đúng và số ban đầu không phải là một bảng màu. Vì 0+Truetrong python ước 1tính tổng của danh sách cuối cùng hoạt động theo thứ tự của số Dennis.


5

Rust, 390 byte

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 mới? : /

Ungolfed và bình luận:

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

Jelly , 33 byte (không cạnh tranh)

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

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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

Phần thân của vòng lặp trả về một vectơ gồm 4 số: 1) đối số bên trái của nó được đọc từ đầu vào, 2) số lượng Dennis cho đến nay, 3) giá trị hiện tại của X- bộ đếm vòng lặp và 4) thứ tự của nó được Ktính là tổng của palindromes trong vòng 1 hoán đổi hoán đổi. Nó chấm dứt khi hai phần tử đầu tiên trở nên bằng nhau và hai phần tử cuối cùng được trả về.


2

JavaScript (ES6), 229

Như thường lệ, JavaScript tỏa sáng vì sự vô dụng của nó đối với tổ hợp (hoặc, có thể đó là sự bất lực của tôi ...). Ở đây tôi nhận được tất cả các vị trí hoán đổi sở hữu tìm tất cả các số nhị phân có độ dài nhất định và chỉ có 2 vị trí được đặt.

Kiểm tra chạy đoạn mã dưới đây trong Firefox (vì MSIE khác xa với EcmaScript 6 tuân thủ và Chrome vẫn thiếu các tham số mặc định)

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

ôi, 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}

Kết cấu

{
    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
}

Sử dụng

Dán cái này vào bàn điều khiển của bạn và thay thế số sau echo, nếu bạn muốn

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}'

Nó bị chậm ở số cao hơn;)

Phiên bản tái sử dụng

{
    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

Ruby, 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]}

Sử dụng tính năng Ruby trong đó gọi "19".next!trả về "20"để tránh phải chuyển đổi các loại qua lại; chúng tôi chỉ sử dụng một regex để bỏ qua hàng đầu 0s. Lặp lại trên tất cả các cặp vị trí chuỗi để kiểm tra các công tắc palindromic. Ban đầu tôi đã viết đây là một hàm đệ quy nhưng nó làm hỏng stack.

Đầu ra cho 774 là ["12012", 3](loại bỏ các dấu ngoặc kép sẽ tốn thêm 4 byte nhưng tôi nghĩ thông số kỹ thuật cho phép chúng).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.