Palindromy Watsona-Cricka


31

Problem

Utwórz funkcję, która może określić, czy dowolny łańcuch DNA jest palindromem Watsona-Cricka. Funkcja pobierze ciąg DNA i wyświetli wartość prawdziwą, jeśli jest to palindrom Watsona-Cricka, a wartość fałszywą, jeśli nie jest. (Prawda i fałsz mogą być reprezentowane odpowiednio jako 1 i 0).

Łańcuch DNA może być pisany wielkimi lub małymi literami, w zależności od preferencji.

Również łańcuch DNA nie będzie pusty.

Wyjaśnienie

Łańcuch DNA jest palindromem Watsona-Cricka, gdy dopełnienie jego rewersu jest sobie równe.

Biorąc pod uwagę ciąg DNA, najpierw odwróć go, a następnie uzupełnij każdy znak zgodnie z zasadami DNA (A ↔ T i C ↔ G). Jeśli oryginalny ciąg znaków jest równy ciągowi uzupełnionego-odwrotnego, jest to palindrom Watsona-Cricka.

Aby uzyskać więcej informacji, zobacz to pytanie . Jest to inne wyzwanie, w którym musisz znaleźć najdłuższy podciąg łańcucha DNA, w którym podciąg ten jest palindromem Watsona-Cricka.

Cel

To jest gra w golfa i wygrywa najkrótszy kod.

Przypadki testowe

Format to <input> = <output>.

ATCGCGAT = true
AGT = false
GTGACGTCAC = true
GCAGTGA = false
GCGC = true
AACTGCGTTTAC = false
ACTG = false


3
Ktoś powinien napisać program w DNA #, który jest także palindromem Watsona-Cricka. : D (może nie być możliwe)
mbomb007 25.04.16

Lub, jeśli chcesz, „słowo jest palindromem Watsona-Cricka, jeśli ma 2 w wolnej grupie na 2 generatorach” (lub n generatorach!).
wchargin 26.04.16

(
Wydaje

1
@AndrasDeak Według książki Watsons Franklin był najwyraźniej cierniem w ich boku. Wielokrotnie odmawiała przekazania promieni rentgenowskich pokazujących helisę (o ile pamiętam), ponieważ nie chciała w to uwierzyć. Warto przeczytać, jeśli w każdym razie jesteś zainteresowany odkryciem.
Obsidian Phoenix

Odpowiedzi:


27

05AB1E , 10 7 bajtów

Kod:

Â'š×‡Q

Wyjaśnienie:

Aby sprawdzić, czy ciąg znaków jest palindromem, musimy tylko sprawdzić dane wejściowe za pomocą danych wejściowych, z atzamianą i cgzamianą, a następnie odwrócić. Tak właśnie zamierzamy zrobić. Naciskamy wejście, a wejście odwracamy za pomocą Â(bifurcate). Teraz przychodzi trudna część. 'š×jest wersją skompresowaną dla creating. Jeśli to odwrócimy, zobaczysz, dlaczego znajduje się w kodzie:

CreATinG
|  ||  |
GniTAerC

Będzie to wykorzystane do transliteracji odwróconego wejścia. Transliteracja odbywa się za pomocą . Następnie sprawdzamy tylko, czy dane wejściowe i dane transliterowane są prawidłowe, Qi wypisujemy tę wartość. Tak wygląda stos dla danych wejściowych actg:

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

Co można również zobaczyć z flagą debugowania ( wypróbuj tutaj ).

Wykorzystuje kodowanie CP-1252 . Wypróbuj online! .


4
Bardzo, eee, kreatywny ...
Toby Speight

2
Ten język ma kilka bardzo fajnych cech
mile

18

Galaretka , 9 bajtów

O%8µ+U5ḍP

Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe .

Jak to działa

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.

4
Myślę, że Python jest bardzo blisko konkurowania z tą odpowiedzią! Porównaj pierwszych dziewięciu bajtów moją odpowiedź: lambda s:. To prawie pełne rozwiązanie!
24.04.16

Czekaj, część „Jak to działa” tak naprawdę nie wyjaśnia, jak to działa ... Dlaczego reszty 8 i sumy 5 ?? Gdzie są uzupełniane litery?
ZeroOne 27.04.16

@ ZeroOne Wyjaśniłem tę część.
Dennis

Och, wow! To cholernie sprytne. :) Dzięki!
ZeroOne

12

Python 2, 56 45 44 bajtów

lambda s:s==s[::-1].translate("_T_GA__C"*32)

lambda s:s==s[::-1].translate("TCG_A"*99)działa w Pythonie 3
Alex Varga,

8

Perl, 27 bajtów

Obejmuje +2 za -lp

Podaj dane na STDIN, drukuje 1 lub nic:

dnapalin.pl <<< ATCGCGAT

dnapalin.pl:

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

Zamień $_=na, $_+=aby otrzymać 0zamiast pustego dla fałszywej sprawy



7

Siatkówka , 34 33 bajty

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

Wypróbuj online! (Nieznacznie zmodyfikowany, aby uruchomić wszystkie przypadki testowe jednocześnie).

Wyjaśnienie

$
;$_

Zduplikuj dane wejściowe, dopasowując koniec łańcucha i wstawiając ;następnie całe dane wejściowe.

T`ACGT`Ro`;.+

Dopasuj tylko drugą połowę danych wejściowych ;.+i dokonaj podstawienia par transliteracją. Jeśli chodzi o zestaw docelowy Ro: oodwołuje się do drugiego zestawu, który ojest zastępowany przez ACGT. Ale Rodwraca ten zestaw, więc dwa zestawy są w rzeczywistości:

ACGT
TGCA

Jeśli dane wejściowe to palindrom DNA, będziemy mieli dane wejściowe, a następnie ich odwrotność (oddzielone przez ;).

+`(.);\1
;

Wielokrotnie ( +) usuń parę identycznych znaków wokół ;. To będzie trwać, dopóki nie pozostaną tylko ;znaki, lub dopóki dwa znaki wokół ;nie będą już identyczne, co oznacza, że ​​ciągi znaków nie są odwrotnością.

^;

Sprawdź, czy pierwszym znakiem jest ;i wydrukuj 0lub 1odpowiednio.


6

JavaScript (ES6), 59 bajtów

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

Najlepsze, co mogłem zrobić bez użycia Regexp, to 62 bajty:

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

5

Ruby, 35 lat

Próbowałem na inne sposoby, ale oczywisty był najkrótszy:

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

w programie testowym

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

2
->s{s.==s.reverse.tr'ACGT','TGCA'}jest bajt krótszy
Mitch Schwartz,

@MitchSchwartz wow, to działa, ale nie mam pojęcia, po co to pierwsze .. Bez niego kod wydaje mi się bardziej odpowiedni, ale jest wymagany, aby go uruchomić. Czy jest to gdziekolwiek udokumentowane?
Level River St

Czy na pewno nie chcesz tego rozgryźć na własną rękę?
Mitch Schwartz,

@MitchSchwartz hahaha Już próbowałem. Uważam, że wymagania Ruby dotyczące białych znaków są bardzo osobliwe. Dziwne wymagania dotyczące okresów to zupełnie inna kwestia. Mam kilka teorii, ale wszystkie mogą się mylić. Podejrzewam, że może to mieć coś wspólnego z traktowaniem ==jako metody, a nie operatora, ale wyszukiwanie za pomocą symboli jest niemożliwe.
Level River St

Podejrzewasz poprawnie. :) To zwykłe stare wywołanie metody.
Mitch Schwartz

5

Haskell, 48 45 bajtów

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

Przykład użycia: (==)=<<reverse.map((cycle"_T_GA__C"!!).fromEnum) $ "ATCGCGAT"-> True.

Wersja nie-punktowa to

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

Edycja: @Mathias Dolidon zapisał 3 bajty. Dzięki!


Działa cycle "TCG_A" również z . :)
Mathias Dolidon


4

Julia, 47 38 bajtów

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

Jest to anonimowa funkcja, która przyjmuje Chartablicę i zwraca wartość logiczną. Aby go wywołać, przypisz go do zmiennej.

Wykorzystuje algorytm Dennisa, który jest krótszy niż naiwne rozwiązanie. Otrzymujemy resztę każdego punktu kodowego podzieloną przez 8, dodajemy to do siebie odwróconą, pobieramy resztę z dzielenia przez 5 i sprawdzamy, czy wszystkie mają wartość 0. Ostatni krok jest wykonywany przy użyciu wersji infiksowej issubset, która rzuca oba argumenty na Setprzed sprawdzeniem. Oznacza to, że [0,0,0]jest zadeklarowany jako podzbiór 0, ponieważ Set([0,0,0]) == Set(0). Jest to krótsze niż jawne sprawdzenie z 0.

Wypróbuj online!

Zaoszczędź 9 bajtów dzięki Dennisowi!


4

Jolf, 15 bajtów

Spróbuj!

=~A_iγ"AGCT"_γi

Wyjaśnienie:

   _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


3

Właściwie 19 bajtów

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

Wykorzystuje algorytm Dennisa .

Wypróbuj online!

Wyjaśnienie:

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

3

Oracle SQL 11.2, 68 bajtów

SELECT DECODE(TRANSLATE(REVERSE(:1),'ATCG','TAGC'),:1,1,0)FROM DUAL; 

2
Z takim SQL jestem pewien, że
musiałeś

3

Julia 0.4, 22 bajty

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

Ciąg zawiera znaki sterujące EOT (4) i NAK (21). Dane wejściowe muszą mieć postać tablicy znaków.

Takie podejście XORs znaków wejściowych z odpowiednimi znakami na odwrotnym wejściu. W przypadku prawidłowych par powoduje to użycie znaków EOT lub NAK. Testowanie włączenia do ciągu tych znaków daje pożądaną wartość logiczną.

Wypróbuj online!


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 bajty zapisane przez Dennisa. Dodatkowe 2 bajty zapisane przez dostosowanie do wprowadzania małych liter: stałe 37i21 są korygowane do 5i 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;}

Zapisano jeden bajt: wyeliminowano nawias, biorąc iloczyn dwóch kodów ASCII mod 37. Prawidłowe pary mają wartość 21. Przyjmuje duże litery.

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

Wykorzystuje fakt, że kody ASCII poprawnych par sumują się do 138 lub 149. Gdy wzięty mod 11, są to jedyne pary, które sumują się do 6. Zakłada się wprowadzanie wielkich liter.

nie wziął udziału w programie testowym

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

1
r,e;f(char*s){for(r=0,e=strlen(s)+1;*s;s++)r|=*s*s[e-=2]%37^21;return!r;}oszczędza kilka bajtów.
Dennis

@Dennis dzięki, naprawdę nie miałem nastroju na modyfikowanie wskaźników, ale to wycisnęło bajt! Należy Widziałem !=> ^siebie. Zmniejszyłem kolejne 2, zmieniając na małe litery: obie magiczne liczby są teraz jednocyfrowe.
Level River St

3

Czynnik , 72 bajty

Niestety regex nie może mi tutaj pomóc.

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

Odwróć, tabela odnośników, porównaj równe.


Wow, to dużo białych znaków !!! Czy to wszystko jest konieczne? Przydałby się również link do strony głównej języka.
Level River St

@LevelRiverSt Niestety, każda jego część jest konieczna. Dodam link do nagłówka.
kot

3

Bash + coreutils, 43 32 bajty

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

Testy:

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

3

J - 21 bajtów

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

Na podstawie metody Dennisa

Stosowanie

   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

Wyjaśnienie

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

3

Labirynt , 42 bajty

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

Kończy się z błędem dzielenia przez zero (komunikat o błędzie na STDERR).

Wypróbuj online!

Układ wydaje się naprawdę nieefektywny, ale po prostu nie widzę teraz sposobu na grę w golfa.

Wyjaśnienie

To rozwiązanie opiera się na sztuczce arytmetycznej Dennisa: weź wszystkie kody znaków modulo 8, dodaj parę z obu końców i upewnij się, że jest podzielna przez5 .

Podkład labiryntowy:

  • Labirynt ma dwa stosy liczb całkowitych o dowolnej precyzji, główny i pomocniczy (iliary), które są początkowo wypełnione (domyślną) nieskończoną liczbą zer.
  • Kod źródłowy przypomina labirynt, w którym wskaźnik instrukcji (IP) podąża za korytarzami, kiedy może (nawet wokół rogów). Kod zaczyna się od pierwszego poprawnego znaku w kolejności czytania, tj. W tym przypadku w lewym górnym rogu. Kiedy IP dojdzie do dowolnej formy połączenia (tj. Kilku sąsiednich komórek oprócz tej, z której pochodzi), wybierze kierunek w oparciu o górę głównego stosu. Podstawowe zasady to: skręć w lewo, gdy wartość jest ujemna, idź naprzód, gdy zero, skręć w prawo, gdy wartość dodatnia. A jeśli jeden z nich nie jest możliwy, ponieważ istnieje ściana, wówczas IP przyjmie przeciwny kierunek. IP zmienia się również po trafieniu w ślepe zaułki.
  • Cyfry są przetwarzane przez pomnożenie górnej części głównego stosu przez 10, a następnie dodanie cyfry.

Kod zaczyna się od małej pętli 2x2 zgodnej z ruchem wskazówek zegara, która odczytuje wszystkie wejściowe moduły 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.

Teraz ;odrzuca -1. Wchodzimy w kolejną pętlę zgodnie z ruchem wskazówek zegara, która przesuwa górę głównego stosu (tj. Ostatniego znaku) na dół:

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

Teraz jest krótki bit liniowy:

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

Adres IP znajduje się teraz na skrzyżowaniu, które działa jak gałąź do testowania podzielności przez 5. Jeśli wynik modulo jest niezerowy, wiemy, że dane wejściowe nie są palindromem Watsona-Cricka i skręcamy na wschód:

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

W przeciwnym razie musimy nadal sprawdzać resztę danych wejściowych, aby IP kontynuowało podróż na południe. Do {ciągnie po dnie pozostałego wejścia. Jeśli wyczerpaliśmy wejście, to będzie to 0(od dołu Aux ), a IP kontynuuje przemieszczanie się na południe:

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

W przeciwnym razie w ciągu będzie więcej znaków do sprawdzenia. IP skręca na zachód i przechodzi do następnej (zgodnej z ruchem wskazówek zegara) pętli 2x2, która składa się głównie z 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.

Po tej pętli mamy ponownie dane wejściowe na głównym stosie, z wyjątkiem pierwszego i ostatniego znaku i zera na górze. W ;odrzuca 0, a następnie =zamienia czubki stosów, ale to jest po prostu anulować pierwszy =w pętli, ponieważ jesteśmy teraz wejściem do pętli w innym miejscu. Wypłukać i powtórzyć.


3

sed, 67 61 bajtów

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

(67 bajtów)

Test

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

Wydajność

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

Używając rozszerzonych wyrażeń regularnych, liczbę bajtów można zmniejszyć do 61.

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

Jeśli potrafisz to zrobić w 61 bajtach, to jest to twój wynik - nie ma nic przeciwko NFA ani pełnemu wyrażeniu regularnemu w tym konkretnym wyzwaniu. Niektóre wyzwania zabronić regex w całości, ale zwykle tylko regex-golf uniemożliwi niż regularne -expressions.
kot

3

C #, 65 bajtów

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

.NET ma czasami dość długie nazwy metod frameworka, co niekoniecznie jest najlepszym frameworkiem do golfa. W tym przypadku nazwy metod ramowych składają się z 33 znaków na 90. :)

Na podstawie sztuczki modułowej z innego miejsca w wątku:

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

Teraz waży 67 znaków, z czego 13 to nazwy metod.

Kolejna drobna optymalizacja, aby zgolić potężne 2 znaki:

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

65 z czego 13 to nazwy ramowe.

Edycja: Pominięcie niektórych ograniczonych „szablonów” z rozwiązania i dodanie kilku warunków pozostawia nam wyraz

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

Co daje 0 wtedy i tylko wtedy, gdy ciąg s jest poprawną odpowiedzią. Jak wskazuje cat, „bool F (string s) =>” można w rzeczywistości zastąpić „s =>” jeśli w kodzie jest inaczej jasne, że wyrażenie jest a Func<string,bool>, tzn. odwzorowuje ciąg na wartość logiczną.


1
Witamy w PPCG, fajna pierwsza odpowiedź! : D
kot

@cat Dzięki za to! :)
robhol 27.04.2016

1
Nie bardzo wiem, C #, ale jeśli to jest lambda, to można pominąć jego typ i przypisanie go jako funkcje anonimowe są w porządku tak długo, jak są one przypisać stanie .
kot

1
Poza tym nie możesz !s.Zip...tego zrobić s.Zip...==0? (Czy nie możesz !ints w C #?) Nawet jeśli nie potrafisz go zaprzeczyć boolean, możesz pominąć jakąkolwiek inwersję i stwierdzić w swojej odpowiedzi, że zwraca to <to coś> dla falsy i <inny deterministyczny, rzecz wyraźnie dostrzegalna> dla prawdy.
kot

1
@cat: Masz rację, porzucając ten typ. Myślałem, że kod musi być bezpośrednio wykonywalny, ale proste założenie dotyczące danych wejściowych i wyjściowych sprawia, że ​​jest to trochę łatwiejsze. Inna sprawa jednak nie zadziała - słusznie, moim zdaniem, ponieważ operacja boolowska nie ma logicznego (odcienia barwy) sposobu na zastosowanie do liczby. Przypisanie 0 i 1 wartości false i true jest przecież tylko konwencją.
robhol 30.04.16

2

REXX 37

s='ATCGCGAT';say s=translate(reverse(s),'ATCG','TAGC')

2

R, 101 bajtów

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

Przypadki testowe

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

strsplit(x,"")[[1]]jest o 3 bajty krótszy niż unlist(strsplit(x,""))i tutaj jest równoważny, ponieważ xzawsze jest jednym ciągiem znaków.
plannapus

2

Oktawa, 52 bajty

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

Podążając za sztuczką Denisa ... weź wartości ASCII mod 8, odwróć i zsumuj; jeśli każda suma jest wielokrotnością pięciu, jesteś złoty.


Czy jeden biały znak jest znaczący? To dziwne.
kot

Możesz także pominąć f=zadanie; funkcje bez nazw są w porządku.
kot

1

Clojure / ClojureScript, 49 znaków

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

Działa na ciągach znaków. Jeśli wymagania zostaną zmniejszone, aby umożliwić listy, mogę zdjąć (list* )i zapisać 7 znaków.


1

R, 70 bajtów

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

Stosowanie:

> 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

1

C, 71 bajtów

Wymaga kodów ASCII dla odpowiednich znaków, ale akceptuje wprowadzanie wielkich, małych i małych liter.

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

Ten kod utrzymuje dwa wskaźniki si pprzemierza łańcuch w przeciwnych kierunkach. Na każdym kroku porównujemy odpowiednie znaki, ustawiając wartość btrue, jeśli się nie zgadzają. Dopasowanie opiera się na XOR wartości znaków:

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

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

W powyższej tabeli widzimy, że chcemy odnotować sukces xx10x i porażkę dla czegokolwiek innego, więc XOR za pomocą 00100(czterech) i maskowania za pomocą 00110(sześciu), aby uzyskać zero dla ATlubCG niezerowe w przeciwnym razie. W końcu zwracamy wartość true, jeśli wszystkie pary zgromadzą wynik zerowy, w bprzeciwnym razie false.

Program testowy:

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.