Texte de golf dans l'ADN

26

SMS sur DNA golf

Défi

Convertissez l'entrée en sortie ADN.

Algorithme

  • Convertir du texte en points de code ASCII (par exemple codegolf-> [99, 111, 100, 101, 103, 111, 108, 102])
  • Enchaînez les codes ASCII ensemble (par exemple 99111100101103111108102)
  • Convertir en binaire (par exemple 10100111111001101001011010001000011001101011011110000110010111111011000000110)
  • Tapez 0s à la fin pour créer un nombre pair de caractères (par exemple 101001111110011010010110100010000110011010110111100001100101111110110000001100)
  • Remplacez 00par A, 01par C, 10par Get 11par T(par exemple GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA)
  • Sortie

Cas de test

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

Caractéristiques

  • C'est du
  • Votre programme doit accepter des espaces en entrée.
  • Votre programme doit fonctionner pour codegolf.
Il n'y a personne
la source
2
Je pense que vous devriez ajouter un cas de test qui nécessite le comportement de remplissage. Le choix paresseux serait }ce que je crois devenir TTGG.
FryAmTheEggman
3
Quelle quantité d'entrées devons-nous prendre en charge? 99111100101103111108102par exemple, est plus grand que uint-64, donc certaines langues peuvent avoir du mal avec des conversions plus importantes.
AdmBorkBork
4
Ce n'est pas ainsi que vous enchaînez les codes ASCII si vous voulez pouvoir à nouveau les décoder.
user253751
@immibis je sais.
NoOneIsHere

Réponses:

17

Gelée , 15 13 octets

OVBs2UḄị“GCTA

Essayez-le en ligne! ou vérifiez tous les cas de test .

Comment ça marche

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
la source
9

CJam, 24 23 octets

Merci à Dennis d'avoir sauvé 1 octet de manière très intelligente. :)

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

Testez-le ici.

Explication

Mise en œuvre très directe de la spécification. Le seul élément intéressant est le remplissage d'un nombre pair de zéros (ce qui était en fait l'idée de Dennis). Au lieu de traiter les chiffres de chaque paire dans l'ordre habituel, nous faisons du deuxième bit le plus significatif. Cela signifie que se terminer par un seul bit est identique à lui ajouter un zéro, ce qui signifie que nous n'avons pas du tout besoin d'ajouter le zéro.

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
la source
Je ne sais rien de CJam, mais pourquoi avez-vous besoin d'inverser chaque paire? Ne pouvez-vous pas les reconvertir directement depuis le binaire?
Value Ink
@ KevinLau-notKenny Inverser chaque paire évite d'ajouter des zéros pour obtenir une longueur uniforme. Dans les paires renversées, vous auriez à préfixer par des zéros, qui n'a pas d' importance pour la conversion de base.
Dennis
Joli tour! Cela aurait probablement permis d'économiser une tonne d'octets sur ma propre solution si j'avais pensé à cette astuce
Value Ink
6

Python 2, 109 103 octets

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

Testez-le sur Ideone .

Dennis
la source
4

Rubis, 59 octets

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

Un programme complet. Courez avec le -pdrapeau.

xsot
la source
comment avez-vous même ... je ne comprends pas
Value Ink
4

Python 3, 130 octets.

Enregistré 2 octets grâce à vaultah.
Enregistré 6 octets grâce à Kevin Lau - pas Kenny.

Je déteste la difficulté de convertir en binaire en python.

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

Cas de test:

assert f('codegolf') == 'GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA'
assert f('ppcg') == 'GGCTAATTGTCGCACTT'
Morgan Thrapp
la source
On dirait que vous avez 1 paire supplémentaire de supports après la seconde''.join
vaultah
@vaultah Oups, oui, vous avez raison.
Morgan Thrapp
Utilisez à la 'ACGT'[int(z+y,2)]place, convertissant directement en binaire au lieu d'utiliser votre chaîne plus longue et convertissant à partir de la base 10. De plus, vous ne savez pas quelle différence cela ferait, mais envisagez d'utiliser à la re.subplace de votre astuce de jointure malpropre?
Value Ink
@ KevinLau-notKenny Oooo, merci. J'ai oublié que vous pouvez spécifier une base avec int. Je vais vérifier re.sub, merci pour la suggestion.
Morgan Thrapp
Belle approche, j'ai trouvé (presque) exactement le même code sans avoir regardé le vôtre. :)
Byte Commander
3

Ruby, 80 octets

->s{s=s.bytes.join.to_i.to_s 2;s+=?0*(s.size%2)
s.gsub(/../){"ACGT"[$&.to_i 2]}}
Encre de valeur
la source
Aussi simple que soit le problème, il est possible d'en extraire beaucoup plus d'octets :)
xsot
3

Mathematica, 108 octets

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

Prend une chaîne en entrée et génère une liste de bases.

LegionMammal978
la source
3

Python 3, 126 octets

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
la source
Bienvenue sur Programmation Puzzles & Code Golf! Au cas où vous vous poseriez des questions sur le downvote, c'est ce qui s'est passé .
Dennis
2

Pyth, 25 octets

sm@"ACGT"id2Pc.B*4sjkCMQ2

Essayez-le ici!

Explication

Creuser le truc de rembourrage de Martins CJam réponse .

sm @ "ACGT" id2Pc.B * 4sjkCMQ2 # Q = entrée

                     CMQ # Mappez chaque caractère de Q à son code de caractère
                  sjk # Joindre en une chaîne et convertir en un entier
              .B * 4 # Mulitply avec 4 et convertir en binaire
             c 2 # Divisé en paires
            P # Jeter la dernière paire
 m # Mapper chaque paire d
         id2 # Convertir la paire du binaire en décimal
  @ "ACGT" # Utilisez le résultat ^ comme index dans une chaîne de recherche
s # Joignez la liste résultante dans une chaîne
Denker
la source
2

Java, 194 octets

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

Non golfé

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

Remarque

  • L'entrée est un tableau de caractères (qui doit compter comme une forme de chaîne), le paramètre est de type int[]car c'est un octet enregistré surchar[] .

Sortie

Input:  codegolf
Output: GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA

Input:  .
Output: GTG

Input:  }
Output: TTGG

Input:  wow
Output: TGATAGTTGTGCTG

Input:  programming puzzles
Output: GTGTCAGAGTTGAAGGCCGTTCCGCAGTGCATTTGGCTCGTCTGGTGTCTACTAGCCTGCGAGAGGAGTTACTTTGGATCCTTGACTTGT
Marv
la source
2

MATL , 21 octets

'CGTA'joV4Y2HZa2e!XB)

Essayez-le en ligne!

Explication

'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
la source
1

Pyth , 23 octets

sm@"AGCT"i_d2c.BsjkCMQ2

Essayez-le en ligne!

Explication

Emprunter l'astuce de la réponse de Dennis 'Jelly .

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
la source
1

Groovy, 114 octets

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

Explication:

{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
la source
Très bonne réponse! Pouvez-vous s'il vous plaît ajouter une explication s'il vous plaît?
NoOneIsHere
La première version ne fonctionnait pas, car j'avais oublié d'ajouter 0. Je l'ai corrigé et je suis descendu avec octets btw.
Krzysztof Atłasik
1

Julia 0.4, 77 octets

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

Cette fonction anonyme prend un tableau de caractères en entrée et renvoie une chaîne.

Essayez-le en ligne!

Dennis
la source
1

Python 2.7, 135 octets

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

Non golfé:

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'

Sortie

f('codegolf')
'GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA'
deustice
la source
@DrGreenEggsandHamDJ J'ai la g(...)fonction là-dedans deux fois, donc je crois que le remplacer par joinajouterait 2 octets?
deustice
Ah, j'ai raté ça. Ma faute!
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``

La partie ES7 est la for(c of s)partie.

Version ES6, 107 105 octets

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

Code non golfé

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

C'est mon premier essai de golf sur PPCG, n'hésitez pas à me corriger si quelque chose ne va pas.

Merci @AlexA pour la petite amélioration.

OccupéÉtreDélicieux
la source
1
C'est un joli premier golf! Étant donné que la fonction n'est pas récursive et que nous n'avons pas besoin que les fonctions soient nommées, vous devriez donc pouvoir les supprimer f=en économisant 2 octets. :)
Alex A.
1

J, 52 octets

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

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

ljeabmreosn
la source
1

Lisp commun (Lispworks), 415 octets

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

non golfé:

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

Usage:

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

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

Perl, 155 148 137 + 1 ( -ppavillon) = 138 octets

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

Testez-le sur Ideone .

Denis Ibaev
la source
0

Perl 6, 57 + 1 ( -pindicateur) = 58 octets

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

Explication étape par étape:

-pL'indicateur amène l'interpréteur Perl 6 à exécuter le code ligne par ligne, à mettre la ligne actuelle $_et à la fin à la remettre $_.

.ords- S'il n'y a rien avant un point, une méthode est appelée $_. ordsretourne la liste des points de code dans une chaîne.

[~]- []est un opérateur de réduction, qui stocke son opérateur de réduction entre parenthèses. Dans ce cas, c'est ~, qui est un opérateur de concaténation de chaînes. Par exemple, [~] 1, 2, 3est équivalent à1 ~ 2 ~ 3 .

+convertit son argument en nombre, nécessaire car la baseméthode n'est définie que pour les entiers.

.base(2) - convertit un entier en une chaîne en base 2

$_=- attribue le résultat à $_.

s:g/..?/{...}/- il s'agit d'une expression régulière remplaçant toute :ginstance ( , en mode global) de regex ..?(un ou deux caractères). Le deuxième argument est un modèle de remplacement, qui dans ce cas en code (en Perl 6, les accolades dans les chaînes et les modèles de remplacement sont exécutés en tant que code).

$/ - une variable de correspondance regex

.flip- inverse une chaîne. Il convertit implicitement $/(un objet de correspondance d'expression régulière) en une chaîne. En effet, un caractère unique 1doit être étendu à 10, par opposition à01 . En raison de ce retournement, l'ordre des éléments dans le tableau a G et C inversés.

:2(...) - analyse une chaîne de base 2 en un entier.

<A G C T> - tableau de quatre éléments.

...[...] - opérateur d'accès à la baie.

Qu'est-ce que ça veut dire? Le programme obtient la liste de tous les points de code dans une chaîne, les concatène ensemble, les convertit en base 2. Ensuite, il remplace toutes les instances de deux ou un caractère en une des lettres A, G, C, T selon la représentation inversée d'un nombre en binaire.

Konrad Borowski
la source
0

Hoon , 148 138 octets

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

"abc" est une liste d'atomes. Interpolez-les en chaînes ( <a>) tout en repliant la liste, en les réunissant en une nouvelle chaîne. Analyser le nombre avec++dem pour le ramener à un atome.

Multipliez le nombre par (longueur au niveau du bit + 1)% 2 pour le remplir. Utilisez ++rippour désassembler chaque paire de deux octets de l'atome dans une liste, mappez sur la liste et utilisez le numéro comme index dans la chaîne "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
la source