Problem:
Score : 1000 points

Problem Statement

You have two strings A = A_1 A_2 ... A_n and B = B_1 B_2 ... B_n of the same length consisting of 0 and 1.

You can transform A using the following operations in any order and as many times as you want:

Shift A by one character to the left (i.e., if A = A_1 A_2 ... A_n, replace A with A_2 A_3 ... A_n A_1).

Shift A by one character to the right (i.e., if A = A_1 A_2 ... A_n, replace A with A_n A_1 A_2 ... A_{n-1}).

Choose any i such that B_i = 1. Flip A_i (i.e., set A_i = 1 - A_i).

You goal is to make strings A and B equal.

Print the smallest number of operations required to achieve this, or -1 if the goal is unreachable.

Constraints

1 \leq |A| = |B| \leq 2,000

A and B consist of 0 and 1.

Input

Input is given from Standard Input in the following format:

A
B

Output

Print the smallest number of operations required to make strings A and B equal, or -1 if the goal is unreachable.

Sample Input 1

1010
1100

Sample Output 1

3

Here is one fastest way to achieve the goal:

Flip A_1: A = 0010

Shift A to the left: A = 0100

Flip A_1 again: A = 1100

Sample Input 2

1
0

Sample Output 2

-1

There is no way to flip the only bit in A.

Sample Input 3

11010
10001

Sample Output 3

4

Here is one fastest way to achieve the goal:

Shift A to the right: A = 01101

Flip A_5: A = 01100

Shift A to the left: A = 11000

Shift A to the left again: A = 10001

Sample Input 4

0100100
1111111

Sample Output 4

5

Flip A_1, A_3, A_4, A_6 and A_7 in any order.

Solution in Rust (1.15.1) (judge verdict: Accepted)

// use std::ops::{Index, IndexMut};
// use std::cmp::{Ordering, min, max};
// use std::collections::{BinaryHeap, BTreeMap};
// use std::collections::btree_map::Entry::{Occupied, Vacant};
// use std::clone::Clone;

fn getline() -> String{
    let mut res = String::new();
    std::io::stdin().read_line(&mut res).ok();
    res
}

macro_rules! readl {
    ($t: ty) => {
        {
            let s = getline();
            s.trim().parse::<$t>().unwrap()
        }
    };
    ($( $t: ty),+ ) => {
        {
            let s = getline();
            let mut iter = s.trim().split(' ');
            ($(iter.next().unwrap().parse::<$t>().unwrap(),)*) 
        }
    };
}

macro_rules! readlvec {
    ($t: ty) => {
        {
            let s = getline();
            let iter = s.trim().split(' ');
            iter.map(|x| x.parse().unwrap()).collect::<Vec<$t>>()
        }
    }
}

macro_rules! mvec {
    ($v: expr, $s: expr) => {
        vec![$v; $s]
    };
    ($v: expr, $s: expr, $($t: expr),*) => {
        vec![mvec!($v, $($t),*); $s]
    };
}

macro_rules! debug {
    ($x: expr) => {
        println!("{}: {:?}", stringify!($x), $x)
    }
}

fn printiter<'a, T>(v: &'a T)
where
    &'a T: std::iter::IntoIterator, 
    <&'a T as std::iter::IntoIterator>::Item: std::fmt::Display {
    for (i,e) in v.into_iter().enumerate() {
        if i != 0 {
            print!(" ");
        }
        print!("{}", e);
    }
    println!("");
}

fn main() {
    let a: Vec<_> = readl!(String).chars().map(|a| a == '1').collect();
    let b: Vec<_> = readl!(String).chars().map(|a| a == '1').collect();
    let n = b.len();
    let mut left_one = vec![n+1; n];
    let mut x = n+1;
    
    if b.iter().filter(|&&x| x).count() == 0 {
        if a.iter().filter(|&&x| x).count() == 0 {
            println!("0");
        } else {
            println!("-1");
        }
        return;
    }

    for i in 0..2*n {
        let p = i%n;
        if b[p] {
            x = 0;
        } else {
            x += 1;
        }
        left_one[p] = x;
    }
    let left_one = left_one;

    let mut right_one = vec![n+1; n];
    let mut x = n+1;
    for i in (0..2*n).rev() {
        let p = i%n;
        if b[p] {
            x = 0;
        } else {
            x += 1;
        }
        right_one[p] = x;
    }
    let right_one = right_one;

    // debug!(left_one);
    // debug!(right_one);
    let inf = 1_000_000_00;
    let mut ans = inf;
    for d in 0..n {
        // debug!(d);
        {
            let mut vv = vec![(0, 0); n];
            let mut diff_cnt = 0;
            for i in 0..n {
                if b[(i+d)%n] !=  a[i] {
                    diff_cnt += 1;
                }
                if !b[(i+d)%n] && a[i] {
                    let left = left_one[i];
                    let right = if right_one[i] <= d {
                        0
                    } else {
                        right_one[i]-d
                    };
                    vv[i] = (left, right);
                }
            }
            // debug!(vv);
            vv.sort();
            for i in (0..n-1).rev() {
                vv[i].1 = std::cmp::max(vv[i+1].1, vv[i].1);
            }
            // debug!(vv);
            let mut val = std::cmp::min(vv[0].1, vv.last().unwrap().0);
            for i in 0..n-1 {
                val = std::cmp::min(val, vv[i+1].1+vv[i].0);
            }
            // debug!(val+d+diff_cnt);
            ans = std::cmp::min(ans, val*2+d+diff_cnt);
        }
        {
            let mut vv = vec![(0, 0); n];
            let mut diff_cnt = 0;
            for i in 0..n {
                if b[(i+d)%n] !=  a[i] {
                    diff_cnt += 1;
                }
                if !b[(i+d)%n] && a[i] {
                    let right = right_one[i];
                    let left = if left_one[i] <= n-d {
                        0
                    } else {
                        left_one[i]-(n-d)
                    };
                    vv[i] = (left, right);
                }
            }
            // debug!(vv);
            vv.sort();
            for i in (0..n-1).rev() {
                vv[i].1 = std::cmp::max(vv[i+1].1, vv[i].1);
            }
            // debug!(vv);
            let mut val = std::cmp::min(vv[0].1, vv.last().unwrap().0);
            for i in 0..n-1 {
                val = std::cmp::min(val, vv[i+1].1+vv[i].0);
            }
            // debug!(val+n-d+diff_cnt);
            // debug!(n-d);
            // debug!(diff_cnt);
            ans = std::cmp::min(ans, val*2+(n-d)+diff_cnt);
        }
    }
    println!("{}", ans);
}