Eşsiz En Kısa Sapanlar


23

Dizelerin bir listesi göz önüne alındığında, her dizeyi, listedeki diğer dizelerin hiçbirinin alt dizisi olmayan boş olmayan alt dizelerinden biriyle ve mümkün olduğunca kısa bir değerle değiştirin.

Örnek

Liste Verilen ["hello","hallo","hola"], "hello"sadece değiştirilmesi gerektiğini "e", bu alt dize bulunan değil "hallo"ve "hola"ve mümkün olduğunca kısa olduğunu. "hallo"herhangi biri ile ikame edilebilir "ha"ya da "al"ve "hola"herhangi biri ile "ho", "ol"ya da "la".

kurallar

  • Dizelerin boş olmadığını ve yalnızca aynı harfin alfabetik karakterlerini içerdiğini varsayabilirsiniz.
  • Listedeki her dize için böyle bir alt dizinin bulunduğunu varsayabilirsiniz, yani listedeki hiçbir dize, diğer dizelerin hiçbirinin alt dizesi olmayacaktır.
  • Giriş ve çıkış herhangi bir makul formatta olabilir.
  • Bu , bu yüzden seçtiğiniz dilde mümkün olduğunca az byte kullanmaya çalışın.

Test Kılıfları

Çoğu durumda yalnızca bir olası çıktı verilir.

["ppcg"] -> ["p"] (or ["c"] or ["g"])
["hello","hallo","hola"] -> ["e","ha","ho"]
["abc","bca","bac"] -> ["ab","ca","ba"]
["abc","abd","dbc"] -> ["abc","bd","db"]
["lorem","ipsum","dolor","sit","amet"] -> ["re","p","d","si","a"]
["abc","acb","bac","bca","cab","cba"] -> ["abc","acb","bac","bca","cab","cba"]

İlgili: En Kısa Tanımlama Alt Dilimi - benzer bir fikir, ancak daha fazla ilgili kural ve zahmetli biçim.


Neden ""tek bir "ppcg"durum için benzersiz tanımlayıcı değil (boş dize) ?
MooseBoys

2
@MooseBoys Dizelerin bir listesi göz önüne alındığında, her dizeyi boş olmayan alt dizelerden biriyle değiştirin
Mr. Xcoder

Yanıtlar:




4

Pyth , 12 bayt

mhf!ts}LTQ.:

Burada dene!

Nasıl çalışır

Temel olarak, listedeki dizelerden yalnızca birinde oluşan (yani, o dizeye özgü olan) her birinin alt dizelerini filtreler ve ilki alır.

mhf!ts}LTQ.:     Full program, Q=eval(stdin_input())
m         .:     Map over Q and obtain all the substrings of each.
  f              And filter-keep those that satisfy (var: T)...
      }LTQ       ... For each string in Q, yield 1 if it contains T, else 0.
   !ts           ... Sum the list, decrement and negate. 
 h               Head. Yields the first valid substring, which is always the shortest.

4

Prolog (SWI) , 175 163 bayt

S/L/R:-sub_string(S,_,L,_,R).
[H|T]+[I|R]:-string_length(H,L),between(1,L,X),H/X/I,T+R.
R+R.
L-R:-L+R,forall(member(E,L),findall(_,(member(F,R),\+ \+ E/_/F),[_])).

Çevrimiçi deneyin!

Buradaki şeylerin çoğu oldukça açık olmalıdır, ancak:

açıklama

İmzalar: ( += giriş, ?= isteğe bağlı, -= çıkış, := ifade)

  • sub_string(+String, ?Before, ?Length, ?After, ?SubString)
  • string_length(+String, -Length)
  • member(?Elem, ?List)
  • between(+Low, +High, ?Value)
  • findall(+Template, :Goal, -Bag)
  • forall(:Cond, :Action)

\+ \+Sadece bir not not(bu durumda mantıksal yani dönüştürür bir eşleşme (her iki eşleştirme önler o pbölgesindeki s ppcg) ayrı ayrı)


O ayrıntılı zihin-blowingly var gerçeği dışında P: Doğru iş için aracı
ASCII sadece


4

J , 30 29 25 bayt

1(|:(0{-.&,)"_1]\.)<\\.&>

Çevrimiçi deneyin!

                   <\\.&>        a 3-dimensional array of substrings
1 |:                             transpose each matrix to sort the substrings by length
1              ]\.               all choices where one word is missing
    (0{-.&,)"_1                  for every matrix, flatten, remove substrings
                                  that are present in the corresponding complement,
                                  pick first


3

JavaScript (ES6), 93 bayt

a=>a.map(s=>(L=s.length,g=n=>a.every(S=>S==s|!~S.search(u=s.substr(n%L,n/L+1)))?u:g(n+1))(0))

Çevrimiçi deneyin!

Nasıl?

Her dizi için in uzunluğu L , giriş dizisi içinde bir [] ile başlayan n = 0 , biz özyinelemeli işlevini kullanın g () tüm alt dizeleri oluşturmak için u arasında s ile:

u = s.substr(n % L, n / L + 1)

Örneğin, s = "abc" ve L = 3 ile :

 n | n%L | floor(n/L+1) | u
---+-----+--------------+-------
 0 |  0  |       1      | "a"
 1 |  1  |       1      | "b"
 2 |  2  |       1      | "c"
 3 |  0  |       2      | "ab"
 4 |  1  |       2      | "bc"
 5 |  2  |       2      | "c"
 6 |  0  |       3      | "abc"
 7 |  1  |       3      | "bc"
 8 |  2  |       3      | "c"

Bazı alt diziler birkaç kez üretilir, ancak fark etmez. Önemli olan, N uzunluktaki tüm alt dizgilerin, N + 1 uzunluktaki alt dizgilerden önce oluşturulmuş olmasıdır .

Biz en kısa sürede işlemini durdurmak u hiçbirinde bulunamaz diğer dize S içinde bir [] zaman garanti edildiği, gerçekleşmesi u == s meydan kural 2. gereğince, en kötü durumda:

Listedeki hiçbir dize, diğer dizelerin herhangi birinin alt dizesi olacaktır.

Bu nedenle, yukarıdaki örnekte, 7. ve 8. adımlar aslında hiçbir zaman işleme alınmayacaktır.


2

PowerShell , 107 bayt

($a=$args)|%{$(for($i=0;$i++-lt($g=($s=$_)|% Le*)){0..($g-$i)|%{$s|% s*g $_ $i}|?{!($a-match$_-ne$s)}})[0]}

Çevrimiçi deneyin!

açıklama

Verilen her dize için (ve dizinin tamamını atayın $a):

  • forDizenin her alt uzunluğu (1 temelli) üzerinde bir döngü yapın (dizinin kendisini $sve uzunluğunu atayın $g)
  • Her uzunluk için ( $i):
    • $iHer bir dizin için 0'dan uzunluğa - kadar bir dizin döngüsü yapın :
      • Geçerli dizginin ( $s) alt $_dizinini (index) konumunda ve uzunluğunda al$i
      • Bu alt dizgiyi Where-Object( ?) 'e iletin ve eğer:
        • $aGeçerli dizgiyi içermeyen array ( ) alt kümesi $s, geçerli alt dizeyle eşleşmiyor$_

Dize düzeyinde, diğerlerinde bulunmayan bu dizenin tüm alt dizgilerine sahibiz, bu yüzden bir tanesine [0]ihtiyaç duyduğumuzdan birincisini alın, bir sonraki dizgiye devam edin.


0

C # (Visual C # Etkileşimli Derleyici) , 149 bayt

a=>a.Select(s=>{var t=s;for(int j=0,k,l=s.Length;j++<l;)for(k=-1;j+k++<l;)if(!a.Where(u=>s!=u&u.Contains(t=s.Substring(k,j))).Any())j=k=l;return t;})

Çevrimiçi deneyin!

Daha az golf oynadım ...

// a is an input array of strings
a=>
  // iterate over input array   
  a.Select(s=>{
    // t is the result string
    var t=s;
    // j is the substring length
    for(int j=0,k,l=s.Length;j++<l;)
      // k is the start index
      for(k=-1;j+k++<l;)
        // LINQ query to check if substring is valid
        // the tested string is collected in t
        if(!a.Where(u=>s!=u&u.Contains(t=s.Substring(k,j))).Any())
          // break loops
          j=k=l;
    // return result
    return t;
  })
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.