จัดลำดับรายการหลักใหม่ตามการจัดเรียงลำดับใหม่


19

ฉันเพิ่งมีปัญหาในการแก้ไขที่ทำงานที่ฉันมีสองรายการ: รายการหลักและรายการขนาดเล็กที่ประกอบด้วยส่วนย่อยของรายการในรายการหลักอาจเรียงลำดับแตกต่างกัน ฉันต้องการจัดลำดับรายการหลักใหม่ในลักษณะที่รายการในชุดย่อยจะปรากฏในลำดับเดียวกันโดยไม่เปลี่ยนลำดับรายการที่ไม่พบในรายการและเก็บรายการไว้ในตำแหน่งเดียวกันทุกครั้งที่ทำได้ ตกลงว่าอาจฟังดูสับสนดังนั้นฉันจะทำลายมันลง:

  • รายการหลักกำหนดลำดับของรายการเริ่มต้น
  • รายการชุดย่อยกำหนดลำดับสัมพัทธ์ของรายการบางอย่าง
  • ในกรณีที่รายการหลักมีองค์ประกอบสองรายการที่ผิดปกติตามรายการชุดย่อยรายการที่อยู่ก่อนหน้าในรายการหลักควรถูกย้ายไปยังดัชนีที่เก่าที่สุดซึ่งอยู่ในตำแหน่งที่ถูกต้องซึ่งสัมพันธ์กับรายการอื่น ๆ ภายในรายการชุดย่อย (เช่นทันทีหลังจากรายการในภายหลัง)

งานของคุณคือการใช้อัลกอริทึมการเรียงลำดับใหม่นี้

ตัวอย่างกรณีทดสอบ

Master: [1, 2, 3]
Subset: []
Result: [1, 2, 3]

Master: [9001, 42, 69, 1337, 420]
Subset: [69]
Result: [9001, 42, 69, 1337, 420]

Master: [9001, 42, 69, 1337, 420, 99, 255]
Subset: [69, 9001, 1337]
Result: [42, 69, 9001, 1337, 420, 99, 255]

Master: [1, 2, 3, 4, 5]
Subset: [2, 5]
Result: [1, 2, 3, 4, 5]

Master: [apple, banana, carrot, duck, elephant]
Subset: [duck, apple]
Result: [banana, carrot, duck, apple, elephant]

Master: [Alice, Betty, Carol, Debbie, Elaine, Felicia, Georgia, Helen, Ilene, Julia]
Subset: [Betty, Felicia, Carol, Julia]
Result: [Alice, Betty, Debbie, Elaine, Felicia, Carol, Georgia, Helen, Ilene, Julia]

Master: [snake, lizard, frog, werewolf, vulture, dog, human]
Subset: [snake, werewolf, lizard, human, dog]
Result: [snake, frog, werewolf, lizard, vulture, human, dog]

Master: [Pete, Rob, Jeff, Stan, Chris, Doug, Reggie, Paul, Alex]
Subset: [Jeff, Stan, Pete, Paul]
Result: [Rob, Jeff, Stan, Pete, Chris, Doug, Reggie, Paul, Alex]

Master: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
Subset: [8, 1, 2, 12, 11, 10]
Result: [3, 4, 5, 6, 7, 8, 1, 2, 9, 12, 11, 10]

Master: [lol, rofl, lmao, roflmao, lqtm, smh, jk, wat]
Subset: [wat, lmao, rofl]
Result: [lol, roflmao, lqtm, smh, jk, wat, lmao, rofl]

กฎระเบียบ

  • ช่องโหว่มาตรฐาน yadda yadda สะดวก I / O blah blah
  • แม้ว่าตัวอย่างจะใช้ตัวเลขและสตริงคุณจะต้องสนับสนุนองค์ประกอบหนึ่งประเภทเท่านั้นไม่ว่าจะเป็นจำนวนเต็มสตริงหรือสิ่งอื่นใดที่มีซีแมนทิกส์เท่าเทียมกันที่กำหนดไว้อย่างดีรวมถึงรายการต่างกันถ้าสะดวกในภาษาของคุณ
  • คุณอาจถือว่าทั้งรายการหลักและรายการชุดย่อยไม่มีรายการที่ซ้ำกัน
  • คุณอาจคิดว่ารายการทั้งหมดที่พบในรายการชุดย่อยที่พบในรายการหลัก
  • รายการใดรายการหนึ่งอาจว่างเปล่า
  • อย่างน้อยที่สุดคุณจะต้องสนับสนุนอาร์เรย์ที่ยาวได้ถึง 100 องค์ประกอบ
  • การจัดเรียงใหม่อาจดำเนินการในสถานที่หรือผ่านการสร้างรายการ / อาร์เรย์ใหม่

มีความสุขในการเล่นกอล์ฟ!


1
เป็นปัญหาที่ดีและอ้วน
โยนาห์

เป็น8 1 3 4 5 6 7 2 9 12 11 10วิธีการแก้ปัญหาที่ถูกต้องเพื่อคนที่สองไปสุดท้าย?
Ven

@Ven No แม้ว่าจะเหมาะสมกับข้อ จำกัด ในการรักษารายการย่อยในลำดับเดียวกันฉันต้องการให้แน่ใจว่ามีคำตอบที่ถูกต้องเพียงข้อเดียวดังนั้นรายการที่ล้าสมัยก่อนหน้านี้ควรจะย้ายไปอยู่หลัง รายการที่เลิกใช้ในภายหลัง
Beefster

เหตุใดจึงสำคัญว่ามีคำตอบที่ถูกต้องมากกว่าหนึ่งคำตอบ โปรดเพิ่มข้อ จำกัด ในกฎของความท้าทายด้วย
Ven

คำตอบ:


4

เรติน่า 0.8.2 , 51 ไบต์

+`(\b(\w+),(\w+)\b.*¶.*\b)\3,(.*\b\2\b)
$1$4,$3
1A`

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

(\b(\w+),(\w+)\b.*¶.*\b)\3,(.*\b\2\b)

ค้นหาคำย่อยสองคำที่อยู่ติดกันโดยที่คำที่สองนำหน้าคำแรกในรายการหลัก

$1$4,$3

ย้ายคำที่สองให้ปรากฏหลังคำแรกในรายการหลัก

+`

ทำซ้ำจนกระทั่งไม่มีคำปรากฏ

1A`

ลบ subwords


4

JavaScript (ES6),  96 89 74  71 ไบต์

เรื่องนี้เริ่มเป็นระเบียบขนาดใหญ่และในที่สุดก็หดตัวลงในรูปแบบที่ค่อนข้างกระชับและสง่างาม ฉันอยากจะขอบคุณวิธีการ. splice ()สำหรับการทำงานร่วมกันที่ประสบความสำเร็จในครั้งนั้น ;)

(master)(subset)จะเข้าเป็น เอาต์พุตโดยการอัพเดตรายการหลัก

m=>s=>s.map(p=x=>m.splice(p,0,...m.splice(i=m.indexOf(x),p>i||!(p=i))))

ลองออนไลน์!

อย่างไร?

ผมพี

m.splice(p, 0, ...m.splice(i, condition))

1

  • ผม[อีล.อีม.อีnเสื้อ]
  • พี

0

  • .spliceด้านใน()จะไม่ลบสิ่งใดเลยและส่งกลับอาร์เรย์ว่าง
  • เป็นผลให้. spliceด้านนอก()ได้รับการไม่ได้กำหนดเป็นอาร์กิวเมนต์ที่ 3 และไม่มีการแทรกอะไรเลย

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

m => s =>                 // m[] = master list, s[] = subset list
  s.map(                  //
    p =                   // p = position in the master list of the last element from
                          //     the subset list (initialized to a non-numeric value)
    x =>                  // for each element x in the subset list:
    m.splice(             //   insert in the master list:
      p,                  //     at position p
      0,                  //     without removing any element
      ...m.splice(        //     remove from the master list and flatten:
        i = m.indexOf(x), //       i = position of x in the master list
        p > i             //       if p is greater than i, remove x from its current
                          //       position and insert it at position p
        || !(p = i)       //       otherwise, set p to i and don't remove/insert anything
      )                   //     end of inner splice()
    )                     //   end of outer splice()
  )                       // end of map()

1
"ฉันอยากจะขอบคุณวิธีการ. splice ()สำหรับ ... " Cue PPCG Oscar's Music ... :)
Chas Brown

อย่างถูกต้องมากขึ้นการเรียก splice ด้านนอกได้รับอาร์กิวเมนต์ 3 หรือ 2 ตามลำดับซึ่งทำให้สิ่งที่ถูกต้อง
Neil

2

Haskell, 79 ไบต์

(m:n)#u@(s:t)|m==s=m:n#t|all(/=m)u=m:n#u|(x,_:z)<-span(/=s)n=(x++s:m:z)#u
m#_=m

ลองออนไลน์!

(m:n)#u@(s:t)                 -- m: head of master list
                              -- n: tail of master list
                              -- s: head of subset
                              -- t: tail of subset
                              -- u: whole subset
   |m==s                      -- if m==s
        =m:n#t                -- return 'm' and append a recursive call with 'n' and 't'
   |all(/=m)u                 -- if 'm' is not in 'u'
             =m:n#u           -- return 'm' and append a recursive call with 'n' and 'u'
   |                          -- else (note: 's' is element of 'n')
    (x,_:z)<-span(/=s)n       -- split 'n' into a list 'x' before element 's' and
                              -- a list 'z' after element 's' and
       = (x++s:m:z)#u         -- make a recursive call with
                              -- x++s:m:z as the new master list (i.e. 'm' inserted into 'n' after 's') 
                              -- and 'u'
m # _ = m                     -- if either list is emtpy, return the master list

2

Ruby , 73 68 ไบต์

->a,b{0while b.zip(a&b).find{|m,n|m!=n&&a=a[0..a.index(m)]-[n]|a};a}

ลองออนไลน์!

อย่างไร?

  • จุดตัดระหว่างaและbมีองค์ประกอบทั้งหมดของbแต่ตามลำดับเดียวกับที่เราจะหาได้a
  • ดังนั้นถ้าเราทำซ้ำ bและแยกเป็นสองเท่าในทันทีที่เราพบความแตกต่างเราสามารถย้ายองค์ประกอบเดียวได้
  • การขนย้ายทำได้โดยการตัดaตำแหน่งขององค์ประกอบที่เราพบbจากนั้นลบองค์ประกอบที่เราพบในจุดตัดแล้วเพิ่มส่วนที่เหลือของ a
  • ทำซ้ำตั้งแต่ต้นจนกระทั่งองค์ประกอบทั้งหมดbอยู่ในลำดับที่ถูกต้องa

0 กำลังทำอะไรอยู่0while?
โยนาห์

มันเป็นแค่ NOP
GB

ทำไมมันจำเป็น?
โยนาห์

1
เพราะการเปรียบเทียบและการจัดการจะกระทำในบล็อกเดียวเพื่อหลีกเลี่ยงการประกาศตัวแปรก่อนที่จะเริ่มวง หมายความว่า: "ไม่ต้องทำอะไรขณะที่การดำเนินการกลับมาเป็นจริง" รหัสนั้นสั้นกว่า "ดำเนินการในขณะที่ผลลัพธ์เป็นจริง"
GB


1

Perl 6 , 40 ไบต์

{*.permutations.first(*.grep(.any)eq$_)}

ลองออนไลน์!

บล็อกโค้ดแบบไม่ระบุชื่อที่รับอินพุต curried (เช่นf(subList)(masterList), และค้นหาการเปลี่ยนแปลงคำศัพท์เล็ก ๆ ครั้งแรกของดัชนีของรายการหลักที่องค์ประกอบจากรายการย่อยอยู่ในลำดับที่ถูกต้อง

การเรียงสับเปลี่ยนครั้งแรกที่น่าพอใจจะปล่อยให้องค์ประกอบเรียงลำดับอย่างถูกต้องในลำดับเดิมในขณะที่เคลื่อนย้ายวัตถุที่วางไว้อย่างไม่ถูกต้องตามระยะทางขั้นต่ำที่ต้องการไปข้างหน้าเพื่อให้อยู่ในลำดับที่ถูกต้อง

คำอธิบาย:

{*                                     } # Anonymous code block that returns a lambda
  .permutations                          # In all permutations of the master list
               .first(                )  # Find the first permutation
                     (*.grep(.any)       # Where the order of the subset
                                  eq$_   # Is the same as the given order


1

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

Œ!iⱮṢƑ¥ƇḢ

ลองออนไลน์! หรือชุดทดสอบ

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

คำอธิบาย

Œ!        | Generate all permutations of the master list
      ¥Ƈ  | Filter including only those where...
  iⱮ      |   the index of each sublist item in this permutation...
     Ƒ    |   is...
    Ṣ     |   in order. 
        Ḣ | Finally take the first item

ดูเหมือนจะไม่เป็นไปตามกฎ "ในกรณีที่รายการหลักมีองค์ประกอบสองรายการที่ไม่เป็นไปตามรายการชุดย่อยรายการที่อยู่ก่อนหน้าในรายการหลักควรถูกย้ายไปยังดัชนีที่เก่าที่สุดที่อยู่ใน ตำแหน่งที่ถูกต้องสัมพันธ์กับรายการอื่น ๆ ภายในรายการชุดย่อย (เช่นทันทีหลังจากรายการในภายหลัง) "
Beefster

@Beefster มันใช้งานได้กับสิ่งที่ฉันได้ลองมาแล้ว ฉันคิดว่าการเรียงลำดับของพีชคณิตเป็นเช่นนี้ว่าเป็นผลที่ถูกต้อง ยินดีที่ได้รับการพิสูจน์ว่าผิดถ้ามีตัวอย่าง
Nick Kennedy

@Beefster ฉันลองตัวอย่างทั้งหมดของคุณแล้วยกเว้นชื่อหญิงและ 1..12 และการเรียงลำดับผลลัพธ์นั้นถูกต้อง
Nick Kennedy

2
@Beefster คำตอบของฉันมีคำอธิบายบางส่วนว่าทำไมงานนี้
Jo King

1

J , 49 ไบต์

[:(<@({:+i.@>:@-/)@i.~C.])^:(>/@i.~)&.>/]|.@;2<\[

ลองออนไลน์!

คำอธิบาย

เรารับเซตย่อยเป็น arg ซ้ายและป้อนข้อมูลเต็มเป็นขวา

เราจะทำงานผ่านโค้ดพร้อมตัวอย่างเฉพาะเพื่อความชัดเจน:

5 2 4 f 1 2 3 4 5

นำ infixes ที่บรรจุอยู่ในกล่องที่มีขนาดสองของชุดย่อย:

2 <\ [

การผลิต:

┌───┬───┐
│5 2│2 4│
└───┴───┘

ผนวกเข้ากับอินพุตต้นฉบับและย้อนกลับสิ่งทั้งหมด:

] |.@;

เราได้รับ:

┌───┬───┬─────────┐
│2 4│5 2│1 2 3 4 5│
└───┴───┴─────────┘

การแก้ปัญหาจะเป็นสิทธิ์ในการลดด้านซ้ายด้านบน เราต้องการเพียงการค้นหาคำกริยาที่เหมาะสมในการแทรก/ระหว่างรายการ

การลดซ้ำแต่ละครั้งจะอัปเดตกล่องขวาสุด (อินพุทเต็มรูปแบบที่เราเปลี่ยน) เพื่อให้สอดคล้องกับข้อ จำกัด การสั่งซื้อที่คู่ทางซ้ายแสดง เมื่อการลดเสร็จสิ้นอินพุตจะเคารพการสั่งซื้อชุดย่อยที่สมบูรณ์

หากการสั่งซื้อของทั้งคู่เหมือนกับการสั่งซื้อในอินพุทสิ่งต่อไปนี้จะประเมินเป็น 0 และเราจะไม่ทำอะไรเลย:

^:(>/@i.~)

มิฉะนั้นจะประเมินเป็น 1 และเราจะใช้กริยาทางด้านซ้ายของ ^:

   {: + i.@>:@-/)@i.~ C. ]

ซึ่งย้ายรายการด้านซ้ายไปทางขวาของรายการด้านขวา การเคลื่อนไหวนี้เป็นเพียงการเปลี่ยนรูปแบบวงจรของรายการทั้งหมดระหว่าง (และรวมถึง) องค์ประกอบทั้งสองที่เป็นปัญหา

เจมีพื้นฐานที่จะใช้วงจรการเปลี่ยนแปลง:

<cyclic permutation definition> C. ]

และส่วนที่เหลือของคำกริยาไม่ทำอะไรเลยนอกจากเลือกดัชนีที่เราต้องใช้ในการวนรอบ:

{: + i.@>:@-/)@i.~

ซึ่งดูเหมือนจะนานกว่าที่ควรจะเป็น แต่ฉันไม่สามารถเล่นวลีนั้นต่อไปได้

ในที่สุดเราก็ทำซ้ำผลลัพธ์<@และเสร็จแล้ว


0

เยลลี่ 24 ไบต์

i@€MƤFṬœṗƲḊ;JḟF}W€ʋ@¥ṢFị

ลองออนไลน์! หรือชุดทดสอบ

คำอธิบาย

ลิงก์ dyadic ที่ใช้เซ็ตย่อยเป็นรายการด้านซ้ายและมาสเตอร์เป็นอาร์กิวเมนต์ที่ถูกต้อง ตัวอย่างด้านล่างใช้ 9001, 42, 69, 1337, 420, 99, 255 เป็นมาสเตอร์และ 69, 9001, 1337 เป็นเซ็ตย่อย

i@€                      | Find the index of each subset item in the master list [3, 1, 4]
         Ʋ               | Previous 4 links as a monad
   MƤ                    | Find the index of the maximum for each prefix of this list [1, 1, 3]
     F                   | Flatten (because the previous result are actually each length one lists)
      Ṭ                  | Convert to a boolean list [1,0,1]
       œṗ                | Partition the [3, 1, 4] list before each 1 [[], [3, 1], [4]]
          Ḋ              | Remove the empty first list [[3, 1], [4]]
                    ¥    | Previous two links as a dyad
                  ʋ@     | Previous 4 links as a dyad with reversed arguments
            J            | Sequence along the master list [1, 2, 3, 4, 5, 6, 7]
             ḟF}         | Filter out items in the flattened [3, 1, 4] list
                W€       | Wrap each item as a list [[2], [5], [6], [7]]
           ;             | Concatenate rhis to the [[3, 1], [4]] list
                     Ṣ   | Sort (effectively by first item in each list) [[2], [3, 1], [4], [5], [6], [7]]
                      F  | Flatten
                       ị | Look up in original master list (and implicitly output)

0

C # (Visual C # Interactive Compiler) , 118 ไบต์

a=>b=>{for(int j;b.Any();)foreach(var e in b.Intersect(a.Take(j=a.IndexOf(b.Dequeue())))){a.Remove(e);a.Insert(j,e);}}

ลองออนไลน์!

ใช้ประโยชน์จากบางคลาสในSystem.Collections.Genericเนมสเปซ ต้นแบบเป็นและเซตเป็นList<T>Queue<T>

// a: master
// b: subset
a=>b=>{
  // continue until b is empty
  for(int j;b.Any();)
    // iterate over values that are out of order in a
    // per the head of b using loop variable e
    foreach(var e in
      // the out of order values are determined by
      // intersecting remaining values in b with
      b.Intersect(
        // values in a occurring before the current head of b
        // save the position in a to variable j and remove the head of b
        a.Take(j=a.IndexOf(b.Dequeue()))
      )
    ){
      // push back the out of order element in a
      a.Remove(e);
      a.Insert(j,e);
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.