Найкоротші унікальні ідентифікаційні підрядки


23

Враховуючи список рядків, замініть кожну рядок однією з її непустих підрядків, яка не є підрядкою жодної з інших рядків у списку, і якомога коротшою.

Приклад

З огляду на список ["hello","hallo","hola"], "hello"повинні бути замінені тільки "e"як це підрядок не міститься в "hallo"і , "hola"і це якомога коротше. "hallo"може бути замінений або "ha"або "al"і "hola"будь-яким "ho", "ol"або "la".

Правила

  • Ви можете припустити, що рядки будуть не порожніми і містять лише алфавітні символи того самого випадку.
  • Можна припустити, що така підрядка існує для кожної рядки у списку, тобто жодна рядок у списку не буде підрядкою будь-якого з інших рядків.
  • Введення та вихід можуть бути у будь-якому розумному форматі.
  • Це , тому намагайтеся використовувати якомога менше байтів мовою, яку ви обрали.

Випробування

У більшості випадків подається лише один можливий вихід.

["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"]

Пов’язано: Найкоротша ідентифікаційна підрядка - схожа ідея, але більше стосується правил та громіздкого формату.


Чому isnt ""(порожній рядок) однозначно ідентифікує для одного "ppcg"випадку?
MooseBoys

2
@MooseBoys Враховуючи список рядків, замініть кожну рядок однією з непустих підрядків
Mr. Xcoder

Відповіді:




4

Pyth , 12 байт

mhf!ts}LTQ.:

Спробуйте тут!

Як це працює

Basicaly фільтрує підрядки кожної, які зустрічаються лише в одній із рядків у списку (тобто вона є унікальною для цього рядка) і отримує першу.

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 байт

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),[_])).

Спробуйте в Інтернеті!

Більшість речей тут має бути досить очевидними, але:

Пояснення

Підписи: ( += вхід, ?= необов'язково, -= вихід, := вираз)

  • 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)

\+ \+є справедливим not not(тобто перетворює відповідність на булеву (у цьому випадку заважає йому поєднувати обидва ps ppcgокремо))


Правильний інструмент для роботи: P за винятком того, що це приголомшливо багатослівне
лише ASCII


4

J , 30 29 25 байт

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

Спробуйте в Інтернеті!

                   <\\.&>        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 байти

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

Спробуйте в Інтернеті!

Як?

Для кожного рядка s довжиною L у вхідному масиві a [] і, починаючи з n = 0 , ми використовуємо рекурсивну функцію g () для генерації всіх підрядків u з s :

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

Наприклад, з s = "abc" і L = 3 :

 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"

Деякі підрядки генеруються кілька разів, але це не має значення. Важливо те, що всі підрядки довжини N були згенеровані перед будь-якою підрядкою довжиною N + 1 .

Ми зупиняємо процес, як тільки u не може бути знайдено в жодному іншому рядку S у [] , що гарантовано відбудеться, коли u == s у гіршому випадку, згідно правила №2 виклику:

жоден рядок у списку не буде підрядком будь-якого з інших рядків

Тому у наведеному вище прикладі кроки 7 та 8 насправді ніколи не будуть оброблені.


2

PowerShell , 107 байт

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

Спробуйте в Інтернеті!

Пояснення

Для кожного рядка, що постачається (і призначте весь масив $a):

  • Зробіть forцикл по кожній довжині підрядка (на основі 1) рядка (присвоївши собі рядок $sі довжину до $g)
  • Для кожної довжини ( $i):
    • Зробіть цикл індексу від 0 до довжини - $i, а потім для кожного індексу:
      • Отримайте підрядку поточного рядка ( $s) у положенні $_(індекс) та довжині$i
      • Передайте цю підрядку до Where-Object( ?) і поверніть її, якщо:
        • Підмножина масиву ( $a), що не містить поточного рядка $s, не відповідає збігу для поточної підрядки$_

Повернувшись на рівні рядка, у нас є всі підрядки цього рядка, яких не було знайдено в інших, тому візьміть першу, [0]оскільки нам потрібна лише одна з них, а потім продовжуйте з наступним рядком.


0

C # (Visual C # Interactive Compiler) , 149 байт

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

Спробуйте в Інтернеті!

Менше гольфу ...

// 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;
  })
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.