Texto de golf en ADN


26

Texto a DNA golf

Reto

Convierta la entrada en una salida de ADN.

Algoritmo

  • Convierta texto en puntos de código ASCII (por ejemplo, codegolf-> [99, 111, 100, 101, 103, 111, 108, 102])
  • Cadena los códigos ASCII juntos (por ejemplo 99111100101103111108102)
  • Convertir a binario (p 10100111111001101001011010001000011001101011011110000110010111111011000000110. Ej. )
  • Almohadillas 0en el extremo para formar un número par de caracteres (p 101001111110011010010110100010000110011010110111100001100101111110110000001100. Ej. )
  • Reemplazar 00con A, 01con C, 10con Gy 11con T(p GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA. Ej. )
  • Salida

Casos de prueba

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

Presupuesto

  • Esto es
  • Su programa debe aceptar espacios en la entrada.
  • Su programa debe funcionar para codegolf.

2
Creo que debería agregar un caso de prueba que requiera el comportamiento de relleno. La elección perezosa sería en }lo que creo que se convierte TTGG.
FryAmTheEggman

3
¿Qué cantidad de información necesitamos admitir? 99111100101103111108102por ejemplo, es más grande que uint-64, por lo que algunos idiomas pueden tener dificultades con conversiones más grandes.
AdmBorkBork

44
No es así como encadenan los códigos ASCII si quieren volver a decodificarlos.
user253751

@immibis lo sé.
NoOneIsHere

Respuestas:


17

Jalea , 15 13 bytes

OVBs2UḄị“GCTA

Pruébalo en línea! o verificar todos los casos de prueba .

Cómo funciona

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 bytes

Gracias a Dennis por guardar 1 byte de una manera realmente inteligente. :)

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

Pruébalo aquí.

Explicación

Implementación muy directa de la especificación. Lo único interesante es el relleno de un número par de ceros (que en realidad fue idea de Dennis). En lugar de tratar los dígitos de cada par en el orden habitual, hacemos que el segundo bit sea el más significativo. Eso significa que terminar en un solo bit es idéntico a agregarle un cero, lo que significa que no tenemos que agregarle el cero.

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.

No sé nada sobre CJam, pero ¿por qué necesitas invertir cada par? ¿No puedes convertirlos directamente desde binario?
Value Ink

@ KevinLau-notKenny Invertir cada par evita agregar ceros para obtener una longitud uniforme. En los pares invertidos, tendría que anteponer ceros, lo que no importa para la conversión de base.
Dennis

¡Buen truco! Probablemente habría ahorrado una tonelada de bytes en mi propia solución si hubiera pensado en ese truco
Value Ink

6

Python 2, 109103 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))

Pruébalo en Ideone .


4

Ruby, 59 bytes

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

Un programa completo Corre con la -pbandera.


¿cómo es que ... no entiendo
Value Ink

4

Python 3, 130 bytes.

Guardado 2 bytes gracias a vaultah.
Guardado 6 bytes gracias a Kevin Lau, no a Kenny.

Odio lo difícil que es convertir a binario 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))

Casos de prueba:

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

Parece que tienes 1 par de paréntesis extra después del segundo''.join
vaultah

@vaultah Vaya, sí, tienes razón.
Morgan Thrapp

Use en su 'ACGT'[int(z+y,2)]lugar, convirtiendo directamente de binario en lugar de usar su cadena más larga y convirtiendo desde la base 10. Además, ¿no está seguro de cuánta diferencia haría, pero mire usar en re.sublugar de su truco de unión desordenado?
Value Ink

@ KevinLau-notKenny Oooo, gracias. Olvidé que puedes especificar una base con int. Lo investigaré re.sub, gracias por la sugerencia.
Morgan Thrapp

Buen enfoque, se me ocurrió (casi) exactamente el mismo código sin haber mirado el suyo. :)
Byte Commander

3

Rubí, 80 bytes.

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

Tan sencillo como es el problema, es posible exprimir muchos más bytes de esto :)
xsot

3

Mathematica, 108 bytes

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

Toma una cadena como entrada y genera una lista de bases.


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

¡Bienvenido a Programming Puzzles & Code Golf! En caso de que se esté preguntando sobre el voto negativo, esto es lo que sucedió .
Dennis

2

Pyth, 25 bytes

sm@"ACGT"id2Pc.B*4sjkCMQ2

Pruébalo aquí!

Explicación

Excavando el truco de relleno de la respuesta de Martins CJam .

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

                     CMQ # Asigna cada carácter de Q a su código de caracteres
                  sjk # Únete en una cadena y convierte a un entero
              .B * 4 # Mulitply con 4 y convertir a binario
             c 2 # dividir en pares
            P # Descarta el último par
 m # Mapa de cada par d
         id2 # Convertir par de binario a decimal
  @ "ACGT" # Use el resultado ^ como índice en una cadena de búsqueda
s # Únete a la lista resultante en la cadena


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

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

Nota

  • La entrada es una matriz de caracteres (que debe contar como una forma de Cadena), el parámetro es de tipo int[]porque ese es un byte guardado char[].

Salida

Input:  codegolf
Output: GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA

Input:  .
Output: GTG

Input:  }
Output: TTGG

Input:  wow
Output: TGATAGTTGTGCTG

Input:  programming puzzles
Output: GTGTCAGAGTTGAAGGCCGTTCCGCAGTGCATTTGGCTCGTCTGGTGTCTACTAGCCTGCGAGAGGAGTTACTTTGGATCCTTGACTTGT

2

MATL , 21 bytes

'CGTA'joV4Y2HZa2e!XB)

Pruébalo en línea!

Explicación

'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 bytes

sm@"AGCT"i_d2c.BsjkCMQ2

Pruébalo en línea!

Explicación

Tomando prestado el truco de la respuesta 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

1

Groovy, 114 bytes

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

Explicación:

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

¡Gran respuesta! ¿Puedes agregar una explicación por favor?
NoOneIsHere

La primera versión no funcionaba, porque olvidé agregar 0. Lo arreglé y bajé con bytes por cierto.
Krzysztof Atłasik

1

Julia 0.4, 77 bytes

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

Esta función anónima toma una matriz de caracteres como entrada y devuelve una cadena.

Pruébalo en línea!


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

Sin 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'

Salida

f('codegolf')
'GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA'

@DrGreenEggsandHamDJ Tengo la g(...)función allí dos veces, así que creo que reemplazarla con la joinagregaría 2 bytes.
Deustice

Ah, me perdí eso. ¡Mi error!
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 parte ES7 es la for(c of s)parte.

Versión ES6, 107105 bytes

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

Código sin 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``
}

Este es mi primer intento de jugar golf en PPCG, no dude en corregirme si algo está mal.

Gracias @AlexA por la pequeña mejora.


1
Este es un buen primer golf! Dado que la función no es recursiva y no necesitamos que se nombren las funciones, debería poder eliminarlas f=, ahorrando 2 bytes. :)
Alex A.

1

J, 52 bytes

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

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


1

Lisp común (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")))))))))

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

Uso:

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

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

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

Pruébalo en Ideone .


0

Perl 6, 57 + 1 ( -pbandera) = 58 bytes

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

Explicación paso a paso:

-pEl indicador hace que el intérprete de Perl 6 ejecute el código línea por línea, coloque la línea actual $_y, al final, vuelva a colocarlo $_.

.ords- Si no hay nada antes de un período, se llama a un método $_. ordsEl método devuelve una lista de puntos de código en una cadena.

[~]- []es un operador de reducción, que almacena su operador de reducción entre paréntesis. En este caso, es ~, que es un operador de concatenación de cadenas. Por ejemplo, [~] 1, 2, 3es equivalente a1 ~ 2 ~ 3 .

+convierte su argumento en un número, necesario porque el basemétodo solo se define para enteros.

.base(2) - convierte un entero en una cadena en la base 2

$_=- asigna el resultado a $_.

s:g/..?/{...}/- esta es una expresión regular que reemplaza cualquier :ginstancia (de modo global) de expresiones regulares ..?(uno o dos caracteres). El segundo argumento es un patrón de reemplazo, que en este caso en el código (en Perl 6, las llaves en cadenas y los patrones de reemplazo se ejecutan como código).

$/ - una variable de coincidencia de expresiones regulares

.flip- invierte una cadena. Se convierte implícitamente $/(un objeto de coincidencia de expresiones regulares) en una cadena. Esto se debe a que un solo carácter 1debe expandirse 10, en lugar de01 . Debido a ese cambio, el orden de los elementos en la matriz tiene G y C invertidos.

:2(...) - analiza una cadena de base 2 en un entero.

<A G C T> - conjunto de cuatro elementos.

...[...] - operador de acceso a la matriz.

Qué significa eso? El programa obtiene una lista de todos los puntos de código en una cadena, los concatena juntos, los convierte en base 2. Luego, reemplaza todas las instancias de dos o un carácter en una de las letras A, G, C, T dependiendo de la representación invertida de un número en binario


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" es una lista de átomos. Interpolarlos en cadenas ( <a>) mientras se pliega sobre la lista, uniéndolos en una nueva cadena. Analiza el número con++dem para devolverlo a un átomo.

Multiplique el número por (longitud en bits + 1)% 2 para rellenarlo. Use ++rippara desarmar cada par de dos bytes del átomo en una lista, mapee sobre la lista y use el número como índice en la cadena "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"
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.