Tekst golfa w DNA

26

Tekst do golfa DNA

Wyzwanie

Przekształć dane wejściowe w dane wyjściowe DNA.

Algorytm

  • Konwertuj tekst na punkty kodowe ASCII (np. codegolf-> [99, 111, 100, 101, 103, 111, 108, 102])
  • Połącz razem kody ASCII (np. 99111100101103111108102)
  • Konwertuj na binarny (np. 10100111111001101001011010001000011001101011011110000110010111111011000000110)
  • Pad 0na końcu, aby uzyskać parzystą liczbę znaków (np. 101001111110011010010110100010000110011010110111100001100101111110110000001100)
  • Wymienić 00z A, 01z C, 10z G, i 11z T(na przykład GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA)
  • Wydajność

Przypadki testowe

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

Dane techniczne

  • To jest
  • Twój program musi akceptować spacje na wejściu.
  • Twój program musi działać codegolf.
Nikogo tu nie ma
źródło
2
Myślę, że powinieneś dodać przypadek testowy, który wymaga zachowania wypełnienia. Leniwy wybór stałby się }moim zdaniem TTGG.
FryAmTheEggman
3
Jak duży wkład musimy wesprzeć? 99111100101103111108102na przykład jest większy niż uint-64, więc niektóre języki mogą mieć problemy z większymi konwersjami.
AdmBorkBork
4
Nie tak łączysz razem kody ASCII, jeśli chcesz kiedykolwiek móc je ponownie odkodować.
user253751
@immibis Wiem.
NoOneIsHere

Odpowiedzi:

17

Galaretka , 15 13 bajtów

OVBs2UḄị“GCTA

Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe .

Jak to działa

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
źródło
9

CJam, 24 23 bajty

Dzięki Dennisowi za zaoszczędzenie 1 bajtu w naprawdę sprytny sposób. :)

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

Sprawdź to tutaj.

Wyjaśnienie

Bardzo bezpośrednie wdrożenie specyfikacji. Jedynym interesującym bitem jest dopełnianie parzystej liczby zer (co w rzeczywistości było pomysłem Dennisa). Zamiast traktować cyfry w każdej parze w zwykłej kolejności, drugi bit jest najbardziej znaczący. Oznacza to, że kończenie na jednym bicie jest identyczne z dodawaniem do niego zera, co oznacza, że ​​wcale nie musimy dodawać zera.

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
źródło
Nic nie wiem o CJam, ale dlaczego musisz cofnąć każdą parę? Czy nie możesz przekonwertować ich bezpośrednio z binarnego?
Wartość tuszu
@ KevinLau-notKenny Cofanie każdej pary pozwala uniknąć dodawania zer, aby uzyskać równą długość. W parach odwróconych musisz wstawić zera, co nie ma znaczenia dla konwersji podstawowej.
Dennis
Niezła sztuczka! Prawdopodobnie zaoszczędziłbym mnóstwo bajtów na moim własnym rozwiązaniu, gdybym pomyślał o tej sztuczce
Value Ink
6

Python 2, 109 103 bajty

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

Przetestuj na Ideone .

Dennis
źródło
4

Ruby, 59 bajtów

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

Pełny program. Uruchom z -pflagą.

xsot
źródło
jak to w ogóle ... nie rozumiem
Value Ink
4

Python 3, 130 bajtów.

Zaoszczędzono 2 bajty dzięki vaultah.
Zaoszczędził 6 bajtów dzięki Kevinowi Lau - nie Kenny'emu.

Nienawidzę, jak trudno jest przekonwertować na binarny w Pythonie.

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

Przypadki testowe:

assert f('codegolf') == 'GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA'
assert f('ppcg') == 'GGCTAATTGTCGCACTT'
Morgan Thrapp
źródło
Wygląda na to, że po drugiej masz 1 dodatkową nawias''.join
vaultah
@vaultah Ups, tak, masz rację.
Morgan Thrapp
Użyj 'ACGT'[int(z+y,2)]zamiast tego, konwertuj bezpośrednio z pliku binarnego zamiast używać dłuższego łańcucha i konwertuj z bazy 10. Ponadto, nie wiesz, ile by to zmieniło, ale spójrz na użycie re.subzamiast bałaganu w sztuczce łączenia?
Wartość tuszu
@ KevinLau-notKenny Oooo, dzięki. Zapomniałem, że możesz podać bazę int. Zajrzę do re.sub, dzięki za sugestię.
Morgan Thrapp
Ładne podejście, wymyśliłem (prawie) dokładnie ten sam kod, nie oglądając twojego. :)
Byte Commander
3

Rubinowy, 80 bajtów

->s{s=s.bytes.join.to_i.to_s 2;s+=?0*(s.size%2)
s.gsub(/../){"ACGT"[$&.to_i 2]}}
Wartość tuszu
źródło
Problem jest prosty, ale można z niego wycisnąć o wiele więcej bajtów :)
xsot
3

Mathematica, 108 bajtów

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

Pobiera ciąg znaków jako dane wejściowe i wyświetla listę zasad.

LegionMammal978
źródło
3

Python 3, 126 bajtów

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
źródło
Witamy w Programowaniu Puzzle i Code Golf! Jeśli zastanawiasz się nad przegłosowaniem, tak się stało .
Dennis
2

Pyth, 25 bajtów

sm@"ACGT"id2Pc.B*4sjkCMQ2

Wypróbuj tutaj!

Wyjaśnienie

Zagrzebując sztuczkę padding z odpowiedzi Martins CJam .

sm @ „ACGT” id2Pc.B * 4sjkCMQ2 # Q = wejście

                     CMQ # Odwzoruj każdy znak Q na jego kod znaku
                  sjk # Połącz w jeden ciąg i przekonwertuj na liczbę całkowitą
              .B * 4 # Mulitply z 4 i konwertuj na binarne
             c 2 # Podziel na pary
            P # Odrzuć ostatnią parę
 m # Mapuj każdą parę d
         id2 # Konwertuj parę z binarnej na dziesiętną
  @ „ACGT” # Użyj wyniku ^ jako indeksu w ciągu wyszukiwania
s # Dołącz wynikową listę do ciągu
Denker
źródło
2

05AB1E , 23 bajty

Kod:

SÇJb00«2÷¨C3210"TGCA"‡á

Wykorzystuje kodowanie CP-1252 . Wypróbuj online! .

Adnan
źródło
2

Java, 194 bajty

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

Nie golfił

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

Uwaga

  • Dane wejściowe to tablica znaków (która powinna być traktowana jako forma ciągu), parametr jest typu, int[]ponieważ zapisano jeden bajt char[].

Wydajność

Input:  codegolf
Output: GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA

Input:  .
Output: GTG

Input:  }
Output: TTGG

Input:  wow
Output: TGATAGTTGTGCTG

Input:  programming puzzles
Output: GTGTCAGAGTTGAAGGCCGTTCCGCAGTGCATTTGGCTCGTCTGGTGTCTACTAGCCTGCGAGAGGAGTTACTTTGGATCCTTGACTTGT
Marv
źródło
2

MATL , 21 bajtów

'CGTA'joV4Y2HZa2e!XB)

Wypróbuj online!

Wyjaśnienie

'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
źródło
1

Pyth , 23 bajty

sm@"AGCT"i_d2c.BsjkCMQ2

Wypróbuj online!

Wyjaśnienie

Pożyczenie sztuczki od Jelly's Jelly odpowiedź .

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
Leaky Nun
źródło
1

Groovy, 114 bajtów

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

Wyjaśnienie:

{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
źródło
Świetna odpowiedź! Czy możesz proszę dodać wyjaśnienie?
NoOneIsHere
Pierwsza wersja nie działała, ponieważ zapomniałem dołączyć 0. Naprawiłem ją i poszedłem z bajtami btw.
Krzysztof Atłasik
1

Julia 0.4, 77 bajtów

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

Ta anonimowa funkcja pobiera tablicę znaków jako dane wejściowe i zwraca ciąg znaków.

Wypróbuj online!

Dennis
źródło
1

Python 2.7, 135 bajtów

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

Nie golfowany:

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'

Wydajność

f('codegolf')
'GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA'
deustice
źródło
@DrGreenEggsandHamDJ Mam tam g(...)funkcję dwa razy, więc uważam, że zastąpienie jej joindodaniem 2 bajtów?
deustice
Ach, tęskniłem za tym. Mój błąd!
DJMcMayhem
1

JavaScript ES7, 105 103 bajtów

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

Część ES7 jest for(c of s)częścią.

Wersja ES6, 107 105 bajtów

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

Nieskluczony kod

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

To moja pierwsza gra w golfa na PPCG, nie krępuj się i popraw mnie, jeśli coś jest nie tak.

Dzięki @AlexA za drobną poprawę.

BusyBeingDelicious
źródło
1
To fajny pierwszy golf! Ponieważ funkcja nie jest rekurencyjna i nie wymagamy nazywania funkcji, więc powinieneś być w stanie ją usunąć f=, oszczędzając 2 bajty. :)
Alex A.,
1

J, 52 bajty

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

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

ljeabmreosn
źródło
1

Common Lisp (Lispworks), 415 bajtów

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

bez golfa:

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

Stosowanie:

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

CL-USER 2061 > (f "golf")
"TAAAAATTATCCATAAATA"
sadfaf
źródło
0

Perl, 155 148 137 + 1 ( -pflaga) = 138 bajtów

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

Przetestuj na Ideone .

Denis Ibaev
źródło
0

Perl 6, 57 + 1 ( -pflaga) = 58 bajtów

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

Wyjaśnienie krok po kroku:

-pFlaga powoduje, że interpreter Perla 6 uruchamia kod wiersz po wierszu, umieszcza bieżącą linię $_, a na końcu umieszcza ją z powrotem $_.

.ords- Jeśli przed kropką nie ma nic, wywoływana jest metoda $_. ordsMetoda zwraca listę punktów kodowych w ciągu.

[~]- []jest operatorem redukcji, który przechowuje swojego operatora redukcji między nawiasami. W tym przypadku ~jest to operator konkatenacji łańcuchów. Na przykład [~] 1, 2, 3jest równoważne z 1 ~ 2 ~ 3.

+konwertuje argument na liczbę, potrzebną, ponieważ basemetoda jest zdefiniowana tylko dla liczb całkowitych.

.base(2) - konwertuje liczbę całkowitą na ciąg znaków w bazie 2

$_=- przypisuje wynik do $_.

s:g/..?/{...}/- jest to wyrażenie regularne zastępujące dowolne wystąpienie wyrażenia regularnego (w :gtrybie globalnym) ..?(jeden lub dwa znaki). Drugi argument to wzorzec zastępujący, który w tym przypadku w kodzie (w Perlu 6, nawiasy klamrowe w łańcuchach i wzorce zastępcze są wykonywane jako kod).

$/ - zmienna dopasowania wyrażenia regularnego

.flip- odwraca ciąg. Niejawnie konwertuje $/(obiekt dopasowania wyrażenia regularnego) na ciąg. Wynika to z faktu, że jeden znak 1należy rozwinąć do 10, w przeciwieństwie do 01. Z powodu tego odwrócenia kolejność elementów w tablicy odwróciła G i C.

:2(...) - analizuje ciąg base-2 na liczbę całkowitą.

<A G C T> - tablica czterech elementów.

...[...] - operator dostępu do tablicy.

Co to znaczy? Program pobiera listę wszystkich współrzędnych kodowych w ciągu, łączy je ze sobą, konwertuje na bazę 2. Następnie zastępuje wszystkie wystąpienia dwóch lub jednego znaku na jedną z liter A, G, C, T w zależności od odwróconej reprezentacji liczby binarnie.

Konrad Borowski
źródło
0

Hoon , 148 138 bajtów

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

„abc” to lista atomów. Interpoluj je w łańcuchy ( <a>), jednocześnie składając listę, łącząc je w nowy łańcuch. Analizuj liczbę za pomocą, ++demaby uzyskać z powrotem atom.

Pomnóż liczbę przez (długość bitowa + 1)% 2, aby ją uzupełnić. Służy ++ripdo rozłożenia co dwie pary bajtów atomu na listę, zamapowania na liście i użycia liczby jako indeksu w ciągu „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"
RenderSettings
źródło