use std::collections::{HashMap, HashSet};
fn main() {
//twitter.com/own_touch/status/1249253680475295749
Solver::new(
Exp::v("MISSHU")
.add(Exp::v("MIPPEI"))
.add(Exp::v("MISSETU"))
.eql(Exp::v("SAKETEE")),
)
.solve();
}
enum Exp {
V(String),
Add(Box<Exp>, Box<Exp>),
Eql(Box<Exp>, Box<Exp>),
}
impl Exp {
fn v(s: &str) -> Box<Exp> {
Box::new(Exp::V(s.to_string()))
}
fn add(self: Box<Exp>, b: Box<Exp>) -> Box<Exp> {
Box::new(Exp::Add(self, b))
}
fn eql(self: Box<Exp>, b: Box<Exp>) -> Box<Exp> {
Box::new(Exp::Eql(self, b))
}
fn calc(&self, map: &HashMap<char, i64>) -> Option<i64> {
match *self {
Exp::Add(ref a, ref b) => {
if let (Some(a), Some(b)) = (a.calc(map), b.calc(map)) {
Some(a + b)
} else {
None
}
}
Exp::Eql(ref a, ref b) => {
if let (Some(a), Some(b)) = (a.calc(map), b.calc(map)) {
if a == b {
Some(-1)
} else {
None
}
} else {
None
}
}
Exp::V(ref s) => {
let mut v = 0;
for c in s.chars() {
v *= 10;
v += map.get(&c).unwrap();
if v == 0 {
return None;
}
}
Some(v)
}
}
}
fn print(&self) {
match *self {
Exp::Add(ref a, ref b) => {
a.print();
print!(" + ");
b.print();
}
Exp::Eql(ref a, ref b) => {
a.print();
print!(" = ");
b.print();
}
Exp::V(ref s) => {
print!("{}", s);
}
}
}
fn print_with(&self, map: &HashMap<char, i64>) {
match *self {
Exp::Add(ref a, ref b) => {
a.print_with(&map);
print!(" + ");
b.print_with(&map);
}
Exp::Eql(ref a, ref b) => {
a.print_with(&map);
print!(" = ");
b.print_with(&map);
}
Exp::V(ref s) => {
let mut v = 0;
for c in s.chars() {
v *= 10;
v += map.get(&c).unwrap();
}
print!("{}", v);
}
}
}
}
struct Solver {
set: Vec<char>,
}
impl Solver {
fn new
(exp: Box
<Exp
>) -> Solver
{ let mut set = HashSet::new();
Solver
::pick(&mut set
, &exp); Solver {
set: set.into_iter().collect(),
}
}
fn pick
(set
: &mut HashSet
<char
>, exp: &Exp
) { Exp::Add(ref a, ref b) | Exp::Eql(ref a, ref b) => {
Solver::pick(set, &a);
Solver::pick(set, &b);
}
Exp::V(ref s) => {
for c in s.chars() {
set.insert(c);
}
}
}
}
fn solve(&self) {
let mut ind: Vec<_> = (0..self.set.len()).collect();
let mut map = HashMap::new();
let mut flag = (1 << (ind.len() + 1)) - 1;
loop {
for (i, ix) in ind.iter().enumerate() {
map.insert(self.set[*ix], i as i64);
}
if self.
exp.
calc(&map
).
is_some() { println!("found");
for (k, v) in &map {
print!("{}={}, ", k, v);
}
println!();
println!();
self.
exp.
print_with(&map
); println!();
}
let mut p = ind.len() - 1;
loop {
flag ^= 1 << ind[p];
ind[p] += 1;
while ind[p] < ind.len() && (flag & (1 << ind[p])) != 0 {
ind[p] += 1;
}
if ind[p] < ind.len() {
flag |= 1 << ind[p];
p += 1;
break;
}
if p == 0 {
return;
}
p -= 1;
}
while p < ind.len() {
ind[p] = 0;
while ind[p] < ind.len() && (flag & (1 << ind[p])) != 0 {
ind[p] += 1;
}
flag |= 1 << ind[p];
p += 1;
}
}
}
}
dXNlIHN0ZDo6Y29sbGVjdGlvbnM6OntIYXNoTWFwLCBIYXNoU2V0fTsKCmZuIG1haW4oKSB7CiAgICAvL3R3aXR0ZXIuY29tL293bl90b3VjaC9zdGF0dXMvMTI0OTI1MzY4MDQ3NTI5NTc0OQogICAgU29sdmVyOjpuZXcoCiAgICAgICAgRXhwOjp2KCJNSVNTSFUiKQogICAgICAgICAgICAuYWRkKEV4cDo6digiTUlQUEVJIikpCiAgICAgICAgICAgIC5hZGQoRXhwOjp2KCJNSVNTRVRVIikpCiAgICAgICAgICAgIC5lcWwoRXhwOjp2KCJTQUtFVEVFIikpLAogICAgKQogICAgLnNvbHZlKCk7Cn0KCmVudW0gRXhwIHsKICAgIFYoU3RyaW5nKSwKICAgIEFkZChCb3g8RXhwPiwgQm94PEV4cD4pLAogICAgRXFsKEJveDxFeHA+LCBCb3g8RXhwPiksCn0KCmltcGwgRXhwIHsKICAgIGZuIHYoczogJnN0cikgLT4gQm94PEV4cD4gewogICAgICAgIEJveDo6bmV3KEV4cDo6VihzLnRvX3N0cmluZygpKSkKICAgIH0KICAgIGZuIGFkZChzZWxmOiBCb3g8RXhwPiwgYjogQm94PEV4cD4pIC0+IEJveDxFeHA+IHsKICAgICAgICBCb3g6Om5ldyhFeHA6OkFkZChzZWxmLCBiKSkKICAgIH0KICAgIGZuIGVxbChzZWxmOiBCb3g8RXhwPiwgYjogQm94PEV4cD4pIC0+IEJveDxFeHA+IHsKICAgICAgICBCb3g6Om5ldyhFeHA6OkVxbChzZWxmLCBiKSkKICAgIH0KICAgIGZuIGNhbGMoJnNlbGYsIG1hcDogJkhhc2hNYXA8Y2hhciwgaTY0PikgLT4gT3B0aW9uPGk2ND4gewogICAgICAgIG1hdGNoICpzZWxmIHsKICAgICAgICAgICAgRXhwOjpBZGQocmVmIGEsIHJlZiBiKSA9PiB7CiAgICAgICAgICAgICAgICBpZiBsZXQgKFNvbWUoYSksIFNvbWUoYikpID0gKGEuY2FsYyhtYXApLCBiLmNhbGMobWFwKSkgewogICAgICAgICAgICAgICAgICAgIFNvbWUoYSArIGIpCiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIE5vbmUKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBFeHA6OkVxbChyZWYgYSwgcmVmIGIpID0+IHsKICAgICAgICAgICAgICAgIGlmIGxldCAoU29tZShhKSwgU29tZShiKSkgPSAoYS5jYWxjKG1hcCksIGIuY2FsYyhtYXApKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgYSA9PSBiIHsKICAgICAgICAgICAgICAgICAgICAgICAgU29tZSgtMSkKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBOb25lCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBOb25lCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgRXhwOjpWKHJlZiBzKSA9PiB7CiAgICAgICAgICAgICAgICBsZXQgbXV0IHYgPSAwOwogICAgICAgICAgICAgICAgZm9yIGMgaW4gcy5jaGFycygpIHsKICAgICAgICAgICAgICAgICAgICB2ICo9IDEwOwogICAgICAgICAgICAgICAgICAgIHYgKz0gbWFwLmdldCgmYykudW53cmFwKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgdiA9PSAwIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5vbmU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgU29tZSh2KQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgZm4gcHJpbnQoJnNlbGYpIHsKICAgICAgICBtYXRjaCAqc2VsZiB7CiAgICAgICAgICAgIEV4cDo6QWRkKHJlZiBhLCByZWYgYikgPT4gewogICAgICAgICAgICAgICAgYS5wcmludCgpOwogICAgICAgICAgICAgICAgcHJpbnQhKCIgKyAiKTsKICAgICAgICAgICAgICAgIGIucHJpbnQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBFeHA6OkVxbChyZWYgYSwgcmVmIGIpID0+IHsKICAgICAgICAgICAgICAgIGEucHJpbnQoKTsKICAgICAgICAgICAgICAgIHByaW50ISgiID0gIik7CiAgICAgICAgICAgICAgICBiLnByaW50KCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgRXhwOjpWKHJlZiBzKSA9PiB7CiAgICAgICAgICAgICAgICBwcmludCEoInt9Iiwgcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgZm4gcHJpbnRfd2l0aCgmc2VsZiwgbWFwOiAmSGFzaE1hcDxjaGFyLCBpNjQ+KSB7CiAgICAgICAgbWF0Y2ggKnNlbGYgewogICAgICAgICAgICBFeHA6OkFkZChyZWYgYSwgcmVmIGIpID0+IHsKICAgICAgICAgICAgICAgIGEucHJpbnRfd2l0aCgmbWFwKTsKICAgICAgICAgICAgICAgIHByaW50ISgiICsgIik7CiAgICAgICAgICAgICAgICBiLnByaW50X3dpdGgoJm1hcCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgRXhwOjpFcWwocmVmIGEsIHJlZiBiKSA9PiB7CiAgICAgICAgICAgICAgICBhLnByaW50X3dpdGgoJm1hcCk7CiAgICAgICAgICAgICAgICBwcmludCEoIiA9ICIpOwogICAgICAgICAgICAgICAgYi5wcmludF93aXRoKCZtYXApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEV4cDo6VihyZWYgcykgPT4gewogICAgICAgICAgICAgICAgbGV0IG11dCB2ID0gMDsKICAgICAgICAgICAgICAgIGZvciBjIGluIHMuY2hhcnMoKSB7CiAgICAgICAgICAgICAgICAgICAgdiAqPSAxMDsKICAgICAgICAgICAgICAgICAgICB2ICs9IG1hcC5nZXQoJmMpLnVud3JhcCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcHJpbnQhKCJ7fSIsIHYpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgpzdHJ1Y3QgU29sdmVyIHsKICAgIGV4cDogQm94PEV4cD4sCiAgICBzZXQ6IFZlYzxjaGFyPiwKfQoKaW1wbCBTb2x2ZXIgewogICAgZm4gbmV3KGV4cDogQm94PEV4cD4pIC0+IFNvbHZlciB7CiAgICAgICAgbGV0IG11dCBzZXQgPSBIYXNoU2V0OjpuZXcoKTsKICAgICAgICBTb2x2ZXI6OnBpY2soJm11dCBzZXQsICZleHApOwogICAgICAgIFNvbHZlciB7CiAgICAgICAgICAgIGV4cCwKICAgICAgICAgICAgc2V0OiBzZXQuaW50b19pdGVyKCkuY29sbGVjdCgpLAogICAgICAgIH0KICAgIH0KICAgIGZuIHBpY2soc2V0OiAmbXV0IEhhc2hTZXQ8Y2hhcj4sIGV4cDogJkV4cCkgewogICAgICAgIG1hdGNoICpleHAgewogICAgICAgICAgICBFeHA6OkFkZChyZWYgYSwgcmVmIGIpIHwgRXhwOjpFcWwocmVmIGEsIHJlZiBiKSA9PiB7CiAgICAgICAgICAgICAgICBTb2x2ZXI6OnBpY2soc2V0LCAmYSk7CiAgICAgICAgICAgICAgICBTb2x2ZXI6OnBpY2soc2V0LCAmYik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgRXhwOjpWKHJlZiBzKSA9PiB7CiAgICAgICAgICAgICAgICBmb3IgYyBpbiBzLmNoYXJzKCkgewogICAgICAgICAgICAgICAgICAgIHNldC5pbnNlcnQoYyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBmbiBzb2x2ZSgmc2VsZikgewogICAgICAgIGxldCBtdXQgaW5kOiBWZWM8Xz4gPSAoMC4uc2VsZi5zZXQubGVuKCkpLmNvbGxlY3QoKTsKICAgICAgICBsZXQgbXV0IG1hcCA9IEhhc2hNYXA6Om5ldygpOwogICAgICAgIGxldCBtdXQgZmxhZyA9ICgxIDw8IChpbmQubGVuKCkgKyAxKSkgLSAxOwogICAgICAgIGxvb3AgewogICAgICAgICAgICBmb3IgKGksIGl4KSBpbiBpbmQuaXRlcigpLmVudW1lcmF0ZSgpIHsKICAgICAgICAgICAgICAgIG1hcC5pbnNlcnQoc2VsZi5zZXRbKml4XSwgaSBhcyBpNjQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIHNlbGYuZXhwLmNhbGMoJm1hcCkuaXNfc29tZSgpIHsKICAgICAgICAgICAgICAgIHByaW50bG4hKCJmb3VuZCIpOwogICAgICAgICAgICAgICAgZm9yIChrLCB2KSBpbiAmbWFwIHsKICAgICAgICAgICAgICAgICAgICBwcmludCEoInt9PXt9LCAiLCBrLCB2KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHByaW50bG4hKCk7CiAgICAgICAgICAgICAgICBzZWxmLmV4cC5wcmludCgpOwogICAgICAgICAgICAgICAgcHJpbnRsbiEoKTsKICAgICAgICAgICAgICAgIHNlbGYuZXhwLnByaW50X3dpdGgoJm1hcCk7CiAgICAgICAgICAgICAgICBwcmludGxuISgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxldCBtdXQgcCA9IGluZC5sZW4oKSAtIDE7CiAgICAgICAgICAgIGxvb3AgewogICAgICAgICAgICAgICAgZmxhZyBePSAxIDw8IGluZFtwXTsKICAgICAgICAgICAgICAgIGluZFtwXSArPSAxOwogICAgICAgICAgICAgICAgd2hpbGUgaW5kW3BdIDwgaW5kLmxlbigpICYmIChmbGFnICYgKDEgPDwgaW5kW3BdKSkgIT0gMCB7CiAgICAgICAgICAgICAgICAgICAgaW5kW3BdICs9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiBpbmRbcF0gPCBpbmQubGVuKCkgewogICAgICAgICAgICAgICAgICAgIGZsYWcgfD0gMSA8PCBpbmRbcF07CiAgICAgICAgICAgICAgICAgICAgcCArPSAxOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgcCA9PSAwIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwIC09IDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgd2hpbGUgcCA8IGluZC5sZW4oKSB7CiAgICAgICAgICAgICAgICBpbmRbcF0gPSAwOwogICAgICAgICAgICAgICAgd2hpbGUgaW5kW3BdIDwgaW5kLmxlbigpICYmIChmbGFnICYgKDEgPDwgaW5kW3BdKSkgIT0gMCB7CiAgICAgICAgICAgICAgICAgICAgaW5kW3BdICs9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmbGFnIHw9IDEgPDwgaW5kW3BdOwogICAgICAgICAgICAgICAgcCArPSAxOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9Cg==