Make same
Source: codechef
Difficulty: 1492

Make same
You are given three binary strings$^\dagger$$S_{1}, S_{2}, S_{3}$each of length$N$. Your goal is to make each string contain identical characters (all$0's$or all$1's$).
To achieve this, you can perform the following operation:
Choose$x, y$from$\{1, 2, 3\}$.
Choose index$i, j$such that$0 \leq i, j \lt N$.
Swap$S_{xi}$and$S_{yj}$(character at$i^{th}$index in$S_{x}$and character at$j^{th}$index in$S_{y}$).
Find the
minimum
number of operations required to make each string contain identical characters. Print$-1$if not possible.$^\dagger$A
binary string
is a sequence of characters where each character is either$'0'$or$'1'$.
Input Format
The first line of input will contain a single integer$T$, denoting the number of test cases.
Each test case consists of multiple lines of input.
The first line of each test case contains$N$, the length of the string.
The next$3$lines of input contain$3$binary strings.
Output Format
For each test case, output on a new line the minimum number of operations to required to make all strings have same characters,$-1$if it is not possible.
Constraints$1 \leq T \leq 10^{5}$$1 \leq N \leq 10$Sum of$N$over all test cases$\leq 10^5$Sample 1:
Explanation:
Test case 1:
Swap$0^{th}$character of$S_1$and$0^{th}$character of$S_3$(zero based indexing).
Test case 2:
Swap$1^{st}$character of$S_1$and$0^{th}$character of$S_3$.
Test case 3:
It can be shown that no sequence of allowed operations can make all three strings contain the same character simultaneously.
Test case 4:
All strings already contain the same characters.

Sample Input:
4
3
100
000
011
2
10
00
10
2
11
00
10
3
000
000
000

Sample Output:
1
1
-1
0

C++ solution:
#include <bits/stdc++.h>
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        string s1, s2, s3;
        cin >> s1 >> s2 >> s3;
        
        int a1 = count(s1.begin(), s1.end(), '1');
        int a2 = count(s2.begin(), s2.end(), '1');
        int a3 = count(s3.begin(), s3.end(), '1');
        
        int totalOnes = a1 + a2 + a3;
        if(totalOnes != 0 && totalOnes != n && totalOnes != 2*n && totalOnes != 3*n){
            cout << -1 << "\n";
            continue;
        }
        
        int k = totalOnes / n;
        vector<int> dspp = {a1, a2, a3};
        int minn = INT_MAX;
        
        for(int dev = 0; dev < 8; dev++){
            if(__builtin_popcount(dev) == k){
                int sum = 0;
                for(int i = 0; i < 3; i++){
                    if(dev & (1 << i))
                        sum += (n - dspp[i]);
                }
                minn = min(minn, sum);
            }
        }
        
        cout << minn << "\n";
    }
    
    return 0;
}

Go solution:
package main

import (
    "bufio"
    "fmt"
    "os"
)

var reader *bufio.Reader = bufio.NewReader(os.Stdin)
var writer *bufio.Writer = bufio.NewWriter(os.Stdout)

func printf(format string, a ...interface{}) { fmt.Fprintf(writer, format, a...) }
func scanf(format string, a ...interface{})  { fmt.Fscanf(reader, format, a...) }

func main() {
    defer writer.Flush()

    var tc int
    scanf("%d\n", &tc)

    for t := 0; t < tc; t++ {
        var n int
        scanf("%d\n", &n)

        var s [3]string
        scanf("%s\n", &s[0])
        scanf("%s\n", &s[1])
        scanf("%s\n", &s[2])

        if n == 1 {
            printf("0\n")

            continue
        }

        var zeroCount [3]int
        for i := 0; i < 3; i++ {
            for j := 0; j < n; j++ {
                if s[i][j] == '0' {
                    zeroCount[i]++
                }
            }
        }

        totalZero := zeroCount[0] + zeroCount[1] + zeroCount[2]
        if totalZero%n != 0 {
            printf("-1\n")

            continue
        }

        if totalZero == 0 || totalZero == 3*n {
            printf("0\n")

            continue
        }

        if totalZero == n {
            maxZero := 0
            for i := 0; i < 3; i++ {
                if zeroCount[i] > maxZero {
                    maxZero = zeroCount[i]
                }
            }

            printf("%d\n", n-maxZero)

            continue
        }

        minZero := 30
        for i := 0; i < 3; i++ {
            if zeroCount[i] < minZero {
                minZero = zeroCount[i]
            }
        }

        printf("%d\n", minZero)
    }
}

Java solution:
/**
 * @author Abhisek Singh (Zyroßeast)
 * 
 */

import java.io.DataInputStream;
import java.io.IOException;

public class Main {

   /**
    * Main logic for the program.
    * 
    * @param args Not Used anywhere
    * @throws IllegalArgumentException If any Error happens while processing data.
    * 
    */
    public static void main(String[] args) throws IllegalArgumentException {
        initializeIO();
        try {
            int __ = nextInt(), n, i, count[][] = new int[3][2], min = 0;
  
            while(__ -- > 0) {
                n = nextInt();
                
                for(i = 0; i < 3; i++) {
                    count[i][0] = 0;
                    
                    skipWhiteSpace();
                    while(c != '\n' && c != '\r') {
                        if(c == '0') count[i][0]++;
                        read();
                    }
                    
                    count[i][1] = n - count[i][0];
                }
                
                
                if ((count[0][0] + count[1][0] + count[2][0]) % n > 0) outData.append(-1);
                else {
                    switch((count[0][0] + count[1][0] + count[2][0]) / n) {
                        case 0, 3 -> outData.append(0);
                        case 1 -> outData.append(n - Math.max(Math.max(count[0][0], count[1][0]), count[2][0]));
                        case 2 -> outData.append(n - Math.max(Math.max(count[0][1], count[1][1]), count[2][1]));
                    }
                }
                
                outData.append('\n');
            }
        
        } catch(IllegalArgumentException iae) {
            close();
            throw iae;
        }
        
        close();
    }
    
    
    
    
    
    
    
    
    
    
   /* The methods below are used for low level IO operations
    that will be used in the program. */
     
   /** InputStream with implemented buffering for faster input */
    private static DataInputStream dis;
   /** Buffer for input */
    private static byte[] buffer;
   /** Variables for reading buffer */
    private static int bytesRead, bufferPos;
   /** Unsynchronized Mutable String to store Output */
    private static StringBuilder outData;
    
   /**
    * Initializes the IO objects.
    * To be called before using IO methods.
    * 
    */
    private static void initializeIO() {
        dis = new DataInputStream(System.in);
        buffer = new byte[1 << 16];
        read();
        
        outData = new StringBuilder();
    }
    
   /**
    * Closes IO objects after execution.
    * 
    */
    private static void close() {
        try {
            System.out.print(outData);
            dis.close();
        }
        catch(IOException e) {
        }
    }
    
   /** To store next byte in buffer for Operations. */
    private static byte c;
   /** To store if a integer type data is negative or not. */
    private static boolean neg;
    
   /**
    * @throws IllegalArgumentException If the next input data is not an integer type.
    * 
    * @return The next Integer data from the input data
    * 
    */
    private static int nextInt() throws IllegalArgumentException {
        skipWhiteSpace();
        int temp = 0;
        
        neg = (c == '-');
        if(neg) {
            read();
        }

        do {
            if(!isDigit()) {
                throw new IllegalArgumentException();
            }
            
            temp = temp * 10 + c - '0';
            read();
        } while(!(c == '\n' || c == ' ' || c == '\r') && (c != -1));
        
        return neg ? -temp : temp;
    }
    
   /**
    * @param n The size of the array.
    * @throws IllegalArgumentException If the next input data is not an integer type.
    * @return The Integer array with the specified number of elements.
    * 
    */
    private static int[] nextIntArr(int n) throws IllegalArgumentException {
        int[] arr = new int[n];
        for(int i = 0; i < n; i ++) arr[i] = nextInt();
        return arr;
    }
    
   /**
    * @throws IllegalArgumentException If the next input data is not an integer type.
    * 
    * @return The next Long data in the input data
    * 
    */
    private static long nextLong() throws IllegalArgumentException {
        skipWhiteSpace();
        long temp = 0;

        neg = (c == '-');
        if (neg) {
            read();
        }
        
        do {
            if(!isDigit()) {
                throw new IllegalArgumentException();
            }
            
            temp = temp * 10L + c - '0';
            read();
        } while(!(c == '\n' || c == ' ' || c == '\r') && (c != -1));

        return neg ? -temp : temp;
    }

   /**
    * @param n The size of the array.
    * @throws IllegalArgumentException If the next input data is not an long type.
    * @return The Long array with the specified number of elements.
    * 
    */
    private static long[] nextLongArr(int n) throws IllegalArgumentException {
        long[] arr = new long[n];
        for(int i = 0; i < n; i ++) arr[i] = nextLong();
        return arr;
    }
    
   /**
    * @throws IllegalArgumentException If the next input data is not float or integer.
    * 
    * @return The next Double data in the input stream.
    * 
    */
    private static double nextDouble() {
        skipWhiteSpace();
        double temp = 0.0d;
        
        neg = (c == '-');
        if(neg) {
            read();
        }
        
        if(c != '.') {
            do {
                if(!isDigit()) {
                    throw new IllegalArgumentException();
                }
            
                temp = temp * 10.0d + c - '0';
                read();
            } while(c != '.' && !(c == '\n' || c == ' ' || c == '\r') && (c != -1));
        }
        
        if(c == '.') {
            double div = 1.0d;
            read();
            
            while(!(c == '\n' || c == ' ' || c == '\r') && (c != -1)) {
                if(!isDigit()) {
                    throw new IllegalArgumentException();
                }
            
                temp = temp * 10.0d + c - '0';
                div *= 10.0d;
                read();
            }
            
            temp /= div;
        }
        
        return neg ? -temp : temp;
    }

   /**
    * @param n The size of the array.
    * @throws IllegalArgumentException If the next input data is not an double type.
    * @return The Double array with the specified number of elements.
    * 
    */
    private static double[] nextDoubleArr(int n) throws IllegalArgumentException {
        double[] arr = new double[n];
        for(int i = 0; i < n; i ++) arr[i] = nextDouble();
        return arr;
    }
    
   /**
    * Checks if a byte is number or not.
    * 
    */
    private static boolean isDigit() {
        return (c >= '0' && c <= '9');
    }
  
   /** Stores the initial length of the given StringBuilder in the following functions. */
    private static int length;
   
   /**
    * Writes the remaining data from the current line from the input data in the given StringBuilder.
    * 
    * @param sb StringBuilder object in which the data will be stored.
    * @throws IllegalArgumentException If there is no byte left in input data.
    * @return The StringBuilder object after refilling it.
    *
    */
    private static StringBuilder getLine(StringBuilder sb) throws IllegalArgumentException {
        sb.setLength(0);
        
        while(c != -1) {
            if(c == '\n' || c == '\r') {
                break;
            }
            
            sb.append((char)c);
            read();
        }
        
        if(sb.length() == 0) {
            throw new IllegalArgumentException();
        }
        
        return sb;
    }
    
   /**
    * Writes the next line from the current line from the input data in the given StringBuilder.
    * 
    * @param sb StringBuilder object in which the data will be stored.
    * @return The StringBuilder object after refilling it.
    *
    */
    private static StringBuilder nextLine(StringBuilder sb) {
        skipLine(); getLine(sb);
        return sb;
    }
    
   /**
    * Appends the next word from the input data in the given StringBuilder
    * 
    * @param sb StringBuilder object in which the data will be stored.
    * @throws IllegalArgumentException If there is no byte left in input data.
    * @return The StringBuilder object after filling it.
    *
    */
    private static StringBuilder addNext(StringBuilder sb) throws IllegalArgumentException {
        skipWhiteSpace();
        length = sb.length();
        
        while(c != -1) {
            if(c == ' ' || c == '\n' || c == '\r') {
                break;
            }
            
            sb.append((char)c);
            read();
        }
        
        if(sb.length() == length) {
            throw new IllegalArgumentException();
        }
        
        return sb;
    }
    
   /**
    * Writes the next word from the input data in the given StringBuilder
    * 
    * @param sb StringBuilder object in which the data will be stored.
    * @return The StringBuilder object after refilling it.
    *
    */
    private static StringBuilder next(StringBuilder sb) {
        sb.setLength(0);
        addNext(sb);
        return sb;
    }
    
   /**
    * Skips any prevailing space or empty lines.
    * 
    */ 
    private static void skipWhiteSpace() {
        while((c == '\n' || c == ' ' || c == '\r') && (c != -1)) {
            read();
        }
    }
   
   /**
    * Skips any prevailing space.
    * 
    */
    private static void skipSpace() {
        while(c == ' ' && c != -1) {
            read();
        }
    }
     
   /**
    * Skips a line from the input stream.
    * 
    */
    private static void skipLine() {
        while(c != '\n' && c != '\r' && c != -1) {
            read();
        }
        
        while(c != -1 && (c == '\n' || c == '\r')) {
            read();
        }
    }
    
   /**
    * Skips a word from the input stream.
    * 
    */
    private static void skipWord() {
        while(c != '\n' && c != ' ' && c != '\r' && c != -1) {
            read();
        }
        
        read();
    }
    
   /**
    * Refills the buffer with new data.
    * 
    */
    private static void fillBuffer() throws IOException {
        bytesRead = dis.read(buffer, bufferPos = 0, buffer.length);
        
        if(bytesRead == -1) {
            buffer[0] = -1;
        }
    }
   
   /**
    * Reads the next byte from the input data and stores it in {@link c}
    * 
    */
    private static void read() {
        if(bufferPos >= bytesRead) {
            try {
                fillBuffer();
            }
            catch(IOException e) {
            }
        }
        
        c = buffer[bufferPos ++];
    }
}

JavaScript solution:
// your code goes here
function processInput(input) {
    let lines = input.trim().split("\n");
    let index = 0;
    let t = parseInt(lines[index++]);
    let results = [];

    while (t--) {
        let N = parseInt(lines[index++]);

        // Read the three binary strings.
        let s1 = lines[index++];
        let s2 = lines[index++];
        let s3 = lines[index++];

        // Count the number of '1's in each string.
        let onesCount = [0, 0, 0];
        for (let i = 0; i < N; i++) {
            if (s1[i] === '1') onesCount[0]++;
            if (s2[i] === '1') onesCount[1]++;
            if (s3[i] === '1') onesCount[2]++;
        }

        let totalOnes = onesCount[0] + onesCount[1] + onesCount[2];

        // Check if it's possible.
        if (totalOnes === 0 || totalOnes === 3 * N) {
            // Already uniform.
            results.push("0");
        } else if (totalOnes === N) {
            // Exactly one string will be ones-target.
            // Choose the string with the maximum number of ones to minimize the deficit.
            let maxOnes = Math.max(...onesCount);
            results.push((N - maxOnes).toString());
        } else if (totalOnes === 2 * N) {
            // Exactly two strings will be ones-target.
            // The minimum operations equal the number of ones in the string with the smallest count.
            let minOnes = Math.min(...onesCount);
            results.push(minOnes.toString());
        } else {
            // Not possible to redistribute ones to get all strings uniform.
            results.push("-1");
        }
    }

    console.log(results.join("\n"));
}

// Read input and call the function
const fs = require("fs");
const input = fs.readFileSync(0, "utf8");
processInput(input);

Python solution:
def count10(s):
    n0, n1 = 0, 0
    for i in s:
        if i=='0':
            n0 += 1
        else:
            n1 += 1
    return n0, n1
    
t = int(input())
for T in range(t):
    n = int(input())
    s1 = input()
    s2 = input()
    s3 = input()
    n10, n11 = count10(s1)
    n20, n21 = count10(s2)
    n30, n31 = count10(s3)
    if (n10 + n20 + n30)%n:
        print(-1)
    else:
        if (n10 + n20 + n30)>(n11 + n21 + n31):
            x = n - max(n11, n21, n31)
        else:
            x = n - max(n10, n20, n30)
        if x==n:
            print(0)
        else:
            print(x)

Ruby solution:
def solve
  input = $stdin.read.split("\n")
  ptr = 0
  t = input[ptr].to_i
  ptr += 1
  results = []
  t.times do
    n = input[ptr].to_i
    ptr += 1
    s = []
    3.times do
      s << input[ptr].strip
      ptr += 1
    end
    l = []
    m = []
    o = 0
    s.each do |str|
      cnt1 = str.count('1')
      l << cnt1
      m << n - cnt1
      o += cnt1
    end
    z = 3 * n - o
    possible = false
    res = Float::INFINITY
    if o % n == 0
      x = o / n
      l_sorted = l.sort
      sum = 0
      (3 - x).times do |i|
        sum += l_sorted[i]
      end
      res = [res, sum].min
      possible = true
    end
    if z % n == 0
      y = z / n
      m_sorted = m.sort
      sum = 0
      (3 - y).times do |i|
        sum += m_sorted[i]
      end
      res = [res, sum].min
      possible = true
    end
    if possible
      results << res
    else
      results << -1
    end
  end
  puts results.join("\n")
end

solve