Chuỗi con DNA ngược dài nhất


11

Như bạn có thể biết, trong DNA có bốn bazơ - adenine ( A), cytosine ( C), guanine ( G) và thymine ( T). Thông thường Aliên kết với TCliên kết với G, tạo thành "nấc thang" của cấu trúc xoắn kép DNA .

Chúng tôi định nghĩa phần của một cơ sở là cơ sở mà nó liên kết với - tức là phần bù của AT, phần bù của TA, phần bù của CGvà phần bù của GC. Chúng ta cũng có thể định nghĩa phần bù của chuỗi DNA là chuỗi có mỗi cơ sở được bổ sung, ví dụ phần bù GATATCCTATAG.

Do cấu trúc sợi kép của DNA, các bazơ trên một sợi này bổ sung cho các bazơ trên chuỗi kia. Tuy nhiên DNA có một hướng và phiên mã DNA xảy ra theo hai hướng ngược nhau trên hai sợi. Do đó, các nhà sinh học phân tử thường quan tâm đến phần bù ngược của chuỗi DNA - hoàn toàn theo nghĩa đen của phần bổ sung của chuỗi.

Để mở rộng ví dụ trước của chúng tôi, bổ sung ngược GATATCCTATAGngược, vì vậy GATATC. Như bạn có thể nhận thấy, trong ví dụ này, phần bù ngược bằng với chuỗi gốc - chúng tôi gọi một chuỗi như vậy là một bảng màu ngược . *

Đưa ra một chuỗi DNA, bạn có thể tìm thấy chuỗi con dài nhất là một palindrom ngược không?

* Tôi sử dụng thuật ngữ "palindrom ngược", được lấy từ Rosalind , để phân biệt với ý nghĩa thông thường của palindrom.


Đầu vào

Đầu vào sẽ là một chuỗi duy nhất chỉ bao gồm các ký tự ACGTin hoa. Bạn có thể viết một chức năng hoặc một chương trình đầy đủ cho thử thách này.

Đầu ra

Bạn có thể chọn xuất thông qua in hoặc trả lại (lựa chọn sau chỉ khả dụng trong trường hợp chức năng).

Chương trình của bạn sẽ xuất ra chuỗi con palindromic ngược dài nhất của chuỗi đầu vào, nếu có một giải pháp duy nhất. Nếu có nhiều giải pháp tồn tại, thì bạn có thể xuất bất kỳ một trong số chúng, hoặc tất cả chúng (lựa chọn của bạn). Các bản sao đều ổn nếu bạn chọn xuất tất cả chúng.

Đầu vào được đảm bảo có giải pháp ít nhất là chiều dài 2.

Ví dụ làm việc

ATGGATCCG -> GGATCC

Phần bù ngược của GGATCCchính nó ( GGATCC --complement--> CCTAGG --reverse--> GGATCC), do đó GGATCClà một bảng màu ngược. GATCcũng là một palindome ngược, nhưng nó không phải là dài nhất.

Các trường hợp thử nghiệm

AT -> AT
CGT -> CG
AGCA -> GC
GATTACA -> AT, TA
ATGGATCCG -> GGATCC
CCCCCGGGGG -> CCCCCGGGGG
ACATATATAGACT -> ATATAT, TATATA
ATTCGATCTATGTAAAGAGG -> TCGA, GATC
CGCACGTCTACGTACCTACGTAG -> CTACGTAG
TCAATGCATGCGGGTCTATATGCAT -> ATGCAT, GCATGC [, ATGCAT]
CGCTGAACTTTGCCCGTTGGTAGAACGGACTGATGTGAACGAGTGACCCG -> CG, GC, TA, AT [, GC, CG, CG, CG, CG]
CTCGCGTTTGCATAACCGTACGGGCGGAACAGTCGGCGGTGCCTCCCAGG -> CCGTACGG

Chấm điểm

Đây là mã golf, vì vậy giải pháp trong ít byte nhất sẽ thắng.


Nó sẽ đẹp hơn nếu in tất cả chúng có một số phần thưởng.
Tối ưu hóa

@Optimizer không in được khó khăn lâu nhất so với in tất cả chúng?
trichoplax

Hay bạn có nghĩa là in tất cả những cái dài nhất?
trichoplax

@githubphagocyte vâng, bình luận thứ hai của bạn.
Tối ưu hóa

Câu trả lời:


6

Pyth, 37 36 28 24 byte

ef&}TzqmaCd6T_mx4aCk6Tyz

Kết hợp các mẹo từ FryAmTheEggman và thủ thuật kiểm tra bảng màu ngược từ Peter, đây là một phiên bản siêu ngắn.

Tuy nhiên, điều này chỉ hoạt động với Pyth 3.0.1 mà bạn có thể tải xuống từ liên kết này và chạy như

python3 pyth.py -c "ef&}TzqmaCd6T_mx4aCk6Tyz" <<< "ATTCGATCTATGTAAAGAGG"

(chỉ bash linux. Trên windows, nhấn Enter thay vì <<< và sau đó nhập dữ liệu)


Đây là lần gửi trước của tôi - giải pháp 28 byte

J"ACGT"ef&}TzqTjk_m@_JxJdTyz

Cảm ơn FryAmTheEggman cho phiên bản này. Cái này tạo ra tất cả các tập hợp con có thể có của chuỗi DNA đầu vào, lọc các tập hợp con với điều kiện tập hợp con là một chuỗi con của đầu vào và đảo ngược của phép biến đổi bằng chính tập hợp con đó.

Do tất cả các tạo tập hợp con có thể, điều này chiếm nhiều bộ nhớ hơn câu trả lời của Peter.


Đây là lần gửi đầu tiên của tôi - giải pháp 36 byte.

J"ACGT"eolNfqTjk_m@_JxJdTm:zhkek^Uz2

Đây là bản dịch chính xác của câu trả lời của tôi . Tôi đã hy vọng rằng nó sẽ nhỏ hơn nhiều nhưng hóa ra việc thiếu phương thức dịch khiến nó có kích thước gần như tương tự (mặc dù vẫn nhỏ hơn 2 byte)

Dùng thử trực tuyến tại đây


Uztương đương với Ulz.
isaacg

1
J"ACGT"eolNf&}TzqTjk_m@_JxJdTyzSử dụng ycho các tập hợp con và sau đó lọc ra các chuỗi không có chuỗi con zngắn hơn :)
FryAmTheEggman

1
Ồ, và nếu bạn làm điều đó, bạn không cần phải sắp xếp vì yđã được sắp xếp theo chiều dài. Bạn chỉ có thể làmef...
FryAmTheEggman

5

GolfScript ( 35 34 byte)

]{{..(;\);}%)}do{{6&}%.{4^}%-1%=}?

Đối với mục đích thử nghiệm, bạn có thể muốn sử dụng

]{{..(;\);}%.&)}do{{6&}%.{4^}%-1%=}?

trong đó thêm một .&để giảm các nỗ lực trùng lặp.

Mổ xẻ

]{         # Gather string into an array and do-while...
  {        #   Map over each string in the array
    ..     #     Make a couple of copies of the string
    (;     #     Remove the first character from one of them
    \);    #     Remove the last character from the other
  }%
  )        #   Extract the last string from the array
}do        # Loop until that last string is ''
           # Because of the duplication we now have an array containing every substring
           # of the original string, and if we filter to the first occurrence of each
           # string then they're in descending order of length
{          # Find the first element in the string satisfying the condition...
  {6&}%    #   Map each character in the string to its bitwise & with 6
  .{4^}%   #   Duplicate, and map each to its bitwise ^ with 4
           #   This serves to test for A <-> T, C <-> G
  -1%=     #   Reverse and test for equality
}?

q{]{__(;\);}%~}h]{:c:i6f&_4f^W%=}=ở CJam. Cùng cỡ. Không thử nó trong trình biên dịch trực tuyến cho bất cứ thứ gì lớn hơn 7 chiều dài đầu vào
Trình tối ưu hóa

4

CJam, 39 38 byte

Tôi chắc chắn rằng điều này có thể được đánh gôn hơn nữa ...

q:Q,,_m*{~Q<>}%{,~}${_"ACGT"_W%erW%=}=

Lấy chuỗi DNA từ STDIN và đưa ra DNA ngược dòng dài nhất thành STDOUT

Dùng thử trực tuyến tại đây

(Giải thích sớm) (Đã lưu 1 byte nhờ Peter)


4

Python 3, 125 ký tự

S=input()
l=[]
while S:
 s=_,*S=S
 while s:l+=[s]*all(x+y in"ATA CGC"for x,y in zip(s,s[::-1]));*s,_=s
print(*max(l,key=len))

Nhìn ma, không có chỉ mục! (Chà, ngoại trừ việc đảo ngược chuỗi, điều đó không được tính.)

Lặp lại các chuỗi con được thực hiện bằng cách tắt các ký tự từ phía trước và cuối bằng cách sử dụng gán sao . Vòng lặp bên ngoài sẽ loại bỏ các ký tự khi bắt đầu Svà đối với mỗi hậu tố như vậy, scác vòng lặp trên tất cả các tiền tố của nó, kiểm tra từng ký tự một.

Việc kiểm tra đối với palindrom ngược được thực hiện bằng mã

all(x+y in"ATA CGC"for x,y in zip(s,s[::-1]))

trong đó kiểm tra xem mỗi ký hiệu và đối tác chuỗi đảo ngược của nó là một trong các "AT", "TA", "CG" và "GC". Tôi cũng tìm thấy một giải pháp dựa trên tập hợp ngắn hơn một ký tự, nhưng mất hai ký tự khi yêu cầu các dấu ngoặc ngoài khi sử dụng.

set(zip(s,s[::-1]))<=set(zip("ACTG","TGAC"))

Điều này vẫn cảm thấy như nó có thể được rút ngắn.

Cuối cùng, bảng màu dài nhất được in.

print(*max(l,key=len))

Tôi hy vọng đầu ra phân tách không gian là OK. Nếu một danh sách cũng tốt, ngôi sao có thể được gỡ bỏ. Thay vào đó, tôi đã cố gắng theo dõi max chạy trong vòng lặp, cũng như nhồi nhét các vòng lặp bên trong vào một sự hiểu biết danh sách để tôi có thể lấy max tối đa mà không cần xây dựng l, và cả hai đều bật ra lâu hơn một chút. Nhưng, nó đủ gần để khó có thể nói phương pháp nào thực sự tốt nhất.


Tôi muốn linh hoạt hơn với câu hỏi này vì vậy tôi đã không chỉ định một định dạng đầu ra chính xác cho các giải pháp gắn liền. Nếu nó rõ ràng các giải pháp là gì thì nó vẫn ổn, vì vậy một danh sách là ổn.
Sp3000

3

J (45)

{.@(\:#&.>)@,@(('ACGT'&(|.@]-:[{~3-i.)#<)\\.)

Đây là một hàm có một chuỗi:

   {.@(\:#&.>)@,@(('ACGT'&(|.@]-:[{~3-i.)#<)\\.) 'ATGGATCCG'
┌──────┐
│GGATCC│
└──────┘

Giải trình:

{.@(\:#&.>)@,@(('ACGT'&(|.@]-:[{~3-i.)#<)\\.) 

              (                          \\.)  for each prefix of each suffix
               (                      #<)      include the argument if,
                        |.@]                      its reverse
                            -:                    is equal to
                'ACGT'&(      [{~3-i.)            the complement
            ,@                                 ravel
   (\:#&.>)@                                   sort by length of item
{.@                                            take the first one   

3

Perl - 59 byte

#!perl -p
$_=$_[~!map$_[length]=$_,/((.)(?R)?(??{'$Q5'^$+.-$+}))/gi]

Đếm shebang là một, đầu vào được lấy từ STDIN.

Sử dụng mẫu:

$ echo CTCGCGTTTGCATAACCGTACGGGCGGAACAGTCGGCGGTGCCTCCCAGG | perl dna.pl
CCGTACGG

3

Python 2 - 177 byte

s=raw_input()
r,l,o=range,len(s),[]
for a in[s[i:j+1]for i in r(l)for j in r(i,l)]:q=['TC GA'.index(c)-2for c in a];o+=[a if[-n for n in q][::-1]==q else'']
print max(o,key=len)

Lực lượng vũ phu đơn giản. Kiểm tra "palindromic ngược" thực tế là phần thú vị duy nhất. Ở đây nó được viết dễ đọc hơn:

check = ['TC GA'.index(c)-2 for c in substring]
if [-n for n in check][::-1] == check:
    # substring is reverse palindromic

Tôi làm điều đó trên mọi chuỗi con có thể và đưa chúng vào danh sách nếu nó đúng. Nếu nó sai, tôi thay vào đó là một chuỗi trống. Khi tất cả các kiểm tra được thực hiện, tôi xuất phần tử dài nhất của danh sách. Tôi đã sử dụng một chuỗi rỗng vì nó tiết kiệm byte hơn là không đưa gì vào, nhưng điều đó cũng có nghĩa là chương trình sẽ không bị sặc nếu không có giải pháp. Nó xuất ra một dòng trống và thoát ra một cách duyên dáng.


1
Điều này dường như ngắn hơn nếu bạn đưa mọi thứ vào một danh sách không hiểu. Tôi đã phải thay đổi logic một chút, nhưng tôi đã có 162 với s=raw_input();r,l,g=range,len(s),'TGCA';print max([a for a in[s[i:j+1]for i in r(l)for j in r(i,l)]if[g[n]for n in[~g.find(c)for c in a]]==list(a)[::-1]],key=len). Ngoài ra, đối với các chuỗi, sử dụng findhơn index:)
FryAmTheEggman
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.