Yeniden Sıralanan Alt Kümeye Göre Ana Listeyi Yeniden Sıralama


19

Son zamanlarda iki liste vardı iş yerinde çözmek için bir sorun vardı: bir ana liste ve ana listedeki öğelerin bir alt kümesini potansiyel olarak farklı bir sırayla içeren daha küçük bir liste. Ana listeyi, listede bulunmayan öğelerin sırasını değiştirmeden ve öğeleri mümkün olduğunca aynı konumda tutmadan alt kümedeki öğelerin aynı sırada görüneceği şekilde yeniden sıralamam gerekiyordu. Tamam, bu muhtemelen kafa karıştırıcı geliyor, bu yüzden onu yıkacağım:

  • Ana liste, öğelerin varsayılan sırasını tanımlar.
  • Altküme listesi, belirli öğelerin göreli sırasını tanımlar.
  • Ana liste, altküme listesine göre iki öğenin arızalı olduğu durumlarda, ana listede daha önce yer alan öğenin, alt küme listesindeki diğer öğelere göre doğru konumda olduğu en eski dizine taşınması gerekir. (yani sonraki öğeden hemen sonra)

Göreviniz bu yeniden sıralama algoritmasını uygulamaktır.

Örnek Test Durumları

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]

kurallar

  • Standart boşluklar, yadda yadda, uygun I / O, falan filan.
  • Örnekler sayı ve dize kullansa da, tamsayı, dize veya dilinizde uygunsa heterojen listeler de dahil olmak üzere iyi tanımlanmış eşitlik anlambilimine sahip başka bir öğe olsun, yalnızca bir öğe türünü desteklemeniz gerekir.
  • Hem ana listenin hem de alt küme listesinin kopya içermediğini varsayabilirsiniz.
  • Alt küme listesinde bulunan tüm öğelerin ana listede bulunduğunu varsayabilirsiniz.
  • Her iki liste de boş olabilir
  • En az 100 eleman uzunluğunda dizileri desteklemelisiniz.
  • Yeniden sıralama yerinde veya yeni bir liste / dizi oluşturularak uygulanabilir.

Mutlu Golf!


1
Güzel, etli bir sorun.
Jonah

8 1 3 4 5 6 7 2 9 12 11 10İkinci-sonuncu için geçerli bir çözüm mü ?
Ven

@Ven Hayır. Bu, alt küme öğelerini aynı göreli sırayla tutma kısıtlamalarına uysa da, yalnızca bir doğru yanıt olduğundan emin olmak istedim, bu yüzden önceki sipariş dışı öğe, daha sonra sipariş dışı ürün.
Beefster

Birden fazla doğru cevabın olması neden önemlidir? Lütfen kısıtlamayı meydan okuma kurallarına ekleyiniz.
Ven

Yanıtlar:


4

Retina 0.8.2 , 51 bayt

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

Çevrimiçi deneyin! Girdiyi ilk satırdaki virgülle ayrılmış bir alt sözcük listesi ve ikinci satırdaki virgülle ayrılmış bir ana sözcük listesi olarak alır. Açıklama:

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

İkinci sözcüğün ana listede ilkinden önce geldiği iki bitişik alt kelimeyi bulun.

$1$4,$3

Ana listedeki ilk kelimeden sonra görünecek ikinci kelimeyi taşıyın.

+`

Hiçbir kelime sıra dışı görünene kadar tekrarlayın.

1A`

Alt kelimeleri silin.


4

JavaScript (ES6),  96 89 74  71 bayt

Bu hantal bir karmaşa olarak başladı ve sonunda oldukça özlü ve zarif bir forma büzüştü. .Splice () ' a teşekkür etmek istiyorum verimli işbirliğinden yöntemine . ;)

Girişi alır (master)(subset). Ana listeyi güncelleyerek çıktılar.

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

Çevrimiçi deneyin!

Nasıl?

benp

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

1

  • ben[element]
  • forma sözdizimi sayesinde , bu öğe dış .splice () için 3. bağımsız değişken olarak genişletilir ve bu da konumuna geri eklenmesine neden olurp

0

  • .splice () yöntemi hiçbir şeyi kaldırmaz ve boş bir dizi döndürür
  • Bir sonuç olarak, dış .splice () alır tanımlanmamış olan 3 değişken olarak ve hiçbir şey ya sokulur

Yorumlananlar

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 () yöntemine ... için teşekkür etmek istiyorum ." Cue PPCG Oscar'ın Müziği ... :)
Chas Brown

Daha doğru olarak, dış ekleme çağrısı sırasıyla 3 veya 2 argüman alır, bu da doğru şeyi yapmasını sağlar.
Neil

2

Haskell, 79 bayt

(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

Çevrimiçi deneyin!

(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

Yakut , 73 68 bayt

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

Çevrimiçi deneyin!

Nasıl?

  • Arasındaki kesişme ave btüm unsurları içerirb , ama onları bulacağımız sıraylaa
  • Yani, bparalel olarak kavşak üzerinde ve üzerinde tekrarlarsak, bir fark bulur bulmaz, tek bir elemanı yeniden konumlandırabiliriz.
  • Yer değiştirme, abulduğumuz elemanın konumunu kesip b, kavşakta bulduğumuz elemanı kaldırarak ve a'nın geri kalanını ekleyerek yapılır.
  • Öğesinin tüm öğeleri bdoğru sırada olana kadar en baştan tekrarlayın .a

0 ne yapıyor 0while?
Jonah

Sadece bir NOP.
GB

neden gerekli?
Jonah

1
Çünkü döngü başlatılmadan önce bir değişken bildirmekten kaçınmak için karşılaştırma ve manipülasyon tek bir blokta yapılır. Bu şu anlama gelir: kod daha kısadır "operasyonu yapmak sonuç doğru ise" "gerçek operasyon döner iken hiçbir şey yapmam."
TR


1

Perl 6 , 40 bayt

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

Çevrimiçi deneyin!

Girdiyi alan (anonim kod bloğu f(subList)(masterList), alt listedeki öğelerin doğru sırada olduğu ana listenin dizinlerinin ilk sözlüksel permütasyonunu bulur ve bulur).

Sezgisel olarak, ilk tatmin edici permütasyon, doğru sıralanmış elemanları orijinal sırada bırakırken, yanlış yerleştirilmiş olanları, doğru bir şekilde yerleştirmek için gerekli minimum mesafeyi ileriye doğru hareket ettirir, bu da onları alt kümedeki önceki öğeden hemen sonra yerleştirir.

Açıklama:

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

Jöle , 9 bayt

Œ!iⱮṢƑ¥ƇḢ

Çevrimiçi deneyin! veya Test takımı

Verimsiz, özellikle büyük ana listelerde. Tüm olası permütasyonları oluşturur, altkümenin yanlış sırada olduğu süzgeçleri filtreler ve sonra ilkini döndürür.

açıklama

Œ!        | 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

Bu, "Ana listenin, alt küme listesine göre iki öğenin bozuk olduğu durumda, ana listede daha önce yer alan öğenin, en eski dizine taşınması gerekir . alt küme listesindeki diğer öğelere göre doğru konum (yani sonraki öğeden hemen sonra) "
Beefster

@Beefster şimdiye kadar denediklerim üzerinde çalışıyor. Bence permütasyonların sırası doğru sonuç budur. Karşı bir örnek varsa yanlış kanıtlamaktan mutluluk duyarız.
Nick Kennedy

@ Beefster Kadın isimleri ve 1..12 hariç tüm örneklerinizi denedim ve sonucun sıralaması doğru.
Nick Kennedy

2
@Beefster Cevabım bunun neden işe yaradığına dair kısmi bir açıklama var
Jo King

1

J , 49 bayt

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

Çevrimiçi deneyin!

açıklama

Altkümeyi sol argüman olarak ve tam girdiyi sağ olarak alıyoruz.

Netlik için belirli bir örnekle kod üzerinde çalışacağız:

5 2 4 f 1 2 3 4 5

Altkümenin iki boyutlu kutulu eklerini alın:

2 <\ [

üreten:

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

onları orijinal girdiye ekleyin ve her şeyi tersine çevirin:

] |.@;

Biz:

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

Sorunu çözmek, yukarıdakiler üzerinde sağdan sola bir azalma haline gelir. Eklemek için sadece doğru fiili bulmamız gerekiyor/Öğeler arasına .

İndirgeme işleminin her yinelemesi en sağdaki kutuyu (dönüştürdüğümüz tam girdi) güncelleyecek, böylece çift tarafından solunda gösterilen sipariş kısıtlamasına uyacaktır. İndirgeme işlemi tamamlandığında, giriş tüm alt küme sırasına saygı gösterir.

Çiftin sıralaması girişteki sıralamayla aynı ise, aşağıdakiler 0 olarak değerlendirilir ve hiçbir şey yapmayacağız:

^:(>/@i.~)

Aksi takdirde 1 olarak değerlendirilir ve fiili ^:

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

sol öğeyi sağ öğenin sağına taşır. Bu hareket basitçe döngüsel bir permütasyon söz konusu iki unsur arasındaki (ve dahil) tüm öğelerin .

J, böyle bir döngüsel permütasyon uygulamak için ilkeldir:

<cyclic permutation definition> C. ]

ve fiilin geri kalanı, döngü yapmamız gereken dizinleri seçmekten başka bir şey yapmaz:

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

ki bu olması gerekenden daha uzun görünüyor, ama bu ifadeyi daha fazla golf oynayamadım.

Sonunda sonucu yeniden kutladık <@ve işimiz bitti.


0

Jöle , 24 bayt

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

Çevrimiçi deneyin! veya Test takımı

açıklama

Altkümeyi sol ve ana listeyi sağ argümanlar olarak alan ikili bir bağlantı. Aşağıdaki örnekte master olarak 9001, 42, 69, 1337, 420, 99, 255 ve alt küme olarak 69, 9001, 1337 kullanılmıştır.

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 # Etkileşimli Derleyici) , 118 bayt

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);}}

Çevrimiçi deneyin!

Ad alanındaki bazı sınıflardan yararlanma System.Collections.Generic. Master bir List<T>ve alt küme bir 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);
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.