Texto de golfe no DNA

26

Text to DNA golf

Desafio

Converter entrada em uma saída de DNA.

Algoritmo

  • Converter texto em pontos de código ASCII (por exemplo, codegolf-> [99, 111, 100, 101, 103, 111, 108, 102])
  • Coloque os códigos ASCII juntos (por exemplo 99111100101103111108102)
  • Converter em binário (por exemplo 10100111111001101001011010001000011001101011011110000110010111111011000000110)
  • Coloque 0s no final para formar um número par de caracteres (por exemplo 101001111110011010010110100010000110011010110111100001100101111110110000001100)
  • Substitua 00por A, 01por C, 10com Ge 11com T(por exemplo GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA)
  • Saída

Casos de teste

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

Especificações

  • Isso é
  • Seu programa deve aceitar espaços na entrada.
  • Seu programa deve funcionar codegolf.
Ninguém está aqui
fonte
2
Eu acho que você deve adicionar um caso de teste que exija o comportamento de preenchimento. A escolha preguiçosa seria a }que eu acredito que se torna TTGG.
FryAmTheEggman
3
Qual o tamanho da contribuição que precisamos apoiar? 99111100101103111108102por exemplo, é maior que o uint-64, portanto, alguns idiomas podem ter dificuldades com conversões maiores.
AdmBorkBork 2/16
4
Não é assim que você codifica os códigos ASCII, se quiser decodificá-los novamente.
User253751
@immibis eu sei.
NoOneIsHere

Respostas:

17

Geléia , 15 13 bytes

OVBs2UḄị“GCTA

Experimente online! ou verifique todos os casos de teste .

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

CJam, 24 23 bytes

Agradecemos a Dennis por economizar 1 byte de uma maneira realmente inteligente. :)

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

Teste aqui.

Explicação

Implementação muito direta da especificação. A única parte interessante é o preenchimento de um número par de zeros (que na verdade era idéia de Dennis). Em vez de tratar os dígitos de cada par na ordem usual, tornamos o segundo bit o mais significativo. Isso significa que terminar em um único bit é idêntico a acrescentar um zero a ele, o que significa que não precisamos acrescentar o zero.

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
fonte
Não sei nada sobre CJam, mas por que você precisa reverter cada par? Você não pode convertê-los diretamente de volta do binário?
Value Ink
@ KevinLau-notKenny A inversão de cada par evita acrescentar zeros para obter um comprimento uniforme. Nos pares invertidos, você teria que acrescentar zeros, o que não importa para a conversão de base.
Dennis
Bom truque! Provavelmente teria salvo uma tonelada de bytes em minha própria solução se eu tinha pensado sobre esse truque
Valor 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 em Ideone .

Dennis
fonte
4

Ruby, 59 bytes

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

Um programa completo. Corra com a -pbandeira.

xsot
fonte
como você mesmo ... eu não entendo
Valor Ink
4

Python 3, 130 bytes.

Economizou 2 bytes graças a vaultah.
Economizou 6 bytes graças a Kevin Lau - não a Kenny.

Eu odeio o quão difícil é converter para binário em 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 teste:

assert f('codegolf') == 'GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA'
assert f('ppcg') == 'GGCTAATTGTCGCACTT'
Morgan Thrapp
fonte
Parece que você tem 1 par extra de colchetes após o segundo''.join
vaultah 2/16/16
@vaultah Opa, sim, você está certo.
Morgan Thrapp
Em 'ACGT'[int(z+y,2)]vez disso, use a conversão diretamente do binário em vez de usar sua string mais longa e a partir da base 10. Além disso, não tenha certeza de quanta diferença isso faria, mas observe o uso em re.subvez do seu truque de junção bagunçado?
Value Ink
@ KevinLau-notKenny Oooo, obrigado. Esqueci que você pode especificar uma base com int. Vou dar uma olhada re.sub, obrigado pela sugestão.
Morgan Thrapp
Boa abordagem, criei (quase) exatamente o mesmo código sem ter olhado para o seu. :)
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]}}
Value Ink
fonte
Tão simples como o problema é que é possível espremer muito mais bytes fora deste :)
xsot
3

Mathematica, 108 bytes

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

Pega uma string como entrada e gera uma lista de bases.

LegionMammal978
fonte
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
fonte
Bem-vindo à programação de quebra-cabeças e código de golfe! Caso você esteja se perguntando sobre o voto negativo, foi isso que aconteceu .
Dennis #
2

Pitão, 25 bytes

sm@"ACGT"id2Pc.B*4sjkCMQ2

Experimente aqui!

Explicação

Burrowing o truque de preenchimento da resposta Martins CJam .

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

                     CMQ # Mapeie cada caractere de Q para seu código de caractere
                  sjk # Junte-se a uma string e converta-a em um número inteiro
              .B * 4 # Multiplique por 4 e converta em binário
             c 2 # Dividido em pares
            P # Descartar o último par
 m # Mapear cada par d
         id2 # Converte o par de binário em decimal
  @ "ACGT" # Use o resultado ^ como índice em uma string de pesquisa
s # Ingressar na lista resultante na string
Denker
fonte
2

05AB1E , 23 bytes

Código:

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

Usa a codificação CP-1252 . Experimente online! .

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

Nota

  • Input é uma matriz de caracteres (que deve contar como uma forma de String), o parâmetro é do tipo int[]porque esse é um byte salvo char[].

Saída

Input:  codegolf
Output: GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA

Input:  .
Output: GTG

Input:  }
Output: TTGG

Input:  wow
Output: TGATAGTTGTGCTG

Input:  programming puzzles
Output: GTGTCAGAGTTGAAGGCCGTTCCGCAGTGCATTTGGCTCGTCTGGTGTCTACTAGCCTGCGAGAGGAGTTACTTTGGATCCTTGACTTGT
Marv
fonte
2

MATL , 21 bytes

'CGTA'joV4Y2HZa2e!XB)

Experimente online!

Explicação

'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
fonte
1

Pitão , 23 bytes

sm@"AGCT"i_d2c.BsjkCMQ2

Experimente online!

Explicação

Tomando emprestado o truque da resposta 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
Freira Furada
fonte
1

Groovy, 114 bytes

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

Explicação:

{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
fonte
Ótima resposta! Você pode, por favor, adicionar uma explicação, por favor?
NoOneIsHere 3/16
A primeira versão não estava funcionando, porque esqueci de acrescentar 0. Corrigi-a e desativei com bytes btw.
Krzysztof Atłasik
1

Julia 0.4, 77 bytes

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

Essa função anônima recebe uma matriz de caracteres como entrada e retorna uma string.

Experimente online!

Dennis
fonte
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'

Saída

f('codegolf')
'GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA'
justiça
fonte
@DrGreenEggsandHamDJ Eu tenho a g(...)função lá duas vezes, então acredito que substituí-lo pelo joinadicionaria 2 bytes?
03 de
Ah, eu senti falta disso. Minha culpa!
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``

A parte ES7 é a for(c of s)parte.

Versão ES6, 107 105 bytes

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

Código ungolfed

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

Esta é a minha primeira tentativa de jogar golfe no PPCG, sinta-se à vontade para me corrigir se algo estiver errado.

Obrigado @AlexA pela pequena melhoria.

BusyBeingDelicious
fonte
1
Este é um bom primeiro golfe! Como a função não é recursiva e não exigimos que as funções sejam nomeadas, você poderá removê-lo f=, economizando 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

ljeabmreosn
fonte
1

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

Uso:

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

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

Perl, 155 148 137 + 1 ( -psinalizador) = 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 em Ideone .

Denis Ibaev
fonte
0

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

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

Explicação passo a passo:

-pflag faz com que o intérprete Perl 6 execute o código linha por linha, coloque a linha atual $_e, no final, coloque-o de volta $_.

.ords- Se não houver nada antes de um período, é chamado um método $_. ordsO método retorna a lista de pontos de código em uma sequência.

[~]- []é um operador de redução, que armazena seu operador de redução entre parênteses. Nesse caso, ~é um operador de concatenação de cadeias. Por exemplo, [~] 1, 2, 3é equivalente a 1 ~ 2 ~ 3.

+converte seu argumento em um número, necessário porque o basemétodo é definido apenas para números inteiros.

.base(2) - converte um número inteiro em uma string na base 2

$_=- atribui o resultado a $_.

s:g/..?/{...}/- esta é uma expressão regular que substitui qualquer :ginstância ..?( modo global) de regex (um ou dois caracteres). O segundo argumento é um padrão de substituição, que nesse caso no código (no Perl 6, colchetes nas strings e padrões de substituição são executados como código).

$/ - uma variável de correspondência de regex

.flip- inverte uma string. Ele converte implicitamente $/(um objeto de correspondência de regex) em uma string. Isso ocorre porque um único caractere 1deve ser expandido para 10, ao contrário de 01. Por causa dessa inversão, a ordem dos elementos na matriz tem G e C invertidos.

:2(...) - analisa uma string de base 2 em um número inteiro.

<A G C T> - matriz de quatro elementos.

...[...] - operador de acesso ao array.

O que isso significa? O programa obtém a lista de todos os pontos de código em uma string, concatena-os juntos, converte-os na base 2. Em seguida, substitui todas as instâncias de dois ou um caractere em uma das letras A, G, C, T, dependendo da representação invertida de um número em binário.

Konrad Borowski
fonte
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" é uma lista de átomos. Interpole-os em strings ( <a>) enquanto dobra a lista, juntando-os em uma nova string. Analise o número com ++dempara retornar ao átomo.

Multiplique o número por (comprimento bit a bit + 1)% 2 para preenchê-lo. Use ++rippara desmontar cada par de dois bytes do átomo em uma lista, mapeie sobre a lista e use o número como índice na cadeia "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
fonte