Chuỗi tạo ngắn nhất, từ vựng nhỏ nhất


16

Một chuỗi x tạo ra một chuỗi ynếu ylà một chuỗi con lặp lại vô hạn x. Ví dụ abctạo ra bcabcab.

Viết chương trình tìm chuỗi ngắn nhất, từ vựng nhỏ nhất sẽ tạo đầu vào. Bạn được cung cấp trên đầu vào tiêu chuẩn một dòng văn bản. Bạn nên in chuỗi tạo ra đầu ra tiêu chuẩn. Ví dụ:

đầu vào

bcabcabca

đầu ra

abc

Mã ngắn nhất sẽ thắng. Bạn có thể giả sử đầu vào chỉ chứa các ký tự az (và một dòng mới theo sau nếu bạn muốn).


Đầu ra nên theo thứ tự nào? Nói đầu ra có thể bactrong ví dụ của bạn chứ không phải abc?
Ant's

@GroovyUser: không, đầu vào không phải là chuỗi con của mẫu lặp lại của bacs.
Keith Randall

Nhưng đầu vào có thể bao gồm một chuỗi con (bca)^n, có nghĩa bcalà hợp lệ đối với ví dụ đã cho là abc.
JAB

1
@JAB: bcakhông phải là từ vựng nhỏ nhất.
Keith Randall

Ah, bằng cách nào đó tôi đã bỏ lỡ phần đó.
JAB

Câu trả lời:


9

Ruby 1.9, 40 ký tự

gets;a=?a;a.next!until(a*~/$/)[$_];$><<a

Giả sử đầu vào không bị chấm dứt bởi một dòng mới. Ngoài ra, nó có thể chậm một cách lố bịch cho kết quả lớn hơn.

$ echo -n "bcabcabca" | ruby genlex.rb 
abc
$ echo -n "barfoobarfoobarfoo" | ruby1.9 genlex.rb 
arfoob

2

Python 88 185 ký tự

import re
s=raw_input()
m=s.index(min(s))
s=s[m:]+s[:m]
i=0
while s.replace(s[:i],''):i+=1
m=min(s[:i])
s=re.findall('%s[\w]*?(?=%s|$)'%(m,m),s[:i])
m=s.index(min(s))
print ''.join(s[m:]+s[:m])

Đầu ra:

bcabcabca
abc

aaa
a

abc
abc

cccbbcccbbcccbb
bbccc

barfoofoobarfoofoo
arfoofoob

bacabac
abacbac

Không cung cấp cho bạn chuỗi nhỏ nhất về mặt từ vựng cho một số đầu vào, ví dụ: "bacabac"
Howard

@Howard Bạn nói đúng. Tôi đã cập nhật mã của mình, nó dài hơn nhiều, nhưng xử lý các chuỗi như bacabacchính xác.
Vader

"abac" sẽ đúng, xem câu trả lời của @ Yogsototh: abac bacabac.
Howard

2

Haskell, 299 128 ký tự

import Data.List
main=interact(\z->minimum$filter(\w->isInfixOf z$concat$replicate(length z)w) $filter((/=)"")$inits=<<tails z)

Cảm ơn jloy! Bây giờ phiên bản ngắn hơn nhiều và tôi tin là chính xác.


1
Vì vậy, tin tốt là có thể đánh golf giải pháp này xuống còn khoảng 91 ký tự nếu bạn chấp nhận đầu vào trên stdin như trong giải pháp Ruby của Venter. Thật không may, đầu vào cabcabcabctạo ra abcabc, vì vậy giải pháp này không hoàn toàn ở đó. Tôi nghĩ bạn sẽ cần phải sửa đổi q++q++qđể có được kết quả mong muốn. Mặc dù vậy, nỗ lực nhanh chóng của tôi trong việc sửa chữa những thứ bị va đập lên tới 145 ký tự. ( Kẻ phá hoại đang ở đây: gist.github.com/1035161 )

Cảm ơn! Tôi đã không biết về tương tác cũng như không bao giờ về các đầu vào << = đuôi để có được tất cả các chuỗi con. Tôi hơi sửa đổi phiên bản của bạn để có được một chút ký tự. Tôi đã loại bỏ sắp xếp và thay đổi bộ lọc (not.null) bằng bộ lọc ((/ =) ""). Cảm ơn một lần nữa!
Yogsototh

Tại sao bạn cần (/=)""điều kiện? Nó dường như không làm gì cả. Ngoài ra, việc loại bỏ lambdas giúp: bạn có thể loại bỏ hoàn toàn w bằng cách sử dụng .toán tử và thay đổi chức năng chính main=interact sđể lưu một vài ký tự.
Rotsor

Tôi nghĩ rằng câu trả lời cho "bca" là sai. Nó phải là "abc", nhưng bây giờ là "bca".
Rotsor

Một giải pháp có thể là sử dụng permutationsthay vì tails.
Rotsor

2

Python, 121 137 129 ký tự

s=raw_input()
n=len(s)
l=[(s+s)[i/n:i/n+i%n+1]for i in range(n*n)]
print min(filter(lambda x:(x*len(s)).find(s)+1,sorted(l)),key=len)

EDIT: đã sửa lỗi phát hiện bởi JiminP


Wow thật tuyệt vời! Thật không may, nó in aababcho chuỗi ababa... :(
JiminP

Ok, đã sửa ... nó sẽ dài hơn :(
Jules Olléon

2

Hồng ngọc 1.9, 36

$><<(?a..gets).find{|s|(s*~/$/)[$_]}

Sử dụng phương pháp tương tự như giải pháp của Ventero.


2

Con trăn 161 159 166 140 141 134 132 ký tự

y=raw_input();i=n=l=len(y)
while i:
 if (y[:i]*l)[:l]==y:n=i
 i-=1
x=y[:n];y=x*2
while i<n:
 x=min(x,y[i:i+n])
 i+=1
print x

EDIT : Đánh gôn mã sau khi đọc bình luận của Jules Olléon. Đã xóa một 'lỗi' bcdabcdabdẫn đến abbc.

EDIT2 : Đã sửa lỗi ( abaakết quả aaa) được phát hiện bởi Jules Olléon.

Tôi không biết rõ về Python, vì vậy mã này có thể là 'không được đánh gôn'.

Tôi yêu quy tắc này:

Bạn có thể giả sử đầu vào chỉ chứa các ký tự az ...

Đầu vào và đầu ra

bcdabcd
abcd

bcabcabca
abc


abcdabcd
abcd

bcdabcdab
abcd

barfoofoobarfoofoobar
arfoofoob

cccbbcccbbcccbb
bbccc

aaaaaaaaaaaaaaaa
a

thequickbrownfox
brownfoxthequick

ababa
ab

abaa
aab

1
Cáo nâu, nhanh lên! Con chó, con lười!
JiminP

Giải pháp tốt đẹp, khá ngắn và có lẽ là phức tạp tốt nhất ở đây! Bạn có thể chơi golf một chút - ví dụ, bạn không cần "int" để so sánh các chuỗi; và thay thế "while i> 0" bằng "while i" và "y = y + y" bằng "y * = 2".
Jules Olléon

Trên thực tế có một vấn đề: vì abaa nó in aaa ...
Jules Olléon

@Jules Cảm ơn các bình luận! Tôi đã không nghĩ về điều đó ...
JiminP

Bạn có thể làm i-=1thay vì i=i-1. Tương tự như vậy cho sự gia tăng.
Lowjacker

1

Toán học 124 byte

x = StringLength@(y = "");
For[i = 1, ! (s = y~StringTake~i)~StringRepeat~x~StringContainsQ~y,i++];
First@Sort@StringPartition[s <> s, i, 1]

Khoảng trắng và dòng mới (với sự hiện diện của dấu chấm phẩy ở cuối dòng) không có ý nghĩa gì trong Mathicala và được đưa vào đây để dễ đọc.

Đầu vào đi vào giữa các dấu ngoặc kép trong dòng đầu tiên. Nếu recast là một hàm, có chuỗi đầu vào như vậy:

f=(x=StringLength@(y=#);For[i=1,!(s=y~StringTake~i)~StringRepeat~x~StringContainsQ~y,i++];First@Sort@StringPartition[s<>s,i,1])&

f@"bca"

(* "abc" *)

f@"abaa"

(* "aab" *)

sau đó là 128 byte.

Các Forvòng lặp sẽ là người đầu tiên inhân vật của đầu vào và lặp lại chúng ít nhất lên đến chiều dài của đầu vào, sau đó kiểm tra nếu đầu vào là một chuỗi của kết quả. Đã tìm thấy độ dài của chu kỳ của chuỗi, StringPartitionlệnh ghép hai bản sao của khoảng thời gian đó và lấy tất cả các chuỗi con có độ dài đó (về cơ bản nhận được tất cả các hoán vị theo chu kỳ), sau đó First@Sorttìm thấy một trong số chúng khi được sắp xếp theo từ vựng.


0

javascript 96 Chars.

var temp = {},len = str.length;
for(i in str) 
temp[str[i]] = true;
Object.keys(temp).join(""); 

Làm việc Plunkr


1
Chào mừng đến với cộng đồng! Mặc dù vậy, tôi không thể kiểm tra mã của mình, bạn có thể cung cấp đọc mã từ GET / POST và viết bằng cảnh báo hoặc console.log hoặc một hàm lấy đầu vào làm tham số và trả về đầu ra không?
Aaron

@AaronGOUZIT đã thêm pluckr
ngLover

Cảm ơn, điều đó giúp. Tuy nhiên, mã bạn đã đăng không thể được sử dụng một mình, do đó gian lận số byte. Quan trọng hơn, tôi e rằng mã của bạn không tôn trọng thông số kỹ thuật: Tôi tin rằng bạn trả lại một tập hợp các chữ cái duy nhất được sử dụng thay vì "chuỗi tạo", mà chúng ta sẽ có thể lặp lại (nói chung) với việc cắt bớt tùy chọn để có được đầu vào. Tôi đang mong đợi để xem mã cập nhật của bạn!
Aaron
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.