Golf-Text in DNA

26

Text zu DNA Golf

Herausforderung

Umwandlung von Input in einen DNA-Output.

Algorithmus

  • Text in ASCII-Codepunkte konvertieren (z. B. codegolf-> [99, 111, 100, 101, 103, 111, 108, 102])
  • String die ASCII-Codes zusammen (zB 99111100101103111108102)
  • In Binärdatei konvertieren (z. B. 10100111111001101001011010001000011001101011011110000110010111111011000000110)
  • Füge 0s am Ende ein, um eine gerade Anzahl von Zeichen zu erhalten (zB 101001111110011010010110100010000110011010110111100001100101111110110000001100)
  • Ersetze 00mit A, 01mit C, 10mit Gund 11mit T(zB GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA)
  • Ausgabe

Testfälle

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

Spezifikationen

  • Das ist
  • Ihr Programm muss Leerzeichen in der Eingabe akzeptieren.
  • Ihr Programm muss funktionieren codegolf.
Niemand ist hier
quelle
2
Ich denke, Sie sollten einen Testfall hinzufügen, der das Füllverhalten erfordert. Die faule Wahl wäre, }was meiner Meinung nach wird TTGG.
FryAmTheEggman
3
Wie viel Input müssen wir unterstützen? 99111100101103111108102ist beispielsweise größer als uint-64, sodass einige Sprachen möglicherweise mit größeren Konvertierungen zu kämpfen haben.
AdmBorkBork
4
Auf diese Weise können Sie ASCII-Codes nicht aneinanderreihen, wenn Sie sie jemals wieder dekodieren möchten.
user253751
@immibis Ich weiß.
NoOneIsHere

Antworten:

17

Jelly , 15 bis 13 Bytes

OVBs2UḄị“GCTA

Probieren Sie es online! oder überprüfen Sie alle Testfälle .

Wie es funktioniert

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].
Dennis
quelle
9

CJam, 24 23 Bytes

Vielen Dank an Dennis für das wirklich clevere Speichern von 1 Byte. :)

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

Teste es hier.

Erläuterung

Sehr direkte Umsetzung der Spezifikation. Das einzig interessante ist das Auffüllen auf eine gerade Anzahl von Nullen (was eigentlich Dennis 'Idee war). Anstatt die Ziffern in jedem Paar in der üblichen Reihenfolge zu behandeln, machen wir das zweite Bit zum höchstwertigen. Das bedeutet, dass das Beenden eines einzelnen Bits mit dem Anhängen einer Null identisch ist. Das bedeutet, dass wir überhaupt keine Null anhängen müssen.

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.
Martin Ender
quelle
Ich weiß nichts über CJam, aber warum müssen Sie jedes Paar umkehren? Können Sie sie nicht direkt aus der Binärdatei zurückkonvertieren?
Value Ink
@ KevinLau-notKenny Beim Umkehren jedes Paares werden keine Nullen angehängt, um eine gerade Länge zu erhalten. In den umgekehrten Paaren müssten Sie Nullen voranstellen , was für die Basiskonvertierung keine Rolle spielt.
Dennis
Guter Trick! Es hätte wahrscheinlich eine Menge Bytes in meiner eigenen Lösung gespart, wenn ich über diesen Trick nachgedacht hätte
Value Ink
6

Python 2, 109 103 Bytes

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

Teste es auf Ideone .

Dennis
quelle
4

Ruby, 59 Bytes

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

Ein volles Programm. Laufen Sie mit der -pFlagge.

xsot
quelle
Wie hast du es überhaupt verstanden
?
4

Python 3, 130 Bytes.

2 Bytes dank Vaultah gespart.
6 Bytes dank Kevin Lau gespeichert - nicht Kenny.

Ich hasse es, wie schwer es ist, in Python nach Binär zu konvertieren.

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

Testfälle:

assert f('codegolf') == 'GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA'
assert f('ppcg') == 'GGCTAATTGTCGCACTT'
Morgan Thrapp
quelle
Sieht aus wie Sie haben ein zusätzliches Paar von Klammern nach dem zweiten''.join
vaultah
@vaultah Ups, yup, du hast recht.
Morgan Thrapp
Verwenden Sie 'ACGT'[int(z+y,2)]stattdessen, konvertieren Sie direkt aus dem Binären, anstatt Ihren längeren String zu verwenden, und konvertieren Sie von der Basis 10. Sie können sich auch nicht sicher sein, welchen Unterschied es machen würde, wenn Sie re.subanstelle Ihres chaotischen Join-Tricks die Verwendung betrachten?
Value Ink
@ KevinLau-notKenny Oooo, danke. Ich habe vergessen, dass Sie eine Basis mit angeben können int. Ich werde nachsehen re.sub, danke für den Vorschlag.
Morgan Thrapp
Netter Ansatz, ich habe mir (fast) genau den gleichen Code ausgedacht, ohne auf deinen geschaut zu haben. :)
Byte Commander
3

Ruby, 80 Bytes

->s{s=s.bytes.join.to_i.to_s 2;s+=?0*(s.size%2)
s.gsub(/../){"ACGT"[$&.to_i 2]}}
Wert Tinte
quelle
So einfach das Problem auch ist, es ist möglich, viel mehr Bytes daraus herauszuholen :)
xsot
3

Mathematica, 108 Bytes

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

Nimmt einen String als Eingabe und gibt eine Liste von Basen aus.

LegionMammal978
quelle
3

Python 3, 126 Bytes

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))])
Hunter VL
quelle
Willkommen bei Programming Puzzles & Code Golf! Falls Sie sich über die Ablehnung wundern, ist dies geschehen .
Dennis
2

Pyth, 25 Bytes

sm@"ACGT"id2Pc.B*4sjkCMQ2

Probieren Sie es hier aus!

Erläuterung

Den Polstertrick von Martins CJam-Antwort ausgraben .

sm @ "ACGT" id2Pc.B * 4sjkCMQ2 # Q = input

                     CMQ # Ordne jedes Zeichen von Q seinem Zeichencode zu
                  sjk # Füge einen String zusammen und wandle ihn in eine Ganzzahl um
              .B * 4 # Multipliziert mit 4 und konvertiert nach binär
             c 2 # In Paare teilen
            P # Das letzte Paar verwerfen
 m # Ordne jedes Paar zu d
         id2 # Paar von binär in dezimal konvertieren
  @ "ACGT" # Verwenden Sie das Ergebnis ^ als Index für eine Suchzeichenfolge
s # Füge die resultierende Liste zu einem String zusammen
Denker
quelle
2

Java, 194 Bytes

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

Hinweis

  • Die Eingabe ist ein Array von Zeichen (das als int[]Zeichenfolge gelten sollte). Der Parameter ist vom Typ, da dies ein Byte ist, über das gespeichert wurde char[].

Ausgabe

Input:  codegolf
Output: GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA

Input:  .
Output: GTG

Input:  }
Output: TTGG

Input:  wow
Output: TGATAGTTGTGCTG

Input:  programming puzzles
Output: GTGTCAGAGTTGAAGGCCGTTCCGCAGTGCATTTGGCTCGTCTGGTGTCTACTAGCCTGCGAGAGGAGTTACTTTGGATCCTTGACTTGT
Marv
quelle
2

MATL , 21 Bytes

'CGTA'joV4Y2HZa2e!XB)

Probieren Sie es online!

Erläuterung

'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
Luis Mendo
quelle
1

Pyth , 23 Bytes

sm@"AGCT"i_d2c.BsjkCMQ2

Probieren Sie es online!

Erläuterung

Den Trick von Dennis 'Gelee-Antwort ausleihen .

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
Undichte Nonne
quelle
1

Groovy, 114 Bytes

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

Erläuterung:

{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
        }
     ]
}
Krzysztof Atłasik
quelle
Gute Antwort! Können Sie bitte eine Erklärung hinzufügen?
NoOneIsHere
Die erste Version hat nicht funktioniert, weil ich vergessen habe, 0 anzufügen. Ich habe sie behoben und bin übrigens mit Bytes gesunken.
Krzysztof Atłasik
1

Julia 0,4, 77 Bytes

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

Diese anonyme Funktion verwendet ein Zeichenarray als Eingabe und gibt eine Zeichenfolge zurück.

Probieren Sie es online!

Dennis
quelle
1

Python 2.7, 135 Bytes

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'

Ausgabe

f('codegolf')
'GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA'
Ungerechtigkeit
quelle
@DrGreenEggsandHamDJ Ich habe die g(...)Funktion dort zweimal, also glaube ich, sie durch die zu ersetzen, joinwürde 2 Bytes hinzufügen?
Deustice
Ah, das habe ich verpasst. Mein Fehler!
DJMcMayhem
1

Javascript ES7, 105 103 Bytes

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

Der ES7-Teil ist der for(c of s)Teil.

ES6-Version, 107 105 Bytes

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

Ungolfed Code

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

Dies ist mein erster Versuch, auf PPCG zu golfen. Sie können mich jederzeit korrigieren, wenn etwas nicht stimmt.

Danke @AlexA für die kleine Verbesserung.

BusyBeingDelicious
quelle
1
Dies ist ein schönes erstes Golf! Da die Funktion nicht rekursiv ist und keine Funktionen benannt werden müssen, sollten Sie in der Lage sein, zu entfernen f=und 2 Bytes zu sparen. :)
Alex A.
1

J, 52 Bytes

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

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

ljeabmreosn
quelle
1

Common Lisp (Lispworks), 415 Bytes

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

Verwendung:

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

CL-USER 2061 > (f "golf")
"TAAAAATTATCCATAAATA"
sadfaf
quelle
0

Perl, 155 148 137 + 1 ( -pFlag) = 138 Bytes

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

Teste es auf Ideone .

Denis Ibaev
quelle
0

Perl 6, 57 + 1 ( -pFlag) = 58 Bytes

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

Schritt für Schritt Erklärung:

-pflag bewirkt, dass der Perl 6-Interpreter den Code Zeile für Zeile ausführt, die aktuelle Zeile $_einfügt und am Ende von dort zurückgibt $_.

.ords- Wenn vor einem Punkt nichts steht, wird eine Methode aufgerufen $_. ordsMethode gibt Liste der Codepunkte in einer Zeichenfolge zurück.

[~]- []ist ein Reduktionsoperator, der seinen Reduktionsoperator in eckigen Klammern speichert. In diesem Fall handelt es sich ~um einen Operator zur Verkettung von Zeichenfolgen. Zum Beispiel [~] 1, 2, 3ist äquivalent zu 1 ~ 2 ~ 3.

+ konvertiert sein Argument in eine Zahl, die benötigt wird, weil base Methode nur für Ganzzahlen definiert ist.

.base(2) - konvertiert eine Ganzzahl in eine Zeichenfolge in Basis 2

$_=- weist das Ergebnis zu $_.

s:g/..?/{...}/- Dies ist ein regulärer Ausdruck, der eine beliebige ( :gim globalen Modus) Regex-Instanz ..?(ein oder zwei Zeichen) ersetzt. Das zweite Argument ist ein Ersetzungsmuster, das in diesem Fall im Code enthalten ist (in Perl 6 werden geschweifte Klammern in Zeichenfolgen und Ersetzungsmuster als Code ausgeführt).

$/ - Eine reguläre Übereinstimmungsvariable

.flip- Invertiert eine Zeichenkette. Es konvertiert implizit $/(ein reguläres Übereinstimmungsobjekt) in einen String. Dies liegt daran , ein einzelne Zeichen 1erweitert werden soll 10, im Gegensatz zu 01. Aufgrund dieser Umkehrung sind G und C in der Reihenfolge der Elemente im Array umgekehrt.

:2(...) - Parst eine Base-2-Zeichenfolge in eine Ganzzahl.

<A G C T> - Array von vier Elementen.

...[...] - Array-Zugriffsoperator.

Was bedeutet das? Das Programm ruft eine Liste aller Codepunkte in einer Zeichenfolge ab, verknüpft sie miteinander und konvertiert sie zur Basis 2. Anschließend werden alle Instanzen von zwei oder einem Zeichen in einen der Buchstaben A, G, C, T ersetzt, abhängig von der gespiegelten Darstellung einer Zahl in binär.

Konrad Borowski
quelle
0

Hoon , 148 138 Bytes

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

"abc" ist eine Liste von Atomen. Interpolieren Sie sie in Strings ( <a>), während Sie die Liste überlagern, und fügen Sie sie zu einem neuen String zusammen. Analysieren Sie die Zahl mit ++dem, um sie auf ein Atom zurückzuführen.

Multiplizieren Sie die Zahl mit (bitweise Länge + 1)% 2, um sie aufzufüllen. Verwenden Sie ++ripdiese Option, um jedes Zwei-Byte-Paar des Atoms in eine Liste zu zerlegen, die Liste zuzuordnen und die Nummer als Index für die Zeichenfolge "ACGT" zu verwenden.

> =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"
Rendereinstellungen
quelle