สร้างหมายเลขเดนนิส


69

ความท้าทายนี้เป็นเครื่องบรรณาการไปPPCGใช้เดนนิสสำหรับผู้ชนะส่วนโจรของภาษาการเขียนโปรแกรมแบบทดสอบ

ดูที่หน้าโปรไฟล์ PPCG ของ Dennisเราสามารถเห็นสิ่งที่น่าประทับใจ:

โปรไฟล์ของ Dennis

ปัจจุบันเขามีชื่อเสียงกว่าหกหมื่นแปดพันคนทำให้เขาเป็นที่สองในภาพรวมโดยมีอันดับที่สามเกือบสามหมื่นคน เมื่อเร็ว ๆ นี้เขาชนะการเลือกตั้งของเราเพื่อเป็นผู้ดำเนินรายการใหม่และได้รับเพชรรูปเงางามใหม่ถัดจากชื่อของเขา แต่ส่วนตัวแล้วฉันคิดว่าส่วนที่น่าสนใจที่สุดเกี่ยวกับ Dennis คือหมายเลขประจำตัวผู้ใช้ PPCG ของเขา: 12012

เมื่อมองดูครั้งแรก12012เกือบจะดูเหมือนเป็นPalindromeตัวเลขที่อ่านเหมือนกันเมื่อกลับด้าน แต่มันออกเล็กน้อย มันจะกลายเป็น palindrome 21012ถ้าเราสลับตำแหน่งของแรก1และ2และมันจะกลายเป็น palindrome 12021ถ้าเราสลับสุดท้ายและ1 2นอกจากนี้การปฏิบัติตามอนุสัญญาที่เลขศูนย์นำหน้าในตัวเลขนั้นไม่ได้ถูกเขียนขึ้นการสลับอันดับแรก1และ0ผลลัพธ์ใน02112หรือมากกว่า2112ซึ่งเป็นอีกรูปแบบหนึ่ง

ลองกำหนดหมายเลขเดนนิสเป็นจำนวนเต็มบวกที่ไม่ได้เป็นแบบ palindromic แต่สามารถสร้างเป็นแบบ palindrome โดยการสลับตำแหน่งอย่างน้อยหนึ่งคู่ของสองหลักใด ๆ การสั่งซื้อของจำนวนเดนนิสเป็นจำนวนคู่ที่แตกต่างของตัวเลขที่สามารถสลับที่จะทำให้ (ไม่จำเป็นต้องแตกต่างกัน) palindrome

ดังนั้นคำสั่งของ120123 ตั้งแต่ 3 คู่ที่แตกต่างของตัวเลขมัน ( 12012, , ) สามารถสลับไปรอบ ๆ เพื่อผลิต palindromes เกิดขึ้นเป็นคำสั่งที่เล็กที่สุด 3 หมายเลขเดนนิส120121201212012

10เป็นหมายเลขเดนนิสที่เล็กที่สุดและมีลำดับที่ 1 เนื่องจากการสลับไปมา1และ0ให้01aka 1ซึ่งเป็น palindrome

เลขศูนย์นำจำนวนจินตภาพของตัวเลขไม่นับเป็นหลักที่เปลี่ยนได้ ยกตัวอย่างเช่นการเปลี่ยนแปลง8908ไป08908และการแลกเปลี่ยนตัวเลขสองหลักแรกที่จะได้รับ palindrome 80908ไม่ถูกต้อง 8908ไม่ใช่หมายเลขเดนนิส

หมายเลขที่ไม่ใช่เดนนิสอาจถูกกล่าวว่ามีคำสั่ง 0

ท้าทาย

เขียนโปรแกรมหรือฟังก์ชั่นที่ใช้ในจำนวนเต็มบวก 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 = 1,000


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
ฉันกดปุ่มตัวแทนแล้ว แต่ฉันต้องโพสต์คำตอบแรก
เดนนิส

1
ฮึ. ฉันจะบังคับตัวเองให้โหวตความคิดเห็นด้วย 42 upvotes ได้อย่างไร
NieDzejkob

ฉันได้รับการ
โหวต

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 ตรวจสอบว่ารายการเป็น Palindrome หรือไม่

x!yคือTrueiff รายการxและy(ซึ่งควรมีความยาวเท่ากัน) แตกต่างกันในสองแห่ง โดยเฉพาะอย่างยิ่งถ้าxเป็นการเปลี่ยนแปลงของy, x!yกำหนดว่ามันคือ "สลับ"

o nnพบเดนนิสใบสั่งของ มันกรองการแลกเปลี่ยนในหมู่พีชคณิตของx = show nแล้วนับจำนวนแลกเปลี่ยนเหล่านั้นเป็น palindromes ความเข้าใจในรายการที่ดำเนินการนับมียามพิเศษnot (p x)ซึ่งหมายความว่ามันจะกลับมา0ถ้าnเป็น Palindrome ที่จะเริ่มต้นด้วย

snd (span (<'1') v)บิตเป็นเพียงdropWhileแต่หนึ่งไบต์สั้น; มันจะเปิดเข้าไป"01221""1221"

fดัชนีจากรายการ(i, o i)ที่o i > 0( iคือหมายเลขเดนนิส) โดยปกติจะมีข้อผิดพลาดแบบไม่อยู่ที่นี่(!!)นับจาก 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)

ฉันไม่สามารถจินตนาการได้ว่ารหัสการแลกเปลี่ยนของฉันนั้นดีที่สุดเป็นพิเศษ แต่นี่เป็นสิ่งที่ดีที่สุดที่ฉันสามารถทำได้ ฉันไม่ชอบความถี่ที่ฉันแปลงระหว่างสตริงและจำนวนเต็ม ...

สำหรับแต่ละหมายเลขมันจะสร้างรายการของการสลับของตัวเลขสองหลักทั้งหมดเป็น palindromes มันจะลดตัวนับเมื่ออย่างน้อยหนึ่งในค่าเหล่านี้เป็นจริงและหมายเลขเดิมไม่ใช่ palindrome ตั้งแต่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)}

Java ใหม่ : /

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

Jelly , 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คำนวณเป็นผลรวมของ palindromes ภายในการสับเปลี่ยน 1-swap มันสิ้นสุดลงเมื่อองค์ประกอบสองรายการแรกเท่ากันและทั้งสองจะถูกส่งกลับเป็นผล


2

JavaScript (ES6), 229

ตามปกติแล้วจาวาสคริปต์ส่องความไร้ประสิทธิภาพสำหรับ combinatorics (หรืออาจเป็นความไม่เหมาะสมของฉัน ... ) ที่นี่ฉันจะได้รับตำแหน่ง swap possibile ทั้งหมดเพื่อค้นหาเลขฐานสองทั้งหมดของความยาวที่กำหนดและเพียง 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]}

ใช้คุณสมบัติ Ruby ที่การโทร"19".next!กลับ"20"เพื่อหลีกเลี่ยงการแปลงชนิดไปมา เราเพียงแค่ใช้ regex 0sที่จะไม่สนใจชั้นนำ วนซ้ำทุกตำแหน่งสตริงเพื่อตรวจสอบสวิตช์ palindromic ตอนแรกฉันเขียนฟังก์ชันแบบเรียกซ้ำ แต่มันทำหน้าที่ซ้อนกัน

ผลลัพธ์สำหรับ 774 คือ["12012", 3](การลบเครื่องหมายคำพูดจะมีค่าใช้จ่าย 4 ไบต์ขึ้นไป แต่ฉันคิดว่าข้อมูลจำเพาะอนุญาตให้ทำได้)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.