En Kısa Benzersiz Substring


14

(STDIN'de, komut satırı bağımsız değişkenleri veya işlev bağımsız değişkenleri olarak) iki farklı boş olmayan dize verildiğinde, ikinci dizenin alt dizesi olmayan ilk dizenin en kısa alt dizesini bulup döndürür. Böyle bir alt dize yoksa, boş dizeyi döndürebilir, orijinal dizenin alt dizesi olmayan herhangi bir dizeyi döndürebilir veya bir istisna atabilirsiniz. Bir işlevden dönüyorsanız, bu durumda null (veya undefined, None, vb.) Döndürebilirsiniz. Bu tür birden çok alt dize en kısa için bağlıysa bunlardan herhangi birini döndürebilirsiniz.

Dizeler yazdırılabilir ascii karakterlerden oluşabilir.

STDIN'de verilen girdi her satırda bir dize ile verilecektir. İsteğiniz üzerine, girdinin sonuna tek bir boş satır eklenebilir.

Bu kod golf, bu yüzden en kısa geçerli program kazanır.

BAZI TEST OLGULARI

GİRİŞ:

STRING ONE
STRING TWO

ÇIKTI:

E

GİRİŞ:

A&&C
A&$C

GEÇERLİ ÇIKTILAR:

&&
&C

GİRİŞ:

(İki rastgele oluşturulmuş 80 harfli dize)

QIJYXPYWIWESWBRFWUHEERVQFJROYIXNKPKVDDFFZBUNBRZVUEYKLURBJCZJYMINCZNQEYKRADRYSWMH
HAXUDFLYFSLABUCXUWNHPSGQUXMQUIQYRWVIXGNKJGYUTWMLLPRIZDRLFXWKXOBOOEFESKNCUIFHNLFE

TÜM GEÇERLİ ÇIKTILAR:

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
en kısa ya da en uzun?
Leaky Nun

@FryAmTheEggman O zaman hala benim çözüm göndermek gerekir ...
Leaky Nun

Tırnaklı veya tırnaksız "Her satırda bir dize" var mı?
Leaky Nun

1
Bir dizi dizi alabilir miyiz?
Dennis

"B", "aBc" nin bir alt dizisidir?
downrep_nation

Yanıtlar:


4

Brachylog , 23 bayt

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

Eski Java transpiler üzerinde çalışır. Bir listedeki iki dizeyi girdi olarak bekler, çıktıyı alt dize ile birleştirir. Hiçbir alt dize bulunmazsa, false değerini döndürür.

Ne yazık ki, yeni Prolog transpilerindeki yerleşik altkümeyi henüz kodlamadım.

açıklama

: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

Python, 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]

Test senaryoları:

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

Kısaltmak için çalışıyorum, ama bu benim beyin içgüdüm. Henüz bir golfçü yok.

Ekstra baytlar için @ user81655 ve @ NononearFruit sayesinde.

Düzenle :

Dang. Bu kodu denedim:

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

Birkaç bayt daha kısa olduğunu düşündüm. Düzenlemeden önce sahip olduğumdan 1 bayt daha uzun olduğu ortaya çıktı.


Fazla python bilmiyorum, ama belki (r=range)(1,len(a)+1)o zaman kullanabilirsiniz r?
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Bu şekilde yapamam. Ben atarsanız rangeiçin ryukarıdaki satırda, aslında bir bayt ekler. İyi fikir olsa. Muhtemelen alt dizeleri yinelemenin daha kısa bir yolu vardır.
Taylor Lopez

range(1,len(a))ve range(len(a)-1)çalışmalı, değil mi? Ayrıca iki boşluk girintisi için bir sekme karakteri kullanmak bir bayt tasarruf düşünüyorum.
user81655

Hayır, range(1,len(a))dördüncü test kadrosu başarısız olur çünkü tam dizeyi denemeyecektir; sadece dize uzunluğuna gidecektir - 1. Ve ile range(len(a)-1), 1. test durumu 'cd'sadece yerine dönmüyor 'd'. Yine de orada bir şeyler olabilir.
Taylor Lopez

Maalesef Python'a aşina değilim ve aralıkların kapsayıcı olduğunu varsaydım. Bu durumda range(1,len(a)+1)ve deneyin range(len(a)).
user81655

3

Python, 87 86 bayt

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]

Varsa, bu, en kısa benzersiz alt dizelerin en solunu döndürür.

Benzersiz bir alt dize yoksa, bir IndexError oluşturulur.

Ideone üzerinde test edin .


İşte burada. Birisinin lambda olmayan uygulamamı öldürmesini bekliyordum. güzel lol
Taylor Lopez

Ben size opsiyonel ikinci argümanı sağlayarak bu kısa yapabilir düşünmek enumeratebaşlatmak için jde i+1.
user2357112,

@ user2357112 Maalesef bu bir NameError hatası veriyor . Kod tanımlar jsonra, ilk i.
Dennis

@Dennis: Evet, ama buna gerek yok. Döngü sırasını değiştirebilirsiniz.
user2357112 Monica

1
@ user2357112 Döngü sırasını değiştirirsem, bulduğu ilk benzersiz alt dize en kısa olmayabilir. 'ab'Giriş için sipariş iadelerini değiştirmeniz yeterlidir 'abc','aaa'.
Dennis

2

Python, 82 bayt

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

Kullanım: f('A&&C', 'A&$C')-> döner'&&'

Uygun alt dize yoksa ValueError değerini yükseltir.

Açıklama:

g=lambda u:{u}|g(u[1:])|g(u[:-1])if u else{''}özyinelemeli u f=lambda s,t:min(g(s)-g(t),key=len)olarak ayarlanan farktan en kısa alt dizeyi alır


2

JavaScript (ES6), 79 bayt

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>

İade falsekabul edilebilir durumdaysa, &&syerine 2 bayt tasarruf edin ?s:''.



1

JavaScript (Firefox), 80 bayt

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

Test yalnızca Firefox'ta çalışır. Alt undefineddize yoksa döndürür .


Dizeler \ veya diğer RegExp metakarakterleri gibi yazdırılabilir ASCII karakterleri içerebilir, ancak kendinizi Firefox ile sınırlandırıyorsanız, b.includesbunun yerine neden kullanmıyorsunuz ?
Neil

@Neil Soru, dizelerin daha önce herhangi bir karakter olabileceğini söylemedi ama bana bildirdiğiniz için teşekkürler! Kullanmak için güncellendi includes.
user81655

1
Test pasajı aSyntaxError: unexpected token 'for'
NoOneIsHere

Firefox kullanmıyorsanız alacağınız hata budur ...
user81655

1

Retina , 37 bayt

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

Geçerli bir alt dize bulunmazsa çıktı boştur A.

Çevrimiçi deneyin! (Aynı anda birkaç test vakasını çalıştırmak için biraz değiştirildi. Giriş formatı aslında satır besleme ile ayrılmış, ancak test paketleri her satırda bir test senaryosu ile yazmak için en kolay olanıdır. Test çerçevesi, alanı gerçek kod başlamadan önce bir satır beslemesine dönüştürür.)

açıklama

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

İçindeki her olası başlangıç ​​konumu için A, görünmeyen en kısa alt dizeyi eşleştirin B. Üst &üste binen eşleşmeler içindir, böylece bir eşleşme birden fazla karakter olsa bile her başlangıç ​​pozisyonunu deneriz. \GHerhangi pozisyonları atlamak yok olmasını sağlar - özellikle de bu şekilde biz ek eşleşmeleri alamadım öyle ki, satır besleme durağında zorunda Bkendisi. Bunun işleri karıştırmamasının nedeni oldukça incedir: çünkü Ageçerli bir alt dize bulamadığımız bir başlangıç ​​pozisyonu varsa, bu da \Gbaşka pozisyonları kontrol etmeyi durdurmaya neden olacak bir başarısızlıktır . Ancak, (geçerli başlangıç ​​konumundan itibaren) tüm alt dizelerB, geçerli konumun daha sağından başlayan tüm alt dizeler de geçerli olacaktır, bu nedenle bunları atmak bir sorun değildir (ve aslında performansı artırır).

M!Konfigürasyon nedeniyle , bu eşleşmelerin tümü sahneden, hat beslemeleriyle birlikte iade edilecektir.

O$#`.+
$.&

Bu, önceki sonucun çizgilerini uzunluğa göre sıralar. Bu, çizgi ile eşleştirilerek yapılır .+. Daha sonra $, $.&sıralama düzenini belirlemek için eşleşmenin yerini alacak şekilde bir "sıralama şekli" etkinleşir . $.&Kendisi uzunluğu ile maç değiştirir. Son olarak, #seçenek Retina'ya sayısal olarak sıralamasını söyler (aksi takdirde, elde edilen sayılara dize olarak davranır ve bunları sözlükbilimsel olarak sıralar).

G1`

Son olarak, boş regex (her zaman eşleşir) ve sınırı olan bir grep aşaması kullanarak sadece ilk satırı tutarız 1.


1

Perl, 87 85

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

Bu ilk (konuma göre) en kısa altdizgelerin döner anonim fonksiyonudur $_[0]meydana gelmez $_[1]ya da undefböyle bir alt dize varsa.

Dizeler @ iAmMortos'un cevabından alınmış, Perl 5.22.1 ile test edilmiş test programı:

#!/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 bayt

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

Kullanım örneği: "abcd" # "dabc"-> "cd".

Basit bir uygulama: Görünmeyenlerin tüm alt dizelerini oluşturun ave saklayın b. argminBurada 2 argüman, verilen işlevi en aza indiren bir listenin öğe döndürür: length.


Bilmiyordum argmin! Son derece yararlı görünüyor.
Zgarb

0

Pyth - 9 6 bayt

h-Fm.:

Burada çevrimiçi deneyin .


9 çarpı hala 9
kedi

Bunun nasıl çalıştığını bilmek isterim.
mroman

@mroman.: bir arg ile tüm altstrelerdir. Bu yüzden her iki dizginin üzerine de eşleştiriyorum, sonra da farklı şekilde katlayın, bu yüzden ikincisinin arnt'ının ilk altstreleri var, o zaman ilkini seçiyorum, ki en küçük cuz.: Sıralanmış.
Maltysen

0

C #, 152 bayt

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

Yakut, 70 bayt

İlk dizeden belirli bir uzunluktaki tüm alt dizeleri toplar ve ikinci dizede olmayan bir alt dizeyi döndürür.

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

0

Burlesque - 26 bayt

Şu anda karşılaşabileceğim en kısa yol:

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

0

Japt , 14 bayt

Êõ!ãU c k!èV g

Çevrimiçi deneyin!

Geçerli bir alt dizeundefined yoksa döndürür . Bu fark "undefined" dizesini döndürmekten farklıdır, ancak fark sadece -Q bayrağı nedeniyle görülebilir.

Açıklama:

Ê                 :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 bayt

à f@øX «VøX

Dene

                :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
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.