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


14

Подано (на STDIN, як аргументи командного рядка або як аргументи функції) два різних непусті рядки, знайдіть і поверніть найкоротшу підрядку першого рядка, яка не є підрядкою другої. Якщо такої підрядки не існує, ви можете повернути порожню рядок, повернути будь-яку рядок, що не є підрядкою вихідної рядки, або викинути виняток. Якщо ви повертаєтесь з функції, у цьому випадку ви також можете повернути нульові (або невизначені, Ні, тощо). Якщо кілька таких підрядів пов'язані найкоротше, ви можете повернути будь-яку з них.

Рядки можуть складатися з будь-яких символів для друку ascii.

Вхід, заданий на STDIN, буде надаватися по одній рядку в кожному рядку. На ваш запит, в кінці введення може бути доданий один порожній рядок.

Це кодовий гольф, тому виграє найкоротша дійсна програма.

ДЕЯКІ ТЕСТОВІ СПРАВИ

ВХОД:

STRING ONE
STRING TWO

ВИХІД:

E

ВХОД:

A&&C
A&$C

ВІДХІДНІ ВИХІДИ:

&&
&C

ВХОД:

(Два випадково згенерованих 80-літерних рядків)

QIJYXPYWIWESWBRFWUHEERVQFJROYIXNKPKVDDFFZBUNBRZVUEYKLURBJCZJYMINCZNQEYKRADRYSWMH
HAXUDFLYFSLABUCXUWNHPSGQUXMQUIQYRWVIXGNKJGYUTWMLLPRIZDRLFXWKXOBOOEFESKNCUIFHNLFE

ВСІ ПРАВИЛЬНІ ВИХІДИ:

AD
BJ
BR
CZ
DD
EE
ER
EY
EY
FF
FJ
FW
FZ
HE
IJ
IN
IW
JC
JR
JY
KL
KP
KR
KV
LU
MH
MI
NB
NQ
OY
PK
PY
QE
QF
QI
RA
RB
RF
RO
RV
RY
RZ
SW
UE
UH
UN
UR
VD
VQ
VU
WB
WE
WI
WU
XN
XP
YI
YK
YK
YM
YS
YW
YX
ZB
ZJ
ZN
ZV

1
найкоротший чи найдовший?
Leaky Nun

@FryAmTheEggman Тоді я все-таки повинен розмістити своє рішення ...
Leaky Nun

"По одному рядку в кожному рядку" з лапками або без них?
Leaky Nun

1
Чи можемо ми взяти масив рядків?
Денніс

"B" є підрядком "aBc"?
downrep_nation

Відповіді:


4

Брахілог , 23 байти

:1foh.,{,.[A:B]hs?'~sB}

Працює над старим транслятором Java. Очікує, що два рядки у списку є вхідними, об'єднує вихід із підрядкою. Якщо підрядка не знайдена, повертається false.

На жаль, я ще не зашифрував підмножину, вбудовану в новий транспілятор Prolog.

Пояснення

:1f               Find all bindings which satisfy predicate 1 with that binding as input and
                  with the Input of the main predicate as output.
   oh.,           Order that list of bindings, and unify the output with the first one.

{
 ,.[A:B]          Unify the output with the list [A,B]
        hs?       Unify the input with a subset of A
           '~sB   Check that no subset of B can be unified with the input
               }

4

Пітона, 119 115 91

lambda a,b:[a[m:m+n]for n in range(1,len(a)+1)for m in range(len(a))if a[m:m+n]not in b][0]

Тестові приклади:

| Input 1  | Input 2     | Output        |
|----------+-------------+---------------|
| 'abcd'   | 'abc'       |  'd'          |
| 'abcd'   | 'dabc'      |  'cd'         |
| 'abcd'   | 'dcbabbccd' |  'abc'        |
| 'abcdf'  | 'abcdebcdf' |  'abcdf'      |
| 'abc'    | 'abc'       |  (IndexError) |

Працюю над тим, щоб скоротити її, але це мій інстинкт мозку. Ще не дуже гольфіст.

Завдяки @ user81655 та @NonlinearFruit за зайві байти.

Редагувати :

Данг. Спробував цей код:

def z(a,b):
 for s in [a[m:m+n]for n in range(1,len(a)+1)for m in range(len(a)-n+1)]:
  if s not in b:return s
 return''

Думав, що це на кілька байт коротше. Виявляється, це було на 1 байт довше, ніж у мене до редагування.


Я не знаю багато python, але, можливо, ви можете (r=range)(1,len(a)+1)потім використовувати r?
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Не можу зробити це зовсім так. Якщо я задаю , rangeщоб rв рядку вище, він фактично додає байт. Хороша ідея, хоча. Мабуть, існує коротший спосіб перебрати підрядок.
Тейлор Лопес

range(1,len(a))і чи range(len(a)-1)варто працювати, чи не так? Крім того, я думаю, що використання символу табуляції для двох відступів простору врятує байт.
користувач81655

Ні, з range(1,len(a)), четвертий тестовий склад не вдається, тому що він не буде випробовувати повний рядок; він буде переходити лише до довжини рядка - 1. І при range(len(a)-1)цьому 1-й тестовий випадок не повертається 'cd'замість просто 'd'. Там може щось бути.
Тейлор Лопес

Вибачте, я не знайомий з Python, і я припустив, що діапазони включають. У такому випадку спробуйте range(1,len(a)+1)і range(len(a)).
користувач81655

3

Пітон, 87 86 байт

lambda s,t,e=enumerate:[s[i:i-~j]for j,_ in e(s)for i,_ in e(s)if(s[i:i-~j]in t)<1][0]

Якщо він існує, це поверне крайню ліву частину найкоротших унікальних підрядків.

Якщо унікальної підрядки немає, піднімається IndexError .

Перевірте це на Ideone .


Там. Я чекав, коли хтось вб’є мою не лямбда-реалізацію. nice lol
Тейлор Лопес

Я думаю , що ви можете зробити це коротше, забезпечуючи необов'язковий другий аргумент , enumerateщоб почати jв i+1.
user2357112 підтримує Моніка

@ user2357112 Це , на жаль, кидає NameError Код визначається jспочатку, потім i.
Денніс

@Dennis: Так, але це не потрібно. Ви можете змінити порядок циклу.
user2357112 підтримує Моніку

1
@ user2357112 Якщо я переключаю порядок циклу, перша унікальна підрядка, яку він знайде, може виявитися не найкоротшою. Просто помінявши повернення замовлень 'ab'на введення 'abc','aaa'.
Денніс

2

Пітон, 82 байти

g=lambda u:{u}|g(u[1:])|g(u[:-1])if u else{''}
f=lambda s,t:min(g(s)-g(t),key=len)

Використання: f('A&&C', 'A&$C')-> повертає'&&'

Підвищує ValueError, якщо немає відповідної підрядки.

Пояснення:

g=lambda u:{u}|g(u[1:])|g(u[:-1])if u else{''}рекурсивно створює набір підрядків u f=lambda s,t:min(g(s)-g(t),key=len)відбирає найкоротший підрядок із заданої різниці


2

JavaScript (ES6), 79 байт

f=
(a,b)=>[...a].some((_,i,c)=>c.some((_,j)=>b.indexOf(s=a.substr(j,i+1))<0))?s:''
<div oninput=o.textContent=f(a.value,b.value)><input id="a"/><input id="b"/><pre id=o>

Якщо повернення falseприйнятне, збережіть 2 байти, використовуючи &&sзамість ?s:''.



1

JavaScript (Firefox), 80 байт

solution=

a=>b=>[for(_ of(i=0,a))for(_ of(j=!++i,a))if(b.includes(s=a.substr(j++,i)))s][0]

document.write("<pre>"+
[ [ "test", "best" ], [ "wes", "west" ], [ "red", "dress" ] ]
.map(c=>c+": "+solution(c[0])(c[1])).join`\n`)

Тест працює лише у Firefox. Повертається, undefinedякщо немає підрядки.


Рядки можуть містити символи ASCII для друку, такі як \ або інші метадані RegExp, але якщо ви обмежуєте себе Firefox, чому б не використати b.includesнатомість?
Ніл

@Neil У запитанні не було сказано, що струни раніше могли бути будь-якими символами, але дякую, що повідомили мені! Оновлено для використання includes.
користувач81655

1
Тест-фрагмент кидає:SyntaxError: unexpected token 'for'
NoOneIsHere

@NoOneIsHere Ось ця помилка ви отримаєте, якщо не використовуєте Firefox ...
user81655

1

Сітківка , 37 байт

M!&`\G(.+?)(?!.*¶.*\1)
O$#`.+
$.&
G1`

Вихід порожній, якщо в ньому не знайдено дійсної підрядки A .

Спробуйте в Інтернеті!(Трохи модифікований для запуску декількох тестових випадків одночасно. Формат вводу насправді розділений підводкою ліній, але тестові набори найпростіше записати з одного тестового випадку на рядок. Тестовий фрейм перетворює простір у виклик рядків до початку фактичного коду.)

Пояснення

M!&`\G(.+?)(?!.*¶.*\1)

Для кожної можливої ​​вихідної позиції в A, відповідайте найкоротшому підрядку, який не відображається в B. Це &стосується збігів, що перекриваються, таким чином, що ми реально намагаємося кожну стартову позицію, навіть якщо збіг довший одного символу. У \Gгарантує , що ми не пропустити ні однієї позиції - зокрема, таким чином , ми повинні зупинитися на новий рядок, так що ми не отримуємо додаткові матчі від Bсебе. Причина, по якій це не зіпсує, насправді є досить тонкою: адже якщо є вихідна позиція, Aде ми не можемо знайти жодної дійсної підрядки, то це теж збій, який призведе \Gдо припинення перевірки будь-яких подальших позицій. Однак якщо (з поточного вихідного положення) всі підрядки з'являються уB, так і всі підрядки, які починають надалі право від поточної позиції, тому відмова від них не є проблемою (і фактично покращує продуктивність).

Завдяки M!конфігурації всі ці поєдинки будуть повернуті зі сцени, об'єднані з стрічковими стрічками.

O$#`.+
$.&

Це сортує рядки попереднього результату за довжиною. Це робиться шляхом зіставлення рядка з .+. Потім $активується форма "сортування", така що відповідність замінюється $.&на визначення порядку сортування. $.&Сам замінює матч з його довжиною. Нарешті, #опція пропонує Retina сортувати чисельно (інакше отримані числа будуть розглядатися як рядки та сортувати їх лексикографічно).

G1`

Нарешті, ми просто зберігаємо лише перший рядок, використовуючи греп-етап із порожнім регулярним виразом (який завжди відповідає) та обмеженням 1.


1

Perl, 87 85

sub{(grep{$_[1]!~/\Q$_/}map{$}=$_;map{substr($_[0],$_,$})}@}}(@}=0..length$_[0]))[0]}

Це анонімна функція, яка повертає першу (за позицією) найкоротші підрядки $_[0], які не зустрічаються $_[1], або undefякщо таких підрядків не існує.

Тестова програма з рядками, взятіми з відповіді @ iAmMortos, перевірена Perl 5.22.1:

#!/usr/bin/perl -l
use strict;
use warnings;

my $f = <see above>;
print $f->('abcd', 'abc');
print $f->('abcd', 'dabc');
print $f->('abcd', 'dcbabbccd');
print $f->('abcdf', 'abcdebcdf');
print $f->('abc', 'abc');

1

Haskell, 72 байти

import Data.Lists
a#b=argmin length[x|x<-powerslice a,not$isInfixOf x b]

Приклад використання: "abcd" # "dabc"-> "cd".

Проста реалізація: будуйте всі підрядки aта зберігайте ті, які не відображаються b. argminповертає елемент списку , який зводить до мінімуму функції по заданій 2 - й аргументу, тут: length.


Я не знав про це argmin! Це здається надзвичайно корисним.
Згарб

0

Закреслено 9 все ще 9
кіт

Я хотів би знати, як це працює.
mroman

@mroman the.: з одним аргументом є всі substrs. Тож я відображаю те, що над обома рядками, згорнувшись, встановіть різницю, тож у мене є всі підстрочки першого спочатку другого, а потім я вибираю перше, яке є найменшим, тому що: сортується.
Малтісен

0

C #, 152 байти

string f(string a,string b){int x=a.Length;for(int i=1;i<=x;i++)for(int j=0;j<=x-i;j++){var y=a.Substring(j,i);if(!b.Contains(y))return y;}return null;}

0

Рубін, 70 байт

Збирає всі підрядки певної довжини з першого рядка, і якщо є такий, який не є у другому рядку, поверніть його.

->a,b{r=p;(1..l=a.size).map{|i|(0...l).map{|j|b[s=a[j,i]]?0:r||=s}};r}

0

Бурлеск - 26 байт

Зараз найкоротший спосіб, який я можу придумати, це:

lnp^sujbcjz[{^p~[n!}f[-][~

0

Japt , 14 байт

Êõ!ãU c k!èV g

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

Повертається, undefinedякщо немає дійсної підрядки . Це відрізняється від повернення рядка "undefined" , хоча різниця видно лише через прапор -Q.

Пояснення:

Ê                 :Length of the first input
 õ                :For each number in the range [1...length]:
  !ãU             : Get the substrings of the first input with that length
      c           :Flatten to a single array with shorter substrings first
        k         :Remove ones which return non-zero to:
         !èV      : Number of times that substring appears in second input
             g    :Return the shortest remaining substring

0

Japt -h, 11 байт

à f@øX «VøX

Спробуй це

                :Implicit input of strings U & V
à               :All combinations of U
  f@            :Filter each as X
    øX          :  Does U contain X?
       «        :  Logical AND with the negation of
        VøX     :  Does V contain X?
                :Implicit output of last element
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.