C ++ 11
Pequeña actualización adicional: agregue mucho menos y pruebe todos los números del formulario A * B + C. Creo que, dentro del límite de tiempo, esto es bastante óptimo, suponiendo que solo use +
, *
y !
. ¡Dejo otros operadores a personas con más tiempo que yo!
Pequeña actualización: trate de utilizar factores y números como 11 ... 111. También solucioné un error que no estaba contando !
en mi costeo
Nuevo resultado:
Puntaje primario = 3,810,660
Puntaje secundario = 12/09/2016 20:00
2532 1
s, 1505 operadores.
Varios trucos juntos. Mi programa comienza estableciendo el programa más corto para todos los factores y números de la forma 111..111 (no creo que esto incumple la regla de cableado, ya que estas son las formas más cortas de hacer estos números. Podría reorganizar mi código, así que verifico estos patrones en mi programación dinámica si lo desea). Luego, realice un enfoque de programación dinámica parcial, probando varias formas:
- A + B
- A * B + C
- ¡UNA! + B
- 11 .... 11 + B
Desafortunadamente, no puedo probar todas las formas de descomponer un número, así que elijo factorial y 11 ... 11 para probar solo el número más cercano, para A + B para probar cosas cerca de A / 2 y para A * B + C para probar solo As bastante pequeño.
Sería fácil extender esto para intentar algunos '-s, tratando de sobrepasar ligeramente a veces (particularmente en A * B - C), pero me gusta solo tratar de crecer.
Además, es muy difícil optimizar la condición de optimización (¡no me gusta!) Porque, en principio, no se puede encontrar el "mejor" valor para cada número de forma aislada, debe considerar su conjunto de respuestas a nivel mundial (que no tengo la intención de hacer).
Advertencia: Este programa necesita una máquina de 64 bits y alrededor de 10 GB de memoria (ya que ineficientemente hago una matriz gigante para todos los resultados parcialmente calculados).
Programa:
#include <algorithm>
#include <vector>
#include <string>
#include <assert.h>
#include <iostream>
#include <cmath>
std::vector<int> numints;
std::vector<int> numops;
std::vector<std::string> strings;
void fill_all_ones(long maxval)
{
int val = 1;
int len = 1;
std::string name = "1";
while(val < maxval) {
val = val * 10 + 1;
len++;
name = name + "1";
numints[val] = len;
strings[val] = name;
}
}
void get_best_for_next_full(long i);
// let's just assume this is the best way to make factorials
void fill_all_factorials(long maxval)
{
// skip 1 and 2
long result = 6;
long val = 3;
while(result < maxval) {
get_best_for_next_full(val);
strings[result] = "(" + strings[val] + ")!";
numints[result] = numints[val];
numops[result] = numops[val] + 1;
val++;
result = result * val;
}
}
long get_nearest_all_ones(long i)
{
int val = 11;
int prevval = 1;
while(val < i) {
prevval = val;
val = val * 10 + 1;
}
return prevval;
}
long get_nearest_factorial(long i)
{
int val = 6;
int prevval = 2;
int step = 3;
while(val < i) {
prevval = val;
step++;
val = val * step;
}
return prevval;
}
int getlen(long i);
void get_best_for_next_full(long i)
{
if(numints[i] > 0)
return;
int best = INT_MAX; // we'll do better than this
std::string beststring = "invalid2";
int ones = -1;
int ops = -1;
for(long loop = 1; loop <= i/2; loop++)
{
int new_val = getlen(loop) + getlen(i - loop);
if(new_val < best) {
best = new_val;
ones = numints[loop] + numints[i - loop];
beststring = "(" + strings[loop] + "+" + strings[i - loop] + ")";
ops = numops[loop] + numops[i - loop] + 1;
}
}
for(long loop = 2; loop * loop <= i; loop++)
{
long divisor = i / loop;
long rem = i - loop*divisor;
assert(rem >= 0);
int new_val;
if(rem == 0)
{
new_val = getlen(divisor) + getlen(loop);
}
else
{
new_val = getlen(divisor) + getlen(rem) + getlen(loop);
}
if(new_val < best) {
best = new_val;
if(rem == 0) {
ones = numints[divisor] + numints[loop];
beststring = "(" + strings[divisor] + "*" + strings[loop] + ")";
ops = numops[divisor] + numops[loop] + 1;
} else {
ones = numints[divisor] + numints[loop] + numints[rem];
beststring = "(" + strings[divisor] + "*" + strings[loop] + "+" + strings[rem] + ")";
ops = numops[divisor] + numops[loop] + numops[rem] + 2;
}
}
}
numints[i] = ones;
strings[i] = beststring;
numops[i] = ops;
}
void check_divising(const long i, const long loop, long& best, long& ones, std::string& beststring, long& ops);
void check_adding(const long i, const long loop, long& best, long& ones, std::string& beststring, long& ops);
void get_best_for_next_partial(long i)
{
if(numints[i] > 0)
return;
long best = INT_MAX; // we'll do better than this
long ones = 1;
std::string beststring = "invalid";
long ops = 1;
// Special: Try a nearby all ones
{
long loop = get_nearest_all_ones(i);
check_adding(i, loop, best, ones, beststring, ops);
}
// Special: Try nearest factorial
{
long loop = get_nearest_factorial(i);
check_adding(i, loop, best, ones, beststring, ops);
}
for(long loop = 2; loop * loop <= i; loop++)
{
check_divising(i, loop, best, ones, beststring, ops);
}
numints[i] = ones;
strings[i] = beststring;
numops[i] = ops;
}
void check_adding(const long i, const long loop, long& best, long& ones, std::string& beststring, long& ops)
{
int new_val = getlen(loop) + getlen(i - loop);
if(new_val < best) {
best = new_val;
ones = numints[loop] + numints[i - loop];
beststring = "(" + strings[loop] + "+" + strings[i - loop] + ")";
ops = numops[loop] + numops[i - loop] + 1;
}
}
void check_divising(const long i, const long loop, long& best, long& ones, std::string& beststring, long& ops)
{
long divisor = i / loop;
long rem = i - loop*divisor;
assert(rem >= 0);
int new_val;
if(rem == 0)
{
new_val = getlen(divisor) + getlen(loop);
}
else
{
new_val = getlen(divisor) + getlen(rem) + getlen(loop);
}
if(new_val < best) {
best = new_val;
if(rem == 0) {
ones = numints[divisor] + numints[loop];
beststring = "(" + strings[divisor] + "*" + strings[loop] + ")";
ops = numops[divisor] + numops[loop] + 1;
}
else {
ones = numints[divisor] + numints[loop] + numints[rem];
beststring = "(" + strings[divisor] + "*" + strings[loop] + "+" + strings[rem] + ")";
ops = numops[divisor] + numops[loop] + numops[rem] + 2;
}
}
}
long count = 0;
long countops = 0;
const int little_cutoff = 200000;
int getlen(long i)
{
if(numints[i] == 0) {
if(i < little_cutoff)
get_best_for_next_full(i);
else
get_best_for_next_partial(i);
}
if(numints[i] == 0) {
std::cout << i << " failure!" << numops[i] << ":" << strings[i] << std::endl;
exit(1);
}
return numints[i] + numops[i];
}
const std::vector<long> vals = {945536, 16878234, 32608778, 42017515, 48950830, 51483452, 52970263, 54278649, 63636656, 78817406, 89918907, 90757642, 95364861, 102706605, 113965374, 122448605, 126594161, 148064959, 150735075, 154382918, 172057472, 192280850, 194713795, 207721209, 220946392, 225230299, 227043979, 241011012, 248906099, 249796314, 250546528, 258452706, 276862988, 277140688, 280158490, 286074562, 308946627, 310972897, 322612091, 324445400, 336060042, 346729632, 349428326, 352769482, 363039453, 363851029, 392168304, 401975104, 407890409, 407971913, 425780757, 459441559, 465592122, 475898732, 482826596, 484263150, 506235403, 548951531, 554295842, 580536366, 587051904, 588265985, 588298051, 590968352, 601194306, 607771869, 618578932, 626776380, 667919873, 681786366, 689854904, 692055400, 697665495, 711608194, 734027104, 750869335, 757710567, 759967747, 777616154, 830071127, 833809927, 835873060, 836438554, 836945593, 863728236, 864158514, 871273503, 881615667, 891619600, 897181691, 918159061, 920521050, 924502226, 929983535, 943162304, 950210939, 950214176, 962610357, 974842859, 988572832};
const long biggest = 988572832;
int main(void)
{
numints.push_back(2);
strings.push_back("(1-1)");
numops.push_back(1);
numints.push_back(1);
strings.push_back("1");
numops.push_back(0);
numints.push_back(2);
strings.push_back("(1+1)");
numops.push_back(1);
numints.resize(biggest + 1);
strings.resize(biggest + 1);
numops.resize(biggest + 1);
fill_all_ones(biggest);
fill_all_factorials(biggest);
for(long i = 0; i < little_cutoff; ++i)
get_best_for_next_full(i);
for(long v : vals) {
get_best_for_next_partial(v);
std::cout << v << ":" << strings[v] << "\n";
count += numints[v];
countops += numops[v];
}
std::cout << count << ":" << countops << ":" << count * countops << "\n";
}
Resultados:
945536:((1111*(1+(11+11))+(1+1))*((1+11)*(1+(1+1))+1)+1)
16878234:(((1+(1+1111))*(1+(1+(1+111)))+(11+11))*((1+11)*11+1)+(1+1))
32608778:((((((1+(1+1)))!+(111+11111))*(11*11)+111)*(1+11)+1)*(1+1))
42017515:((11)!+((((1+111)*11)*11+1)*((1+11)*(1+11)+11)))
48950830:((((11+11)*(1+11))+(11111*(1+(1+1))))*((1+111)*(1+(1+11))+1)+1)
51483452:(((1+(1+1111))*(1+111)+1)*(11+(((1+11)*11+(1+1))*(1+(1+1))))+111)
52970263:((11+((1111*11+(1+(1+1)))*(1+(1+1))))*(111*(1+(1+11))+1)+11)
54278649:((11)!+(((1+(11+(11+(11+1111))))*111+1)*(1+(1+111))+1))
63636656:((((11+111)*(1+(1+1)))*(1+111)+11)*(1+(111+((((1+(1+1)))!)!*(1+1)))))
78817406:(((((111*(11+11)+1)*(1+1))*(1+111)+111)*(1+11)+1)*(1+11)+(1+1))
89918907:(((111+((1+(1+((1+(1+1)))!)))!)*(1+1))*(1+1111)+((11*11)*(1+(1+1))))
90757642:((1111+((11+11111)*(1+1)))*(111*(11+((1+(1+(1+1))))!)+1)+(1+111))
95364861:((11)!+(((((((11+11)*11)+11111)*111)*11+(1+1))*(1+1))*(1+1)+1))
102706605:(((11)!+(((111+((11*11)*11))*(1+(((1+(1+1)))!)!))*11))*(1+1)+1)
113965374:((((111*(1+(1+(1+11))))*1111+((1+(11+11))*11+1))*11+1)*((1+(1+1)))!)
122448605:(((((1+(1+1)))!)!+((111*11)*11))*((1+(((1+(1+1)))!)!)*(1+11)+1)+(1+1))
126594161:(((((11*11)+(((1+(1+1)))!)!)*(1+111))*(1+11)+1)*(1+111)+1)
148064959:((11)!+(((111*111+(1+11))*111+1)*((1+(1+11))*((1+(1+1)))!+1)+(1+(1+1))))
150735075:(((111*111+(1+1))*(1+1111)+(1+11))*11+(1+((1+(1+1)))!))
154382918:((1111*(1+11)+1)*(((1+(11+(111+111)))*(1+1))+11111)+111)
172057472:((((((1+11)*11)*11+1)*(1+(1+1)))+11111)*(11+11111)+((1+11)*11))
192280850:(((11111*(1+11)+11)*(1+(((1+(1+1)))!)!)+(11+111))*(1+1))
194713795:((11)!+((((111+11111)*(1+(1+(1+111)))+((1+(1+1)))!)*11)*11+1))
207721209:(((111*111)*(1+(11+11))+(1+1))*(1+(1+(11+(((1+(1+1)))!)!)))+(1+(1+(1+1))))
220946392:((11)!+((((1+(1+(1+1111)))*(11+111))*111+11)*(1+11)+(1+(1+(1+1)))))
225230299:((111111111+((111*111+(1+((1+(1+1)))!))*(11+111)+(11+11)))*(1+1)+1)
227043979:((((((11+11)*11)+11111)*(1+(1+1))+1)*1111+(1+(1+1)))*((1+(1+1)))!+1)
241011012:(((11)!+((11)!+((11)!+((11+1111)*((1+111)*((1+(1+1)))!+1)))))*(1+1))
248906099:(((11111+(((((1+(1+1)))!)!*111)*(1+1)))*(1+111)+111)*(1+(1+11)))
249796314:(((11)!+(((((1+(1+1)))!)!+((1+1111)*(1+11)))*(11+111)+111))*((1+(1+1)))!)
250546528:((11)!+(((111*111)*(1+(1+(1+11)))+11)*(111*11)+(1+(11+1111))))
258452706:(((11)!+(((((1+(1+1)))!)!*((1+(1+1)))!+1)*(11+(((1+(1+1)))!)!)))*((1+(1+1)))!)
276862988:(((11+(1111*(1+1)))*(((1+(1+1)))!+1111))*111+(((1+(1+1)))!+11))
277140688:(((111*111+(1+(1+(1+(1+11)))))*(1+1))*(11+(111+11111))+(1+111))
280158490:((11)!+(((1+(111+111111))*(((1+(1+1)))!)!+(1+(1+1)))*(1+(1+1))+1))
286074562:(((11)!+((((11+1111)*(11+11))*(1+1)+1)*(1+(11+1111))))*(1+(1+1))+1)
308946627:((11)!+((((1+1111)*(((1+(1+1)))!)!+((11+11)*(1+1)))*(1+111)+1)*(1+(1+1))))
310972897:((11111*(1+(1+1))+1)*(((1111+(111*11))*(1+1))*(1+1)+1)+11)
322612091:((((((1+11)*(1+11))*(1+11)+(1+1))*111+1)*(1+111))*(1+(1+(1+(1+11))))+11)
324445400:(((1111111+(1+(1+1)))*(1+1))*((1+11)*(1+11)+(1+1))+(1+111))
336060042:(((1+1111)*(1+(11+111))+(1+111))*(11+((111*11+1)*(1+1)))+(1+1))
346729632:(((1+(1+(11111+(111*111))))*((1+111)*11+1)+(1+(1+(1+11))))*(1+11))
349428326:(((((11+11)*11)*11+1)*(1+1111)+1)*(1+(((1+(1+1)))!+111)))
352769482:(((1+11111)*(111*(11+11))+((11+111)*((1+1)*(1+1)+1)))*(1+(1+11)))
363039453:(((((1+111)*(1+111)+1)*(1+1))*(1+(1+11))+11)*(1+(1+1111)))
363851029:((((111*11+1)*1111+11)*((1+11)*11+(1+1))+(1+11))*(1+1)+1)
392168304:(((((1+(1+1111))*(1+111))*11+1)*(1+(1+11))+11)*(11+11))
401975104:(((((1+11)*(1+11)+1)*111)*111+11)*((1+111)*(1+1)+1)+(1+(1+(1+1))))
407890409:(((1+11111)*11)*((1+1111)*(1+(1+1))+1)+((1+1111)*(1+1)+1))
407971913:((11)!+((11)!+(((1+(1+11111))*(1+1)+1)*(((11+111)*11)*11+1)+(1+1111))))
425780757:(((1111+((((1+11)*11)+11111)*(1+(1+1))))*11+1)*1111+((1+(1+1)))!)
459441559:(((11111+(((1+(1+111))*(1+1)+1)*111))*111+1)*(1+(1+(1+111)))+(1+(1+11)))
465592122:(((11)!+((((1111*(11*(1+(1+1))+1)+1)*(1+(11+11)))*(1+1)+1)*111))*(1+1))
475898732:(((11)!+(((((1+111)*11+(1+1))*(1+11))*(1+1)+1)*(1+(1+111))))*11+1)
482826596:(((1+(((111*11)*11)+(11111*(1+1))))*111+1)*(11+111)+((1+(1+1)))!)
484263150:(((111*111+(1+(1+1)))*111+11)*(1+(111+((11+11)*11))))
506235403:(((1+11))!+((((1+(1+1111))*(1+1111)+((11+111)*(1+1)))*11+1)*(1+1)+1))
548951531:((((111+111)*(1+1)+1)*111+11)*11111+((11+111)*(1+11)+1))
554295842:(((1+11))!+((((1+1111)*111+1)*((1+1)*(1+1)+1))*(11+111)+(1+111)))
580536366:(((1+(111+((111*111+11)*(1+11))))*(1+111)+1)*(11+((1+(1+(1+1))))!)+11)
587051904:(((((1+1111)*(1+11))*(1+(1+1))+1)*(111*11+1)+(111*((1+(1+1)))!))*(1+11))
588265985:(((1+11))!+((1+(111+(1111*(1+(1+11)))))*((1+111)*(11*((1+(1+1)))!+1)+(1+(1+1)))))
588298051:((((((11+111)*11)*11)+(11111*(1+(1+1))))*(1+1111)+1)*11)
590968352:(((((((1+(1+1)))!)!+11111)*111+(11+11))*((1+111)*(1+1)+1)+1)*(1+1))
601194306:((((1111*(1+(1+(1+(11+111))))+1)*111+(1+1))*(1+(1+1))+1)*(1+(1+11))+11)
607771869:(((1+11))!+(((11)!+(((1111*11+1)*(1+1))*(1+(11+111))+11))*(1+(1+1))))
618578932:(((((1111*111)*11+1)*(1+1)+1)*(1+1))*(1+(1+(1+111)))+(1+111))
626776380:((((1+(1+(1+1))))!+((((1+(1+1)))!)!+(1111*111)))*(1+(11+((1+((1+(1+1)))!))!)))
667919873:((((((1+(11+111))*11+1)*111+(1+(1+1)))*1111+1)*(1+1))*(1+1)+1)
681786366:(((1+11))!+((11)!+(((11)!+((11)!+((1+(1+11111))*((1+11)*(1+11))+111)))*(1+1))))
689854904:(((11+((11111+((1+1111)*11))*(1+1)))*((11+111)*11+1)+11)*11+(1+1))
692055400:(((1+11))!+(((((1+(1+111))*(1+(1+(1+11))))*11)*11+1)*(1+(1+1111))+1))
697665495:(((1+11))!+(((((((1+(1+1)))!)!*(1+(1+(1+111)))+1)*(1+11))*(1+1)+1)*111))
711608194:(((11)!+(((1+(1+(1+(1+1111))))*(11+((11+111)*(1+1)))+(1+1))*1111))*(1+1))
734027104:(((111*(11+((1+(1+(1+1))))!)+1)*(((1+(1+1)))!+11)+1)*11111+1111)
750869335:((11111111+((1+(((1+(1+1)))!)!)*((1+11)*11+1)+1))*(11*((1+(1+1)))!+1))
757710567:((((((11+111)*11)+111111)*(1+(1+1))+1)*(1+(11+1111))+(1+(1+1)))*(1+1)+1)
759967747:(((11)!+(((1+(1+(111+11111)))*(1+(1+111)))*(1+(11+11))+1))*11)
777616154:((11111*(111+(((111*11+1)*(1+1))*(1+1)))+(11+111))*(1+(1+(1+11))))
830071127:((((1+111)*111)*((1+(1+1)))!+1)*(((1+(1+1)))!+(11+11111))+(111*(1+1)+1))
833809927:((((11+1111)*(1+1)+1)*111+1)*(1+(1+(11+(1111*(1+(1+1))))))+111)
835873060:(((((11+(111+111))*111+1)*(1+(1+111))+1)*(1+(1+11))+1)*(11+11))
836438554:(((1+11))!+(((11111*(1+1)+1)*((11+(((1+(1+1)))!)!)*11+1)+1111)*(1+1)))
836945593:(((1111*1111+(1+111))*(1+(1+111))+(1+(1+1)))*((1+(1+1)))!+1)
863728236:(((1+(1111+((11+11111)*(1+1))))*(111*111+((1+(1+1)))!))*(1+(1+1)))
864158514:(((1+11))!+(((1111*(1+(1+(1+11)))+((1+(1+1)))!)*111+1)*(111*(1+1)+1)+11))
871273503:((((1+11111)*(11+11)+1)*((1+(1+11))*(1+1)+1)+1)*((1+11)*11)+111)
881615667:((11111+((111*111+11)*(1+1)))*((111*111)*(1+1)+1)+((11+1111)*11))
891619600:(((11)!+((11)!+((((1+(11+11))*(1+1))+111111)*11)))*11+(1+(1+1)))
897181691:((11+(11+(11+((1+(1+((1+(1+1)))!)))!)))*(11+(11111*(1+1)))+((111*11+1)*11))
918159061:(((11)!+(((11+11)*11+1)*(1+(1+11))))*(1+(11+11))+(1+(1+(1+1))))
920521050:(((11)!+((((1+(11+1111))*(1+(1+(1+1111))))*(1+111)+111)*(1+(1+1))))*(1+1))
924502226:((((1111*(1+11))*(1+1)+1)*((111*(1+11)+1)*(1+1)+1))*(1+(1+11))+11)
929983535:(((11)!+((((11+111)*111+1)*111)*((1+11)*(1+1)+1)+(1+1)))*(1+11)+11)
943162304:(((11)!+((((((1+((1+(1+1)))!))!+(111*111))*111+(1+1))*(1+111))*(1+1)))*(1+1))
950210939:(((11+(111+11111))*(1+(1+(1+(((1+(1+1)))!)!)))+(1+1))*(((1+(1+1)))!+111)+(1+1))
950214176:(((11)!+((((111*111)*(1+(1+11)))*11+1)*((1+(11+111))*(1+1)+1)))*(1+1))
962610357:((((1+11))!+((1+((((1+(1+1)))!)!+(111*(1+11))))*(11+1111)+(1+111)))*(1+1)+1)
974842859:((((((11*(1+((1+(1+1)))!))+1111)*11+1)*(1+111))*((1+(1+1)))!)*111+11)
988572832:(((111111111+((11111*(1+(1+1111))+11)*11+(1+(1+1))))*(1+1))*(1+1))