Palindromes Watson-Crick

31

Problème

Créez une fonction qui peut déterminer si une chaîne d'ADN arbitraire est un palindrome Watson-Crick. La fonction prendra une chaîne d'ADN et affichera une vraie valeur si la chaîne est un palindrome Watson-Crick et une fausse valeur si ce n'est pas le cas. (Vrai et faux peuvent également être représentés par 1 et 0, respectivement.)

La chaîne d'ADN peut être en majuscules ou en minuscules selon votre préférence.

De plus, la chaîne d'ADN ne sera pas vide.

Explication

Une chaîne d'ADN est un palindrome de Watson-Crick lorsque le complément de son revers est égal à lui-même.

Étant donné une chaîne d'ADN, inversez-la d'abord, puis complétez chaque caractère en fonction des bases d'ADN (A ↔ T et C ↔ G). Si la chaîne d'origine est égale à la chaîne inversée complémentée, il s'agit d'un palindrome Watson-Crick.

Pour en savoir plus, consultez cette question . C'est un défi différent où vous devez trouver la plus longue sous-chaîne d'une chaîne d'ADN où cette sous-chaîne est un palindrome Watson-Crick.

Objectif

C'est le code-golf et le code le plus court l'emporte.

Cas de test

Le format est <input> = <output>.

ATCGCGAT = true
AGT = false
GTGACGTCAC = true
GCAGTGA = false
GCGC = true
AACTGCGTTTAC = false
ACTG = false
milles
la source
En relation.
Martin Ender
3
Quelqu'un devrait écrire un programme en ADN # qui est également un palindrome Watson-Crick. : D (peut-être pas possible)
mbomb007
Ou, si vous voulez, "un mot est un palindrome de Watson – Crick s'il a l'ordre 2 dans le groupe libre sur 2 générateurs" (ou sur n générateurs!).
wchargin
(Je suppose que techniquement, c'est "commander au plus 2".)
wchargin
1
@AndrasDeak Selon le livre de Watsons, Franklin était apparemment surtout une épine dans leur côté. Elle a refusé à plusieurs reprises de remettre des rayons X montrant l'hélice (si je me souviens bien), parce qu'elle refusait de le croire. Cela vaut la peine d'être lu si vous êtes intéressé par la découverte en tout cas.
Obsidian Phoenix

Réponses:

27

05AB1E , 10 7 octets

Code:

Â'š×‡Q

Explication:

Pour vérifier si une chaîne est un palindrome, il suffit de vérifier l'entrée avec l'entrée, avec atswapped et cgswapped puis de l'inverser. Voilà donc ce que nous allons faire. Nous poussons l'entrée et l'entrée inversée en utilisant Â(bifurquer). Vient maintenant une partie délicate. 'š×est la version compressée pour creating. Si nous l'inversons, vous pouvez voir pourquoi c'est dans le code:

CreATinG
|  ||  |
GniTAerC

Cela sera utilisé pour translittérer l'entrée inversée. La translittération se fait avec . Après cela, nous vérifions simplement si l'entrée et l'entrée translittérée sont e Quales et imprimons cette valeur. Voici donc à quoi ressemble la pile pour l'entrée actg:

          # ["actg", "gtca"]
 'š×       # ["actg", "gtca", "creating"]
    Â      # ["actg", "gtca", "creating", "gnitaerc"]
     ‡     # ["actg", "cagt"]
      Q    # [0]

Ce qui peut également être vu avec le drapeau de débogage ( essayez-le ici ).

Utilise le codage CP-1252 . Essayez-le en ligne! .

Adnan
la source
4
Très, euh, créatif ...
Toby Speight
2
Cette langue a des fonctionnalités très soignées
miles
18

Gelée , 9 octets

O%8µ+U5ḍP

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

Comment ça marche

O%8µ+U5ḍP  Main link. Argument: S (string)

O          Compute the code points of all characters.
 %8        Compute the residues of division by 8.
           This maps 'ACGT' to [1, 3, 7, 4].
   µ       Begin a new, monadic link. Argument: A (array of residues)
    +U     Add A and A reversed.
      5ḍ   Test the sums for divisibility by 5.
           Of the sums of all pairs of integers in [1, 3, 7, 4], only 1 + 4 = 5
           and 3 + 7 = 10 are divisible by 5, thus identifying the proper pairings.
        P  Take the product of the resulting Booleans.
Dennis
la source
4
Je pense que Python est assez proche de rivaliser avec cette réponse! Comparer les neuf premiers octets de ma réponse: lambda s:. C'est presque la solution complète!
orlp
Attendez, la partie "Comment ça marche" n'explique pas vraiment comment ça marche ... Pourquoi des résidus de 8 et des sommes de 5 ?? Où sont complétées les lettres?
ZeroOne
@ZeroOne J'ai clarifié cette partie.
Dennis
Oh wow! C'est sacrément intelligent. :) Merci!
ZeroOne
12

Python 2, 56 45 44 octets

lambda s:s==s[::-1].translate("_T_GA__C"*32)
orlp
la source
lambda s:s==s[::-1].translate("TCG_A"*99)fonctionne en Python 3
Alex Varga
8

Perl, 27 octets

Comprend +2 pour -lp

Donnez une entrée sur STDIN, imprime 1 ou rien:

dnapalin.pl <<< ATCGCGAT

dnapalin.pl:

#!/usr/bin/perl -lp
$_=y/ATCG/TAGC/r=~reverse

Remplacer $_=par $_+=pour obtenir 0au lieu de vide pour le faux cas

Ton Hospel
la source
7

Rétine , 34 33 octets

$
;$_
T`ACGT`Ro`;.+
+`(.);\1
;
^;

Essayez-le en ligne! (Légèrement modifié pour exécuter tous les cas de test en même temps.)

Explication

$
;$_

Dupliquez l'entrée en faisant correspondre la fin de la chaîne et en insérant a ;suivi de l'entrée entière.

T`ACGT`Ro`;.+

Faites correspondre uniquement la seconde moitié de l'entrée avec ;.+et effectuez la substitution des paires avec une translittération. Quant à l'ensemble cible Ro: fait oréférence à l' autre ensemble, qui oest remplacé par ACGT. Mais Rinverse cet ensemble, donc les deux ensembles sont en fait:

ACGT
TGCA

Si l'entrée est un palindrome d'ADN, nous aurons maintenant l'entrée suivie de son inverse (séparés par ;).

+`(.);\1
;

À plusieurs reprises ( +), supprimez une paire de caractères identiques autour du ;. Cela se poursuivra jusqu'à ce qu'il ne ;reste que le ou jusqu'à ce que les deux caractères autour du ;ne soient plus identiques, ce qui signifierait que les chaînes ne sont pas l'inverse l'une de l'autre.

^;

Vérifiez si le premier caractère est ;et imprimez 0ou en 1conséquence.

Martin Ender
la source
6

JavaScript (ES6), 59 octets

f=s=>!s||/^(A.*T|C.*G|G.*C|T.*A)$/.test(s)&f(s.slice(1,-1))

Le mieux que je pouvais faire sans utiliser Regexp était de 62 octets:

f=s=>!s||parseInt(s[0]+s.slice(-1),33)%32%7<1&f(s.slice(1,-1))
Neil
la source
5

Rubis, 35

J'ai essayé d'autres moyens, mais le plus évident était le plus court:

->s{s.tr('ACGT','TGCA').reverse==s}

dans le programme de test

f=->s{s.tr('ACGT','TGCA').reverse==s}

puts f['ATCGCGAT']
puts f['AGT']
puts f['GTGACGTCAC']
puts f['GCAGTGA']
puts f['GCGC']
puts f['AACTGCGTTTAC'] 
Level River St
la source
2
->s{s.==s.reverse.tr'ACGT','TGCA'}est un octet plus court
Mitch Schwartz
@MitchSchwartz wow, cela fonctionne, mais je ne sais pas à quoi cela .sert en premier . Le code me semble plus juste sans lui, mais il est nécessaire pour le faire fonctionner. Est-ce documenté quelque part?
Level River St
Êtes-vous sûr de ne pas vouloir le découvrir par vous-même?
Mitch Schwartz
@MitchSchwartz hahaha j'ai déjà essayé. Je trouve les exigences de Ruby pour les espaces très idiosyncrasiques. Des exigences étranges pour les périodes sont un tout autre problème. J'ai plusieurs théories mais toutes peuvent être fausses. Je soupçonne que cela peut avoir quelque chose à voir avec le traitement ==comme une méthode plutôt qu'un opérateur, mais la recherche par symboles est impossible.
Level River St
Vous vous en doutez bien. :) C'est juste un ancien appel de méthode.
Mitch Schwartz
5

Haskell, 48 45 octets

(==)=<<reverse.map((cycle"TCG_A"!!).fromEnum)

Exemple d'utilisation: (==)=<<reverse.map((cycle"_T_GA__C"!!).fromEnum) $ "ATCGCGAT"-> True.

Une version sans point est

f x = reverse (map h x) == x           -- map h to x, reverse and compare to x
h c = cycle "TCG_A" !! fromEnum c      -- take the ascii-value of c and take the
                                       -- char at this position of string
                                       -- "TCG_ATCG_ATCG_ATCG_A..."

Edit: @Mathias Dolidon a enregistré 3 octets. Merci!

nimi
la source
Fonctionne cycle "TCG_A" aussi avec . :)
Mathias Dolidon
4

Rétine, 52 octets

^G(.*)C$
$1
^A(.*)T$
$1
^T(.*)A$
$1
}`^C(.*)G$
$1
^$
CalculatriceFeline
la source
4

Julia, 47 38 octets

s->((x=map(Int,s)%8)+reverse(x))%50

Il s'agit d'une fonction anonyme qui accepte un Chartableau et renvoie un booléen. Pour l'appeler, affectez-le à une variable.

Cela utilise l'algorithme de Dennis, qui est plus court que la solution naïve. Nous obtenons le reste de chaque point de code divisé par 8, ajoutons-le à lui-même inversé, obtenons les restes de la division par 5 et vérifions si tous sont 0. La dernière étape est accomplie en utilisant la version infixe de issubset, qui convertit les deux arguments en Setavant de vérifier. Cela signifie que [0,0,0]est déclaré un sous-ensemble de 0, depuis Set([0,0,0]) == Set(0). C'est plus court qu'une vérification explicite contre 0.

Essayez-le en ligne!

9 octets enregistrés grâce à Dennis!

Alex A.
la source
4

Jolf, 15 octets

Essayez le!

=~A_iγ"AGCT"_γi

Explication:

   _i            Reverse the input
 ~A_iγ"AGCT"_γ   DNA swap the reversed input
=~A_iγ"AGCT"_γi  Check if the new string is the same as the original input
gonfle
la source
3

Jolf, 16 octets

Essayez-le ici!

pe+i~Aiγ"GATC"_γ

Explication

pe+i~Aiγ"GATC"_γ
    ~Aiγ"GATC"_γ  perform DNA transformation
  +i              i + (^)
pe                is a palindrome
Conor O'Brien
la source
3

En fait, 19 octets

O`8@%`M;RZ`5@Σ%Y`Mπ

Cela utilise l'algorithme de Dennis .

Essayez-le en ligne!

Explication:

O`8@%`M;RZ`5@Σ%Y`Mπ
O                    push an array containing the Unicode code points of the input
 `8@%`M              modulo each code point by 8
       ;RZ           zip with reverse
          `5@Σ%Y`M   test sum for divisibility by 5
                  π  product
Mego
la source
3

Oracle SQL 11.2, 68 octets

SELECT DECODE(TRANSLATE(REVERSE(:1),'ATCG','TAGC'),:1,1,0)FROM DUAL; 
Jeto
la source
2
Avec SQL comme ça, je suis convaincu que vous devez avoir écrit des rapports pour certains de mes projets avant ...
corsiKa
3

Julia 0,4, 22 octets

s->s$reverse(s)⊆""

La chaîne contient les caractères de contrôle EOT (4) et NAK (21). L'entrée doit être sous la forme d'un tableau de caractères.

Cette approche XOR les caractères de l'entrée avec les caractères correspondants dans l'entrée inversée. Pour les appariements valides, cela donne les caractères EOT ou NAK. Le test d'inclusion dans la chaîne de ces caractères produit le booléen souhaité.

Essayez-le en ligne!

Dennis
la source
3

C, 71

r,e;f(char*s){for(r=0,e=strlen(s)+1;*s;s++)r|=*s*s[e-=2]%5^2;return!r;}

2 octets enregistrés par Dennis. 2 octets supplémentaires enregistrés en s'adaptant aux entrées minuscules: constantes 37et 21sont révisés en 5et 2.

C, 75

i,j;f(char*s){for(i=j=0;s[i];i++)j|=s[i]*s[strlen(s)-i-1]%37!=21;return!j;}

Un octet enregistré: parenthèses éliminées en prenant le produit des deux codes ASCII mod 37. Les paires valides valent jusqu'à 21. Suppose une entrée en majuscules.

C, 76

i,j;f(char*s){for(i=j=0;s[i];i++)j|=(s[i]+s[strlen(s)-i-1])%11!=6;return!j;}

Utilise le fait que les codes ASCII des paires valides totalisent 138 ou 149. Lorsqu'ils sont pris en mod 11, ce sont les seules paires qui totalisent 6. Suppose une entrée en majuscule.

programme non testé

i,j;

f(char *s){
   for(i=j=0;s[i];i++)                  //initialize i and j to 0; iterate i through the string
     j|=(s[i]+s[strlen(s)-i-1])%11!=6;  //add characters at i from each end of string, take result mod 11. If not 6, set j to 1
return!j;}                              //return not j (true if mismatch NOT detected.)

main(){
  printf("%d\n", f("ATCGCGAT"));
  printf("%d\n", f("AGT"));
  printf("%d\n", f("GTGACGTCAC"));
  printf("%d\n", f("GCAGTGA"));
  printf("%d\n", f("GCGC"));
  printf("%d\n", f("AACTGCGTTTAC"));
} 
Level River St
la source
1
r,e;f(char*s){for(r=0,e=strlen(s)+1;*s;s++)r|=*s*s[e-=2]%37^21;return!r;}enregistre quelques octets.
Dennis
@Dennis merci, je n'étais vraiment pas d'humeur à modifier les pointeurs, mais ça m'a fait un octet! Je l' ai vu !=> ^moi - même. J'ai réduit encore 2 en changeant en entrée minuscule: les deux nombres magiques sont maintenant à un seul chiffre.
Level River St
3

Facteur , 72 octets

Malheureusement, regex ne peut pas m'aider ici.

[ dup reverse [ { { 67 71 } { 65 84 } { 71 67 } { 84 65 } } at ] map = ]

Inverser, table de recherche, comparer égal.

chat
la source
Wow, c'est beaucoup d'espace blanc !!! Est-ce tout nécessaire? Un lien vers la page d'accueil de la langue serait également utile.
Level River St
@LevelRiverSt Malheureusement, chaque élément est nécessaire. Je vais ajouter un lien vers l'en-tête.
cat
3

Bash + coreutils, 43 32 octets

[ `tr ATCG TAGC<<<$1|rev` = $1 ]

Tests:

for i in ATCGCGAT AGT GTGACGTCAC GCAGTGA GCGC AACTGCGTTTAC; do ./78410.sh $i && echo $i = true || echo $i = false; done
ATCGCGAT = true
AGT = false
GTGACGTCAC = true
GCAGTGA = false
GCGC = true
AACTGCGTTTAC = false
Toby Speight
la source
3

J - 21 octets

0=[:+/5|[:(+|.)8|3&u:

Basé sur la méthode de Dennis

Usage

   f =: 0=[:+/5|[:(+|.)8|3&u:
   f 'ATCGCGAT'
1
   f 'AGT'
0
   f 'GTGACGTCAC'
1
   f 'GCAGTGA'
0
   f 'GCGC'
1
   f 'AACTGCGTTTAC'
0
   f 'ACTG'
0

Explication

0=[:+/5|[:(+|.)8|3&u:
                 3&u:    - Convert from char to int
               8|        - Residues from division by 8 for each
            |.           - Reverse the list
           +             - Add from the list and its reverse element-wise
        [:               - Cap, compose function
      5|                 - Residues from division by 5 for each
    +/                   - Fold right using addition to create a sum
  [:                     - Cap, compose function
0=                       - Test the sum for equality to zero
milles
la source
3

Labyrinthe , 42 octets

_8
,%
;
"}{{+_5
"=    %_!
 = """{
 ;"{" )!

Se termine par une erreur de division par zéro (message d'erreur sur STDERR).

Essayez-le en ligne!

La disposition semble vraiment inefficace, mais je ne vois tout simplement pas de moyen de jouer au golf en ce moment.

Explication

Cette solution est basée sur l'astuce arithmétique de Dennis: prenez tous les codes de caractères modulo 8, ajoutez une paire des deux extrémités et assurez-vous qu'elle est divisible par 5.

Primaire labyrinthe:

  • Labyrinth possède deux piles d'entiers de précision arbitraire, principale et auxiliaire (iliaire), qui sont initialement remplis d'une quantité infinie (implicite) de zéros.
  • Le code source ressemble à un labyrinthe, où le pointeur d'instruction (IP) suit les couloirs quand il le peut (même dans les coins). Le code commence au premier caractère valide dans l'ordre de lecture, c'est-à-dire dans le coin supérieur gauche dans ce cas. Lorsque l'IP arrive à n'importe quelle forme de jonction (c'est-à-dire plusieurs cellules adjacentes en plus de celle dont elle est issue), elle choisira une direction basée sur le haut de la pile principale. Les règles de base sont les suivantes: tourner à gauche lorsque négatif, continuer à avancer à zéro, tourner à droite lorsqu'il est positif. Et lorsque l'un d'eux n'est pas possible parce qu'il y a un mur, l'IP prendra la direction opposée. L'IP se retourne également en cas d'impasse.
  • Les chiffres sont traités en multipliant le haut de la pile principale par 10, puis en ajoutant le chiffre.

Le code commence par une petite boucle 2x2, dans le sens horaire, qui lit tous les modules d'entrée 8:

_   Push a 0.
8   Turn into 8.
%   Modulo. The last three commands do nothing on the first iteration
    and will take the last character code modulo 8 on further iterations.
,   Read a character from STDIN or -1 at EOF. At EOF we will leave loop.

;Jette maintenant le -1. Nous entrons dans une autre boucle dans le sens des aiguilles d'une montre qui déplace le haut de la pile principale (c'est-à-dire le dernier caractère) vers le bas:

"   No-op, does nothing.
}   Move top of the stack over to aux. If it was at the bottom of the stack
    this will expose a zero underneath and we leave the loop.
=   Swap top of main with top of aux. The effect of the last two commands
    together is to move the second-to-top stack element from main to aux.
"   No-op.

Il y a maintenant un petit bit linéaire:

{{  Pull two characters from aux to main, i.e. the first and last (remaining)
    characters of the input (mod 8).
+   Add them.
_5  Push 5.
%   Modulo.

L'IP est maintenant à une jonction qui agit comme une branche pour tester la divisibilité par 5. Si le résultat du modulo est non nul, nous savons que l'entrée n'est pas un palindrome Watson-Crick et nous tournons vers l'est:

_   Push 0.
!   Print it. The IP hits a dead end and turns around.
_   Push 0.
%   Try to take modulo, but division by zero fails and the program terminates.

Sinon, nous devons continuer à vérifier le reste de l'entrée, afin que l'IP continue de se diriger vers le sud. Le {tire sur le bas de l'entrée restante. Si nous avons épuisé l'entrée, ce sera un 0(à partir du bas de aux ), et l'IP continue de se déplacer vers le sud:

)   Increment 0 to 1.
!   Print it. The IP hits a dead end and turns around.
)   Increment 0 to 1.
{   Pull a zero over from aux, IP keeps moving north.
%   Try to take modulo, but division by zero fails and the program terminates.

Sinon, il y a plus de caractères dans la chaîne à vérifier. L'IP se tourne vers l'ouest et se déplace dans la boucle 2x2 suivante (dans le sens des aiguilles d'une montre) qui se compose principalement de no-ops:

"   No-op.
"   No-op.
{   Pull one value over from aux. If it's the bottom of aux, this will be
    zero and the IP will leave the loop eastward.
"   No-op.

Après cette boucle, nous avons à nouveau l'entrée sur la pile principale, à l'exception de son premier et dernier caractère et avec un zéro en haut. Le ;jette le 0puis =échange les sommets des piles, mais ceci est juste pour annuler le premier =de la boucle, car nous entrons maintenant dans la boucle à un emplacement différent. Rincer et répéter.

Martin Ender
la source
3

sed, 67 61 octets

G;H;:1;s/\(.\)\(.*\n\)/\2\1/;t1;y/ACGT/TGCA/;G;s/^\(.*\)\1$/1/;t;c0

(67 octets)

Tester

for line in ATCGCGAT AGT GTGACGTCAC GCAGTGA GCGC AACTGCGTTTAC ACTG
do echo -n "$line "
    sed 'G;H;:1;s/\(.\)\(.*\n\)/\2\1/;t1;y/ACGT/TGCA/;G;s/^\(.*\)\1$/1/;t;c0' <<<"$line"
done

Sortie

ATCGCGAT 1
AGT 0
GTGACGTCAC 1
GCAGTGA 0
GCGC 1
AACTGCGTTTAC 0
ACTG 0

En utilisant des expressions régulières étendues, le nombre d'octets peut être réduit à 61.

sed -r 'G;H;:1;s/(.)(.*\n)/\2\1/;t1;y/ACGT/TGCA/;G;s/^(.*)\1$/1/;t;c0'
PM 2Ring
la source
Si vous pouvez le faire en 61 octets, alors c'est votre score - il n'y a rien contre NFA ou l'expression rationnelle complète sur ce défi particulier. Certains défis interdisent l'intégralité des regex, mais en général, seul regex-golf interdira les expressions non régulières .
chat
3

C #, 65 octets

bool F(string s)=>s.SequenceEqual(s.Reverse().Select(x=>"GACT"[("GACT".IndexOf(x)+2)%4]));

.NET a parfois des noms de méthode de framework assez longs, ce qui ne fait pas nécessairement le meilleur framework de golf de code. Dans ce cas, les noms de méthode de framework représentent 33 caractères sur 90. :)

Basé sur l'astuce du module ailleurs dans le fil:

bool F(string s)=>s.Zip(s.Reverse(),(a,b)=>a%8+b%8).All(x=>x%5==0);

Pèse désormais 67 caractères, dont 13 sont des noms de méthode.

Une autre optimisation mineure pour raser un énorme 2 caractères:

bool F(string s)=>s.Zip(s.Reverse(),(a,b)=>(a%8+b%8)%5).Sum()<1;

Donc, 65 dont 13 sont des noms de framework.

Edit: Omettre une partie du «passe-partout» limité de la solution et ajouter quelques conditions nous laisse avec l'expression

s.Zip(s.Reverse(),(a,b)=>(a%8+b%8)%5).Sum()

Ce qui donne 0 si et seulement si la chaîne s est une réponse valide. Comme le souligne cat, "bool F (string s) =>" est en fait remplaçable par "s =>" s'il est par ailleurs clair dans le code que l'expression est un Func<string,bool>, c'est-à-dire. mappe une chaîne à un booléen.

robhol
la source
1
Bienvenue chez PPCG, belle première réponse! : D
cat
@cat Merci pour ça! :)
robhol
1
Je ne suis pas vraiment savoir C #, mais si cela est un lambda, vous pouvez laisser son type et lui attribuer, comme des fonctions anonymes sont très bien aussi longtemps qu'ils sont assign capables .
chat
1
Aussi, ne pouvez-vous pas faire à la !s.Zip...place de s.Zip...==0? (Ou ne pouvez-vous pas !entrer en C #?) Même si vous ne pouvez pas le nier booléen, vous pouvez laisser de côté toute sorte d'inversion et indiquer dans votre réponse que cela renvoie <cette chose> pour la falsification et <cet autre déterministe, chose clairement discernable> pour la vérité.
chat
1
@cat: Vous avez raison de supprimer le type. Je pensais que le code devait être directement exécutable, mais faire des hypothèses simples sur l'entrée et la sortie le rend un peu plus facile. Cependant, l'autre chose ne fonctionnera pas - à juste titre, à mon avis, car une opération booléenne n'a aucun moyen logique (teinte de teinte) de s'appliquer à un nombre. Affecter 0 et 1 les valeurs false et true est, après tout, juste une convention.
robhol
2

REXX 37

s='ATCGCGAT';say s=translate(reverse(s),'ATCG','TAGC')
aja
la source
2

R, 101 octets

g=function(x){y=unlist(strsplit(x,""));all(sapply(rev(y),switch,"C"="G","G"="C","A"="T","T"="A")==y)}

Cas de test

g("ATCGCGAT")
[1] TRUE
g("AGT")
[1] FALSE
g("GTGACGTCAC")
[1] TRUE
g("GCAGTGA")
[1] FALSE
g("GCGC")
[1] TRUE
g("AACTGCGTTTAC")
[1] FALSE
g("ACTG")
[1] FALSE
syntonicC
la source
strsplit(x,"")[[1]]est 3 octets plus court que unlist(strsplit(x,""))et, ici, est équivalent puisqu'il xs'agit toujours d'une seule chaîne de caractères.
plannapus
2

Octave, 52 octets

f=@(s) prod(mod((i=mod(toascii(s),8))+flip(i),5)==0)

Suivant l'astuce de Denis ... prenez les valeurs ASCII mod 8, retournez et additionnez; si chaque somme est un multiple de cinq, vous êtes en or.

dcsohl
la source
Ce un des espaces est important? C'est étrange.
chat
Vous pouvez également f=omettre la mission; les fonctions sans nom sont correctes.
chat
1

Clojure / ClojureScript, 49 caractères

#(=(list* %)(map(zipmap"ATCG""TAGC")(reverse %)))

Fonctionne sur les cordes. Si les exigences sont assouplies pour autoriser les listes, je peux retirer (list* )et enregistrer 7 caractères.

MattPutnam
la source
1

R, 70 octets

f=function(x)all(chartr("GCTA","CGAT",y<-strsplit(x,"")[[1]])==rev(y))

Usage:

> f=function(x)all(chartr("GCTA","CGAT",y<-strsplit(x,"")[[1]])==rev(y))
> f("GTGACGTCAC")
[1] TRUE
> f("AACTGCGTTTAC")
[1] FALSE
> f("AGT")
[1] FALSE
> f("ATCGCGAT")
[1] TRUE
planificateur
la source
1

C, 71 octets

Nécessite des codes ASCII pour les caractères appropriés, mais accepte les entrées en majuscules, en minuscules ou en casse mixte.

f(char*s){char*p=s+strlen(s),b=0;for(;*s;b&=6)b|=*--p^*s++^4;return!b;}

Ce code maintient deux pointeurs set ptraverse la chaîne dans des directions opposées. À chaque étape, nous comparons les caractères correspondants, en définissant btrue s'ils ne correspondent pas. La correspondance est basée sur XOR des valeurs de caractères:

'A' ^ 'T' = 10101
'C' ^ 'G' = 00100

'C' ^ 'T' = 10111
'G' ^ 'A' = 00110
'A' ^ 'C' = 00010
'T' ^ 'G' = 10011
 x  ^  x  = 00000

Nous pouvons voir dans le tableau ci-dessus que nous voulons enregistrer le succès xx10xet l'échec pour tout le reste, nous avons donc XOR avec 00100(quatre) et masque avec 00110(six) pour obtenir zéro pour ATou CGet non nul sinon. Enfin, nous retournons vrai si toutes les paires ont accumulé un résultat nul dans b, sinon faux.

Programme de test:

#include <stdio.h>
int main(int argc, char **argv)
{
    while (*++argv)
        printf("%s = %s\n", *argv, f(*argv)?"true":"false");
}
Toby Speight
la source
1

𝔼𝕊𝕄𝕚𝕟, 13 caractères / 17 octets

⟮ïĪ`ACGT”⟯ᴙ≔Ⅰ

Try it here (Firefox only).

Explication

Translittérer l'entrée de ACGTà TGCAet vérifier si la chaîne résultante est un palindrome.

Mama Fun Roll
la source