สตริงย่อยที่ไม่ซ้ำกันสั้นที่สุด


14

รับ (บน STDIN เป็นอาร์กิวเมนต์บรรทัดคำสั่งหรือเป็นอาร์กิวเมนต์ฟังก์ชัน) สองสตริงที่ไม่ว่างที่แตกต่างกันค้นหาและส่งกลับสตริงย่อยสั้นที่สุดของสตริงแรกซึ่งไม่ได้เป็นสตริงย่อยของที่สอง หากไม่มีซับสตริงดังกล่าวอยู่คุณสามารถส่งคืนสตริงว่างส่งคืนสตริงใด ๆ ที่ไม่ใช่สตริงย่อยของสตริงต้นฉบับหรือส่งข้อยกเว้น หากคุณกลับมาจากฟังก์ชั่นคุณอาจคืนค่าเป็นโมฆะ (หรือไม่ได้กำหนดไม่มี ฯลฯ ) ในกรณีนี้ หากมีการเชื่อมโยงสตริงย่อยหลายรายการในระยะเวลาอันสั้นคุณสามารถส่งคืนค่าใดก็ได้

สตริงสามารถประกอบด้วยอักขระ ASCII ที่พิมพ์ได้

อินพุตที่กำหนดบน STDIN จะถูกกำหนดด้วยหนึ่งสตริงในแต่ละบรรทัด ตามคำขอของคุณอาจเพิ่มบรรทัดว่างหนึ่งบรรทัดที่ส่วนท้ายของอินพุต

นี่คือรหัสกอล์ฟดังนั้นโปรแกรมที่ถูกต้องที่สุดจะเป็นผู้ชนะ

บางกรณีทดสอบ

INPUT:

STRING ONE
STRING TWO

เอาท์พุท:

E

INPUT:

A&&C
A&$C

ผลลัพธ์ที่ถูกต้อง:

&&
&C

INPUT:

(สตริง 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
สั้นหรือยาวที่สุด?
Leun Nun

@FryAmTheEggman แล้วควรฉันยังคงโพสต์วิธีการแก้ปัญหาของฉัน ...
รั่วนูน

"หนึ่งสตริงในแต่ละบรรทัด" โดยมีหรือไม่มีเครื่องหมายคำพูด?
Leun Nun

1
เราสามารถจัดเรียงสตริงได้หรือไม่?
เดนนิส

"B" คือสตริงย่อยของ "aBc"
downrep_nation

คำตอบ:


4

Brachylogขนาด 23 ไบต์

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

ทำงานกับ transpiler Java เก่า คาดหวังว่าทั้งสองสายในรายการเป็นอินพุตรวมเอาท์พุทรวมกับสตริงย่อย หากไม่พบสตริงย่อยจะส่งคืนค่าเท็จ

น่าเสียดายที่ฉันยังไม่ได้เข้ารหัสชุดย่อยในตัวใน Prolog transpiler ใหม่

คำอธิบาย

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

กรณีทดสอบ:

| 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 ไบต์ก่อนที่จะมีการแก้ไข


ฉันไม่รู้จักงูหลามมากนัก แต่บางทีคุณสามารถ(r=range)(1,len(a)+1)ใช้งานได้rไหม
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴทำแบบนั้นไม่ได้ ถ้าฉันกำหนดrangeให้rในบรรทัดด้านบนมันเพิ่มไบต์จริง ความคิดที่ดีแม้ว่า อาจมีวิธีที่สั้นกว่าในการวนซ้ำผ่านสตริงย่อย
Taylor Lopez

range(1,len(a))และrange(len(a)-1)ควรจะใช้งานได้หรือไม่ นอกจากนี้ฉันคิดว่าการใช้อักขระแท็บสำหรับการเยื้องสองช่องว่างจะช่วยประหยัดไบต์
user81655

ไม่ด้วยrange(1,len(a))การทดสอบการโยนครั้งที่ 4 ล้มเหลวเพราะจะไม่ลองใช้สายเต็ม มันจะไปตามความยาวของสตริง - 1 และมีrange(len(a)-1)กรณีการทดสอบที่ 1 ล้มเหลวกลับมาแทนเพียง'cd' 'd'แม้ว่าอาจมีบางสิ่งบางอย่างที่นั่น
Taylor Lopez

ขออภัยฉันไม่คุ้นเคยกับงูหลามและฉันคิดว่าช่วงนั้นรวมอยู่ด้วย ในกรณีที่ลองและrange(1,len(a)+1) range(len(a))
user81655

3

Python, 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
Taylor Lopez

ฉันคิดว่าคุณสามารถทำให้สั้นลงโดยการจัดหาอาร์กิวเมนต์ที่สองไม่จำเป็นที่จะenumerateที่จะเริ่มต้นที่j i+1
user2357112 รองรับ Monica

@ user2357112 ที่ส่งNameErrorน่าเสียดาย รหัสกำหนดก่อนแล้วj i
เดนนิส

@Dennis: ใช่ แต่มันไม่จำเป็นต้อง คุณสามารถสลับลำดับการวนซ้ำ
user2357112 รองรับ Monica

1
@ user2357112 ถ้าฉันสลับลำดับลูปสตริงย่อยที่ไม่ซ้ำกันครั้งแรกที่พบอาจไม่สั้นที่สุด เพียงแค่การแลกเปลี่ยนผลตอบแทนการสั่งซื้อสำหรับการป้อนข้อมูล'ab' 'abc','aaa'
เดนนิส

2

Python ขนาด 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 ที่พิมพ์ได้เช่น \ หรือ metacharacters RegExp อื่น ๆ แต่ถ้าคุณ จำกัด ตัวเองไว้ที่ Firefox ทำไมไม่ใช้b.includesแทน
Neil

@ Neil คำถามไม่ได้บอกว่าสายอาจเป็นตัวละครใด ๆ มาก่อน แต่ขอบคุณที่แจ้งให้ฉันทราบ! includesการปรับปรุงเพื่อให้การใช้งาน
user81655

1
ตัวอย่างทดสอบพ่นSyntaxError: unexpected token 'for'
NoOneIsHere

@NoOneIsHere นี่เป็นข้อผิดพลาดที่คุณจะได้รับหากคุณไม่ได้ใช้ Firefox ...
user81655

1

เรติน่า 37 ไบต์

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

Aผลผลิตเป็นที่ว่างเปล่าถ้าไม่มีย่อยที่ถูกพบใน

ลองออนไลน์! (แก้ไขเล็กน้อยเพื่อเรียกใช้กรณีทดสอบหลายกรณีพร้อมกันรูปแบบอินพุตแยกจากกันแล้ว แต่ชุดทดสอบนั้นง่ายที่สุดในการเขียนด้วยหนึ่งกรณีทดสอบต่อบรรทัดกรอบการทดสอบเปลี่ยนพื้นที่เป็น linefeed ก่อนเริ่มรหัสจริง)

คำอธิบาย

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

สำหรับแต่ละตำแหน่งเริ่มต้นเป็นไปได้ในตรงกับสตริงย่อยที่สั้นที่สุดซึ่งไม่ปรากฏในA Bนี่&คือการจับคู่ที่ทับซ้อนกันดังนั้นเราจึงลองทุกตำแหน่งเริ่มต้นแม้ว่าการแข่งขันจะมีความยาวมากกว่าหนึ่งตัว ความ\Gมั่นใจว่าเราจะไม่ข้ามตำแหน่งใด ๆ - โดยเฉพาะอย่างยิ่งวิธีนี้เราต้องหยุดที่ linefeed เช่นที่เราไม่ได้รับการจับคู่เพิ่มเติมจากดังนั้นจึงจะสารตั้งต้นทั้งหมดที่เริ่มต้นถูกต้องจากตำแหน่งปัจจุบันดังนั้นทิ้ง สิ่งเหล่านี้ไม่ใช่ปัญหา (และปรับปรุงประสิทธิภาพการทำงานจริง)Bตัวเอง เหตุผลที่สิ่งนี้ไม่ได้เกิดขึ้นจริง ๆ แล้วค่อนข้างบอบบาง: เพราะหากมีตำแหน่งเริ่มต้นAที่เราไม่สามารถหาซับสตริงที่ถูกต้องได้นั่นก็เป็นความล้มเหลวที่จะ\Gหยุดตรวจสอบตำแหน่งอื่น ๆ เพิ่มเติม อย่างไรก็ตามหาก (จากตำแหน่งเริ่มต้นปัจจุบัน) สตริงย่อยทั้งหมดจะปรากฏขึ้นB

เนื่องจากการM!กำหนดค่าการแข่งขันเหล่านี้ทั้งหมดจะถูกส่งคืนจากสเตจเข้าร่วมกับ linefeeds

O$#`.+
$.&

นี่เป็นการเรียงลำดับบรรทัดของผลลัพธ์ก่อนหน้าตามความยาว .+นี้จะกระทำโดยการจับคู่บรรทัดด้วย จากนั้น$เปิดใช้งานรูปแบบ "เรียงลำดับตาม" เพื่อให้การจับคู่ถูกแทนที่ด้วย$.&สำหรับการกำหนดลำดับการจัดเรียง $.&ตัวเองแทนการแข่งขันด้วยความยาวของมัน ในที่สุด#ตัวเลือกบอก Retina เพื่อเรียงลำดับตัวเลข (มิฉะนั้นจะถือว่าตัวเลขผลเป็นสตริงและเรียงตามพจนานุกรม)

G1`

สุดท้ายเราก็ให้บรรทัดแรกเท่านั้นโดยใช้เวที grep กับ regex ว่างเปล่า (ซึ่งมักจะตรงกับ) และขีด จำกัด 1ของการ


1

เพิร์ล 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ซับซ้อน: สร้าง substrings ทั้งหมดและเก็บสิ่งที่ไม่ปรากฏ argminส่งกลับองค์ประกอบของรายการที่ลดฟังก์ชั่นที่ได้รับข้อโต้แย้งที่ 2 ที่นี่: length.


ฉันไม่รู้เกี่ยวกับargmin! ดูเหมือนว่ามีประโยชน์มาก
Zgarb

0

Pyth - 9 6 ไบต์

h-Fm.:

ลองมันออนไลน์ได้ที่นี่


ตัดออก 9 ยังคงเป็น 9
แมว

ฉันชอบที่จะรู้ว่ามันทำงานอย่างไร
mroman

@mroman.: หนึ่ง arg เป็น substrs ทั้งหมด ดังนั้นฉันแมปที่เหนือทั้งสองสตริงจากนั้นพับ setwise diff ดังนั้นฉันจึงมี substrs ทั้งหมดที่ไม่ได้เป็นอันดับที่สองจากนั้นฉันเลือกอันแรกซึ่ง cuz ที่เล็กที่สุด: ถูกเรียงลำดับ
Maltysen


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

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.