Menjalankan algoritma crossover gen

16

Tugas Anda adalah untuk menerima sebagai input dua urutan gen, dan urutan "cross over points", dan mengembalikan urutan gen yang dihasilkan dari cross over yang ditunjukkan.

Yang saya maksud dengan ini adalah, katakan Anda memiliki urutan [A, A, A, A, A, A, A]dan [Z, Z, Z, Z, Z, Z, Z], dan lintas poin dari 2dan 5. Urutan yang dihasilkan adalah [A, A, Z, Z, Z, A, A], karena:

Silang Di Sini: VV
Indeks: 0 1 2 3 4 5 6

Gen 1: AAAAAAA
Gen 2: ZZZZZZZ

Hasil: AAZZZAA
              ^ ^

Perhatikan bahwa saat saya menggunakan huruf di sini untuk kejelasan, tantangan sebenarnya menggunakan angka untuk gen.

Hasilnya adalah urutan pertama sampai titik lintas ditemui, maka hasilnya mengambil dari urutan kedua sampai titik lintas lainnya ditemui, kemudian hasilnya mengambil dari urutan pertama sampai titik persimpangan berakhir ...

Memasukkan:

  • Input dapat berupa bentuk apa pun yang masuk akal. Dua urutan bisa menjadi pasangan, dengan poin sebagai argumen kedua, ketiganya bisa menjadi argumen terpisah, triplet tunggal (genes 1, genes 2, cross-points), peta dengan tombol bernama ...

  • Poin silang akan selalu berurutan, dan akan selalu berada di dalam batas. Tidak akan ada duplikat poin, tetapi daftar lintas poin mungkin kosong.

  • Urutan gen akan selalu sama panjangnya, dan akan kosong.

  • Indeks dapat berbasis 0 atau 1.

  • Gen akan selalu menjadi angka di kisaran 0-255.

  • Tidak masalah argumen mana yang merupakan "gen 1" atau "gen 2". Dalam hal tidak ada titik lintas, hasilnya dapat berupa "gen 1" atau "gen 2".


Keluaran

  • Output dapat berupa bentuk yang wajar yang tidak ambigu. Ini bisa berupa array / daftar angka, array nomor string, string angka yang dibatasi (beberapa karakter non-numerik harus memisahkan angka) ...

  • Itu dapat dikembalikan atau dicetak ke std-out.


Entri dapat dengan program atau fungsi lengkap.


Kasus uji (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]

Ini Golf Code.

Carcigenicate
sumber
Contoh yang Anda kerjakan akan sedikit lebih jelas jika indeks crossover tidak juga elemen dalam urutan.
Shaggy
1
Tetap. Mengubahnya menjadi A dan Z. Semoga itu lebih jelas.
Carcigenicate

Jawaban:

1

Jelly , 12 10 byte

ṁ⁹L‘¤ḣ"ḷ"/

Cobalah online!

Argumen 1: seq1, seq2
Argumen 2: titik silang (0-diindeks)

Erik the Outgolfer
sumber
Ada alasannya ... ini tidak berfungsi untuk salah satu kasus uji !
Jonathan Allan
Juga gagal dalam skenario lain, misalnya
Jonathan Allan
Sepertinya diperlukan sesuatu seperti ;⁹ZL‘¤Ṭ+\ịŒDḢini :(
Jonathan Allan
@ Jonathan Allan Saya sebenarnya berhasil menemukan versi 12-byte yang sangat berbeda dari yang Anda sarankan. :)
Erik the Outgolfer
@ JonathanAllan ... dan kemudian saya menemukan versi 10-byte yang sama sekali berbeda, diperiksa dengan tautan Anda dan test case lain (santai, saya ingat untuk mengubah ke pengindeksan berbasis 0). : D
Erik the Outgolfer
4

Haskell, 58 53 51 45 byte

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

Dua sekuens gen diambil sebagai pasangan daftar dan titik silang sebagai argumen kedua.

Cobalah online!

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   
nimi
sumber
4

JavaScript (ES6), 47 45 byte

Disimpan 2 byte berkat produk @ETH

Mengambil input sebagai triplet [a, b, c] di mana a dan b adalah sekuens gen dan c adalah daftar titik-lintas terindeks 0.

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

Cobalah online!

Berkomentar

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()
Arnauld
sumber
Saya percaya Anda dapat melakukan sesuatu seperti x[(j+=x[2][j]==i)%2][i++]menyimpan beberapa byte.
ETHproduksi
@ ETHproduk Terima kasih! Saya dengan bodoh mencoba menambahkan variabel ke-3 untuk melacak pointer di x [2] tetapi mengabaikan optimasi ini.
Arnauld
3

APL (Dyalog 16.0) , 26 byte

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

Cobalah online!

Input adalah a , c , lalu b . c adalah 1diindeks.

Bagaimana?

a←⎕- mendapatkan sebuah .

0⍴⍨≢- buat array 0s pada panjangnya.

1@⎕⊢- ambil c dan ubah 0s ke 1s pada indeks.

d←- ditugaskan ke d .

⊂≠\d- perluas d dengan xor untuk membuat urutan pemilihan ( 0untuk a , 1untuk b ), dan melampirkan.

(~,⊢)- ambil d dan kebalikannya.

a⎕×- dan kalikan masing-masing dengan yang dimasukkan b dan a .

+/- jumlah setiap pasangan elemen, menghasilkan a s pada 0s dan b s pada 1s.

Uriel
sumber
⊢0⍴⍨≢-> ≠⍨( tip )
ngn
@ Ngn Saya tidak bisa menjalankannya [tio ]
Uriel
Anda memerlukan ,vektor 1-elemen sebelum di input
ngn
2

Perl 5 -a , 45 40 byte

Berikan input dalam urutan "kontrol", "urutan kedua", "urutan pertama" sebagai baris terpisah pada STDIN

#!/usr/bin/perl -alp
@{$.}=@F}for(map${$.^=$%~~@1}[$%++],@2){

Cobalah online!

Ton Hospel
sumber
2

J , 24 byte

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

Cobalah online!

Saya tidak menghitung f=: karakter, karena berfungsi sama baiknya dengan fungsi anonim (seperti yang ditunjukkan dalam sampel TIO)

Catatan: Itu tidak berfungsi untuk daftar kosong poin lintas!

Oneliner eksplisit, xadalah argumen kiri - daftar cross over points,y adalah argumen kanan, tabel dua baris dari urutan.

Penjelasan:

4 :' ... ' - kata kerja diad

(...)}y - Setiap atom operan (...) memilih atom dari posisi yang sesuai dari item y

#{.y - ambil urutan pertama dan temukan panjangnya

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

I. membuat daftar nol dengan panjang argumen

   I.6
0 0 0 0 0 0

1 x}mengubah item dari argumen rigth (daftar nol) menjadi 1 pada indeks yang ditunjukkan oleh x(daftar cors atas poin)

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

+/\ menjalankan jumlah daftar

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

2| modulo 2

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

Dirakit:

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

R , 84 79 byte

function(G,K){o=G[,1]
m=1:nrow(G)
for(i in K)o[m>=i]=G[m>=i,match(i,K)%%2+1]
o}

Cobalah online!

Mengambil input sebagai matriks 2 kolom dan a vector.

Giuseppe
sumber
2

Python 3, 61 60 byte

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

Cobalah online!

-1 byte dari Jonathan Frech

Penjelasan:

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
pizzapants184
sumber
1
Kemungkinan 60 byte ; dengan asumsi itu a[d:c[0]]+f(b,a,c[1:],c[0])tidak akan pernah salah.
Jonathan Frech
1

Jelly , 13 byte

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

Sebuah link diad yang menerima titik crossover (1-diindeks) di sebelah kiri dan daftar dari dua urutan di sebelah kanan yang mengembalikan daftar yang dihasilkan.

Cobalah online!

Bagaimana?

ṬœṗЀż/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]
Jonathan Allan
sumber
@Carcigenicate - terima kasih saya baru saja memperhatikan setelah bertanya: D
Jonathan Allan
: Sungguh hal yang tidak berguna untuk pengindeksan ke daftar 2-elemen. ż/: Betapa sia-sianya komplikasi, itu diratakan pergi dengan truk besar!
Erik the Outgolfer
1

Arang , 19 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Mengambil input sebagai pasangan urutan gen string dan daftar titik persimpangan 0-indeks. Penjelasan:

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

Atau, bisa disubstitusikan untuk mencetak hasilnya sebagai string. Cobalah online!

Neil
sumber
1

SWI-Prolog, 78 byte

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.

Penggunaan: Panggil "Genes1 / Genes2 / CrossoverPoints / X" di mana "Genes1", "Genes2", "CrossoverPoints" adalah daftar yang tertutup tanda kurung, dipisahkan koma.

ashtraypettingzoo
sumber
1

C (dentang) , 79 byte

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

Cobalah online!

Input:
g[0]adalah urutan gen 1,
g[1]urutan gen 2,
cadalah titik lintas.
lpanjang g[0]dan g[1]
mpanjang c
Semua input array adalah array bilangan bulat dengan indeks berbasis 0.

Keluaran:
Keluaran disimpan dig[0]

macro a () di footer melakukan pencetakan kasus dan hasil pengujian

GPS
sumber