Запуск алгоритму кросовер для генів


16

Ваше завдання полягає в тому, щоб прийняти як введення дві послідовності генів і послідовність "перехресних точок", і повернути послідовність генів, що є результатом зазначених перехресних переключень.

Що я маю на увазі під цим, скажіть, у вас є послідовності [A, A, A, A, A, A, A]і [Z, Z, Z, Z, Z, Z, Z], і перетнути точки 2і 5. Отримана послідовність буде [A, A, Z, Z, Z, A, A], оскільки:

Хрест Тут: В.В.
Індекси: 0 1 2 3 4 5 6

Гени 1: ААААААА
Гени 2: ZZZZZZZ

Результат: AAZZZAA
              ^ ^

Зауважте, що хоча я тут використовую літери для наочності, справжній виклик використовує цифри для генів.

Результатом є перша послідовність, поки не зустрінеться точка перехрестя, потім результат бере від другої послідовності до появи іншої точки перетину, потім результат бере від першої послідовності, поки не виникне точка перехрестя ...

Вхід:

  • Введення може бути будь-якою розумною формою. Дві послідовності можуть бути парними, причому точки є другим аргументом, всі три можуть бути окремими аргументами, однією трійкою (genes 1, genes 2, cross-points), картою з іменованими ключами ...

  • Перехресні точки завжди будуть в порядку, і завжди будуть вхідними. Дублікатів не буде, але список перекреслених пунктів може бути порожнім.

  • Послідовності генів завжди будуть однакової довжини і не будуть порожніми.

  • Індекси можуть бути 0 або 1 на основі.

  • Гени завжди будуть числами в діапазоні 0-255.

  • Не має значення, який аргумент "гени 1" або "гени 2". У випадку відсутності перехресних точок результат може бути або повністю "генами 1", або "генами 2".


Вихідні дані

  • Вихід може бути будь-якою розумною формою, яка не є неоднозначною. Це може бути масив / список чисел, масив рядкових чисел, обмежений рядок чисел (деякі нечислові символи повинні відокремлювати числа) ...

  • Він може бути повернутий або роздрукований у std-out.


Записи можна за допомогою повних програм або функцій.


Випробування (genes 1, genes 2, cross points) => result:

[0], [1], [0] => [1]
[0, 1], [9, 8], [1] => [0, 8]
[0, 2, 4, 6, 8, 0], [1, 3, 5, 7, 9, 1], [1, 3, 5] => [0, 3, 5, 6, 8, 1]
[1, 2, 3, 4], [5, 6, 7, 8], [] => [1, 2, 3, 4]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 2, 3, 6, 8] => [1, 1, 0, 1, 1, 1, 0, 0, 1, 1]

Це Code Golf.


Ваш відпрацьований приклад був би дещо зрозумілішим, якби індекси кросовера не були також елементами в послідовностях.
Кудлатий

1
Виправлено. Змінив його на A і Z. Сподіваюсь, це зрозуміліше.
Carcigenicate

Відповіді:


1

Желе , 12 10 байт

ṁ⁹L‘¤ḣ"ḷ"/

Спробуйте в Інтернеті!

Аргумент 1: seq1, seq2
Аргумент 2: перехресні точки (0-індексовано)


Була причина ... це не працює для одного з тестових випадків !
Джонатан Аллан

Невдача також в інших сценаріях, наприклад
Джонатан Аллан

Схоже, потрібно щось подібне ;⁹ZL‘¤Ṭ+\ịŒDḢ:(
Джонатан Аллан

@JonathanAllan Насправді мені вдалося знайти 12-байтову версію, зовсім іншу, ніж ви запропонували. :)
Ерік Аутгольфер

@JonathanAllan ... а потім я виявив зовсім іншу 10-байтну версію, перевірив як ваші посилання, так і інший тестовий випадок (розслабтеся, я пам’ятав, що змінився на 0-індексацію). : D
Ерік Аутгольфер

4

Haskell, 58 53 51 45 байт

(fst.).foldl(\(a,b)p->(take p a++drop p b,a))

Дві генетичні послідовності приймаються як пара списків, а перехресні точки - як другий аргумент.

Спробуйте в Інтернеті!

foldl           -- fold the pair of genes into the list of
                -- cross points and on each step
    \(a,b) p -> -- let the pair of genes be (a,b) and the next cross point 'p'
      (take p a++drop p b,a)  
                -- let 'b' the new first element of the pair, but
                --   drop the first 'p' elements and 
                --   prepend the first 'p' elements of 'a'
                -- let 'a' the new second element 
fst             -- when finished, return the first gene   

4

JavaScript (ES6), 47 45 байт

Збережено 2 байти завдяки @ETHproductions

Вводиться як триплет [a, b, c], де a і b - послідовності генів, а c - список 0-індексованих перехресних точок.

x=>x[i=j=0].map(_=>x[(j+=x[2][j]==i)&1][i++])

Спробуйте в Інтернеті!

Прокоментував

x =>                    // given x = [ geneSeqA, geneSeqB, crossPoints ]
  x[i = j = 0]          // initialize i = gene sequence pointer and j = cross point pointer
  .map(_ =>             // for each value in the first gene sequence:
    x[(                 //   access x[]
      j += x[2][j] == i //     increment j if i is equal to the next cross point
    ) & 1]              //   access either x[0] or x[1] according to the parity of j
    [i++]               //   read gene at x[0][i] or x[1][i]; increment i
  )                     // end of map()

Я вважаю, що ви можете зробити щось на кшталт, x[(j+=x[2][j]==i)%2][i++]щоб зберегти пару байтів.
ETHproductions

@ETHproductions Дякую! Я нерозумно намагався додати 3-ю змінну, щоб відслідковувати покажчик у x [2], але пропустив цю оптимізацію.
Арнольд

3

APL (Dyalog 16.0) , 26 байт

+/a⎕×(~,⊢)⊂≠\d1@⎕⊢0⍴⍨≢a←⎕

Спробуйте в Інтернеті!

Введення - a , c , то b . з буде 1індексуватися.

Як?

a←⎕- отримати .

0⍴⍨≢- створити масив 0s на його довжину.

1@⎕⊢- взяти c і змінити 0s на 1s на індекси.

d←- призначити д .

⊂≠\d- розгорніть d за допомогою xor для створення послідовності вибору ( 0для a , 1для b ) та додайте.

(~,⊢)- взяти d та його зворотну.

a⎕×- і помножити відповідно на введені b і a .

+/- підсумовуйте кожну пару елементів, отримуючи a s на 0s і b s на 1s.


⊢0⍴⍨≢-> ≠⍨( підказка )
ngn

@ngn Я не можу змусити його працювати [tio ]
Уріель,

вам потрібні ,вектори перед 1 елементом на вході
ngn



2

J , 24 байти

4 :'(2|+/\1 x}I.#{.y)}y'

Спробуйте в Інтернеті!

Я не рахую f=:символів, оскільки він працює так само добре, як і анонімна функція (як показано у зразку TIO)

Примітка. Це не працює для порожнього списку перехресних точок!

Явний oneliner, xце лівий аргумент - список перекреслених точок, yце правий аргумент, дворядкова таблиця послідовностей.

Пояснення:

4 :' ... ' - дієслівне дієслово

(...)}y - Кожен атом операнда (...) вибирає атом з відповідних позицій елементів у

#{.y - бере першу послідовність і знаходить її довжину

    #{. 0 2 4 6 8 0,: 1 3 5 7 9 1
6

I. створює список нулів з довжиною аргументу

   I.6
0 0 0 0 0 0

1 x}змінює елементи аргументу rigth (список нулів) на 1 в індексах, позначених x(перелік корів над точками)

   1(1 3 5)}I.6
0 1 0 1 0 1

+/\ складання сум списку

   +/\ 0 1 0 1 0 1
0 1 1 2 2 3

2| модуль 2

   2|+/\ 0 1 0 1 0 1
0 1 1 0 0 1

Зібрано:

    0 1 1 0 0 1 } 0 2 4 6 8 0 ,: 1 3 5 7 9 1
0 3 5 6 8 1


2

Python 3, 61 60 байт

f=lambda a,b,c,d=0:c and a[d:c[0]]+f(b,a,c[1:],c[0])or a[d:]

Спробуйте в Інтернеті!

-1 байт від Джонатана Фреха

Пояснення:

f=lambda a,b,c,d=0:c and a[d:c[0]]+f(b,a,c[1:],c[0])or a[d:]
f=lambda a,b,c,d=0:
 # recursive lambda: a and b are the two lists,
 # c is the crossovers, and d is where to start
                   c and
 # if there is at least one crossover left
 #  then
                         a[d:c[0]]
 #  return the items of the first list from the
 #  starting point up to the first crossover
                                  +f(b,a,c[1:],c[0])
 #  plus the result of the inverted lists with
 #  the remaining crossovers, starting where
 #  the first part left off
                                                    or
 # else
                                                       a[d:]
 #  the first list from the starting point to the end

1
Можливо 60 байт ; припускаючи, що a[d:c[0]]+f(b,a,c[1:],c[0])ніколи не буде помилковим.
Джонатан Фрех

1

Желе , 13 байт

ṬœṗЀż/JḂị"ƊF

Діадичне посилання, що приймає (1-індексовану) кроссовер зліва та список двох послідовностей праворуч, що повертає отриманий список.

Спробуйте в Інтернеті!

Як?

ṬœṗЀż/JḂị"ƊF - Link: list, C; list, S     e.g. [2,4,6]; [[0,2,4,6,8,0],[1,3,5,7,9,1]]
Ṭ             - untruth C                       [0,1,0,1,0,1]
   Ѐ         - map across S with:
 œṗ           -   partition at truthy indices   [[0],[2,4],[6,8],[0]]  /  [[1],[3,5],[7,9],[1]]
      /       - reduce with:
     ż        -   zip                           [[[0],[1]],[[2,4],[3,5]],[[6,8],[7,9]],[[0],[1]]]
           Ɗ  - last three links as a monad:
       J      -   range of length               [1,2,3,4]
        Ḃ     -   bit (modulo by 2)             [1,0,1,0]
          "   -   zip with:
         ị    -     index into                  [[0],[3,5],[6,8],[1]]
            F - flatten                         [0,3,5,6,8,1]

@Carcigenicate - дякую, що я щойно помітив після запитання: D
Джонатан Аллан

: Яка марна річ для індексації у 2-елементний список. ż/: Як марний склад, все одно жорстоко сплюндрований великою вантажівкою!
Ерік Аутгольфер

1

Вугілля деревне , 19 байт

AθAηE§θ⁰§§θLΦ⊕κ№ηλκ

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Приймає дані як пару послідовностей генних рядків та 0-індексований список точок схрещування. Пояснення:

Aθ                  Input the pair of gene sequences into `q`
  Aη                Input the list of crossing points into `h`
    E§θ⁰            Loop over one of the gene sequences
              κ     Current index
             ⊕      Incremented
            Φ  №ηλ  Intersect implicit range with crossing points
           L        Take the length
         §θ         Cyclically index into the pair of gene sequences
        §         κ Take the appropriate element of that sequence
                    Implicitly output on separate lines

Крім того, можна встановити для друку результату у вигляді рядка. Спробуйте в Інтернеті!


1

SWI-Prolog, 78 байт

A/B/[0|C]/D:-B/A/C/D. [H|A]/[_|B]/C/[H|D]:-maplist(succ,E,C),A/B/E/D. A/_/_/A.

Використання: виклик "Genes1 / Genes2 / CrossoverPoints / X", де "Genes1", "Genes2", "CrossoverPoints" містяться в дужках, розділені комами.


1

C (стук) , 79 байт

*g[2],*c,l,m;f(i,j,k){for(i=j=k=0;i<l;g[0][i++]=g[k][i])m&&c[j]==i?k=!k,j++:0;}

Спробуйте в Інтернеті!

Вхідні дані:
g[0]це генна послідовність 1,
g[1]є генна послідовність 2,
cє точки перехрещення.
l- довжина g[0]і g[1]
mдовжина c
Усі входи масиву - це масиви цілих чисел з 0-базисним індексом.

Виходи:
Вихідні дані зберігаються вg[0]

macro a () у нижньому колонтитулі робить друк тестових випадків та результат

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.