运行基因交叉算法


16

您的任务是接受两个基因序列和一个“交叉点”序列作为输入,并返回由所示交叉产生的基因序列。

我的意思是说您有序列[A, A, A, A, A, A, A][Z, Z, Z, Z, Z, Z, Z],并且交叉了2和的点5。结果序列为[A, A, Z, Z, Z, A, A],因为:

穿越这里:VV
指数:0 1 2 3 4 5 6

基因1:AAAAAAA
基因2:ZZZZZZZ

结果:AAZZZAA
              ^^

请注意,尽管我在这里使用字母是为了清楚起见,但实际的挑战是将数字用于基因。

结果是第一个序列直到遇到交叉点,然后结果从第二个序列开始直到遇到另一个交叉点,然后结果从第一个序列开始直到遇到一个交叉点...

输入:

  • 输入可以是任何合理的形式。这两个序列可以是一对,点是第二个参数,所有三个都可以是单独的参数,一个的三元组(genes 1, genes 2, cross-points),一个具有命名键的映射...

  • 交叉点将始终是有序的,并且将始终是入站。不会有重复的点,但是交叉点列表可能为空。

  • 基因序列将始终具有相同的长度,并且将为非空。

  • 索引可以基于0或1。

  • 基因将始终是0-255范围内的数字。

  • 哪个参数是“ genes 1”或“ genes 2”都没有关系。在没有交叉点的情况下,结果可以完全是“基因1”或“基因2”。


输出量

  • 输出可以是任何不模糊的合理形式。它可以是数字数组/列表,字符串数字数组,带分隔符的数字字符串(某些非数字字符必须分隔数字)...

  • 可以将其返回或打印到标准输出。


可以通过完整的程序或功能进行输入。


测试用例(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

Answers:


1

果冻12 10字节

ṁ⁹L‘¤ḣ"ḷ"/

在线尝试!

参数1:seq1,seq2
参数2:交叉点(索引为0)


原因是...这对于其中一个测试用例不起作用!
乔纳森·艾伦

在其他情况下
Jonathan Allan '18

看起来像是需要的东西;⁹ZL‘¤Ṭ+\ịŒDḢ:(
乔纳森·艾伦

@JonathanAllan我实际上设法找到了一个与您建议的完全不同的12字节版本。:)
暴民埃里克(Erik the Outgolfer)

@JonathanAllan ...然后我发现了一个完全不同的10字节版本,同时检查了您的链接和另一个测试用例(放松,我确实记得更改为基于0的索引)。:D
暴民埃里克(Erik the Outgolfer)

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字节

@ETHproductions节省了2个字节

将输入作为三元组[a,b,c],其中ab是基因序列,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]中的指针,但忽略了此优化。
Arnauld

3

APL(Dyalog 16.0),26字节

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

在线尝试!

输入是ac,然后是bc已建立1索引。

怎么样?

a←⎕-得到一个

0⍴⍨≢-创建0长度为的数组。

1@⎕⊢-取c并将索引上的s 更改为0s 1

d←-分配给d

⊂≠\d- 使用xor展开d以创建选择序列(对于a,对于b),然后将其括起来。01

(~,⊢)-取d及其倒数。

a⎕×-和分别与输入的ba相乘。

+/-综上所述每对元件,产生一个在S 0S和b在S 1秒。


⊢0⍴⍨≢-> ≠⍨技巧
ngn

@ngn我无法使用它[tio ]
Uriel

您需要,在输入中输入1之前的向量
ngn



2

J,24字节

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

在线尝试!

我不算 f=:字符数,因为它与匿名函数一样有效(如TIO示例所示)

注意:不适用于交叉点的空列表!

显式的oneliner x是左参数-交叉点列表,y是右参数,是序列的两行表。

说明:

4 :' ... ' -二元动词

(...)}y -每个操作数(...)的原子都从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参数(零列表)的项在(由x点表示的cors列表)指示的索引处更改为1

   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

R84 79字节

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}

在线尝试!

将输入作为2列和1的矩阵vector


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

在线尝试!

乔纳森·弗雷奇(Jonathan Frech)的-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
Jonathan Allan

:将内容索引到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(clang),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]

页脚中的宏a()可以很好地打印测试用例和结果

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.