Scientists have recently found a new type of bacteria that replicates in odd ways. To reproduce, two bacteria each split into 3 (for a total of 6) and pairs combine (resulting in 3 bacteria, two parents, one child). However, the bacteria can only split if it has a partner. For example, 2 bacteria split and combine into 3, 3 into 4, 4 into 6, etc. Additionally, when a bacteria splits, only one of the daughter cells combines with the other parent cell's daughter cells, and vice versa. In other words, if bacteria A and B split, the daughter cells will combine to be AA, AB, and BB.

The Challenge

Your challenge is to make a program that accepts or generates 4 bacteria's DNA, each with a strand in a 10-bit Quaternary format. An example DNA strand could be 0123302012. When two daughter bacteria combine, the DNA is merged in a punnet-square style (the DNA can be merged in every pair or only the AB pair, your choice). Meaning that 0 is the recessive trait, 1 is the mixed trait, and 2 is the dominant trait. However, when there is a 3, it is a mutated trait (more on this later). Starting with the 4 bacteria, have your program run 20 trials (4 splitting into 6 would be the first trial). Once it is done, have the program output through STDOUT (or equivalent) each cell's DNA on a seperate line, but only from the cells generated from the 20th trial.

Key Features

  • Each trial must calculate the new number of cells and each new cell's DNA (see below).
  • The program must output each 20th-trial cell's DNA (The 4046 new bacteria) each on a seperate line in STDOUT (or equivalent).
  • The bacteria must each replicate in the method stated above. (A and B split into AA, AB, and BB).

How the DNA is Passed on

The DNA is passed from the parents to child in a punnet-square style where:

  • 0 is a recessive trait (rr).
  • 1 is a mixed trait (Rr).
  • 2 is a dominant trait (RR).

If one of the traits is a 3 (a mutation), the ending trait is decided randomly, but if both are 3,the ending trait is a 3. Parents can be decided randomly or in order (A & B, C & D, etc).


    |   DNA A    |   DNA B    | DNA C (Child) |
    | 0123311200 | 1203123213 |  0113012203   |


This is code golf, so shortest character count wins! For legibility, please include a version that separates the code onto multiple lines, if possible. If the challenge is not explained well or you have suggestions, post a comment!

Here is an example program (in java) that successfully completes the challenge: Ideone Link.

  • 3
    \$\begingroup\$ Are you sure you want to discount newlines? That gives an advantage to certain languages. You can always just ask for an ungolfed version for clarity. \$\endgroup\$ – Geobits Feb 5 '15 at 4:14
  • \$\begingroup\$ @Geobits good point, i'll change that. \$\endgroup\$ – GamrCorps Feb 5 '15 at 4:16
  • 1
    \$\begingroup\$ There are a few things which aren't clear to me. 1. What's the point of the introduction? The rest of the question looks like basis meiosis, but the introduction confuses me and makes me unsure whether that's the intention or not. 2. What exactly is a trial? Is the intention that we start with generation 0 of 4 bacteria, and at each trial we pair up the current generation (possibly with an unpaired specimen) and add the offspring to the current generation to get the new generation? And then we have to output the 12138 members of gen 20? Or the 4046 members of gen 20 who aren't in gen 19? \$\endgroup\$ – Peter Taylor Feb 5 '15 at 10:01
  • \$\begingroup\$ 3. When you say that "the ending trait is decided randomly", from what distribution? Is it a 50/50 between the two traits being combined, a 25/25/25/25 between all 4 possibilities, or something else? \$\endgroup\$ – Peter Taylor Feb 5 '15 at 10:04
  • \$\begingroup\$ 1. The introduction is just for people to get familiar with the question and to explain what is happening. 2. A trial is a new generation where trial 1 is where the population is 6. 3. Say the parent's genes are a 0 and a 3. The child's gene could be 0, 1, 2, or 3. \$\endgroup\$ – GamrCorps Feb 5 '15 at 13:10

CJam: 71



Indented and commented:

qS/             "Read the input and split around spaces";
{               "Loop";
  mr2/            "Shuffle the DNA strings and group into pairs";
  {               "For each pair";
    _,(             "Check if it's really a pair";
    {               "If it's really a pair AB";
      3*$2/           "Create the breeding combinations AA AB BB";
      {               "For each breeding combination";
        z               "Pair the corresponding alleles together";
        {               "For each pair of alleles";
          :~              "Map each allele (currently a string) to an int";
          _3#)            "Check if one of the alleles is a 3";
          {               "If one allele is a 3";
            ~=              "Check if both alleles are 3";
            Z               "If so, generate a 3 as the new allele";
            4mr?            "Otherwise, generate a random number from 0 to 3 as the new allele";
          }{              "If neither allele is a 3";
            {[0Ymr1]=}%     "For each allele, map 0 to 0, 1 to 0 or 1 (random), and 2 to 1";
            :+              "Add the mapped values to generate the new allele";
          }?`             "Convert the allele back to a string";
        }%              "Result: two DNA strings bred into one";
      }/              "Result: two DNA strings combined and bred into three";
    }{~}?           "If it's not a pair, just unwrap it from its group";
  }%              "Result: all pairs of DNA strings combined and bred into three";
}K*             "Result: bred for 20 generations";
{N}/            "Put a newline after each DNA string";

You added the stipulation that DNA is only merged punnet-square-style for "AB" bacteria after I wrote my code, but mine generates all bacteria by merging that way. Based on your description of how breeding occurs, my interpretation (which also seems to be Siddhanathan's interpretation) seemed more accurate. Talking about bacteria splitting into 3 doesn't make any sense otherwise. But I'll change things if necessary.

I also assumed that breeding pairs should be decided randomly, but that seems like a safer assumption.

  • \$\begingroup\$ No need to change anything. Your suggestions were also nice and I incorporated them to the best of my ability! \$\endgroup\$ – GamrCorps Feb 5 '15 at 23:05

Haskell -- 349

import Control.Monad
import System.Random
import Data.List
f 3 _=randomRIO(0,3)
f _ 3=randomRIO(0,3)
f x y=return$div(x+y)2
z x y=zipWithM f x y
c=filter(\x->length x==2).subsequences
y=foldr(<=<)return.replicate 20
main=y r b>>=mapM_ print

Try it online with nicer looking source code: http://ideone.com/9FUMLd

The online example does only till 2 instead of 20 because of ideone's time limit.


Not the answer you're looking for? Browse other questions tagged or ask your own question.