# You will write a function called “genome2features’’ which produces levels of four characteristics for a wug based on its individual genome:Foundations of Computing Report, NUS

Project 2: Superwug Rush

Question 1a:

Write “genome2features’’ function

You will write a function called “genome2features’’ which produces levels of four characteristics for a wug based on its individual genome. This will be the only piece of code where you will be provided and allowed to access “the super wug genome ‘’ and the genome zoning.

def genome2features (genome)

● Input: genome (a list of 0s and 1s)
● Returns: a list of 4 True/False values for Intelligence, Beauty, Strength, Speed. True – Superior, False – Normal

The order of characteristics will be provided and should be preserved!

E.g., characteristics = [“intelligence”, “beauty”, “strength”, “speed”]
superwug_genome = [1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0]
genome_zones = [0, 1, 0, 2, 3, 3, 1, 0, 2, 1, 1, 2, 3, 0, 3, 2]

Question 1a: examples
>>> superwug_genome = [1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
>>> gene_zones = [2, 1, 2, 3, 3, 1, 3, 3, 0, 0, 2, 2, 0, 1, 0, 1]
>>> genome_sample1 = [0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0]
>>> genome_sample2 = [1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0]
>>> genome_sample3 = [1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
>>> genome_sample4 = [1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1]
>>> genome2features(genome_sample1)
[False, False, False, False]
>>> genome2features(genome_sample2)
[False, False, True, False]
>>> genome2features(genome_sample3)
[True, True, True, False]
>>> genome2features(genome_sample4)
[False, False, True, True]

Question 1b:

Write “report_population’’ function

You will write a function called “report_population’’ which aggregates all wugs
(population) based on their characteristics. The function will print out all observed sets of characteristics with their counts (the number of wugs that have the corresponding characteristics)

def report_population (population)

● Input: population (a list of tuples representing wugs)
● Returns: returns a summary of all population (a list of (tuple, int) pairs ) aggregating those that share the same characteristics. Follow a lexicographical order in output records.

E.g, # intelligence,beauty,strength, speed,sex,count
[((True,False,False,False,’F’),2), ((False,False,True,False,’M’),1)]

Question 1c:

Write “rank’’ function

You will write a function called “rank’’ which returns a number indicating how many superior properties a wug has.

● Input: a tuple describing an individual wug (in which the very first element is
genome)

● Returns: a number of superior characteristics that the given wug demonstrates

Question 1c: examples
>>> genome2features(genome_sample1)
[False, False, False, False]
>>> genome2features(genome_sample2)
[False, False, True, False]
>>> genome2features(genome_sample3)
[True, True, True, False]
>>> genome2features(genome_sample4)
[False, False, True, True]
>>> rank((genome_sample1, ‘F’))
0
>>> rank((genome_sample2, ‘M’))
1
>>> rank((genome_sample3, ‘M’))
3
>>> rank((genome_sample4, ‘F’))
2

Question 2a:

Implement ranked wug population

You will write a function called “insert_ranked’’ which adds an element to a list keeping the list
● sorted according to the rank (in a descending order)
● not exceeding a predefined maximum number of elements
● preserving chronological order of elements whenever a rank tie occurs
● Input: a list to insert into; a new element; a ranking function (a reference to the `rank’ function); (opt.; default value = 64) the maximum number of elements in the list
● Returns nothing but modifies the list

Question 2a: examples

>>> population = [ (genome_sample2, ‘F’), (genome_sample1, ‘M’) ]
l>>> list(map(rank, population)) [1, 0]
>>> insert_ranked(population, (genome_sample1, ‘M’), rank, 4)
>>> list(map(rank, population))
[1, 0, 0]
>>> insert_ranked(population, (genome_sample3, ‘F’), rank, 4)
>>> population
[([1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0], ‘F’), ([1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0], ‘F’), ([0,
1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0], ‘M’), ([0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0], ‘M’)]
>>> list(map(rank, population))
[3, 1, 0, 0]

Question 2a: examples (contd.)

>> insert_ranked(population, (genome_sample2, ‘F’), rank, 4)
>>> list(map(rank, population)) [3, 1, 1, 0]

>> insert_ranked(population, (genome_sample1, ‘M’), rank, 4)

# Nothing has been inserted due to a low rank of new record (=0) + the max size limit

>> population

[([1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0], ‘F’), ([1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0], ‘F’), ([1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0], ‘F’), ([0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0], ‘M’)]

>> list(map(rank, population))

[3, 1, 1, 0]

Question 2b:

Implement wug cloning with gene mutations

You will write a function called “proliferate’’ which clones 16 wugs from each existing wug in a population. Each cloned wug has exactly one gene altered from its cloned value, at different positions across the mentioned 16 wugs.

Use previously developed “insert_ranked’’ function to put the offsprings to the population, accounting for the population size limit and ranking requirements.

● Input: a population, i.e. a list of (genome, sex) tuples
● Returns nothing but modifies the list

Question 2b: example
>>> population = [([0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], ‘F’)]
>>> proliferate(population)
>>> population

[([0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], ‘F’), ([1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], ‘F’, 1),

([0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], ‘F’), ([0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], ‘F’), ([0,
1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], ‘F’), ([0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], ‘F’), ([0, 1, 0,
1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], ‘F’), ([0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1], ‘F’), ([0, 1, 0, 1, 0,
1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1], ‘F’), ([0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1], ‘F’), ([0, 1, 0, 1, 0, 1, 0,
1, 0, 0, 0, 1, 0, 1, 0, 1], ‘F’), ([0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1], ‘F’), ([0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 0, 0, 1, 0, 1], ‘F’), ([0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1], ‘F’), ([0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 0, 0, 1], ‘F’), ([0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1], ‘F’), ([0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0], ‘F’)]

Question 3:

Implement breeding cycle

A function “breed(population)’’ should do the following.
For each individual, accounting for their rank (from higher to lower):
Find the best matching individual of the opposite sex, where ‘best matching’ here means having more matching characteristics. In the case of tie, choose the one having lower index in population (associated with higher
rank).

● Combine the first half of female wug genome with the second half of male one to compose a basic offspring genome.

● Produce 16 offsprings with single gene modified at different positions (in ascending order or position). The sex of each offspring with gene mutation should be chosen in such a way that the mutation it bears is able to be promoted to futher generations,

Use previously developed `insert_ranked’’ function to add the offsprings to the population, accounting for the population size limit and ranking requirements.

Then produce two offsprings (of different sex) with the unchanged combined genome.

● Input: a population, i.e. a list of (genome, sex, …) tuples
● Returns nothing but modifies the list

Question 4:

SuperWugs: Make it Faster

Implement a loop that runs proliferation or breeding multiple times until at least one super wug with all the four properties developed to a superior level occurs in population.

Initialize the population with two wugs of different sex, with genomes filled by zero values. Find the best combination of proliferation and breeding rounds that leads to faster obtaining the first N super wugs in a population. Then, find the combination needed to achieve 100% super wugs in a population.