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.

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

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.

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 .


4

Ruby, 59 bytes

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

Um programa completo. Corra com a -pbandeira.


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'

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

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.


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

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


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

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

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

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

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


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'

@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.


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


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"

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 .


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.


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"
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.