แปลงข้อความกอล์ฟเป็น DNA


26

ข้อความถึง DNA golf

ท้าทาย

แปลงอินพุตเป็นเอาต์พุตดีเอ็นเอ

ขั้นตอนวิธี

  • แปลงข้อความเป็นจุดโค้ด ASCII (เช่นcodegolf-> [99, 111, 100, 101, 103, 111, 108, 102])
  • สตริงรหัส ASCII ด้วยกัน (เช่น99111100101103111108102)
  • แปลงเป็นไบนารี่ (เช่น10100111111001101001011010001000011001101011011110000110010111111011000000110)
  • Pad 0s ลงบนปลายเพื่อให้เป็นเลขคู่ของตัวละคร (เช่น101001111110011010010110100010000110011010110111100001100101111110110000001100)
  • แทนที่00ด้วยA, 01ด้วยC, 10ด้วยG, และ11ด้วยT(เช่นGGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA)
  • เอาท์พุต

กรณีทดสอบ

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

ข้อมูลจำเพาะ

  • นี่คือ
  • โปรแกรมของคุณต้องยอมรับช่องว่างในอินพุต
  • โปรแกรมของคุณจะต้องใช้งานcodegolfได้

2
ฉันคิดว่าคุณควรเพิ่มกรณีทดสอบที่ต้องมีพฤติกรรมการแพ็ดดิ้ง ทางเลือกที่จะขี้เกียจซึ่งผมเชื่อว่าจะกลายเป็น} TTGG
FryAmTheEggman

3
เราจำเป็นต้องสนับสนุนอินพุตขนาดใหญ่เท่าใด 99111100101103111108102ตัวอย่างมีขนาดใหญ่กว่า uint-64 ดังนั้นบางภาษาอาจมีปัญหากับการแปลงที่ใหญ่กว่า
AdmBorkBork

4
นั่นไม่ใช่วิธีการที่คุณใส่รหัส ASCII เข้าด้วยกันหากคุณต้องการที่จะสามารถถอดรหัสได้อีกครั้ง
user253751

@ กลไกฉันรู้
NoOneIsHere

คำตอบ:


17

เยลลี่ , 15 13 ไบต์

OVBs2UḄị“GCTA

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทุก

มันทำงานอย่างไร

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 ไบต์

ขอบคุณเดนนิสที่ช่วยประหยัด 1 ไบต์อย่างชาญฉลาด :)

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

ทดสอบที่นี่

คำอธิบาย

การนำข้อกำหนดไปใช้โดยตรง สิ่งที่น่าสนใจเพียงอย่างเดียวคือ padding ไปที่เลขศูนย์คู่ (ซึ่งเป็นความคิดของเดนนิส) แทนการรักษาตัวเลขในแต่ละคู่ตามลำดับปกติเราทำให้บิตที่สองที่สำคัญที่สุด นั่นหมายความว่าการสิ้นสุดในบิตเดียวจะเหมือนกับการต่อท้ายศูนย์ซึ่งหมายความว่าเราไม่ต้องผนวกศูนย์เลย

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.

ฉันไม่รู้เกี่ยวกับ CJam แต่ทำไมคุณต้องย้อนกลับแต่ละคู่ คุณไม่สามารถแปลงมันกลับจากไบนารี่ได้โดยตรงหรือไม่?
หมึกมูลค่า

@ KevinLau-notKenny การย้อนกลับแต่ละคู่หลีกเลี่ยงการผนวกเลขศูนย์เพื่อให้ได้ความยาวเท่ากัน ในคู่กลับคุณจะต้องย่อหน้า zeroes ซึ่งไม่สำคัญสำหรับการแปลงฐาน
เดนนิส

เคล็ดลับดี! อาจเป็นไปได้ที่จะประหยัดได้มากถึงหนึ่งไบต์ในวิธีการแก้ปัญหาของฉันเองถ้าฉันได้คิดถึงเคล็ดลับนั้น
Value Ink


4

Ruby, 59 ไบต์

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

โปรแกรมเต็มรูปแบบ วิ่งด้วย-pธง


คุณเป็นยังไง ... ฉันไม่เข้าใจ
Value Ink

4

Python 3, 130 ไบต์

บันทึก 2 ไบต์ต้องขอบคุณ vaultah
บันทึกไปแล้ว 6 ไบต์ขอบคุณ Kevin Lau - ไม่ใช่ Kenny

ฉันเกลียดการแปลงเป็นไบนารี่ในไพ ธ อน

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

กรณีทดสอบ:

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

ดูเหมือนว่าคุณมีวงเล็บพิเศษ 1 คู่หลังจากที่สอง''.join
vaultah

@vaultah โอ๊ะใช่คุณพูดถูก
Morgan Thrapp

ใช้'ACGT'[int(z+y,2)]แทนการแปลงโดยตรงจากไบนารี่แทนการใช้สตริงที่ยาวกว่าของคุณและแปลงจากฐาน 10 นอกจากนี้ไม่แน่ใจว่าจะสร้างความแตกต่างได้มากน้อยเพียงre.subใด
หมึกมูลค่า

@ KevinLau-notKenny Oooo ขอบคุณ intฉันลืมคุณสามารถระบุฐานด้วย ฉันจะตรวจสอบre.subขอบคุณสำหรับคำแนะนำ
Morgan Thrapp

วิธีการที่ดีฉันมากับ (เกือบ) รหัสเดียวกันโดยไม่ต้องมองคุณ :)
Byte Commander

3

Ruby, 80 ไบต์

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

ในฐานะที่เป็นตรงไปตรงมาเป็นปัญหาคือมันเป็นไปได้ที่จะบีบมากขึ้นไบต์จากนี้ :)
xsot

3

Mathematica, 108 ไบต์

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

รับสตริงเป็นอินพุตและเอาต์พุตรายการฐาน


3

Python 3, 126 ไบต์

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

ยินดีต้อนรับสู่การเขียนโปรแกรมปริศนา & รหัสกอล์ฟ! ในกรณีที่คุณสงสัยเกี่ยวกับ downvote ที่นี่คือสิ่งที่เกิดขึ้น
Dennis

2

Pyth, 25 ไบต์

sm@"ACGT"id2Pc.B*4sjkCMQ2

ลองที่นี่!

คำอธิบาย

เคล็ดลับการขุดขยายจากคำตอบที่มาร์ติน CJam

sm @ "ACGT" id2Pc.B * 4sjkCMQ2 # Q = อินพุต

                     CMQ # จับคู่อักขระแต่ละตัวของ Q กับรหัสอักขระ
                  sjk # เข้าร่วมเป็นหนึ่งสตริงและแปลงเป็นจำนวนเต็ม
              .B * 4 # Mulitply ที่มี 4 และแปลงเป็นไบนารี
             c 2 # แยกเป็นคู่
            P # ทิ้งคู่สุดท้าย
 m # แผนที่แต่ละคู่ d
         id2 # แปลงคู่จากไบนารี่เป็นทศนิยม
  @ "ACGT" # ใช้ผล ^ เป็นดัชนีในสตริงการค้นหา
s # เข้าร่วมรายการผลลัพธ์ในสตริง


2

Java, 194 ไบต์

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;}

Ungolfed

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;
}

บันทึก

  • การป้อนข้อมูลเป็นอาร์เรย์ของตัวอักษร (ซึ่งควรนับเป็นรูปแบบของ String ก) พารามิเตอร์เป็นประเภทint[]เพราะ thats char[]หนึ่งไบต์บันทึกไว้มากกว่า

เอาท์พุต

Input:  codegolf
Output: GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA

Input:  .
Output: GTG

Input:  }
Output: TTGG

Input:  wow
Output: TGATAGTTGTGCTG

Input:  programming puzzles
Output: GTGTCAGAGTTGAAGGCCGTTCCGCAGTGCATTTGGCTCGTCTGGTGTCTACTAGCCTGCGAGAGGAGTTACTTTGGATCCTTGACTTGT

2

MATL , 21 ไบต์

'CGTA'joV4Y2HZa2e!XB)

ลองออนไลน์!

คำอธิบาย

'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

Pyth , 23 ไบต์

sm@"AGCT"i_d2c.BsjkCMQ2

ลองออนไลน์!

คำอธิบาย

เคล็ดลับการกู้ยืมเงินจากเดนนิสคำตอบของวุ้น

sm@"AGCT"i_d2c.BsjkCMQ2
                   CMQ   convert each character to its byte value
                sjk      convert to a string and then to integer
              .B         convert to binary
             c        2  chop into pairs
 m         d             for each pair:
          _                  reverse it
         i  2                convert from binary to integer
  @"AGCT"                    find its position in "AGCT"
s                        join the string

1

Groovy ขนาด 114 ไบต์

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

คำอธิบาย:

{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
        }
     ]
}

คำตอบที่ดี! คุณช่วยเพิ่มคำอธิบายได้มั้ย
NoOneIsHere ที่

รุ่นแรกไม่ทำงานเพราะฉันลืมผนวก 0 ฉันแก้ไขมันและลงไปด้วยไบต์ btw
Krzysztof Atłasik


1

Python 2.7, 135 ไบต์

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

Ungolfed:

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'

เอาท์พุต

f('codegolf')
'GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA'

@DrGreenEggsandHamDJ ฉันมีg(...)ฟังก์ชั่นในนั้นสองครั้งดังนั้นฉันเชื่อว่าการแทนที่ด้วยjoinจะเพิ่ม 2 ไบต์?
deustice

อาฉันคิดถึงเรื่องนั้น ความผิดฉันเอง!
DJMcMayhem

1

Javascript ES7, 105 103 ไบต์

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

ส่วน ES7 เป็นfor(c of s)ส่วนหนึ่ง

รุ่น ES6, 107 105 ไบต์

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

รหัสที่ไม่ได้รับการปรับปรุง

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

นี่เป็นครั้งแรกที่ฉันลองเล่นกอล์ฟที่ PPCG อย่าลังเลที่จะแก้ไขฉันหากมีอะไรผิดปกติ

ขอบคุณ @AlexA สำหรับการปรับปรุงเล็กน้อย


1
นี่เป็นสนามกอล์ฟที่ดีครั้งแรก! เนื่องจากฟังก์ชั่นไม่ซ้ำซ้ำและเราไม่ต้องการฟังก์ชั่นที่จะตั้งชื่อดังนั้นคุณควรจะสามารถลบออกf=ได้ประหยัด 2 ไบต์ :)
อเล็กซ์ A.

1

J, 52 ไบต์

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

การใช้งาน: 3 :'''ACGT''{~#._2,\#:".,&''x''":(,&:(":"0))/3&u:y' 'codegolf'==>GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA


1

Common Lisp (Lispworks), 415 ไบต์

(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")))))))))

ungolfed:

(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")))))))))

การใช้งาน:

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

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

0

Perl, 155 148 137 + 1 ( -pตั้งค่าสถานะ) = 138 ไบต์

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

ทดสอบบนIdeone


0

Perl 6, 57 + 1 ( -pตั้งค่าสถานะ) = 58 bytes

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

คำอธิบายทีละขั้นตอน:

-pธงทำให้เกิด Perl 6 ล่ามในการเรียกใช้รหัสสายโดยสายวางสายในปัจจุบันและในตอนท้ายจะนำมันกลับมาจาก$_$_

.ords- $_หากมีอะไรก่อนระยะเวลาวิธีการที่ถูกเรียกบน ordsวิธีการส่งกลับรายการ codepoints ในสตริง

[~]- []เป็นตัวดำเนินการลดซึ่งจัดเก็บตัวดำเนินการลดระหว่างวงเล็บ ในกรณีนี้มัน~เป็นตัวดำเนินการเชื่อมต่อสตริง ยกตัวอย่างเช่นเทียบเท่ากับ[~] 1, 2, 31 ~ 2 ~ 3

+แปลงอาร์กิวเมนต์เป็นตัวเลขจำเป็นเนื่องจากbaseมีการกำหนดเมธอดสำหรับจำนวนเต็มเท่านั้น

.base(2) - แปลงจำนวนเต็มเป็นสตริงในฐาน 2

$_=- $_กำหนดผลให้

s:g/..?/{...}/- นี่เป็นนิพจน์ปกติแทนที่:gอินสแตนซ์( , โหมดสากล) ของ regex ..?(หนึ่งหรือสองตัวอักษร) อาร์กิวเมนต์ที่สองคือรูปแบบการแทนที่ซึ่งในกรณีนี้ในรหัส (ใน Perl 6, วงเล็บปีกกาในสตริงและรูปแบบการเปลี่ยนจะดำเนินการเป็นรหัส)

$/ - ตัวแปรการจับคู่ regex

.flip- แปลงกลับสตริง มันจะแปลง$/(วัตถุจับคู่ regex) เป็นสตริงโดยปริยาย เพราะนี่คือตัวเดียว1ควรจะขยายไปเมื่อเทียบกับ10 01เนื่องจากการพลิกลำดับขององค์ประกอบในอาร์เรย์จึงกลับ G และ C

:2(...) - แยกวิเคราะห์สตริงฐาน 2 เป็นจำนวนเต็ม

<A G C T> - อาร์เรย์ของสี่องค์ประกอบ

...[...] - ผู้ประกอบการเข้าถึงอาร์เรย์

นั่นหมายความว่าอย่างไร? โปรแกรมรับรายการ codepoints ทั้งหมดในสตริงต่อกันเข้าด้วยกันแปลงเป็นฐาน 2 จากนั้นจะแทนที่อินสแตนซ์ทั้งหมดของอักขระสองหรือหนึ่งตัวเป็นหนึ่งในตัวอักษร A, G, C, T ขึ้นอยู่กับการแสดงตัวเลข ในไบนารี


0

ฮุน , 148 138 ไบต์

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

"abc" เป็นรายการของอะตอม สอดแทรกลงในสายอักขระ ( <a>) ในขณะที่พับทับรายการรวมเข้าด้วยกันเป็นสายอักขระใหม่ แยกตัวเลขด้วย++demเพื่อนำกลับไปที่อะตอม

คูณจำนวนด้วย (ความยาวบิต + 1)% 2 เพื่อปัดมัน ใช้++ripเพื่อแยกทุกสองไบต์คู่ของอะตอมลงในรายการแผนที่เหนือรายการและใช้ตัวเลขเป็นดัชนีลงในสตริง "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"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.