นับจำนวนเส้นทางที่สั้นที่สุดถึง n


21

ความท้าทายของรหัสนี้จะให้คุณคำนวณจำนวนวิธีที่จะไปถึงเริ่มจากโดยใช้แผนที่ในรูปแบบ (ด้วยเป็นจำนวนเต็มไม่เป็นลบ) และทำตามขั้นตอนจำนวนน้อยที่สุดn2xx+xjj

(หมายเหตุนี่เกี่ยวข้องกับลำดับ OEIS A307092 )

ตัวอย่าง

ตัวอย่างเช่นเพราะจำเป็นต้องใช้แผนที่สามแผนที่และมีลำดับที่แตกต่างกันสองแผนที่ในสามแผนที่ซึ่งจะส่งถึง :f(13)=2213

xx+x0xx+x2xx+x0orxx+x2xx+x1xx+x0

ส่งผลให้ในหรือ13231213261213

ค่าตัวอย่าง

f(2)   = 1 (via [])
f(3)   = 1 (via [0])
f(4)   = 1 (via [1])
f(5)   = 1 (via [1,0])
f(12)  = 2 (via [0,2] or [2,1])
f(13)  = 2 (via [0,2,0] or [2,1,0], shown above)
f(19)  = 1 (via [4,0])
f(20)  = 2 (via [1,2] or [3,1])
f(226) = 3 (via [2,0,2,1,0,1], [3,2,0,0,0,1], or [2,3,0,0,0,0])
f(372) = 4 (via [3,0,1,0,1,1,0,1,1], [1,1,0,2,0,0,0,1,1], [0,2,0,2,0,0,0,0,1], or [2,1,0,2,0,0,0,0,1])

ท้าทาย

ความท้าทายคือการผลิตโปรแกรมที่ใช้เวลาจำนวนเต็มเป็น input และเอาท์พุทจำนวนเส้นทางที่แตกต่างจากไปผ่านทางหมายเลขน้อยที่สุดของแผนที่ในรูปแบบ Jn22nxx+xj

นี่คือซึ่งมีจำนวนน้อยที่สุดที่จะชนะ


1
ฉันคิดว่าควรสังเกตอย่างชัดเจนว่า^สัญลักษณ์นั้นหมายถึงการยกกำลัง มันอาจเป็น XOR เช่นกัน (เช่น C ใช้^สำหรับ bitwise XOR)
Ramillies

1
@Ramillies บางทีควรเปลี่ยนเป็น MathJax เช่นแทน x=x+xjx -> x + x^j
Kevin Cruijssen

@KevinCruijssen: ข้อดีแล้วมันจะช่วยได้แน่นอน
Ramillies

ฉันได้เพิ่มนี้ไป OEIS เป็นA309997 (มันจะเป็นแบบร่างจนกว่าจะอนุมัติ)
Peter Kagey

คำตอบ:


2

เยลลี่ขนาด 16 ไบต์

2+*¥þ³Ḷ¤F$n³Ạ$¿ċ

ลองออนไลน์!

โปรแกรมแบบเต็มใช้เป็นอาร์กิวเมนต์และคืนค่าจำนวนวิธีในการเข้าถึงโดยใช้ความยาวพา ธ น้อยที่สุด ไม่มีประสิทธิภาพสำหรับขนาดใหญ่nnnn


5

JavaScript (ES6),  111 ... 84  80 ไบต์

ผลตอบแทนที่แท้จริงมากกว่าสำหรับ 21n=2

f=(n,j)=>(g=(i,x,e=1)=>i?e>n?g(i-1,x):g(i-1,x+e)+g(i,x,e*x):x==n)(j,2)||f(n,-~j)

ลองออนไลน์!

แสดงความคิดเห็น

f = (                     // f is the main recursive function taking:
  n,                      //   n = input
  j                       //   j = maximum number of steps
) => (                    //
  g = (                   // g is another recursive function taking:
    i,                    //   i = number of remaining steps
    x,                    //   x = current sum
    e = 1                 //   e = current exponentiated part
  ) =>                    //
    i ?                   // if there's still at least one step to go:
      e > n ?             //   if e is greater than n:
                          //     add the result of a recursive call with:
        g(i - 1, x)       //       i - 1, x unchanged and e = 1
      :                   //   else:
                          //     add the sum of recursive calls with:
        g(i - 1, x + e) + //       i - 1, x + e and e = 1
        g(i, x, e * x)    //       i unchanged, x unchanged and e = e * x
    :                     // else:
      x == n              //   stop recursion; return 1 if x = n
)(j, 2)                   // initial call to g with i = j and x = 2
|| f(n, -~j)              // if it fails, try again with j + 1

4

Haskell , 78 75 ไบต์

การใช้งานนี้ใช้การค้นหาลมหายใจก่อนใน "แผนผัง" ของการแมปที่จำเป็นทั้งหมดซ้ำx -> x + x^j

j#x=x+x^j
f n=[sum[1|x<-l,x==n]|l<-iterate((#)<$>[0..n]<*>)[2],n`elem`l]!!0

ลองออนไลน์!

คำอธิบาย

-- computes the mapping x -> x + x^j
j#x=x+x^j                          
--iteratively apply this function for all exponents [0,1,...,n] (for all previous values, starting with the only value [2])
                            iterate((#)<$>[0..n]<*>)[2] 
-- find each iteration where our target number occurs
    [                   |l<-...........................,n`elem`l] 
-- find how many times it occurs
     sum   [1|x<-l,x==n] 
-- pick the first entry
f n=.............................................................!!0




1

CJam (27 ไบต์)

qi2a{{_W$,f#f+~2}%_W$&!}ge=

การสาธิตออนไลน์

คำเตือน: สิ่งนี้จะได้รับหน่วยความจำมากอย่างรวดเร็วมาก

ผ่า:

qi            e# Read input and parse to int n (accessed from the bottom of the stack as W$)
2a            e# Start with [2]
{             e# Loop
  {           e#   Map each integer x in the current list
    _W$,f#f+~ e#     to x+x^i for 0 <= i < n
    2         e#   and add a bonus 2 for the special case
  }%          e#   Gather these in the new list
  _W$&!       e#   Until the list contains an n
}g
e=            e# Count occurrences

โบนัส2s (เพื่อจัดการกรณีพิเศษของอินพุต2เนื่องจากwhileลูปมีราคาแพงกว่าdo-whileลูป) หมายความว่าขนาดของรายการเติบโตอย่างรวดเร็วมากและการใช้เลขชี้กำลังn-1ถึงค่าเฉลี่ยของจำนวนที่มากขึ้นในรายการจะเพิ่มขึ้น เร็วมาก.



1

R , 78 77 ไบต์

function(n,x=2){while(!{a=sum(x==n)})x=rep(D<-x[x<n],n+1)+outer(D,0:n,'^')
a}

ลองออนไลน์!

ใช้การค้นหาแบบกว้างแรกที่เรียบง่าย

รหัสที่ไม่ได้ควบคุมพร้อมคำอธิบาย:

function(n){                              # function taking the target value n

  x=2                                     # initialize vector of x's with 2

  while(!(a<-sum(x==n))) {                # count how many x's are equal to n and store in a
                                          # loop while a == 0

    x=rep(D<-x[x<n],n+1)+outer(D,0:n,'^') # recreate the vector of x's 
                                          # with the next values: x + x^0:n
  }
a                                         # return a
}   

รุ่นที่สั้นกว่าพร้อมการจัดสรรหน่วยความจำขนาดใหญ่ (ไม่รองรับกรณีที่ใหญ่กว่า):

R , 70 69 ไบต์

function(n,x=2){while(!{a=sum(x==n)})x=rep(x,n+1)+outer(x,0:n,'^')
a}

ลองออนไลน์!

-1 ไบต์ขอบคุณ @RobinRyder


!(a<-sum(x==n))อาจเป็น!{a=sum(x==n)}-1 ไบต์ในทั้งสองกรณี
Robin Ryder

0

Pyth , 24 ไบต์

VQIJ/mu+G^GHd2^U.lQ2NQJB

ลองออนไลน์!

สิ่งนี้ควรสร้างผลลัพธ์ที่ถูกต้อง แต่ช้ามาก (กรณีทดสอบ 372 ครั้งใช้ TIO) ฉันสามารถทำให้มันสั้นลงโดยแทนที่.lQ2ด้วยQแต่สิ่งนี้จะทำให้รันไทม์น่ากลัว

(n1)

คำอธิบาย

VQ                        # for N in range(Q (=input)):
   J                      #   J =
     m                    #     map(lambda d:
      u                   #       reduce(lambda G,H:
       +G^GH              #         G + G^H,
            d2            #         d (list), 2 (starting value) ),
              ^U.lQ2N     #       cartesian_product(range(log(Q, 2)), N)
    /                Q    #     .count(Q)
  IJ                  JB  #   if J: print(J); break
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.