แปลงตัวอย่างเป็นดัชนี


12

เรากำลังใส่ลูกเป็นจำนวนคงที่ถังขยะ ถังขยะเหล่านี้เริ่มว่างเปล่า

Empty bin (a=4): 0 0 0 0 

และหนึ่งโดยหนึ่งเราเพิ่มลูกไปที่ถังขยะ

0 0 0 1  or
0 0 1 0  or
0 1 0 0  or
1 0 0 0

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

เรากำหนดดัชนีโดยการจัดเรียงการกำหนดค่าที่เป็นไปได้ในวิธีเฉพาะ:

  1. เรียงลำดับจากน้อยไปหามาก: ก่อน0 0 0 0อื่นจากนั้นกำหนดค่าที่เป็นไปได้โดยเพิ่ม 1 ลูกจากนั้น 2 และอื่น ๆ
  2. จากนั้นจัดเรียงภายในแต่ละผลรวมตามลำดับจากน้อยไปหามาก:

    0 0 0 2
    0 0 1 1
    0 0 2 0 
    0 1 0 1
    0 1 1 0 
    0 2 0 0 
    etc
    
  3. ดัชนีจะถูกกำหนดจากน้อยไปมากในรายการนี้:

    0 0 0 0  -> 1
    0 0 0 1  -> 2
    0 0 1 0  -> 3
    0 1 0 0  -> 4
    1 0 0 0  -> 5
    0 0 0 2  -> 6
    0 0 1 1  -> 7
    0 0 2 0  -> 8
    0 1 0 1  -> 9
    0 1 1 0  -> 10
    0 2 0 0  -> 11 
    

กฎระเบียบ

สร้างฟังก์ชั่นหรือโปรแกรมที่รับรายการขนาดใด ๆ ที่มีจำนวนเต็มไม่เป็นลบและพิมพ์หรือส่งออกดัชนี คุณสามารถสมมติเป็นอย่างน้อย 2 ชนะรหัสที่สั้นที่สุด คุณสามารถใช้เอาต์พุต 0 ดัชนีหรือดัชนี 1 แต่ระบุสิ่งที่คุณใช้ หมายเหตุ: ตัวอย่างทั้งหมดที่นี่มีการจัดทำดัชนี 1

รหัสตัวอย่าง

ไม่เล่นกอล์ฟใน R:

nodetoindex <- function(node){
  a <- length(node)
  t <- sum(node)
  if(t == 0) return(1)

  index <- choose(t-1 + a, a)

  while(sum(node) != 0){
    x <- node[1]
    sumrest <- sum(node)
    if(x == 0){
      node <- node[-1]
      next
    }
    a <- length(node[-1])
    index <- index + choose(sumrest + a, a) - choose(sumrest - x + a, a)
    node <- node[-1]
  }
  return(index + 1)
} 

กรณีทดสอบ

10 10 10 10 -> 130571
3 1 4 1 5 9 -> 424407
2 9 -> 69
0 0 0 -> 1
0 0 1 -> 2
0 0 0 0 0 0 -> 1
1 0 0 0 0 1 -> 23

การเรียงลำดับด้วยค่าตัวเลขของการต่อข้อมูลจะทำงานอย่างไรเมื่อการนับมีจำนวนตัวเลขต่างกัน
TheBikingViking

@ TheBikingViking hmm ไม่ได้คิดอย่างนั้นฉันเปลี่ยนถ้อยคำเพื่อสะท้อนรหัสตัวอย่างและกรณีทดสอบ ภายในแต่ละผลรวมการกำหนดค่าจะถูกจัดเรียงก่อนในถังขยะแรกจากนั้นในวินาทีและอื่น ๆ
JAD

คำตอบ:


3

เยลลี่ 8 ไบต์

S0rṗLSÞi

ลองออนไลน์!

วิธีการแก้ปัญหากำลังดุร้าย กรณีทดสอบแรกนั้นมากเกินไปสำหรับ TIO แต่ฉันได้ตรวจสอบแล้วในแล็ปท็อปของฉัน กรณีทดสอบที่สองต้องใช้ RAM มากเกินไปแม้แต่สำหรับคอมพิวเตอร์เดสก์ท็อปของฉัน

มันทำงานอย่างไร

S0rṗLSÞi  Main link. Argument: A (array)

S         Compute the sum s of A.
 0r       Create the range [0, ..., s].
    L     Yield the length l of A.
   ṗ      Cartesian power; yield the array of all l-tuples over [0, ..., s], in
          lexicographical order.
     SÞ   Sort the l-tuples by their sums. The sorting mechanism is stable, so
          l-tuples with the same sum are still ordered lexicographically.
       i  Find the index of A in the generated array of tuples.

ดี คำพูดของคุณเกี่ยวกับ RAM ทำให้ฉันนึกถึงที่มาของความท้าทายนี้ สำหรับวิทยานิพนธ์ของฉันฉันจำเป็นต้องวนซ้ำอาร์เรย์ที่เป็นไปได้ทั้งหมดสำหรับa = 8และสูงที่สุดเท่าที่จะเป็นไปได้ ความคิดในการแปลงอาร์เรย์เป็นดัชนีและวนซ้ำไปมานั้นมาจากข้อ จำกัด ของ RAM: P
JAD

ซึ่งเป็นสาเหตุว่าทำไมโค้ดตัวอย่างจึงใช้คำฟุ่มเฟือย: P
JAD

1

Clojure 152 ไบต์

#(loop[v[(vec(repeat(count %)0))]i 1](if-let[r((zipmap v(range))%)](+ r i)(recur(sort(set(for[v v i(range(count v))](update v i inc))))(+ i(count v)))))

ไม่ง่ายอย่างที่คิด รุ่น golfed น้อยกว่า:

(def f (fn[t](loop[v[(vec(repeat(count t)0))]i 1]
               (if-let[r((zipmap v(range))t)](+ r i)
                 (recur (sort-by (fn[v][(apply + v)v]) (set(for[v v i(range(count v))](update v i inc))))
                        (+ i(count v)))))))

วนรอบสถานะปัจจุบันvสร้างแผนที่แฮชจากองค์ประกอบของvถึงอันดับหากพบสถานะการค้นหาแล้วอันดับจะถูกส่งกลับ (+ จำนวนสถานะที่เห็นก่อนหน้านี้) หากไม่พบจะมีสถานะที่เป็นไปได้ใหม่เกิดขึ้นอีก

โอ้จริงแล้วเราไม่ต้องการฟังก์ชั่นการเรียงลำดับแบบกำหนดเองเนื่องจากสถานะทั้งหมดภายในแต่ละลูปมีผลรวมเหมือนกัน นี่ไม่ช้าอย่างที่ฉันคาดไว้[3 1 4 1 5 9]ใช้เวลาเพียง 2.6 วินาที


1

Mathematica ขนาด 50 ไบต์

พอร์ตของเดนนิสเป็นคำตอบวุ้น

0~Range~Tr@#~Tuples~Length@#~SortBy~Tr~Position~#&

ฟังก์ชั่นที่ไม่ได้ตั้งชื่อใช้รายการของจำนวนเต็มเป็นอินพุตและส่งคืนรายการความลึก 2 พร้อมกับจำนวนเต็มเดียวเป็นเอาต์พุต ตัวอย่างเช่นการป้อนข้อมูลสำหรับกรณีทดสอบสุดท้ายคือและส่งออกเป็น{1,0,0,0,0,1}{{23}}

รุ่นที่ไม่ได้รับเกียรติคือ:

Position[SortBy[Tuples[Range[0,Tr[#]],Length[#]],Tr],#]&

บ่อยครั้งที่เราสามารถบันทึกแต่ละไบต์ใน Mathematica โดยใช้สัญกรณ์คำนำหน้า ( function@nแทนfunction[n]) และสัญกรณ์มัด ( a~function~bแทนfunction[a,b]) อย่างไรก็ตามวิธีนี้ใช้ได้เฉพาะเมื่อโค้ดผลลัพธ์นั้นสอดคล้องกับลำดับความสำคัญที่แท้จริงของ Mathematica สำหรับการใช้ฟังก์ชัน ฉันรู้สึกประหลาดใจที่นี่ที่มีวงเล็บสี่เหลี่ยมหกชุดมันใช้งานได้จริงในการลบพวกเขาทั้งหมดและบันทึกหกไบต์ด้วยรหัสที่ส่งมา

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