java codility training Genomic-range-query

后端 未结 30 2265
悲哀的现实
悲哀的现实 2021-02-01 12:47

The task is:

A non-empty zero-indexed string S is given. String S consists of N characters from the set of upper-case English letters A, C, G, T.

<
相关标签:
30条回答
  • 2021-02-01 13:26

    My C++ solution

    vector<int> solution(string &S, vector<int> &P, vector<int> &Q) {
    
        vector<int> impactCount_A(S.size()+1, 0);
        vector<int> impactCount_C(S.size()+1, 0);
        vector<int> impactCount_G(S.size()+1, 0);
    
        int lastTotal_A = 0;
        int lastTotal_C = 0;
        int lastTotal_G = 0;
        for (int i = (signed)S.size()-1; i >= 0; --i) {
            switch(S[i]) {
                case 'A':
                    ++lastTotal_A;
                    break;
                case 'C':
                    ++lastTotal_C;
                    break;
                case 'G':
                    ++lastTotal_G;
                    break;
            };
    
            impactCount_A[i] = lastTotal_A;
            impactCount_C[i] = lastTotal_C;
            impactCount_G[i] = lastTotal_G;
        }
    
        vector<int> results(P.size(), 0);
    
        for (int i = 0; i < P.size(); ++i) {
            int pIndex = P[i];
            int qIndex = Q[i];
    
            int numA = impactCount_A[pIndex]-impactCount_A[qIndex+1];
            int numC = impactCount_C[pIndex]-impactCount_C[qIndex+1];
            int numG = impactCount_G[pIndex]-impactCount_G[qIndex+1];
    
            if (numA > 0) {
                results[i] = 1;
            }
            else if (numC > 0) {
                results[i] = 2;
            }
            else if (numG > 0) {
                results[i] = 3;
            }
            else {
                results[i] = 4;
            }
        }
    
        return results;
    }
    
    0 讨论(0)
  • 2021-02-01 13:26

    I implemented a Segment Tree solution in Kotlin

    import kotlin.math.*
    
    fun solution(S: String, P: IntArray, Q: IntArray): IntArray {
    
        val a = IntArray(S.length)
        for (i in S.indices) {
            a[i] = when (S[i]) {
                'A' -> 1
                'C' -> 2
                'G' -> 3
                'T' -> 4
                else -> throw IllegalStateException()
            }
        }
    
        val segmentTree = IntArray(2*nextPowerOfTwo(S.length)-1)
        constructSegmentTree(a, segmentTree, 0, a.size-1, 0)
    
        val result = IntArray(P.size)
        for (i in P.indices) {
            result[i] = rangeMinQuery(segmentTree, P[i], Q[i], 0, a.size-1, 0)
        }
        return result
    }
    
    fun constructSegmentTree(input: IntArray, segmentTree: IntArray,  low: Int,  high: Int,  pos: Int) {
    
        if (low == high) {
            segmentTree[pos] = input[low]
            return
        }
        val mid = (low + high)/2
        constructSegmentTree(input, segmentTree, low, mid, 2*pos+1)
        constructSegmentTree(input, segmentTree, mid+1, high, 2*pos+2)
        segmentTree[pos] = min(segmentTree[2*pos+1], segmentTree[2*pos+2])
    }
    
    fun rangeMinQuery(segmentTree: IntArray, qlow:Int, qhigh:Int ,low:Int, high:Int, pos:Int): Int {
    
        if (qlow <= low && qhigh >= high) {
            return segmentTree[pos]
        }
        if (qlow > high || qhigh < low) {
            return Int.MAX_VALUE
        }
        val mid = (low + high)/2
        return min(rangeMinQuery(segmentTree, qlow, qhigh, low, mid, 2*pos+1), rangeMinQuery(segmentTree, qlow, qhigh, mid+1, high, 2*pos+2))
    }
    
    fun nextPowerOfTwo(n:Int): Int {
        var count = 0
        var number = n
        if (number > 0 && (number and (number - 1)) == 0) return number
        while (number != 0) {
            number = number shr 1
            count++
        }
        return 1 shl count
    }
    
    0 讨论(0)
  • 2021-02-01 13:27

    scala solution 100/100

    import scala.annotation.switch
    import scala.collection.mutable
    
    object Solution {
      def solution(s: String, p: Array[Int], q: Array[Int]): Array[Int] = {
    
        val n = s.length
    
        def arr = mutable.ArrayBuffer.fill(n + 1)(0L)
    
        val a = arr
        val c = arr
        val g = arr
        val t = arr
    
        for (i <- 1 to n) {
          def inc(z: mutable.ArrayBuffer[Long]): Unit = z(i) = z(i - 1) + 1L
    
          def shift(z: mutable.ArrayBuffer[Long]): Unit = z(i) = z(i - 1)
    
          val char = s(i - 1)
          (char: @switch) match {
            case 'A' => inc(a); shift(c); shift(g); shift(t);
            case 'C' => shift(a); inc(c); shift(g); shift(t);
            case 'G' => shift(a); shift(c); inc(g); shift(t);
            case 'T' => shift(a); shift(c); shift(g); inc(t);
          }
        }
    
        val r = mutable.ArrayBuffer.fill(p.length)(0)
    
        for (i <- p.indices) {
          val start = p(i)
          val end = q(i) + 1
          r(i) =
            if (a(start) != a(end)) 1
            else if (c(start) != c(end)) 2
            else if (g(start) != g(end)) 3
            else if (t(start) != t(end)) 4
            else 0
        }
    
        r.toArray
      }
    }
    
    0 讨论(0)
  • 2021-02-01 13:28

    This is my JavaScript solution that got 100% across the board on Codility:

    function solution(S, P, Q) {
        let total = [];
        let min;
    
        for (let i = 0; i < P.length; i++) {
            const substring = S.slice(P[i], Q[i] + 1);
            if (substring.includes('A')) {
                min = 1;
            } else if (substring.includes('C')) {
                min = 2;
            } else if (substring.includes('G')) {
                min = 3;
            } else if (substring.includes('T')) {
                min = 4;
            }
            total.push(min);
        }
        return total;
    }
    
    0 讨论(0)
  • 2021-02-01 13:28

    If someone is still interested in this exercise, I share my Python solution (100/100 in Codility)

    def solution(S, P, Q):
    
        count = []
        for i in range(3):
            count.append([0]*(len(S)+1))
    
        for index, i in enumerate(S):
            count[0][index+1] = count[0][index] + ( i =='A')
            count[1][index+1] = count[1][index] + ( i =='C')
            count[2][index+1] = count[2][index] + ( i =='G')
    
        result = []
    
        for i in range(len(P)):
          start = P[i]
          end = Q[i]+1
    
          if count[0][end] - count[0][start]:
              result.append(1)
          elif count[1][end] - count[1][start]:
              result.append(2)
          elif count[2][end] - count[2][start]:
              result.append(3)
          else:
              result.append(4)
    
        return result
    
    0 讨论(0)
  • 2021-02-01 13:28

    perl 100/100 solution:

    sub solution {
        my ($S, $P, $Q)=@_; my @P=@$P; my @Q=@$Q;
    
        my @_A = (0), @_C = (0), @_G = (0), @ret =();
        foreach (split //, $S)
        {
            push @_A, $_A[-1] + ($_ eq 'A' ? 1 : 0);
            push @_C, $_C[-1] + ($_ eq 'C' ? 1 : 0);
            push @_G, $_G[-1] + ($_ eq 'G' ? 1 : 0);
        }
    
        foreach my $i (0..$#P)
        {
            my $from_index = $P[$i];
            my $to_index = $Q[$i] + 1;
            if ( $_A[$to_index] - $_A[$from_index] > 0 )
            {
                push @ret, 1;
                next;
            }
            if ( $_C[$to_index] - $_C[$from_index] > 0 )
            {
                push @ret, 2;
                next;
            }
            if ( $_G[$to_index] - $_G[$from_index] > 0 )
            {
                push @ret, 3;
                next;
            }
            push @ret, 4
        }
    
        return @ret;
    }
    
    0 讨论(0)
提交回复
热议问题