Óxido, puntaje 1412 1411
src/main.rs
extern crate gmp;
use std::collections::BinaryHeap;
use std::collections::hash_map::{HashMap, Entry};
use gmp::mpz::Mpz;
fn visit(
queue: &mut BinaryHeap<(i32, i32, i32, Mpz, Mpz)>,
visited: &mut HashMap<(i32, Mpz), i32>,
score: i32,
h: i32,
k: i32,
d: Mpz,
c: Mpz,
) {
match visited.entry((k, d.clone())) {
Entry::Occupied(mut e) => {
if *e.get() < score {
e.insert(score);
queue.push((score, h, k, d, c));
}
}
Entry::Vacant(e) => {
e.insert(score);
queue.push((score, h, k, d, c));
}
}
}
fn main() {
let mut total = 0;
for n in 1..21 {
let a_range = n / 2 - n + 1..n / 2 + 1;
let min_ab = a_range.start * (a_range.end - 1);
let mut ab = Mpz::zero();
for a in a_range.clone() {
for b in a_range.clone() {
ab.setbit((a * b - min_ab) as usize);
}
}
let heuristic = |k: i32, d: &Mpz| if k == n {
0
} else {
k + 1 - n -
(0..d.bit_length())
.map(|i| (&ab & !(d >> i)).popcount())
.min()
.unwrap() as i32
};
let mut queue = BinaryHeap::new();
let mut visited = HashMap::new();
let (k1, d1) = (0, Mpz::zero());
let h1 = heuristic(k1, &d1);
visit(&mut queue, &mut visited, h1, h1, k1, d1, Mpz::zero());
while let Some((score, h, k, d, c)) = queue.pop() {
if k == n {
println!("n={} |S|={}", n, -score);
println!(" A={:?}", a_range.clone().collect::<Vec<_>>());
println!(" B={:?}", a_range.clone().collect::<Vec<_>>());
println!(
" C={:?}",
(0..c.bit_length())
.filter(|&i| c.tstbit(c.bit_length() - 1 - i))
.collect::<Vec<_>>()
);
total += -score;
break;
}
let kd = (k, d);
if score < visited[&kd] {
continue;
}
let (k, d) = kd;
let (k1, d1) = (k, &d >> 1);
let h1 = heuristic(k1, &d1);
visit(
&mut queue,
&mut visited,
score - h + h1,
h1,
k1,
d1,
&c << 1,
);
let (k1, d1) = (k + 1, (&d | &ab) >> 1);
let h1 = heuristic(k1, &d1);
visit(
&mut queue,
&mut visited,
score - h - (&ab & !&d).popcount() as i32 + h1,
h1,
k1,
d1,
&c << 1 | Mpz::one(),
);
}
}
println!("total={}", total);
}
Cargo.toml
[package]
name = "small"
version = "0.1.0"
authors = ["Anders Kaseorg <andersk@mit.edu>"]
[dependencies]
rust-gmp = "0.5.0"
Compila y ejecuta con cargo run --release
.
Salida
n=1 |S|=1
A=[0]
B=[0]
C=[0]
n=2 |S|=3
A=[0, 1]
B=[0, 1]
C=[0, 1]
n=3 |S|=5
A=[-1, 0, 1]
B=[-1, 0, 1]
C=[0, 1, 2]
n=4 |S|=10
A=[-1, 0, 1, 2]
B=[-1, 0, 1, 2]
C=[0, 1, 2, 3]
n=5 |S|=13
A=[-2, -1, 0, 1, 2]
B=[-2, -1, 0, 1, 2]
C=[0, 1, 2, 3, 4]
n=6 |S|=21
A=[-2, -1, 0, 1, 2, 3]
B=[-2, -1, 0, 1, 2, 3]
C=[0, 2, 3, 4, 5, 6]
n=7 |S|=25
A=[-3, -2, -1, 0, 1, 2, 3]
B=[-3, -2, -1, 0, 1, 2, 3]
C=[0, 2, 3, 5, 6, 7, 8]
n=8 |S|=35
A=[-3, -2, -1, 0, 1, 2, 3, 4]
B=[-3, -2, -1, 0, 1, 2, 3, 4]
C=[0, 3, 4, 6, 7, 8, 10, 11]
n=9 |S|=39
A=[-4, -3, -2, -1, 0, 1, 2, 3, 4]
B=[-4, -3, -2, -1, 0, 1, 2, 3, 4]
C=[0, 3, 4, 6, 7, 8, 10, 11, 14]
n=10 |S|=53
A=[-4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
B=[-4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
C=[0, 1, 4, 5, 6, 9, 10, 11, 14, 15]
n=11 |S|=58
A=[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
B=[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
C=[0, 1, 4, 5, 6, 9, 10, 11, 14, 15, 19]
n=12 |S|=74
A=[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6]
B=[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6]
C=[0, 4, 5, 6, 9, 10, 11, 12, 15, 16, 17, 21]
n=13 |S|=80
A=[-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6]
B=[-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6]
C=[0, 4, 5, 6, 9, 10, 11, 12, 15, 16, 17, 21, 22]
n=14 |S|=100
A=[-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7]
B=[-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7]
C=[0, 1, 6, 7, 8, 12, 13, 14, 15, 19, 20, 21, 26, 27]
n=15 |S|=106
A=[-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7]
B=[-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7]
C=[0, 5, 6, 7, 11, 12, 13, 14, 18, 19, 20, 21, 25, 26, 27]
n=16 |S|=128
A=[-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8]
B=[-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8]
C=[0, 6, 7, 8, 13, 14, 15, 16, 20, 21, 22, 23, 28, 29, 30, 36]
n=17 |S|=135
A=[-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8]
B=[-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8]
C=[0, 6, 7, 8, 13, 14, 15, 16, 20, 21, 22, 23, 28, 29, 30, 36, 44]
n=18 |S|=161
A=[-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
B=[-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
C=[0, 7, 8, 9, 15, 16, 17, 18, 23, 24, 25, 26, 27, 32, 33, 34, 35, 41]
n=19 |S|=167
A=[-9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
B=[-9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
C=[0, 7, 8, 9, 15, 16, 17, 18, 23, 24, 25, 26, 27, 32, 33, 34, 35, 41, 42]
n=20 |S|=197
A=[-9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
B=[-9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
C=[0, 1, 8, 9, 10, 11, 17, 18, 19, 20, 21, 26, 27, 28, 29, 30, 36, 37, 38, 46]
total=1411
En mi computadora portátil, esto usó aproximadamente 8 minutos y aproximadamente 1.5 GiB de memoria.
Cómo funciona
Suponemos (sin ninguna justificación particular) de que A y B son la gama de enteros consecutivos obvia centrada en 0 o ½, y luego hacer una búsqueda A * para una óptima C dada A y B .