细胞竞争问题

问题描述 投票:0回答:25

这是我的作业:

有一个由 8 个细胞组成的菌落,排列成一条直线,每天每个细胞都与其相邻的细胞(邻居)竞争。每天,对于每个单元格,如果其邻居都处于活动状态或都处于非活动状态,则该单元格在第二天就会变为非活动状态。否则第二天就会激活。

假设:两端的两个单元格有一个相邻的单元格,所以 可以假设另一个相邻小区始终处于不活动状态。甚至 更新单元格状态后。考虑其先前状态 更新其他细胞的状态。更新小区信息 所有细胞同时。

编写一个函数 cellCompete,它需要一个 8 元素数组 代表 8 个单元格和 1 个单元格当前状态的整数单元格 表示要模拟的天数的整数天。一个整数 值 1 表示活动单元格,值 0 表示单元格 不活跃的细胞。

节目:

int* cellCompete(int* cells,int days)
{
//write your code here
} 
//function signature ends

Test Case 1:
INPUT:
[1,0,0,0,0,1,0,0],1
EXPECTED RETURN VALUE:
[0,1,0,0,1,0,1,0]

Test Case 2:
INPUT:
[1,1,1,0,1,1,1,1,],2
EXPECTED RETURN VALUE:
[0,0,0,0,0,1,1,0]

这是上面针对该问题给出的问题陈述。下面给出了我为这个问题编写的代码。但输出与输入相同。

#include<iostream>
using namespace std;

// signature function to solve the problem
int *cells(int *cells,int days)
{   int previous=0;
    for(int i=0;i<days;i++)
    {

        if(i==0)
        {
            if(cells[i+1]==0)
            {

            previous=cells[i];
            cells[i]=0;
        }

        else
        {

            cells[i]=0;
        }       


        if(i==days-1)
        {
            if(cells[days-2]==0)
            {
                previous=cells[days-1];
                cells[days-1]=0;
            }
        else
        {
            cells[days-1]=1;
        }
        }



        if(previous==cells[i+1])
        {
            previous=cells[i];
            cells[i]=0;
        }

        else
        {
            previous=cells[i];
            cells[i]=1;
        }
    }

            }
return cells;
}




int main()
{
    int array[]={1,0,0,0,0,1,0,0};
    int *result=cells(array,8);
    for(int i=0;i<8;i++)
    cout<<result[i];
}

我无法得到错误,我认为我的逻辑是错误的。我们可以在这里应用动态规划吗?如果可以,那么如何应用?

arrays data-structures
25个回答
3
投票
private List<Integer> finalStates = new ArrayList<>();

public static void main(String[] args) {
    // int arr[] = { 1, 0, 0, 0, 0, 1, 0, 0 };
    // int days = 1;
    EightHousePuzzle eightHousePuzzle = new EightHousePuzzle();
    int arr[] = { 1, 1, 1, 0, 1, 1, 1, 1 };
    int days = 2;
    eightHousePuzzle.cellCompete(arr, days);
}

public List<Integer> cellCompete(int[] states, int days) {
    List<Integer> currentCellStates = Arrays.stream(states).boxed().collect(Collectors.toList());
    return getCellStateAfterNDays(currentCellStates, days);
}

private List<Integer> getCellStateAfterNDays(List<Integer> currentCellStates, int days) {
    List<Integer> changedCellStates = new ArrayList<>();
    int stateUnoccupied = 0;
    if (days != 0) {
        for (int i1 = 0; i1 < currentCellStates.size(); i1++) {
            if (i1 == 0) {
                changedCellStates.add(calculateCellState(stateUnoccupied, currentCellStates.get(i1 + 1)));

            } else if (i1 == 7) {
                changedCellStates.add(calculateCellState(currentCellStates.get(i1 - 1), stateUnoccupied));

            } else {
                changedCellStates
                        .add(calculateCellState(currentCellStates.get(i1 - 1), currentCellStates.get(i1 + 1)));
            }
        }
        if (days == 1) {
            System.out.println("days ==1 hit");
            finalStates = new ArrayList<>(changedCellStates);
            return finalStates;
        }
        days = days - 1;
        System.out.println("Starting recurssion");
        getCellStateAfterNDays(changedCellStates, days);
    }
    return finalStates;
}

private int calculateCellState(int previousLeft, int previousRight) {
    if ((previousLeft == 0 && previousRight == 0) || (previousLeft == 1 && previousRight == 1)) {
        // the state gets now changed to 0
        return 0;
    }
        // the state gets now changed to 0
    return 1;
}

3
投票

这是我的Java解决方案:

public class Colony
{
  public static int[] cellCompete(int[] cells, int days)
  {
    int oldCell[]=new int[cells.length];
    for (Integer i = 0; i < cells.length ; i++ ){
        oldCell[i] = cells[i];
    }
    for (Integer k = 0; k < days ; k++ ){
        for (Integer j = 1; j < oldCell.length - 1 ; j++ ){
            if ((oldCell[j-1] == 1 && oldCell[j+1] == 1) || (oldCell[j-1] == 0 && oldCell[j+1] == 0)){
                cells[j] = 0;
            } else{
                cells[j] = 1;
            }
        }
        if (oldCell[1] == 0){
            cells[0] = 0;
        } else{
            cells[0] = 1;
        }
        if (oldCell[6] == 0){
            cells[7] = 0;
        } else{
            cells[7] = 1;
        }
        for (Integer i = 0; i < cells.length ; i++ ){
            oldCell[i] = cells[i];
        }
    } 
    return cells;
  }
}

2
投票

您的程序不区分模拟天数和单元格数量。


2
投票
#include <bits/stdc++.h>
using namespace std;
int* cellCompete(int* cells,int days)
{
    for(int j=0; j<days; j++)
    {
        int copy_cells[10];
        for(int i=1; i<9; i++)
            copy_cells[i]=cells[i-1];

        copy_cells[0]=0;copy_cells[9]=0;
        for(int i=0; i<8; i++)
            cells[i]=copy_cells[i]==copy_cells[i+2]?0:1;
    }
    return cells;
}

int main()
{
    int arr[8]={1,1,1,0,1,1,1,1};
    int arr2[8]={1,0,0,0,0,1,0,0};
    cellCompete(arr2,1);
    for(int i=0; i<8; i++)
    {
        cout<<arr2[i]<<" ";
    }
}

2
投票

这里有一些可爱的小Python代码:

def cell(arr, days):
    new = arr[:] #get a copy of the array
    n = len(arr)

    if n == 1: print [0] #when only 1 node, return [0]

    for _ in range(days):
        new[0] = arr[1] #determine the edge nodes first
        new[n - 1] = arr[n - 2]

        for i in range(1, n-1):
            new[i] = 1 - (arr[i-1] == arr[i+1]) #logic for the rest nodes
        arr = new[:] #update the list for the next day

    return new

arr = [1, 1, 1, 0, 1, 1, 1, 1]
days = 2
print cell(arr, days)

2
投票

只需几行代码,您就可以在 Javascript 中轻松完成此操作

let cells = [1,1,1,0,1,1,1,1];
let numOfDays = 2;

let changeState = (cellarr)=> cellarr.map((cur, idx, arr)=> (arr[idx-1] ||0) + (arr[idx+1] || 0)===1?1:0);

let newCells =cells;
for (let i = 0 ; i <numOfDays; i++) newCells = changeState(newCells);


console.log(newCells);

2
投票

这是可能答案的 C# 版本。由于某种原因,我真的为此苦苦挣扎了一段时间! 我还融入了上面 Janardan 的一些内容,因为它帮助我朝着正确的方向前进。 (干杯!)

问题的棘手部分是处理这样一个事实:您必须保留单元格的状态才能找出下一个单元格竞争,我最初尝试使用第二个混乱的数组。

注意: 我选择使用 Array.Copy 方法,因为我相信它比在通读时使用 for 循环复制数组更高效且更具可读性。

希望这对将来的人有帮助!

   public int[] cellCompete(int[] cell, int day)
    {
        //First create an array with an extra 2 cells (these represent the empty cells on either end)
        int[] inputArray = new int[cell.Length + 2];

        //Copy the cell array into the new input array leaving the value of the first and last indexes as zero (empty cells)
        Array.Copy(cell, 0, inputArray, 1, cell.Length);    

        //This is cool I stole this from the guy above! (cheers mate), this decrements the day count while checking that we are still above zero.
        while (day-- > 0) 
        {
            int oldCellValue = 0;

            //In this section we loop through the array starting at the first real cell and going to the last real cell
            //(we are not including the empty cells at the ends which are always inactive/0)

            for (int i = 1; i < inputArray.Length - 1; i++)
            {
                //if the cells below and above our current index are the same == then the target cell will be inactive/0
                //otherwise if they are different then the target cell will be set to active/1
                //NOTE: before we change the index value to active/inactive state we are saving the cells oldvalue to a variable so that
                //we can use that to do the next "cell competition" comparison (this fulfills the requirement to update the values at the same time)

                if (oldCellValue == inputArray[i + 1])
                {
                    oldCellValue = inputArray[i];
                    inputArray[i] = 0;
                }
                else
                {
                    oldCellValue = inputArray[i];
                    inputArray[i] = 1;
                }
            }
        }

        //Finally we create a new output array that doesn't include the empty cells on each end
        //copy the input array to the output array and Bob's yer uncle ;)...(comments are lies)

        int[] outputArray = new int[cell.Length];
        Array.Copy(inputArray, 1, outputArray, 0, outputArray.Length);
        return outputArray;
    }

2
投票

使用C#

    public static int[] cellCompete(int[] states, int days)
    {
        if (days == 0) return states;
        int leftValue = 0;
        int rigthValue = 0;
        for (int i = 0; i < states.Length; i++)
        {

            if (i == states.Length - 1)
                rigthValue = 0;
            else
                rigthValue = states[i + 1];
            if (leftValue == rigthValue){
                leftValue = states[i];
                states[i] = 0;
            }
            else{                    
                leftValue = states[i];
                states[i] = 1;
            }
        }
        cellCompete(states, days - 1);
        return states;
    }

2
投票

我认为上面的一些答案可能更具可读性(除了更高效之外)。使用额外的阵列并根据天数在它们之间交替更新。您可以返回最近更新的数组,该数组始终是正确的。像这样:

    function cellCompete(states, days) {
        const newStates = [];
        let originalStates = true;
    
        while (days--) {
            changeStates(
              originalStates ? states : newStates,
              originalStates ? newStates : states,
              states.length
            );
    
            originalStates = !originalStates;
        }
    
        return originalStates ? states : newStates;
    }
    
    function changeStates(states, newStates, len) {
        newStates[0] = !states[1] ? 0 : 1;
        newStates[len-1] = !states[len-2] ? 0 : 1;
    
        for (let i = 1; i < len - 1; i++) {
            newStates[i] = states[i-1] === states[i+1] ? 0 : 1;
        }
    }

1
投票

这是我在 c++ 中使用 bitwise 运算符的解决方案:

#include <iostream>

using namespace std;

void cellCompete( int *arr, int days )
{
    int num = 0;
    for( int i = 0; i < 8; i++ )
    {
        num = ( num << 1 ) | arr[i];
    }

    for( int i = 0; i < days; i++ )
    {
        num = num << 1;
        num = ( ( ( num << 1 ) ^ ( num >> 1 ) ) >> 1 ) & 0xFF;
    }

    for( int i = 0; i < 8; i++ )
    {
        arr[i] = ( num >> 7 - i ) & 0x01;
    }
}

int main()
{
    int arr[8] = { 1, 0, 0, 0, 0, 1, 0, 0};
    cellCompete( arr, 1 );
    for(int i = 0; i < 8; i++)
    {
        cout << arr[i] << " ";
    }
}

0
投票
#include <stdio.h>
int main() {

    int days,ind,arr[8],outer;
    for(ind=0;ind<8;scanf("%d ",&arr[ind]),ind++);    //Reading the array
    scanf("%d",&days);
    int dupArr[8];
    for(outer=0;outer<days;outer++){ //Number of days to simulate
        for(ind=0;ind<8;ind++){    //Traverse the whole array
        //cells on the ends have single adjacent cell, so the other adjacent cell can be assumsed to be always inactive
            if(ind==0){
                if(arr[ind+1]==0)
                    dupArr[ind]=0;
                else
                    dupArr[ind]=1;
            }
            else if(ind==7){
                if(arr[ind-1]==0)
                    dupArr[ind]=0;
                else
                    dupArr[ind]=1;
            }
            else{
                if((arr[ind-1]==0&&arr[ind+1]==0) || (arr[ind-1]==1&&arr[ind+1]==1)){// if its neighbours are both active or both inactive, the cell becomes inactive the next day
                    dupArr[ind]=0;
                }
                else  //otherwise it becomes active the next day
                    dupArr[ind]=1;
            }
        }
        for(ind=0;ind<8;ind++){
            arr[ind]=dupArr[ind]; //Copying the altered array to original array, so that we can alter it n number of times.
        }
    }
    for(ind=0;ind<8;ind++)
        printf("%d ",arr[ind]);//Displaying output
    return 0;
}



这是我几个月前创建的代码,

  • 您想要创建两个不同的数组,因为更改相同的数组元素会产生不同的结果。

0
投票
func competeCell(cell []uint, days uint) []uint{
    n := len(cell)
    temp := make([]uint, n)
    for i :=0; i < n; i ++ {
        temp[i] = cell[i]
    }

    for days > 0 {
        temp[0] = 0 ^ cell[1]
        temp[n-1] = 0 ^ cell[n-2]

        for i := 1; i < n-2 +1; i++ {
            temp[i] = cell[i-1] ^ cell[i +1]
        }
        for i:=0; i < n; i++ {
            cell[i] = temp[i]
        }
        days -= 1
    }
    return cell
}

0
投票

使用c++

#include <list> 
#include <iterator> 
#include <vector>
using namespace std;
vector<int> cellCompete(int* states, int days) 
{
    vector<int> result1;
    int size=8;
    int list[size];
    int counter=1;
    int i=0;
    int temp;

    for(int i=0;i<days;i++)//computes upto days
    {
        vector<int> result;
         if(states[counter]==0)
         {
         temp=0;
         list[i]=temp;
         //states[i]=0;
         result.push_back(temp);
     }
     else
     {
         temp=1;
         list[i]=temp;
         result.push_back(temp);
     }

        for(int j=1;j<size;j++)
        {
            if(j==size)
            {
                if(states[j-1]==0)
                {
                    temp=0;
                    list[j]=temp;
                    //states[i]=1;
                    result.push_back(temp);
                }
                else
                {
                 temp=1;
                 list[i]=temp;
                  //states[i]=1;
                  result.push_back(temp);   
                }
            }
            else if(states[j-1]==states[j+1])
            {
             temp=0;
             list[j]=temp;
           //states[i]=1;
             result.push_back(temp);
            }
            else
            {
            temp=1;
            list[j]=temp;
            //states[i]=1;
            result.push_back(temp);
            }
        }
        result1=result;
        for(int i=0;i<size;i++)
        {
            states[i]=list[i];
        }
    }
    return result1;
}

0
投票

Java解决方案

这是 Java 解决方案,它将在任意数量的单元和任意天数内工作。

    public class Solution
{
    public List<Integer> cellCompete(int[] states, int days)
    {
        List<Integer> inputList = new ArrayList<Integer>();
        List<Integer> finalList = new ArrayList<Integer>();
  
  // Covert integer array as list 
        
    for (int i :states)
        {
            inputList.add(i);
        }
        
 //  for loop for finding status after number of days. 

        for(int i=1; i<= days; i++)
        {
            if(i==1)
            {
                finalList = nextDayStatus(inputList);
            }
            else
            {
                finalList = nextDayStatus(finalList);
            }
            
        }
        return finalList;
    }

    //  find out status of next day, get return as list 

    public List<Integer> nextDayStatus(List<Integer> input)
    {
        List<Integer> output = new ArrayList<Integer>();
        input.add(0,0);
        input.add(0);
      
        for(int i=0; i < input.size()-2; i++)
        {
            if (input.get(i) == input.get(i+2))
            {
                output.add(0);   
            }
            else
            {
                output.add(1);
            }
        }
        return output;
    }
}

0
投票

我知道这个问题已经得到解答,但我在 Java 中尝试了一下,并且非常确定它适用于任何大小的状态数组以及天数:

public class CellCompete {

  public static List<Integer> cellCompete(int[] states, int days) {

    List<Integer> resultList = new ArrayList<>();

    int active = 1, inactive = 0;

    int dayCount = 1;

    // Execute for the given number of days
    while (days > 0) {

        int[] temp = new int[states.length];
        System.out.print("Day " + dayCount + ": ");

        // Iterate through the states array
        for (int i = 0; i < states.length; i++) {

            // Logic for first end cell
            if (i == 0) {
                temp[i] = states[i + 1] == active ? active : inactive;
                resultList.add(temp[i]);
                System.out.print(temp[i] + ", ");
            }

            // Logic for last end cell
            if (i == states.length - 1) {
                temp[i] = states[i - 1] == active ? active : inactive;
                resultList.add(temp[i]);
                System.out.println(temp[i]);
            }

            // Logic for the in between cells
            if (i > 0 && i < states.length - 1) {
                if ((states[i - 1] == active && states[i + 1] == active) || (states[i - 1] == inactive && states[i + 1] == inactive)) {
                    temp[i] = inactive;
                } else {
                    temp[i] = active;
                }
                resultList.add(temp[i]);
                System.out.print(temp[i] + ", ");
            }
        }
        dayCount++;
        days--;
        // Reset the states array with the temp array
        states = temp;
    }

    return resultList;
  }

  public static void main(String[] args) {

    int[] states = {1, 1, 0, 1, 0, 1, 0, 0};
    int days = 5;

    // Total of 40
    System.out.println(cellCompete(states, days) );
  }
}

0
投票

想要优化解决方案的人去了哪里?

def Solution(states, days):
    for i in range(days):
        for j in range(len(states)):
            if (j == 0):
                states[i] = states[1]
            elif (j == len(states)-1):
                states[i] = states[-2]
            else:
                states[i] = abs(states[i-1] - states[i+1])

    return states

0
投票

根据定义,所有单元格,包括不存在的单元格,实际上都是布尔值:

var cellUpdate =(单元格,天数)=> {

let result = [];
// update states
for(let i = 0; i < cells.length; i++)  result.push((!Boolean(cells[i-1]) === !Boolean(cells[i+1])) ? 0 : 1) ;
    
// repeat for each day
if (days > 1) result = cellUpdate(result, days - 1);
    
return result;

0
投票

这是最好的Python解决方案

value=input()
n=int(input())
lst=[]
for i in value:
    if "1"in i:
        lst.append(1)
    elif "0" in i:
        lst.append(0)

for _ in range(n):
    store = []
    for i in range(8):
        if i==0:
            store.append(lst[i+1])

        elif i==7:
            store.append(lst[i-1])
        elif lst[i-1]==lst[i+1]:
            store.append(0)
        else:
            store.append(1)
    lst=store

print(store)


0
投票

Scala 解决方案:

def cellDayCompete(cells: Seq[Int]): Seq[Int] = {
    val addEdges = 0 +: cells :+ 0
    (addEdges.dropRight(2) zip addEdges.drop(2)).map {
      case (left, right) =>
        (left - right).abs
    }
}

def cellCompete(cells: Seq[Int], days: Int): Seq[Int] = {
    if (days == 0) {
        cells
    } else {
        cellCompete(cellDayCompete(cells), days - 1)
    }
}

使用上述示例运行的代码可以在 Scastie

找到

0
投票

今天刚刚回答了这个问题,这是我在 python3 中的解决方案

def cellCompete(states, days):
for i in range(0, days):
    #this is where we will hold all the flipped states
    newStates = []

    '''
    Algo: if neigbors are the same, append 0 to newStates
          if they are different append 1 to newStates
    '''

    for currState in range(len(states)):
        #left and right ptr's
        left = currState - 1
        right = currState + 1

        #if at beginning of states, left is automatically inactive
        if left < 0:
            if states[right] == 1:
                newStates.append(1)
            else:
                newStates.append(0)
        #if at end of states, right is automatically inactive
        elif right > 7: #we know there is always only 8 elems in the states list
            if states[left] == 1:
                newStates.append(1)
            else
                newStates.append(0)
        #check to see if neighbors are same or different
        elif states[left] != states[right]:
            newStates.append(1)
        else:
            newStates.append(0)

    #Set the states equal to the new flipped states and have it loop N times to get final output.
    states = newStates

return states

0
投票
def cellCompete(states, days):

  d = 0
  l = len(states)

  while d < days:
      new_states = [0] * l
      
      for i in range(l):
          if i == 0 and states[i+1] == 0 or i == l - 1 and states[i-1] == 0:
              new_states[i] = 0
          elif i == 0 and states[i+1] == 1 or i == l - 1 and states[i-1] == 1:
              new_states[i] = 1
          elif states[i+1] == states[i-1]:
              new_states[i] = 0
          else:
              new_states[i] = 1
      states = new_states
      d = d + 1
    
  return states

0
投票

Python 解决方案

for day in range(days):
    new_state = []
    for ind, state in enumerate(states):
        if ind == 0:
            if states[ind + 1]==0:
                new_state.append(0)
            else:
                new_state.append(1)
        elif ind == len(states) - 1:
            if states[ind - 1]==0:
                new_state.append(0)
            else:
                new_state.append(1)
        else:
            if (states[ind - 1]==1 and states [ind + 1]==1) or \
                (states[ind - 1]==0 and states [ind + 1]==0):
                new_state.append(0)
            else:
                new_state.append(1)
    states = new_state
return new_state

-1
投票
    static int[] CellCompete(int[] states, int days)
    {
        int e = states.Length;
        int[] newStates = new int[(e+2)];
        newStates[0] = 0;
        newStates[e+1] = 0;
        Array.Copy(states, 0, newStates, 1, e);
        for (int d = 0; d < days; d++)
        {
            states = Enumerable.Range(1, e).Select(x => newStates[x - 1] ^ newStates[x + 1]).ToArray();
            newStates[0] = 0;
            newStates[e + 1] = 0;
            Array.Copy(states, 0, newStates, 1, e);
        }
        return states;
    }

-1
投票

//这是 C# 中此问题的有效解决方案

public class HousesinSeq
{
    private string _result;

    public string Result
    {
        get { return _result; }
    }
    public void HousesActivation(string houses, int noOfDays)
    {

        string[] housesArr = houses.Split(' ');
        string[] resultArr = new string[housesArr.Length];

        for (int i = 0; i < noOfDays; i++)
        {
            for (int j = 0; j < housesArr.Length; j++)
            {
                if (j == 0)
                {
                    if (housesArr[j + 1] == "0")
                    {
                        resultArr[j] = "0";
                    }
                    else
                    {
                        resultArr[j] = "1";
                    }
                }
                else if (j == housesArr.Length - 1)
                {
                    if (housesArr[j - 1] == "0")
                    {
                        resultArr[j] = "0";
                    }
                    else
                    {
                        resultArr[j] = "1";
                    }
                }
                else
                {
                    if (housesArr[j + 1] == housesArr[j - 1])
                    {
                        resultArr[j] = "0";
                    }
                    else
                    {
                        resultArr[j] = "1";
                    }
                }
            }
            resultArr.CopyTo(housesArr, 0);
        }

        foreach (var item in resultArr)
        {
            //Console.Write($"{item} ");

            _result += item + " ";

        }
        _result = _result.Trim();

    }
}

-2
投票
public class Colony {
    public static int[] cellCompete(int[] cell, int day) {
        int[] ar = new int[10];
        for(int i=1; i<9; i++) {
            ar[i] = cell[i-1];
        }
        while(day-- >0) {
            int temp = 0;
            for(int i=1; i<9; i++) {
                if(Math.abs(temp-ar[i+1])==1) {
                    temp = ar[i];
                    ar[i] = 1;
                }
                else {
                    temp = ar[i];
                    ar[i] = 0;
                }
            }
        }
        return ar;
    }

    public static void main(String[] args) {

        int[] cell = {1,0,1,1,0,1,0,1};
        int day = 1;
        cell = cellCompete(cell, day);
        for(int i=1; i<9; i++) {
            System.out.print(cell[i]+" ");
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.