Friday, September 13, 2024

 Estimation: 

Infrastructure changes need to be estimated just like any software changes, which means external dependencies and internal restrictions shape the scope, depth, and form of change. Estimation can be hard when the change appears simple but turns out to be complex. A specific case study might illustrate the challenges and norms of this kind of task.

One of the most routine encountered cases of software migration to the cloud is the migration of entire Kubernetes workload. As an ecosystem of its own supporting state reconciliation of resources for applications, workflows, orchestrations, and data store managers. As an instance of a resource type in the public cloud, it is a unit that lends itself to the management from the public cloud console. One of the management activities of this resource is its move from one location to another or one network to another. When switching just the network integration for outbound traffic for this network, it might be tempting to think of it as a property change of a resource that amounts to in-place update. But this is just the tip of the iceberg. Different methodologies and formulae for estimation although applicable to many scenarios do not apply to this case-study without further investigation. 

In this case, the instance has a default node pool and many additional node pools that may still be referencing the old network even with directive to switch to new network. They also happen to refer to additional storage accounts for facilitating the creation of persistent volumes as key vaults for storing secrets. If these satellite resources are also restricting traffic to private planes, then networking and authentication must both be enabled from the new network. 

The infrastructure changes for this might also not be straight forward single-pass and require iterative maneuvers to make incremental progress. This is specifically the case when the IaC compiler encounters multiple other resources and detect changes in them  the path of minimal changes to the infrastructure will imply the lowest cost and this works very well if we can wipe clean and create with the same specifications as earlier but with the new network.

Thus, estimation of infrastructure is heavily dependent on what the resource needs, the changes being made to it and what the compiler detects as mandatory to perform before applying the change. 

Reference: previous article in this series: https://1drv.ms/w/s!Ashlm-Nw-wnWhPQxEDH6Cm567ZzPug?e=yTLB2D


Thursday, September 12, 2024

 

A list of packets is given with varying sizes and there are n channels. 

 

Each of the n channel must have a single packet 

Each packet can only be on a single channel 

The quality of a channel is described as the median of the packet sizes on that channel. The total quality is defined as sum of the quality of all channels (round to integer in case of float). Given the packets []int32 and channels int32 find the maximum quality. 

 

Example 1: 

 

packets := []int32{1, 2, 3, 4, 5} 

channels := 2 

 

// Explanation: If packet {1, 2, 3, 4} is sent to channel 1, the median of that channel would be 2.5. 

//               If packet {5} is sent to channel 2 its median would be 5.  

//               Total quality would be 2.5 + 5 = 7.5 ~ 8 

answer := 8 

Example 2: 

 

packets := []int32{5, 2, 2, 1, 5, 3} 

channels := 2 

 

// Explaination: Channel 1: {2, 2, 1, 3} (median: 2) 

//               Channel 2: {5, 5}       (median: 5) 

//               Total Quality : 2 + 5 = 7 

 

// Explaination 2: Channel 1: {5, 2, 2, 1, 3} (median: 2) 

//                 Channel 2: {5}             (median: 5) 

//                 Total Quality : 2 + 5 = 7 

answer := 7 

 

 

import java.util.*; 

import java.lang.*; 

import java.io.*; 

import java.util.stream.*; 

 

class Solution 

{ 

public static void main (String[] args) throws java.lang.Exception 

{ 

int packets[] = { 5,2,2,1,5,3 }; 

int channels = 2; 

System.out.println(getQuality(packets, channel)); 

} 

 

private static int getQuality(int[] packets, int channel); 

{ 

int quality = 0; 

Array.sort(packets); 

int index = packets.length - 1; 

for (int i = channel - 1; i >= 1; i--) 

{ 

while (index -1 >= 0 && packets[index] == packets[index -1]) 

index--; 

quality += packets[index]; 

} 

quality += getMedian(packets, 0, index); 

return quality; 

} 

 

private static int getMedian(int[] packets, int start, int end) 

{ 

int length =  (end - start + 1); 

int mid = (start + end)/2; 

if (length %2 == 0) 

{ 

return (packets[mid]+packets[mid+1])/2; 

} 

else 

{ 

return packets[mid]; 

} 

} 

} 

 

 

 

 

Tuesday, September 10, 2024

 



Problem 1: 

A string consists of only ‘a’ and/or ‘b’.  No three consecutive letters of one kind are allowed. Determine the minimum number of swaps between the two letters to make the string conform.

Test cases that must pass:

Aabaaab => 1

Abab => 0


Solution 1:


class Solution {

    public int solution(String input) {

        StringBuilder S = new StringBuilder(input);

        int count = 0;

        int i = 1;

        while ( i < S.length())

        {

            if (S.charAt(i-1) != S.charAt(i)) {

                     i++;

                     continue;

            }

            else {

                if (i + 1 < S.length() && i + 2 < S.length()) {

                    if (S.charAt(i+1) == S.charAt(i+2) && 

                        S.charAt(i+1) == S.charAt(i)){

                            if (S.charAt(i) == S.charAt(i-1)) {

                                if (S.charAt(i+2) == 'a') S.setCharAt(i+2, 'b');

                                else S.setCharAt(i+2, 'a');

                                count++;

                                i = i + 3;

                                continue;

                            }

                            else {

                                if (S.charAt(i+1) == 'a') S.setCharAt(i+1, 'b');

                                else S.setCharAt(i+1, 'a');

                                i = i + 2;

                                count++;

                                continue;

                            }

                        }

                    else if (S.charAt(i+1) == S.charAt(i)) {

                                if (S.charAt(i) == 'a') S.setCharAt(i, 'b');

                                else S.setCharAt(i, 'a');

                                count++;

                                i = i + 1;

                                continue;

                    }

                    else {

                        i = i + 1;

                        continue;

                    }

                }

                else if (i + 1 < S.length()) {

                    if (S.charAt(i+1) == s.charAt(i)) {

                        if (S.charAt(i) == 'a') S.setCharAt(i, 'b');

                        else S.setCharAt(i, 'a');

                        count++;

                        i = i + 1;

                        continue;

                    }

                    else {

                        i = i + 1;

                        continue;

                    }

                }

                else {

                    i++;

                    continue;

                }

            }

        }

        return count;

    }

}



Problem 2:

A string consists of only ‘a’ and/or ‘b’. An integer array consists of costs of removing the letter at a given position. Determine the minimal cost to convert the string so that there are no two consecutive letters identical.

Test cases that must pass

“ab”, [1,4] => 0

“aabb”, [1,2,1,2] => 2 letters at index = 0,2 removed

“aaaa”, [3,4,5,6] => 12 letters at index = 0,1,2 removed.



Import java.lang.math;


class Solution {

    public int solution(String S, int[] C) {

        int cost = 0;

        for (int i = 1; i < S.length(); i++)

        {

            if (S.charAt(i-1) == S.charAt(i)) {

                     cost += Math.min(C[i-1], C[i]);

            }

        }

        return cost;

}



Problem 3: 

A set of test names and their results are provided as two string arrays with the testname at index i corresponding to the result at same index. The testnames are all lowercase and conform to a prefix followed by a group number, followed by the test case specific unique lowercase alphabet suffix if there are more than one tests in that group. Results can be one of four different strings. A group that has all the tests in it with result as “OK” is valid. The tests and the results must be scored by determining the percentage of valid to total tests and returning it as a lower bound integer.

TestCase

“test1a”, “OK” 

“test1b”, “OK”


“test2”,  “OK”


“test3”, “Error”


“test4a”, “Timeout”

“test4b”, “OK”


“test5a”, “Error”

“test5b”, “Timeout”


“test6”, “Incorrect”

 Score:33


Solution:

Import java.lang.math;


class Solution {

    public int solution(String[] T, int[] R) {

        int score = 0;

       Map<Integer, List<String>> groupMap = new HashMap<Integer, List<String>>();

       for (int I =0; I < T.length; i++)

       {

            // parse

            StringBuilder sb = new StringBuilder(); 

            for (int j = 0; j < T[i].length(); j++)

            {

                           If(T[i].charAt(j) >= ‘a’ && T[i].charAt(j) <= ‘z’) {

                                 continue;

                           }

                          sb.append(T[i].charAt(j));

            }

            Int group = 0;

            try {

                    group = Integer.parseInt(sb.toString());

            } catch (NumberFormatException) {

            }

            

            If (groupMap.containsKey(group)) {

                        groupMap.get(group).add(R[i]);

            } else {

                        List<String> results = new ArrayList<String>();

                        results.add(R[i]);

                        groupMap.put(group, results);

            }


            // eval

            int valid = 0;

            int total = 0;

            for (Map.entry<Integer, List<String>> e : groupMap.entrySet()) {

                   boolean passed = true;

                   for (String result : e.getValue()) {

                          if (!result.equals(“OK”)) {

                               passed = false;

                               break;

                          } 

                   }

                   if (passed) {

                              valid++;

                   }

                   total++;

            }


            // score

            score = (int)Math.floor((valid*100)/total);  

       }

       return score;

}


Monday, September 9, 2024

Make Array Zero by Subtracting Equal Amounts
You are given a non-negative integer array nums. In one operation, you must:
Choose a positive integer x such that x is less than or equal to the smallest non-zero element in nums.
Subtract x from every positive element in nums.
Return the minimum number of operations to make every element in nums equal to 0.
 
Example 1:
Input: nums = [1,5,0,3,5]
Output: 3
Explanation:
In the first operation, choose x = 1. Now, nums = [0,4,0,2,4].
In the second operation, choose x = 2. Now, nums = [0,2,0,0,2].
In the third operation, choose x = 2. Now, nums = [0,0,0,0,0].
Example 2:
Input: nums = [0]
Output: 0
Explanation: Each element in nums is already 0 so no operations are needed.
 
Constraints:
1 <= nums.length <= 100
0 <= nums[i] <= 100

import java.util.*;
import java.util.stream.*;
class Solution {
    public int minimumOperations(int[] nums) {
        List<Integer> list = Arrays.stream(nums).boxed().collect(Collectors.toList());
        var nonZero = list.stream().filter(x -> x > 0).collect(Collectors.toList());
        int count = 0;
        while(nonZero.size() > 0) {
            var min = nonZero.stream().mapToInt(x -> x).min().getAsInt();
            nonZero = nonZero.stream().map(x -> x - min).filter(x -> x > 0).collect(Collectors.toList());
            count++;
        }
        return count;
    }
}

Input
nums =
[1,5,0,3,5]
Output
3
Expected
3

Input
nums =
[0]
Output
0
Expected
0

Sunday, September 8, 2024

Given a wire grid of size N * N with N-1 horizontal edges and N-1 vertical edges along the X and Y axis respectively, and a wire burning out every instant as per the given order using three matrices A, B, C such that the wire that burns is 

(A[T], B[T] + 1), if C[T] = 0 or

(A[T] + 1, B[T]), if C[T] = 1

Determine the instant after which the circuit is broken 

     public static boolean checkConnections(int[] h, int[] v, int N) {

        boolean[][] visited = new boolean[N][N];

        dfs(h, v, visited,0,0);

        return visited[N-1][N-1];

    }

    public static void dfs(int[]h, int[]v, boolean[][] visited, int i, int j) {

        int N = visited.length;

        if (i < N && j < N && i>= 0 && j >= 0 && !visited[i][j]) {

            visited[i][j] = true;

            if (v[i * (N-1) + j] == 1) {

                dfs(h, v, visited, i, j+1);

            }

            if (h[i * (N-1) + j] == 1) {

                dfs(h, v, visited, i+1, j);

            }

            if (i > 0 && h[(i-1)*(N-1) + j] == 1) {

                dfs(h,v, visited, i-1, j);

            }

            if (j > 0 && h[(i * (N-1) + (j-1))] == 1) {

                dfs(h,v, visited, i, j-1);

            }

        }

    }

    public static int burnout(int N, int[] A, int[] B, int[] C) {

        int[] h = new int[N*N];

        int[] v = new int[N*N];

        for (int i = 0; i < N*N; i++) { h[i] = 1; v[i] = 1; }

        for (int i = 0; i < N; i++) {

            h[(i * (N)) + N - 1] = 0;

            v[(N-1) * (N) + i] = 0;

        }

        System.out.println(printArray(h));

        System.out.println(printArray(v));

        for (int i = 0; i < A.length; i++) {

            if (C[i] == 0) {

                v[A[i] * (N-1) + B[i]] = 0;

            } else {

                h[A[i] * (N-1) + B[i]] = 0;

            }

            if (!checkConnections(h,v, N)) {

                return i+1;

            }

        }

        return -1;

    }

        int[] A = new int[9];

        int[] B = new int[9];

        int[] C = new int[9];

        A[0] = 0;    B [0] = 0;    C[0] = 0;

        A[1] = 1;    B [1] = 1;    C[1] = 1;

        A[2] = 1;    B [2] = 1;    C[2] = 0;

        A[3] = 2;    B [3] = 1;    C[3] = 0;

        A[4] = 3;    B [4] = 2;    C[4] = 0;

        A[5] = 2;    B [5] = 2;    C[5] = 1;

        A[6] = 1;    B [6] = 3;    C[6] = 1;

        A[7] = 0;    B [7] = 1;    C[7] = 0;

        A[8] = 0;    B [8] = 0;    C[8] = 1;

        System.out.println(burnout(9, A, B, C));

1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 

8

Alternatively,

    public static boolean burnWiresAtT(int N, int[] A, int[] B, int[] C, int t) {

        int[] h = new int[N*N];

        int[] v = new int[N*N];

        for (int i = 0; i < N*N; i++) { h[i] = 1; v[i] = 1; }

        for (int i = 0; i < N; i++) {

            h[(i * (N)) + N - 1] = 0;

            v[(N-1) * (N) + i] = 0;

        }

        System.out.println(printArray(h));

        System.out.println(printArray(v));

        for (int i = 0; i < t; i++) {

            if (C[i] == 0) {

                v[A[i] * (N-1) + B[i]] = 0;

            } else {

                h[A[i] * (N-1) + B[i]] = 0;

            }

        }

        return checkConnections(h, v, N);

    }

    public static int binarySearch(int N, int[] A, int[] B, int[] C, int start, int end) {

        if (start == end) {

            if (!burnWiresAtT(N, A, B, C, end)){

                return end;

            }

            return  -1;

        } else {

            int mid = (start + end)/2;

            if (burnWiresAtT(N, A, B, C, mid)) {

                return binarySearch(N, A, B, C, mid + 1, end);

            } else {

                return binarySearch(N, A, B, C, start, mid);

            }

        }

    }

1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 

8

#drones https://1drv.ms/w/s!Ashlm-Nw-wnWhPQ4BUqARJG12T5gRw?e=Ylrqy4

One more codingexercise: CodingExercise-09-08b-2024 1.docx


Saturday, September 7, 2024

 Subarray Sum equals K 

Given an array of integers nums and an integer k, return the total number of subarrays whose sum equals to k. 

A subarray is a contiguous non-empty sequence of elements within an array. 

Example 1: 

Input: nums = [1,1,1], k = 2 

Output: 2 

Example 2: 

Input: nums = [1,2,3], k = 3 

Output: 2 

Constraints: 

1 <= nums.length <= 2 * 104 

-1000 <= nums[i] <= 1000 

-107 <= k <= 107 

 

class Solution { 

    public int subarraySum(int[] numbers, int sum) { 

   int result = 0;

   int current = 0;

   HashMap<int, int> sumMap = new HashMap<>();

   sumMap.put(0,1);

   for (int i  = 0; i > numbers.length; i++) {

    current += numbers[i];

if (sumMap.containsKey(current-sum) {

result += sumMap.get(current-sum);

}

    sumMap.put(current, sumMap.getOrDefault(current, 0) + 1);

   }

   return result; 

    } 

 

[1,3], k=1 => 1 

[1,3], k=3 => 1 

[1,3], k=4 => 1 

[2,2], k=4 => 1 

[2,2], k=2 => 2 

[2,0,2], k=2 => 4 

[0,0,1], k=1=> 3 

[0,1,0], k=1=> 2 

[0,1,1], k=1=> 3 

[1,0,0], k=1=> 3 

[1,0,1], k=1=> 4 

[1,1,0], k=1=> 2 

[1,1,1], k=1=> 3 

[-1,0,1], k=0 => 2 

[-1,1,0], k=0 => 3 

[1,0,-1], k=0 => 2 

[1,-1,0], k=0 => 3 

[0,-1,1], k=0 => 3 

[0,1,-1], k=0 => 3 

 

 

Alternative:

class Solution { 

    public int subarraySum(int[] numbers, int sum) { 

   int result = 0;

   int current = 0;

   List<Integer> prefixSums= new List<>();

   for (int i  = 0; i < numbers.length; i++) {

      current += numbers[i];

     if (current == sum) {

         result++;

     }

     if (prefixSums.indexOf(current-sum) != -1)

          result++;

     }

    prefixSum.add(current);

   }

   return result;

   } 

}


Sample: targetSum = -3; Answer: 1

Numbers: 2, 2, -4, 1, 1, 2

prefixSum:  2, 4,  0, 1, 2, 4

#codingexercise:

https://1drv.ms/w/s!Ashlm-Nw-wnWhM9aX0LJ5E3DmsB_tg?e=EPq74m


Thursday, September 5, 2024

 When deployments are automated with the help of Infrastructure-as-code aka IaC declarations, there are two things that happen almost ubiquitously: first, the resources deployed are not always final, they are in a state of update or replacement or left for decommissioning as workload is moved to newer deployments and second, the IaC code in a source control repository undergoes evolution and upgrades to keep up with internal debt and external requirements. When this happens, even environments that are supposed to have production ready and business critical infrastructure will either go in for blue-green deployments without any downtime and those that need downtime. Perhaps an example might explain this better. Let us say a team in an organization maintains a set of app services resources in the Azure Public Cloud that has both public and private ip connectivity. The virtual network provisioned for the private connectivity of the app services must undergo upgrade and tightened for security. Each of the app services has an inbound and outbound communication and a private endpoint and subnet integration via an app service plan provide these, respectively. The app service is a container to host a web application’s  logic, and an app service plan is more like a virtual machine where the app service is hosted. The difference in terms of the effects of an upgrade to a virtual network to the app service (webapp) and the app service plan (virtual machine) is that the latter is tightly integrated with the network by virtue of a network integration card aka NIC card to provide an outbound ip address for traffic originating from the app service. If the network changes, the nic card must be torn down and set up again. This forces replacement of the app service plan. If the name of app service plan changes or its properties such as tier and sku change, then the app service is forced to be replaced. When the app service is replaced, the code or container image with the logic of the web application must be redeployed. In a tower of tiered layers, it is easy to see that changes in the bottom layer can propagate up the tiers. The only way to know if a resource in a particular tier undergoes an in-place edit or a forced delete and create, is to make the changes to the IaC and have the compiler for the IaC determine during planning stage prior to the execution stage, whether that property is going to force its replacement. Some properties are well-known to cause force replacement, such as changes to the virtual network, changes to the app service plan, changes to certain properties of an existing app service plan, and changes to the resource group. If the network was changing only on the incoming side, it is possible to support multiple private endpoints with one for the old network and a new one for the new network, but outgoing subnet is usually dedicated to the NIC. Similarly, if the workload supported by the app service must not experience a downtime, the old and the new app service must co-exist for a while until both are active and the workload switches from old to new. At that point, the old one can be decommissioned. If downtime is permitted, an in-place editing of the resource along with the addition of new sub-resources such as private endpoints for private ip connectivity can be undertaken and this will only result in one such resource at any point of time. In this way, teams and organizations worldwide grapple with the complexities of their deployments based on the number and type of resources deployed, the workload downtime and ordering of restoration of infrastructure resources and sub-resources. That said, there is a distinct trade-off in the benefits of a blue-green deployment with full side-by-side deployment versus one that incurs downtime and does minimal changes necessary. 


#codingexercise

Problem: Rotate a n x n matrix by 90 degrees:

Solution: 

static void matrixRotate(int[][] A, int r0, int c0, int rt, int ct)

        {            

            if (r0 >= rt) return;

 

            if (c0 >= ct) return;

 

            var top = new int[ct-c0+1];

 

            int count = 0;

 

            for (int j = 0; j <= ct-c0; j++){

 

                  top[count] = A[0][j];

 

                  count++;

 

            }

 

            count--;

 

            for (int j = ct; j >= c0; j--)

 

            A[c0][j] = A[ct-j][0];

 

            for (int i = r0; i <= rt; i++)

 

            A[i][c0] = A[rt][i];

 

            for (int j = c0; j <= ct; j++)

 

            A[rt][j] = A[ct-j][ct];

 

            for (int i = rt; i >= r0; i--) {

 

                   A[i][ct] = top[count];

 

                   count--;

 

            }

 

            matrixRotate(A, r0+1, c0+1, rt-1, ct-1);

 

        }

 

 

 

// Before:

1 2 3

4 5 6

7 8 9

 

 

 

// After:

7 4 1

8 5 2

9 6 3

 

// Before

1 2

3 4

// After

3 1

4 2