Golf văn bản vào DNA


26

Nhắn tin tới DNA golf

Thử thách

Chuyển đổi đầu vào thành đầu ra DNA.

Thuật toán

  • Chuyển đổi văn bản thành các điểm mã ASCII (ví dụ codegolf-> [99, 111, 100, 101, 103, 111, 108, 102])
  • Xâu chuỗi các mã ASCII lại với nhau (ví dụ 99111100101103111108102)
  • Chuyển đổi thành nhị phân (ví dụ 10100111111001101001011010001000011001101011011110000110010111111011000000110)
  • Đặt 0s vào cuối để tạo số ký tự chẵn (ví dụ 101001111110011010010110100010000110011010110111100001100101111110110000001100)
  • Thay thế 00bằng A, 01bằng C, 10với G11bằng T(ví dụ GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA)
  • Đầu ra

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

codegolf > GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA
ppcg > GGCTAATTGTCGCACTT
} > TTGG (padding)

Thông số kỹ thuật

  • Đây là
  • Chương trình của bạn phải chấp nhận không gian trong đầu vào.
  • Chương trình của bạn phải làm việc cho codegolf.

2
Tôi nghĩ bạn nên thêm một trường hợp thử nghiệm yêu cầu hành vi đệm. Sự lựa chọn lười biếng sẽ là }điều mà tôi tin sẽ trở thành TTGG.
FryAmTheEggman

3
Chúng ta cần hỗ trợ bao nhiêu đầu vào? 99111100101103111108102ví dụ: lớn hơn uint-64, vì vậy một số ngôn ngữ có thể phải vật lộn với các chuyển đổi lớn hơn.
admBorkBork

4
Đó không phải là cách bạn xâu chuỗi các mã ASCII lại với nhau nếu bạn muốn giải mã chúng một lần nữa.
dùng253751

@immibis Tôi biết.
NoOneIsĐây là

Câu trả lời:


17

Thạch , 15 13 byte

OVBs2UḄị“GCTA

Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm .

Làm thế nào nó hoạt động

OVBs2UḄị“GCTA    Main link. Argument: s (string)

O                Ordinal; replace each character with its code point.
 V               Eval. This converts the list to a string before evaluating, so it
                 returns the integer that results of concatenating all the digits.
  B              Binary; convert from integer to base 2.
   s2            Split into chunks of length 2.
     U           Upend; reverse the digits of each chunk.
                 Reversing means that we would have to conditionally PREPEND a zero
                 to the last chunk, which makes no difference for base conversion.
      Ḅ          Unbinary; convert each chunk from base 2 to integer.
                 `UḄ' maps:
                     [0, 1   ] -> [1,    0] -> 2
                     [1, 0(?)] -> [0(?), 1] -> 1
                     [1, 1   ] -> [1,    1] -> 3
                     [0, 0(?)] -> [0(?), 0] -> 0
       ị“GCTA    Replace each number by the character at that index.
                 Indexing is 1-based, so the indices are [1, 2, 3, 0].

9

CJam, 24 23 byte

Cảm ơn Dennis vì đã tiết kiệm 1 byte một cách thực sự thông minh. :)

l:isi2b2/Wf%2fb"AGCT"f=

Kiểm tra nó ở đây.

Giải trình

Thực hiện rất trực tiếp các đặc điểm kỹ thuật. Điểm thú vị duy nhất là phần đệm cho một số 0 chẵn (thực ra là ý tưởng của Dennis). Thay vì xử lý các chữ số trong mỗi cặp theo thứ tự thông thường, chúng tôi biến bit thứ hai thành số có nghĩa nhất. Điều đó có nghĩa là, kết thúc bằng một bit giống hệt như nối thêm số 0 vào nó, điều đó có nghĩa là chúng ta hoàn toàn không phải nối số 0.

l          e# Read input.
:i         e# Convert to character codes.
si         e# Convert to flat string and back to integer.
2b         e# Convert to binary.
2/         e# Split into pairs.
Wf%        e# Reverse each pair.
2fb        e# Convert each pair back from binary, to get a value in [0 1 2 3].
"AGCT"f=   e# Select corresponding letter for each number.

Tôi không biết gì về CJam, nhưng tại sao bạn cần đảo ngược từng cặp? Bạn có thể không chuyển đổi chúng trực tiếp trở lại từ nhị phân?
Mực giá trị

@ KevinLau-notKenny Đảo ngược mỗi cặp tránh các số 0 bổ sung để có được độ dài đồng đều. Trong các cặp đảo ngược, bạn phải trả trước các số 0, điều này không quan trọng đối với chuyển đổi cơ sở.
Dennis

Bí quyết đẹp! Có lẽ nó đã tiết kiệm được một tấn byte trên giải pháp của riêng tôi nếu tôi nghĩ về thủ thuật đó
Value Ink

6

Python 2, 109 103 byte

lambda s,j=''.join:j('ACGT'[int(j(t),2)]for t in
zip(*[iter(bin(int(j(`ord(c)`for c in s))*2)[2:])]*2))

Kiểm tra nó trên Ideone .


4

Ruby, 59 byte

$_='%b0'.%$_.bytes*''
gsub(/../){:ACGT[$&.hex%7]}
chomp'0'

Một chương trình đầy đủ. Chạy với -pcờ.


làm thế nào bạn thậm chí ... tôi không hiểu
Giá trị mực

4

Python 3, 130 byte.

Đã lưu 2 byte nhờ vaultah.
Đã lưu 6 byte nhờ Kevin Lau - không phải Kenny.

Tôi ghét việc chuyển đổi thành nhị phân trong python khó như thế nào.

def f(x):c=bin(int(''.join(map(str,map(ord,x)))))[2:];return''.join('ACGT'[int(z+y,2)]for z,y in zip(*[iter(c+'0'*(len(c)%2))]*2))

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

assert f('codegolf') == 'GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA'
assert f('ppcg') == 'GGCTAATTGTCGCACTT'

Có vẻ như bạn có thêm 1 cặp dấu ngoặc sau lần thứ hai''.join
vaultah

@vaultah Rất tiếc, yup, bạn nói đúng.
Morgan Thrapp

'ACGT'[int(z+y,2)]Thay vào đó, hãy sử dụng , chuyển đổi trực tiếp ra khỏi hệ nhị phân thay vì sử dụng chuỗi dài hơn của bạn và chuyển đổi từ cơ sở 10. Ngoài ra, không chắc chắn nó sẽ tạo ra bao nhiêu sự khác biệt nhưng hãy nhìn vào việc sử dụng re.subthay vì thủ thuật nối lộn xộn của bạn?
Mực giá trị

@ KevinLau-notKenny Oooo, cảm ơn. Tôi quên bạn có thể chỉ định một cơ sở với int. Tôi sẽ xem xét re.sub, cảm ơn vì lời đề nghị.
Morgan Thrapp

Cách tiếp cận tốt đẹp, tôi đã đưa ra (gần như) chính xác cùng một mã mà không cần nhìn vào mã của bạn. :)
Chỉ huy Byte

3

Ruby, 80 byte

->s{s=s.bytes.join.to_i.to_s 2;s+=?0*(s.size%2)
s.gsub(/../){"ACGT"[$&.to_i 2]}}

Nói một cách đơn giản, vấn đề là có thể thu được nhiều byte hơn trong số này :)
xsot

3

Toán học, 108 byte

{"A","C","G","T"}[[IntegerDigits[Mod[Floor@Log2@#,2,1]#&@FromDigits[""<>ToString/@ToCharacterCode@#],4]+1]]&

Lấy một chuỗi làm đầu vào và đưa ra một danh sách các cơ sở.


3

Python 3, 126 byte

lambda v:"".join(["ACGT"[int(x,2)]for x in map(''.join,zip(*[iter((bin(int("".join([str(ord(i))for i in v])))+"0")[2:])]*2))])

Chào mừng bạn đến với Câu đố lập trình & Code Golf! Trong trường hợp bạn đang tự hỏi về downvote, đây là những gì đã xảy ra .
Dennis

2

Bình thường, 25 byte

sm@"ACGT"id2Pc.B*4sjkCMQ2

Hãy thử nó ở đây!

Giải trình

Khai thác thủ thuật đệm từ câu trả lời của Martins CJam .

sm @ "ACGT" id2Pc.B * 4sjkCMQ2 # Q = đầu vào

                     CMQ # Ánh xạ từng ký tự của Q vào mã ký tự của nó
                  sjk # Tham gia thành một chuỗi và chuyển đổi thành một số nguyên
              .B * 4 # Mulitply với 4 và chuyển đổi thành nhị phân
             c 2 # Chia thành từng cặp
            P # Hủy cặp cuối cùng
 m # Bản đồ mỗi cặp d
         id2 # Chuyển đổi cặp từ nhị phân sang thập phân
  @ "ACGT" # Sử dụng kết quả ^ làm chỉ mục vào chuỗi tra cứu
s # Tham gia danh sách kết quả vào chuỗi


2

Java, 194 byte

String a(int[]a){String s="",r=s;for(int i:a)s+=i;s=new BigInteger(s).toString(2)+0;for(int i=0,y,n=48;i<(s.length()/2)*2;r+=s.charAt(i++)==n?y==n?'A':'G':y==n?'C':'T')y=s.charAt(i++);return r;}

Bị đánh cắp

String a(int[] a) {
    String s = "", r = s;
    for (int i : a) s += i;
    s = new BigInteger(s).toString(2) + 0;
    for (int i = 0, y, n = 48; i < (s.length() / 2) * 2; 
        r += s.charAt(i++) == n 
                 ? y == n 
                 ? 'A' 
                 : 'G' 
                 : y == n 
                 ? 'C' 
                 : 'T')
        y = s.charAt(i++);
    return r;
}

chú thích

  • Đầu vào là một mảng các ký tự (nên được tính là một dạng Chuỗi), tham số có kiểu int[]vì đó là một byte được lưu char[].

Đầu ra

Input:  codegolf
Output: GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA

Input:  .
Output: GTG

Input:  }
Output: TTGG

Input:  wow
Output: TGATAGTTGTGCTG

Input:  programming puzzles
Output: GTGTCAGAGTTGAAGGCCGTTCCGCAGTGCATTTGGCTCGTCTGGTGTCTACTAGCCTGCGAGAGGAGTTACTTTGGATCCTTGACTTGT

2

MATL , 21 byte

'CGTA'joV4Y2HZa2e!XB)

Hãy thử trực tuyến!

Giải trình

'CGTA'   % Push string to be indexed into
j        % Take input string
o        % Convert each char to its ASCII code
V        % Convert to string (*). Numbers are separated by spaces
4Y2      % Push the string '0123456789'
H        % Push number 2
Za       % Convert string (*) from base '0123456789' to base 2, ignoring spaces
2e       % Reshape into a 2-column matrix, padding with a trailing 0 if needed
!        % Transpose
XB       % Convert from binary to decimal
)        % Index into string with the DNA letters. Indexing is 1-based and modular


1

Groovy, 114 byte

{s->'ACGT'[(new BigInteger(((Byte[])s).join())*2).toString(2).toList().collate(2)*.with{0.parseInt(it.join(),2)}]}

Giải trình:

{s->
    'ACGT'[ //access character from string
        (new BigInteger( //create Big Integer from string
           ((Byte[])s).join() //split string to bytes and then join to string
        ) * 2) //multiply by 2 to add 0 at the end in binary
        .toString(2) //change to binary string
        .toList() //split to characters
        .collate(2) //group characters by two
        *.with{
            0.parseInt(it.join(),2) //join every group and parse to decimal
        }
     ]
}

Câu trả lời chính xác! Bạn có thể vui lòng thêm một lời giải thích xin vui lòng?
NoOneIsHãy là

Phiên bản đầu tiên không hoạt động, vì tôi quên nối thêm 0. Tôi đã sửa nó và đi xuống với byte btw.
Krzysztof Atłasik

1

Julia 0,4, 77 byte

s->replace(bin(BigInt(join(int(s)))),r"..?",t->"AGCT"[1+int("0b"reverse(t))])

Hàm ẩn danh này lấy một mảng ký tự làm đầu vào và trả về một chuỗi.

Hãy thử trực tuyến!


1

Python 2.7, 135 byte

def f(A):g=''.join;B=bin(int(g(map(str,map(ord,A)))))[2:];B+=len(B)%2*'0';return g('ACGT'[int(B[i:i+2],2)] for i in range(len(B))[::2])

Ung dung:

def f(A):
    g = ''.join
    B = bin(int(g(map(str,map(ord,A)))))[2:] # convert string input to binary
    B += len(B)%2 * '0' # add extra 0 if necessary
    return g('ACGT'[int(B[i:i+2],2)] for i in range(len(B))[::2]) # map every two characters into 'ACGT'

Đầu ra

f('codegolf')
'GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA'

@DrGreenEggsand HamDJ Tôi có g(...)chức năng trong đó hai lần, vì vậy tôi tin rằng việc thay thế nó bằng joinsẽ thêm 2 byte?
deustice

Ah, tôi đã bỏ lỡ điều đó. Lỗi của tôi!
DJMcMayhem

1

Javascript ES7, 105 103 byte

s=>((+[for(c of s)c.charCodeAt()].join``).toString(2)+'0').match(/../g).map(x=>"ACGT"['0b'+x-0]).join``

Phần ES7 là for(c of s) một phần.

Phiên bản ES6, 107 105 byte

s=>((+[...s].map(c=>c.charCodeAt()).join``).toString(2)+'0').match(/../g).map(x=>"ACGT"['0b'+x-0]).join``

Mã bị đánh cắp

dna = (str)=>{
  var codes = +[for(c of str)c.charCodeAt()].join``;
  var binaries = (codes.toString(2)+'0').match(/../g);
  return binaries.map(x=>"ACGT"['0b'+x-0]).join``
}

Đây là lần thử đầu tiên của tôi khi chơi golf trên PPCG, vui lòng sửa tôi nếu có gì sai.

Cảm ơn @AlexA vì sự cải thiện nhỏ.


1
Đây là một sân golf đầu tiên tốt đẹp! Vì hàm không đệ quy và chúng tôi không yêu cầu các hàm được đặt tên, vì vậy bạn sẽ có thể xóa f=, lưu 2 byte. :)
Alex A.

1

J, 52 byte

 3 :'''ACGT''{~#._2,\#:".,&''x''":(,&:(":"0))/3&u:y'

Cách sử dụng: 3 :'''ACGT''{~#._2,\#:".,&''x''":(,&:(":"0))/3&u:y' 'codegolf'==>GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA


1

Lisp thông thường (Lispworks), 415 byte

(defun f(s)(labels((p(e f)(concatenate'string e f)))(let((b"")(d""))(dotimes(i(length s))(setf b(p b(write-to-string(char-int(elt s i))))))(setf b(write-to-string(parse-integer b):base 2))(if(oddp #1=(length b))(setf b(p b"0")))(do((j 0(+ j 2)))((= j #1#)d)(let((c(subseq b j(+ j 2))))(cond((#2=string="00"c)(setf d(p d"A")))((#2#"01"c)(setf d(p d"C")))((#2#"10"c)(setf d(p d"G")))((#2#"11"c)(setf d(p d"T")))))))))

vô dụng:

(defun f (s)
  (labels ((p (e f)
             (concatenate 'string e f)))
  (let ((b "") (d ""))
    (dotimes (i (length s))
      (setf b
            (p b
               (write-to-string
                (char-int (elt s i))))))
    (setf b (write-to-string (parse-integer b) :base 2))
    (if (oddp #1=(length b))
        (setf b (p b "0")))
      (do ((j 0 (+ j 2)))
          ((= j #1#) d)
        (let ((c (subseq b j (+ j 2))))
          (cond ((#2=string=  "00" c)
                 (setf d (p d "A")))
                ((#2# "01" c)
                 (setf d (p d "C")))
                ((#2# "10" c)
                 (setf d (p d "G")))
                ((#2# "11" c)
                 (setf d (p d "T")))))))))

Sử dụng:

CL-USER 2060 > (f "}")
"TTGG"

CL-USER 2061 > (f "golf")
"TAAAAATTATCCATAAATA"

0

Perl, 155 148 137 + 1 ( -pcờ) = 138 byte

#!perl -p
s/./ord$&/sge;while($_){/.$/;$s=$&%2 .$s;$t=$v="";$t.=$v+$_/2|0,$v=$_%2*5
for/./g;s/^0// if$_=$t}$_=$s;s/(.)(.)?/([A,C],[G,T])[$1][$2]/ge

Kiểm tra nó trên Ideone .


0

Perl 6, 57 + 1 ( -pcờ) = 58 byte

$_=(+[~] .ords).base(2);s:g/..?/{<A G C T>[:2($/.flip)]}/

Từng bước giải thích:

-pcờ làm cho trình thông dịch Perl 6 chạy dòng mã theo dòng, đặt dòng hiện tại $_và cuối cùng đặt lại từ đó $_.

.ords- Nếu không có gì trước một khoảng thời gian, một phương thức được gọi $_. ordsphương thức trả về danh sách các điểm mã trong một chuỗi.

[~]- []là toán tử rút gọn, lưu trữ toán tử khử giữa các dấu ngoặc. Trong trường hợp này ~, đó là toán tử nối chuỗi. Ví dụ,[~] 1, 2, 3 tương đương với1 ~ 2 ~ 3 .

+ chuyển đổi đối số của nó thành một số, cần thiết bởi vì base phương thức chỉ được xác định cho các số nguyên.

.base(2) - chuyển đổi một số nguyên thành một chuỗi trong cơ sở 2

$_= - gán kết quả cho $_ .

s:g/..?/{...}/- đây là biểu thức chính quy thay thế bất kỳ ( :g, chế độ toàn cầu) nào của regex..? (một hoặc hai ký tự). Đối số thứ hai là một mẫu thay thế, trong trường hợp này là mã (trong Perl 6, dấu ngoặc nhọn trong chuỗi và các mẫu thay thế được thực thi dưới dạng mã).

$/ - một biến khớp regex

.flip- đảo ngược một chuỗi. Nó ngầm chuyển đổi $/(một đối tượng khớp regex) thành một chuỗi. Điều này là do một ký tự đơn 1nên được mở rộng thành 10, trái ngược với01 . Do sự lật đó, thứ tự các phần tử trong mảng có G và C đảo ngược.

:2(...) - phân tích một chuỗi cơ sở-2 thành một số nguyên.

<A G C T> - mảng bốn yếu tố.

...[...] - toán tử truy cập mảng.

Điều đó nghĩa là gì? Chương trình lấy danh sách tất cả các điểm mã trong một chuỗi, nối chúng lại với nhau, chuyển đổi chúng thành cơ sở 2. Sau đó, nó thay thế tất cả các trường hợp của hai hoặc một ký tự thành một trong các chữ cái A, G, C, T tùy thuộc vào cách biểu thị lật của một số trong nhị phân.


0

Hoon , 148 138 byte

|*
*
=+
(scan (reel +< |=({a/@ b/tape} (weld <a> b))) dem)
`tape`(flop (turn (rip 1 (mul - +((mod (met 0 -) 2)))) |=(@ (snag +< "ACGT"))))

"abc" là một danh sách các nguyên tử. Nội suy chúng thành các chuỗi ( <a>) trong khi gấp lại danh sách, nối chúng lại với nhau thành một chuỗi mới. Phân tích số với ++demđể đưa nó trở lại nguyên tử.

Nhân số với (chiều dài bit + 1)% 2 để đệm nó. Sử dụng ++ripđể tháo rời mỗi cặp hai byte của nguyên tử thành một danh sách, ánh xạ qua danh sách và sử dụng số này làm chỉ mục vào chuỗi "ACGT".

> =a |*
  *
  =+
  (scan (reel +< |=({a/@ b/tape} (weld <a> b))) dem)
  `tape`(flop (turn (rip 1 (mul - +((mod (met 0 -) 2)))) |=(@ (snag +< "ACGT"))))
> (a "codegolf")
"GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA"
> (a "ppcg")
"GGCTAATTGTCGCACTT"
> (a "}")
"TTGG"
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.