Journey to the Moon

Sort by

recency

|

20 Discussions

|

  • + 0 comments

    Kotlin solution. Note that the return type of journeyToMoon needs to be changed to Long to pass test case 11 which otherwise overflows.

    fun journeyToMoon(n: Int, astronaut: Array<Array<Int>>): Long {
        val nodes = (0..<n).map {Node(it)}
        val visited = mutableSetOf<Node>()
        val groups = mutableListOf<Set<Node>>()
        for (link in astronaut) {
            nodes[link[0]].connections.add(nodes[link[1]])
            nodes[link[1]].connections.add(nodes[link[0]])
        }
        for (node in nodes) {
            if (visited.contains(node)) continue
            val group = findConnections(node)
            groups.add(group)
            visited.addAll(group)
        }
        val sizes = groups.map {it.size.toLong()}
        val allPairs = n.toLong()*(n-1)/2
        val sameCountryPairs = sizes.map {it*(it-1)/2}
            .sum()
        return allPairs - sameCountryPairs
    }
    
    data class Node(val id: Int) {
        val connections = mutableSetOf<Node>()
    }
    
    fun findConnections(start: Node): Set<Node> {
        val visited = mutableSetOf<Node>()
        val queue = ArrayDeque<Node>()
        queue.add(start)
        while (!queue.isEmpty()) {
            val curr = queue.removeFirst()
            visited.add(curr)
            queue.addAll(curr.connections.filter {!visited.contains(it)})
        }
        return visited
    }
    
  • + 0 comments
    from collections import Counter
    
    def journeyToMoon(n, astronaut):
        # Initialize disjoint set (union-find) structures
        root = list(range(n))
        rank = [0] * n
        
        def find_root(a):
            if root[a] != a:
                root[a] = find_root(root[a])  # Path compression
            return root[a]
            
        def union(a, b):
            i, j = find_root(a), find_root(b)
            if i != j:
                if rank[i] > rank[j]:
                    root[j] = i
                elif rank[i] < rank[j]:
                    root[i] = j
                else:
                    root[j] = i
                    rank[i] += 1
        
        # Union all astronaut pairs
        for a, b in astronaut:
            union(a, b)
        
        # Count the size of each connected component
        component_sizes = list(Counter(find_root(i) for i in range(n)).values())
        
        # Calculate the number of valid pairs
        total_pairs = 0
        sum_sizes = 0
        
        for size in component_sizes:
            total_pairs += sum_sizes * size  # Pairs between current and previous components
            sum_sizes += size  # Update the cumulative size sum
        
        return total_pairs
    
  • + 0 comments

    Java O(n+p)

     class Result {
            public static long journeyToMoon(int n, List<List<Integer>> astronaut) {
                List<List<Integer>> adjList = new ArrayList<>();
                for (int i = 0; i < n; i++) {
                    adjList.add(new ArrayList<>());
                }
    
                for (List<Integer> pair : astronaut) {
                    int u = pair.get(0);
                    int v = pair.get(1);
                    adjList.get(u).add(v);
                    adjList.get(v).add(u);
                }
    
                boolean[] visited = new boolean[n];
                List<Integer> countrySizes = new ArrayList<>();
    
                for (int i = 0; i < n; i++) {
                    if (!visited[i]) {
                        int countrySize = dfs(i, adjList, visited);
                        countrySizes.add(countrySize);
                    }
                }
    
                long totalPairs = (long) n * (n - 1) / 2;
                long sameCountryPairs = 0;
                for (int size : countrySizes) {
                    sameCountryPairs += (long) size * (size - 1) / 2;
                }
    
                return totalPairs - sameCountryPairs;
            }
    
            private static int dfs(int node, List<List<Integer>> adjList, boolean[] visited) {
                Stack<Integer> stack = new Stack<>();
                stack.push(node);
                visited[node] = true;
                int size = 0;
    
                while (!stack.isEmpty()) {
                    int current = stack.pop();
                    size++;
                    for (int neighbor : adjList.get(current)) {
                        if (!visited[neighbor]) {
                            visited[neighbor] = true;
                            stack.push(neighbor);
                        }
                    }
                }
    
                return size;
            }
    
    }
    
    public class Solution {
            public static void main(String[] args) throws IOException {
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
                BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));
    
                String[] firstMultipleInput = bufferedReader.readLine().replaceAll("\\s+$", "").split(" ");
    
                int n = Integer.parseInt(firstMultipleInput[0]);
                int p = Integer.parseInt(firstMultipleInput[1]);
    
                List<List<Integer>> astronaut = new ArrayList<>();
    
                IntStream.range(0, p).forEach(i -> {
                    try {
                        astronaut.add(
                                Stream.of(bufferedReader.readLine().replaceAll("\\s+$", "").split(" "))
                                        .map(Integer::parseInt)
                                        .collect(toList())
                        );
                    } catch (IOException ex) {
                        throw new RuntimeException(ex);
                    }
                });
    
                long result = Result.journeyToMoon(n, astronaut); // Change int to long
    
                bufferedWriter.write(String.valueOf(result));
                bufferedWriter.newLine();
    
                bufferedReader.close();
                bufferedWriter.close();
            }
        }
    
  • + 0 comments

    JavaScript

    function journeyToMoon(n, astronaut) {
        // Write your code here
        let arr = []
        for (let i = 0; i < n; i++) arr[i] = [i]
        for (let i = 0; i < astronaut.length; i++) {
            let [m, n] = astronaut[i]
            if (arr[m] === arr[n]) continue
            if (arr[m].length < arr[n].length) [m, n] = [n, m]
            for (let temp of arr[n]) arr[m].push(temp), arr[temp] = arr[m]
        }
        let groups = new Set()
        for (let temp of arr) groups.add(temp)
        // console.log(arr)
        // console.log(groups)
        let countries = Array.from(groups), sum = 0
        for (let i = 0; i < countries.length - 1; i++) {
            for (let j = i + 1; j < countries.length; j++) {
                sum += countries[i].length * countries[j].length
            }
        }
        return sum
    }
    
  • + 0 comments

    Easy C++ Solution:

    #include <iostream>
    #include <list>
    #include <vector>
    #include <stdio.h>
    #include <iterator>
    #include <cmath>
        
    #define MAX 100000
        
    using namespace std;
        
    list<int> *ad;
    int *visited;
    int vertices;
        
    void DFS(int u)
    {
        visited[u] = 1;
        
        vertices++;
        
        list<int>::iterator it;
        
        for(it=ad[u].begin();it!=ad[u].end();it++)
        {
            if(visited[*it] == 0)
            {
                visited[*it] = 1;
                DFS(*it);
            }
        }
    }
        
    int main()
    {
        int i,m,u,v,numComponents=0,allv=0,temp=2,count=0;
        long long int n;
        int eachC[MAX];
        
        cin >> n >> m;
        
        if(n == 1)
        {
            cout <<"0\n";
            return 0;
        }
        
        ad = new list<int>[n];
        
        list<int>::iterator it;
        
        for(i=0;i<m;i++)
        {
            cin >> u >> v;
        
            ad[u].push_back(v);
            ad[v].push_back(u);    
        }
        
        visited = new int[n];
        
        for(i=0;i<n;i++)
        {
            visited[i] = 0;
        }
        
        for(i=0;i<n;i++)
        {
            if(visited[i] == 0)
            {
                vertices = 0;
                DFS(i);
                eachC[numComponents] = vertices;
                numComponents++;
            }
        }
        
        long long int totalWays = n*(n-1) / 2;
        long long int sameWays = 0;
        
        for(i=0;i<numComponents;i++)
        {    
            sameWays = sameWays + (eachC[i]*(eachC[i]-1) / 2);
        }
        cout << (totalWays - sameWays) << endl;
        return 0;
    }