Wednesday, August 13, 2025

#codingexercise

 

You are assigned to put some amount of boxes onto one truck. You are given a 2D array boxTypes, where boxTypes[i] = [numberOfBoxesi, numberOfUnitsPerBoxi]:

  • numberOfBoxesi is the number of boxes of type i.
  • numberOfUnitsPerBoxi is the number of units in each box of the type i.

You are also given an integer truckSize, which is the maximum number of boxes that can be put on the truck. You can choose any boxes to put on the truck as long as the number of boxes does not exceed truckSize.

Return the maximum total number of units that can be put on the truck.

 

Example 1:

Input: boxTypes = [[1,3],[2,2],[3,1]], truckSize = 4

Output: 8

Explanation: There are:

- 1 box of the first type that contains 3 units.

- 2 boxes of the second type that contain 2 units each.

- 3 boxes of the third type that contain 1 unit each.

You can take all the boxes of the first and second types, and one box of the third type.

The total number of units will be = (1 * 3) + (2 * 2) + (1 * 1) = 8.

Example 2:

Input: boxTypes = [[5,10],[2,5],[4,7],[3,9]], truckSize = 10

Output: 91

 

Constraints:

  • 1 <= boxTypes.length <= 1000
  • 1 <= numberOfBoxesi, numberOfUnitsPerBoxi <= 1000
  • 1 <= truckSize <= 106

 

 

class Solution {

    public int maximumUnits(int[][] boxTypes, int truckSize) {

        var boxMap = new TreeMap<Integer, List<Integer>>();

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

            var type = boxTypes[i][0];

            var countOfUnits = boxTypes[i][1];

            if (boxMap.containsKey(countOfUnits)){

                var list = boxMap.get(countOfUnits);

                list.add(type);

                boxMap.put(countOfUnits, list);

            } else {

                var list = new ArrayList<Integer>();

                list.add(type);

                boxMap.put(countOfUnits, list);

            }

        }

        int total = 0;

        int totalUnits = 0;

        for (var entry : boxMap.descendingMap().entrySet()){

            var countOfUnits = entry.getKey();

            var types = entry.getValue();

            for (var type : types){

                if (total + 1 <= truckSize) {

                    for (int i = 0; i < type && total < truckSize; i++) {

                        total += 1;

                        totalUnits += 1 * countOfUnits;

                    }

                } else {

                    return totalUnits;

                }

            }

        }

        return totalUnits;

    }

}

 

Input

boxTypes =

[[1,3],[2,2],[3,1]]

truckSize =

4

Output

8

Expected

8

 

Input

boxTypes =

[[5,10],[2,5],[4,7],[3,9]]

truckSize =

10

Output

91

Expected

91

 

 

You are given a 0-indexed integer array nums.

Swaps of adjacent elements are able to be performed on nums.

A valid array meets the following conditions:

·        The largest element (any of the largest elements if there are multiple) is at the rightmost position in the array.

·        The smallest element (any of the smallest elements if there are multiple) is at the leftmost position in the array.

Return the minimum swaps required to make nums a valid array.

 

Example 1:

Input: nums = [3,4,5,5,3,1]

Output: 6

Explanation: Perform the following swaps:

- Swap 1: Swap the 3rd and 4th elements, nums is then [3,4,5,3,5,1].

- Swap 2: Swap the 4th and 5th elements, nums is then [3,4,5,3,1,5].

- Swap 3: Swap the 3rd and 4th elements, nums is then [3,4,5,1,3,5].

- Swap 4: Swap the 2nd and 3rd elements, nums is then [3,4,1,5,3,5].

- Swap 5: Swap the 1st and 2nd elements, nums is then [3,1,4,5,3,5].

- Swap 6: Swap the 0th and 1st elements, nums is then [1,3,4,5,3,5].

It can be shown that 6 swaps is the minimum swaps required to make a valid array.

Example 2:

Input: nums = [9]

Output: 0

Explanation: The array is already valid, so we return 0.

 

Constraints:

·              1 <= nums.length <= 105

·              1 <= nums[i] <= 105

 

class Solution {

    public int minimumSwaps(int[] nums) {

        int min = Arrays.stream(nums).min().getAsInt();

        int max = Arrays.stream(nums).max().getAsInt();

        int count = 0;

        while (nums[0] != min && nums[nums.length-1] != max && count < 2 * nums.length) {           

            var numsList = Arrays.stream(nums).boxed().collect(Collectors.toList());

            var end = numsList.lastIndexOf(max);

            for (int i = end; i < nums.length-1; i++) {

                swap(nums, i, i+1);

                count++;

            }

 

            numsList = Arrays.stream(nums).boxed().collect(Collectors.toList());

            var start = numsList.indexOf(min);

            for (int j = start; j >= 1; j--) {

                swap(nums, j, j-1);

                count++;

            }

        }

 

        return count;

    }

 

    public void swap (int[] nums, int i, int j) {

        int temp = nums[j];

        nums[j] = nums[i];

        nums[i] = temp;

    }

}

 

Input

nums =

[3,4,5,5,3,1]

Output

6

Expected

6

 

Input

nums =

[9]

Output

0

Expected

0

You are assigned to put some amount of boxes onto one truck. You are given a 2D array boxTypes, where boxTypes[i] = [numberOfBoxesi, numberOfUnitsPerBoxi]:

  • numberOfBoxesi is the number of boxes of type i.
  • numberOfUnitsPerBoxi is the number of units in each box of the type i.

You are also given an integer truckSize, which is the maximum number of boxes that can be put on the truck. You can choose any boxes to put on the truck as long as the number of boxes does not exceed truckSize.

Return the maximum total number of units that can be put on the truck.

 

Example 1:

Input: boxTypes = [[1,3],[2,2],[3,1]], truckSize = 4

Output: 8

Explanation: There are:

- 1 box of the first type that contains 3 units.

- 2 boxes of the second type that contain 2 units each.

- 3 boxes of the third type that contain 1 unit each.

You can take all the boxes of the first and second types, and one box of the third type.

The total number of units will be = (1 * 3) + (2 * 2) + (1 * 1) = 8.

Example 2:

Input: boxTypes = [[5,10],[2,5],[4,7],[3,9]], truckSize = 10

Output: 91

 

Constraints:

  • 1 <= boxTypes.length <= 1000
  • 1 <= numberOfBoxesi, numberOfUnitsPerBoxi <= 1000
  • 1 <= truckSize <= 106

 

class Solution {

    public int maximumUnits(int[][] boxTypes, int truckSize) {

        var boxMap = new TreeMap<Integer, List<Integer>>();

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

            var type = boxTypes[i][0];

            var countOfUnits = boxTypes[i][1];

            if (boxMap.containsKey(countOfUnits)){

                var list = boxMap.get(countOfUnits);

                list.add(type);

                boxMap.put(countOfUnits, list);

            } else {

                var list = new ArrayList<Integer>();

                list.add(type);

                boxMap.put(countOfUnits, list);

            }

        }

        int total = 0;

        int totalUnits = 0;

        for (var entry : boxMap.descendingMap().entrySet()){

            var countOfUnits = entry.getKey();

            var types = entry.getValue();

            for (var type : types){

                if (total + 1 <= truckSize) {

                    for (int i = 0; i < type && total < truckSize; i++) {

                        total += 1;

                        totalUnits += 1 * countOfUnits;

                    }

                } else {

                    return totalUnits;

                }

            }

        }

        return totalUnits;

    }

}

 


 

Given a string s, rearrange the characters of s so that any two adjacent characters are not the same.

Return any possible rearrangement of s or return "" if not possible.

 

Example 1:

Input: s = "aab"

Output: "aba"

Example 2:

Input: s = "aaab"

Output: ""

 

Constraints:

  • 1 <= s.length <= 500
  • s consists of lowercase English letters.

class Solution {

    public String reorganizeString(String s) {

        String result = "";

        Map<Character, Integer> charMap = new HashMap<Character, Integer>();

        for(Character c : s.toCharArray()) {

            if (charMap.containsKey(c)) {

                charMap.put(c, charMap.get(c) + 1);

            } else {

                charMap.put(c, 1);

            }

        }



    int countOfDuplicates = 0;

    TreeMap<Integer, List<Character>> countMap = new TreeMap<Integer, List<Character>>();

    for (var entry : charMap.entrySet()) {

        if (entry.getValue() > 1){

            countOfDuplicates += (int)entry.getValue() - 1;

        }

        if (countMap.containsKey(entry.getValue())) {

            countMap.get(entry.getValue()).add(entry.getKey());

        } else {

            var list = new ArrayList<Character>();

            list.add(entry.getKey());

            countMap.put(entry.getValue(), list);

        }

    }

    System.out.println(countMap);

        if (countMap.firstEntry().getKey() > 1 && countMap.firstEntry().getValue().size() == 1) {

        var firstEntry = countMap.firstEntry();

        var secondEntry = countMap.higherEntry(firstEntry.getKey());

        if (secondEntry != null) {

        int diff = secondEntry.getKey() - firstEntry.getKey();

        countMap.remove(firstEntry.getKey());

        countMap.remove(secondEntry.getKey());

        var list = new ArrayList<Character>();

        list.addAll(secondEntry.getValue());

        list.addAll(firstEntry.getValue());

        countMap.put(firstEntry.getKey(), list);

        countMap.put(diff, secondEntry.getValue());

        }

    }

    System.out.println(countMap);

    StringBuilder sb = new StringBuilder();

    while (countMap.size() > 0) {

    var entry = countMap.pollLastEntry();

    int occurrence = 0;

    while (entry != null && entry.getValue().size() > 1) {

        for (int i = 0; i < entry.getKey(); i++) {

            occurrence++;

            for (int j = 0; j < entry.getValue().size(); j++) {

                sb.append(entry.getValue().get(j));

            }

        }

        entry.getValue().clear();

    }

    while(entry != null && entry.getValue().size() == 1) {

        var last = entry.getValue().get(0);

        int accounted = 0;

        int lastEntryCount = entry.getKey() - occurrence;

        System.out.println("occurrence=" + occurrence);

        if (countMap.size() == 0 && lastEntryCount > 1) {

            return "";

        }

        while (lastEntryCount > 0){

            var lastEntry = countMap.lastEntry();

            while (lastEntry != null && lastEntry.getValue().size() > 0) {

                int secondLastEntryCount = lastEntry.getKey();

                var secondLast = lastEntry.getValue().remove(0);

                while (lastEntryCount > 0 && secondLastEntryCount > 0) {

                    sb.append(last);

                    sb.append(secondLast);

                    lastEntryCount--;

                    occurrence++;

                    secondLastEntryCount--;

                }

                if (secondLastEntryCount > 0) {

                    var list = countMap.get(secondLastEntryCount);

                    if (list == null) {

                        list = new ArrayList<Character>();

                    }

                    list.add(secondLast);

                    countMap.put(secondLastEntryCount, list);

                    break;

                }

            }

            if (lastEntryCount == 1){

                sb.append(last);

                lastEntryCount--;

                occurrence++;

            }



            if (lastEntry != null && lastEntry.getValue().size() == 0) {

                countMap.remove(lastEntry.getKey());

            }



            if (lastEntryCount == 0) {

                countMap.remove(entry.getKey());

                entry.getValue().clear();

            }

            if (lastEntryCount > 0 && countMap.size() == 0) {

                return "";

            }

        }

       

    }

    }

    

    result = sb.toString();

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

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

            return "";

        }

    }

    return result;

    }

}

 

Input

s =

"kkkkzrkatkwpkkkktrq"

Output

"krkrktktkpkakqkwkzk"

Expected

"krkrktktkakpkqkwkzk"

Stdout

{1=[p, a, q, w, z], 2=[r, t], 10=[k]} 10 [k] countMap={1=[p, a, q, w, z], 2=[r, t]}  last=k occurrence=0 lastEntry=2=[r, t] kr 2=[t] 9 1 krkr 2=[t] 8 0 secondLastEntryCount=0 and secondLast=r lastEntryCount=8 krkrkt 2=[] 7 1 krkrktkt 2=[] 6 0 secondLastEntryCount=0 and secondLast=t lastEntryCount=6 lastEntry=1=[p, a, q, w, z] krkrktktkp 1=[a, q, w, z] 5 0 secondLastEntryCount=0 and secondLast=p lastEntryCount=5 krkrktktkpka 1=[q, w, z] 4 0 secondLastEntryCount=0 and secondLast=a lastEntryCount=4 krkrktktkpkakq 1=[w, z] 3 0 secondLastEntryCount=0 and secondLast=q lastEntryCount=3 krkrktktkpkakqkw 1=[z] 2 0 secondLastEntryCount=0 and secondLast=w lastEntryCount=2 krkrktktkpkakqkwkz 1=[] 1 0 secondLastEntryCount=0 and secondLast=z lastEntryCount=1 krkrktktkpkakqkwkzk

  

Tuesday, August 12, 2025

 Role of public cloud in autonomous UAV Swarm flight management

While the previous articles described the possibilities when the capabilities of individual drones in the UAV swarm are enhanced, it does not call out the role of the cloud. The data the drones send each other over gossip or broadcast protocol is for decentralized co-ordination but this does not do away with the cloud. In fact, without the analytics provided by the cloud, it is not only hard to do efficient mission planning, image processing, real-time updates, and secure communications but also impossible to scale out on those tasks. The cloud does not try to be a central controller; it provides capabilities for processing data that are best taken away from the edge/IoT devices when they are part of drone apparatus and enhances the decision-making processes.

The architecture diagram below is an illustration of this role played by the public cloud.


Figure illustrates separation of concerns for cloud, UAV swarm and users along with their components and dependencies.

Specifically, it allows the UAV task assignment graph to be different from the communication graph within the cloud computing plane. The image/video processing and analytics pipeline is helpful even without a control loop back to the drones for aiding their next round of flight if not near-real-time feedback. The architecture is independent of the models and algorithms used within the components so that the user can bring her own models or leverage retrieval-augmented-generation from the analytics stack comprising of vector stores.

#Codingexercise: https://1drv.ms/w/c/d609fb70e39b65c8/EbHRVcgkqM5GgDxzwnEOhKcBnJW4AuOWbdEVMPATcY4N6w?e=2UzoPB


Monday, August 11, 2025

 Augmented capabilities of UAV drone units

One of the tenets of the Drone video sensing platform we have described in the previous articles is that the platform makes no assumptions about the capabilities of the UAV units or their sensors other a camera capable of First-person view aka FPV drones. Let us review what these additional capabilities mean in terms of algorithms. We take the case when UAV swarm are capable of autonomous flight and inter-drone communication. This provides an opportunity for additional layer of computing over centralized and decentralized task assignments via waypoint tracking and self-organizing maps, respectively. In this layer, each drone follows a systematic process to achieve its objectives and collaborate within the swarm.

 We can safely delegate the communication to a mesh network and collaboration with consensus protocols such as Paxos or Raft and instead focus on the computing plane shortly. The Mesh network is decentralized and relaxed enough for the drones to join or leave the network as they move in and out of range; the network itself is self-healing with redundancy for reliable communication over multiple paths and scalable without degradation in performance. If some form of storage were available, cachepoints arranged in a ring can play a part in consistent hashing over a distributed hash table with data versioning to enforce consistency. They also work well with consensus protocol especially those that implement state machine replication that combines transaction logging for consensus with write-ahead logging for data recovery. When these state machines are replicated, they become fully Byzantine tolerant.

In the computing plane, these capabilities provide an opportunity to improve performance by providing the necessary information for agents to select an action. With the payload in exchanges to not be limited to any one type of sensor and getting reinforcement learning from adjoining drones, an adaptive framework can be designed to significantly boost the efficiency of critical tasks such as reconnaissance and collision avoidance. If the collective thinking of the UAV swarm needs to be overridden, a single drone can be targeted to move in the desired direction with a velocity to automatically move the group to follow. Since this computing builds upon decentralized framework without impacting the earlier self-organizing maps, it forms a clean layer of computing above the existing to enhance the dynamic behavior of the swarm and its error corrections.

The systematic processes and reinforcement learning referred to earlier for each drone must include those for inter-drone distance calculations such as Euclidean distance, a minimum spanning tree to care for all the drones in the swarm by creating a graph of drone distances and policy optimization to learn optimal behavior to achieve a given goal by adjusting search patterns from latest data and updating policies while maintaining learning stability. With a frequent iteration of updating positions of each drone, recalculating inter-drone distances between pairs, and constructing the MST by merging the smallest edges between the fragments until all fragments are connected, the UAV swarm can respond faster and better to meet critical operational requirements such as collision avoidance. Additionally, if velocity were to be captured and shared along with the position information, the model can accommodate dynamic changes and better predict agent motion and path planning. Setting a suitable threshold in the policy optimization allows us to counter instability and abrupt policy changes. A classifier that uses the policy optimization loss can ensure coherence for the entire swarm even under varying conditions which significantly boosts reliability of decision making. Inter-agent co-operation is in this way, a desirable layer of computing that the UAV swarm platform can bring to the table when augmented capabilities are available on the drones.


Sunday, August 10, 2025

 Self-organizing maps and UAV Swarm morphing 

Self-Organizing Maps (SOMs) are a type of unsupervised neural network that project high-dimensional data onto a lower-dimensional (typically 2D) grid while preserving topological relationships. In the context of UAV swarm transformations and decentralized coordination, SOMs offer a powerful framework for enabling autonomous behavior, spatial awareness, and adaptive decision-making across distributed agents. The trajectory of a UAV swarm much like that of a standalone drone is specified by waypoint selection and arrival time calculation with specific speed up and speed down between waypoints to fit the schedule. The choice of waypoints is usually decided by controllers or cloud computing by determining nodes representing 3D grids in space between start and finish and edges representing reachability. Usually, it is assumed that there is enough clearance for a UAV swarm to follow the trajectory but dynamic wind turbulence, minimum distance between units and obstructions such as when passing under bridges or through tunnels require UAV swarm transformations. Just like waypoint selection, the obstructions can either be negotiated or avoided in a centralized or decentralized manner usually with some form of error correction to revert to the planned trajectory. The Hungarian algorithm computes the minimum distance transformations for the drones in a centralized manner, but SOM helps to do so in a decentralized manner. The results of SOM can be used to augment the assignments for the units in the drone or for cross-validation of alternative dynamic transformations, if not completely, eliminate the need. 

SOMs consist of a grid of neurons; each associated with a weight vector of the same dimension as input data. When an input vector is presented, the neurons whose weight vector is closest as determined by Euclidean distance, becomes the Best Matching Unit. The BMU and its neighbors update their weights to become more like the input, reinforcing spatial clustering. As with any neural network, there is training involved, and the input data is iteratively fed. In each iteration, the BMU is found, the weights of the BMU and its neighbors are updated, and the learning rate and neighborhood radius are reduced over time. This results in a map where similar inputs are clustered together, preserving the data’s topology. 

This can be applied to a UAV swarm for dynamic collision avoidance from external threats. If the units of a UAV swarm are flying sequentially in a linear path and an external object is going to intrude into the path, the resulting boundary of the object on the flight path can be fed as input vector with sufficient margin from the boundary. Then the units will find their positions on the modified path and continue to follow each other sequentially until the swarm clears the obstruction. The roles and spatial positions of the UAV swarm units can be mapped; the formation can be adapted based on terrain or task density and the node failures can be handled gracefully by reassigning roles. 

Use of SOM can go beyond decentralized coordination to include role assignment and task clustering such as to learn optimal task distributions, mapping swarm participants to mission zones, and dynamically reconfiguring based on environmental feedback. It can also be used to improve scalability and fault tolerance.  

  

Saturday, August 9, 2025

 Regaining chronicle in video indexing.

The previous articles examined various cloud service APIs and dedicated web services to extract gps coordinates (latitude, longitude) with varying degrees of success. This article describes how to regain the timestamps post video indexing so that it can be added as a time field for extracted frames and uploaded in the document to a vector store.

def repeat_video_index(access_token, video_id):

    """Retrieve the index/insights for a video by its ID."""

    url = f"{video_indexer_endpoint}/{video_indexer_region}/Accounts/{video_indexer_account_id}/Videos/{video_id}/ReIndex?accessToken={access_token}"

    response = requests.put(url)

    if response.status_code == 200:

        return response

    return get_video_insights(access_token, video_id)

def get_video_insights(access_token, video_id):

    url = f"{video_indexer_endpoint}/{video_indexer_region}/Accounts/{video_indexer_account_id}/Videos/{video_id}/Index?accessToken={access_token}"

    count = 0

    while True:

        response = requests.get(url)

        data = response.json()

        if "state" in data and data['state'] == 'Processed':

            return data

        count+=1

        if count%10 == 0:

            print(data)

        print("Sleeping for ten seconds...")

        time.sleep(10) # Wait 10 seconds before checking again

def get_timestamps(access_token, video_id):

    # Main workflow

    # access_token = get_access_token()

    insights = get_video_insights(access_token, video_id)

    #pprint(insights)

    timestamps=[]

    for keyframe in insights['videos'][0]['insights']['shots'][0]['keyFrames']:

        timestamps+=[(keyframe['instances'][0]['start'], keyframe['instances'][0]['end'])]

    print(timestamps)

    return timestamps

# [('0:00:00.2219828', '0:00:00.2570043'), ('0:00:00.5030307', '0:00:00.5379849'), ('0:00:00.8780307', '0:00:00.9249731')]


Friday, August 8, 2025

 Since location information from aerial drone images is reliant on the drone capabilities and one of our fundamental tenets for building the drone platform was to allow drones to have any capabilities and not require anything other than a camera, the platform must either be able to process a gps json when available from the drone or allow custom logic to be run by the user to provide the location information.

This extensibility is very similar to how custom scripts can be run on any hosting infrastructure such as Kubernetes. For example, the following declarations are sufficient to create and run a python script on the aerial drone image sensing platform:

--

apiVersion: v1

kind: ConfigMap

metadata:

  name: location-script

data:

  location.py: |

    import json

    import numpy as np

    # Replace this with actual GPS bounds for transformation

    # Example: top-left, top-right, bottom-right, bottom-left in pixel & GPS

    pixel_bounds = np.array([[0, 0], [4096, 0], [4096, 4096], [0, 4096]])

    gps_bounds = np.array([[39.735, -104.997], [39.735, -104.989],

                           [39.729, -104.989], [39.729, -104.997]])

    # Compute affine transform matrix from pixel to GPS

    A = np.linalg.lstsq(pixel_bounds, gps_bounds, rcond=None)[0]

    def pixel_to_gps(coord):

        """Map pixel coordinate to GPS using affine approximation"""

        return tuple(np.dot(coord, A))

    def parse_json_gps(json_data):

        gps_coords = []

        for frame in json_data:

            if frame is None:

                continue

            frame_coords = [pixel_to_gps(coord) for coord in frame]

            gps_coords.append(frame_coords)

        return gps_coords

    # Example JSON input

    data = [None, [[3132, 4151], [3354, 2924], [4044, 3056], [3824, 4275]],

                  [[3095, 4164], [3318, 2939], [4006, 3073], [3787, 4289]]]

    gps_output = parse_json_gps(data)

    for i, frame in enumerate(gps_output):

        print(f"Frame {i+1}:")

        for lat, lon in frame:

            print(f"Latitude: {lat:.6f}, Longitude: {lon:.6f}")

--

apiVersion: v1

kind: Pod

metadata:

  name: location-pod

spec:

  containers:

  - name: python-container

    image: python:3.10-slim

    command: ["/bin/sh", "-c"]

    args:

      - |

        python /scripts/location.py && tail -f /dev/null

    volumeMounts:

    - name: script-volume

      mountPath: /scripts

      readOnly: true

    resources:

      limits:`

        memory: "128Mi"

        cpu: "250m"

  volumes:

  - name: script-volume

    configMap:

      name: location-script

  restartPolicy: Never