Golf Testo nel DNA


26

Testo per DNA golf

Sfida

Converti input in output DNA.

Algoritmo

  • Converti il ​​testo in punti di codice ASCII (ad es. codegolf-> [99, 111, 100, 101, 103, 111, 108, 102])
  • Stringi insieme i codici ASCII (ad es. 99111100101103111108102)
  • Converti in binario (ad es. 10100111111001101001011010001000011001101011011110000110010111111011000000110)
  • Passa 0alla fine per creare un numero pari di caratteri (ad es. 101001111110011010010110100010000110011010110111100001100101111110110000001100)
  • Sostituisci 00con A, 01con C, 10con Ge 11con T(ad es. GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA)
  • Produzione

Casi test

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

specificazioni

  • Questo è
  • Il tuo programma deve accettare spazi in input.
  • Il tuo programma deve funzionare per codegolf.

2
Penso che dovresti aggiungere un test case che richiede il comportamento di riempimento. La scelta pigra sarebbe quella }che credo diventi TTGG.
FryAmTheEggman,

3
Quanto di input abbiamo bisogno di supportare? 99111100101103111108102per esempio è più grande di uint-64, quindi alcune lingue potrebbero avere difficoltà con conversioni più grandi.
AdmBorkBork,

4
Non è così che si mettono insieme i codici ASCII se si desidera poterli decodificare nuovamente.
user253751

@immibis lo so.
NoOneIsHere

Risposte:


17

Gelatina , 15 13 byte

OVBs2UḄị“GCTA

Provalo online! o verifica tutti i casi di test .

Come funziona

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 byte

Grazie a Dennis per aver salvato 1 byte in modo davvero intelligente. :)

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

Provalo qui.

Spiegazione

Implementazione molto diretta della specifica. L'unico elemento interessante è il riempimento di un numero pari di zeri (che era in realtà l'idea di Dennis). Invece di trattare le cifre in ciascuna coppia nel solito ordine, rendiamo la seconda parte la più significativa. Ciò significa che la fine in un singolo bit è identica all'aggiunta di uno zero, il che significa che non è necessario aggiungere lo 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.

Non so nulla di CJam, ma perché devi invertire ogni coppia? Non riesci a convertirli direttamente dal file binario?
Value Ink

@ KevinLau-notKenny Invertire ogni coppia evita di aggiungere zero per ottenere una lunghezza uniforme. Nelle coppie inverse, dovresti anteporre zero, il che non ha importanza per la conversione di base.
Dennis,

Bel trucco! Probabilmente avrebbe risparmiato una tonnellata di byte sulla mia soluzione se avessi pensato a quel trucco
Value Ink

6

Python 2, 109 103 byte

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

Provalo su Ideone .


4

Rubino, 59 byte

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

Un programma completo. Corri con la -pbandiera.


come hai fatto ... non capisco
Value Ink

4

Python 3, 130 byte.

Salvato 2 byte grazie a vaultah.
6 byte salvati grazie a Kevin Lau, non a Kenny.

Odio quanto sia difficile convertire in binario in 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))

Casi test:

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

Sembra che tu abbia 1 paio di parentesi in più dopo il secondo''.join
vaultah

@vaultah Oops, sì, hai ragione.
Morgan Thrapp,

Usa 'ACGT'[int(z+y,2)]invece, convertendo direttamente dal binario invece di usare la tua stringa più lunga e convertendola dalla base 10. Inoltre, non sei sicuro di quanta differenza farebbe ma guarda usando re.subinvece del tuo disordinato trucco di join?
Value Ink

@ KevinLau-notKenny Oooo, grazie. Ho dimenticato che puoi specificare una base con int. Esaminerò re.sub, grazie per il suggerimento.
Morgan Thrapp,

Bel approccio, ho escogitato (quasi) esattamente lo stesso codice senza aver visto il tuo. :)
Byte Commander,

3

Rubino, 80 byte

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

Per quanto il problema sia semplice, è possibile estrarre molti più byte da questo :)
xsot

3

Mathematica, 108 byte

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

Prende una stringa come input e genera un elenco di basi.


3

Python 3, 126 byte

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

Benvenuto in Programmazione di puzzle e codice golf! Nel caso ti stia chiedendo del downvote, questo è quello che è successo .
Dennis,

2

Pyth, 25 byte

sm@"ACGT"id2Pc.B*4sjkCMQ2

Provalo qui!

Spiegazione

Scavalcare il trucco dell'imbottitura dalla risposta di Martins CJam .

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

                     CMQ # Mappa ogni carattere di Q sul suo codice carattere
                  sjk # Unisci in una stringa e converti in un numero intero
              .B * 4 # Mulitply con 4 e conversione in binario
             c 2 # Dividi in coppie
            P # Scarta l'ultima coppia
 m # Mappa ogni coppia d
         id2 # Converte la coppia da binaria a decimale
  @ "ACGT" # Usa il risultato ^ come indice in una stringa di ricerca
s # Unisci l'elenco risultante in stringa


2

Java, 194 byte

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

  • L'input è un array di caratteri (che dovrebbe essere considerato come una forma di stringa), il parametro è di tipo int[]perché è un byte salvato sopra char[].

Produzione

Input:  codegolf
Output: GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA

Input:  .
Output: GTG

Input:  }
Output: TTGG

Input:  wow
Output: TGATAGTTGTGCTG

Input:  programming puzzles
Output: GTGTCAGAGTTGAAGGCCGTTCCGCAGTGCATTTGGCTCGTCTGGTGTCTACTAGCCTGCGAGAGGAGTTACTTTGGATCCTTGACTTGT

2

MATL , 21 byte

'CGTA'joV4Y2HZa2e!XB)

Provalo online!

Spiegazione

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

sm@"AGCT"i_d2c.BsjkCMQ2

Provalo online!

Spiegazione

Prendendo in prestito il trucco dalla risposta di Jelly di Dennis .

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 byte

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

Spiegazione:

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

Bella risposta! Puoi per favore aggiungere una spiegazione per favore?
NoOneIsHere

La prima versione non funzionava, perché ho dimenticato di aggiungere 0. L'ho riparato e sono andato giù con byte a proposito.
Krzysztof Atłasik,

1

Julia 0.4, 77 byte

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

Questa funzione anonima accetta una matrice di caratteri come input e restituisce una stringa.

Provalo online!


1

Python 2.7, 135 byte

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'

Produzione

f('codegolf')
'GGCTTGCGGCCGGAGACGCGGTCTGACGCCTTGTAAATA'

@DrGreenEggsandHamDJ Ho la g(...)funzione lì due volte, quindi credo che sostituirla con joinaggiungerebbe 2 byte?
deustice

Ah, mi è mancato. Colpa mia!
DJMcMayhem

1

Javascript ES7, 105 103 byte

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

La parte ES7 è la for(c of s)parte.

Versione ES6, 107 105 byte

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

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

Questo è il mio primo tentativo di giocare a golf su PPCG, sentiti libero di correggermi se qualcosa non va.

Grazie @AlexA per il piccolo miglioramento.


1
Questo è un bel primo golf! Dal momento che la funzione non è ricorsiva e non è necessario che le funzioni vengano denominate, quindi dovresti essere in grado di rimuoverlo f=, salvando 2 byte. :)
Alex A.

1

J, 52 byte

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

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


1

Lisp comune (Lispworks), 415 byte

(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 ( -pbandiera) = 138 byte

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

Provalo su Ideone .


0

Perl 6, 57 + 1 ( -pflag) = 58 byte

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

Spiegazione dettagliata:

-pflag fa sì che l'interprete Perl 6 esegua il codice riga per riga, inserisca la riga corrente $_e alla fine lo rimetta da $_.

.ords- Se non c'è nulla prima di un punto, viene chiamato un metodo $_. ordsIl metodo restituisce un elenco di punti di codice in una stringa.

[~]- []è un operatore di riduzione, che memorizza il proprio operatore di riduzione tra parentesi. In questo caso, lo è~ , che è un operatore di concatenazione di stringhe. Ad esempio, [~] 1, 2, 3equivale a 1 ~ 2 ~ 3.

+ converte il suo argomento in un numero, necessario perché base metodo è definito solo per numeri interi.

.base(2) - converte un numero intero in una stringa in base 2

$_= - assegna il risultato a $_ .

s:g/..?/{...}/- questa è un'espressione regolare che sostituisce qualsiasi :gistanza ( , modalità globale) di regex..? (uno o due caratteri). Il secondo argomento è un modello di sostituzione, che in questo caso nel codice (in Perl 6, le parentesi graffe nelle stringhe e i modelli di sostituzione vengono eseguiti come codice).

$/ - una variabile di corrispondenza regex

.flip- inverte una stringa. Converte implicitamente $/(un oggetto match regex) in una stringa. Questo perché un singolo personaggio 1dovrebbe essere espanso 10, al contrario di01 . A causa di tale inversione, l'ordine degli elementi nell'array ha G e C invertiti.

:2(...) - analizza una stringa di base 2 in un numero intero.

<A G C T> - matrice di quattro elementi.

...[...] - operatore di accesso agli array.

Cosa significa? Il programma ottiene l'elenco di tutti i punti di codice in una stringa, li concatena insieme, li converte in base 2. Quindi, sostituisce tutte le istanze di due o un carattere in una delle lettere A, G, C, T a seconda della rappresentazione capovolta di un numero in binario.


0

Hoon , 148 138 byte

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

"abc" è un elenco di atomi. Interpolarli in stringhe ( <a>) mentre si ripiega l'elenco, unendoli in una nuova stringa. Analizza il numero con ++demper riportarlo su un atomo.

Moltiplicare il numero per (lunghezza bit a bit + 1)% 2 per riempirlo. Utilizzare ++ripper smontare ogni coppia di due byte dell'atomo in un elenco, mappare l'elenco e utilizzare il numero come indice nella stringa "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"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.