C ++ 11
Pequena atualização adicional: adicione muito menos e tente todos os números do formulário A * B + C. Eu acredito que, dentro do prazo, este é bastante próximo ao ideal, supondo que você use somente +
, *
e !
. Deixo outros operadores para pessoas com mais tempo do que eu!
Pequena atualização: tente usar fatoriais e números como 11 .... 111. Também foi corrigido um erro que eu não contava !
no meu custo
Novo resultado:
Pontuação primária = 3.810.660
Pontuação secundária = 09/09/2016 20:00
2532 1
s, 1505 operadores.
Vários truques juntos. Meu programa começa definindo o programa mais curto para todos os fatoriais e números do formulário 111..111 (não acho que isso se enquadre na regra da instalação elétrica, pois essas são as maneiras mais curtas de fazer esses números. meu código para verificar esses padrões na minha programação dinâmica, se você quiser). Em seguida, faça uma abordagem de programação dinâmica parcial, tentando várias formas:
- A + B
- A * B + C
- UMA! + B
- 11 .... 11 + B
Infelizmente, eu não posso tentar todas as maneiras de decompor um número, então escolhi fatorial e 11 ... 11 para tentar apenas o número mais próximo, para A + B tentar coisas próximas de A / 2 e para A * B + Tentar apenas muito pequeno.
Seria fácil estender isso para tentar alguns '-'s, tentando ultrapassar um pouco às vezes (principalmente em A * B-C), mas eu gosto muito de apenas tentar crescer.
Além disso, é muito difícil otimizar a condição de otimização (não gosto!) Porque, em princípio, você não pode criar um "melhor" valor para cada número isoladamente, é necessário considerar seu conjunto de respostas globalmente (o que não pretendo fazer).
Aviso: Este programa precisa de uma máquina de 64 bits e cerca de 10 GB de memória (como eu ineficientemente faço uma matriz gigante para todos os resultados parcialmente computados).
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))