The best force is brute force
I decided to create a javascript program to find the solutions.
Here it is:
"use strict";
var MIN_RANGE = 1;
var MAX_RANGE = 31;
var MAX_ROOTS_AND_FACTORIALS = 4;
var tablef = [1];
for (var i = 1; i <= 20; i++) {
tablef[i] = tablef[i - 1] * i;
}
function bad(x) {
return isNaN(x) || !isFinite(x);
}
function fact(i) {
return tablef[i] || NaN;
}
function sqrt(i) {
return bad(i) || i < 0 ? NaN : Math.sqrt(i);
}
var funcsCom = [
function plus(a, b) { return {v: a.v + b.v, s: "(" + a.s + " + " + b.s + ")"}; },
function mult(a, b) { return {v: a.v * b.v, s: "(" + a.s + " * " + b.s + ")"}; }
];
var funcsNonCom = [
function sub(a, b) { return {v: a.v - b.v, s: "(" + a.s + " - " + b.s + ")"}; },
function div(a, b) { return {v: a.v / b.v, s: "(" + a.s + " / " + b.s + ")"}; },
function pow(a, b) { return {v: a.v ** b.v, s: "(" + a.s + " ^ " + b.s + ")"}; },
function rad(a, b) { return {v: a.v ** (1 / b.v), s: "Root[" + a.s + "] of (" + b.s + ")"}; }
];
var funcs1 = [
function f(a) { return {v: fact(a.v), s: "(" + a.s + ")!"}; },
function s(a) { return {v: sqrt(a.v), s: "sqrt(" + a.s + ")"}; }
];
function rework1(op, array, a) {
var s = array.slice(0);
try {
s[a] = op(s[a]);
if (bad(s[a].v)) return [];
return s;
} catch (x) {
return [];
}
}
function rework2(op, array, a, b) {
try {
var k = op(array[a], array[b]);
if (bad(k.v)) return [];
var s = [k];
for (var i = 0; i < array.length; i++) {
if (i !== a && i !== b) s.push(array[i]);
}
return s;
} catch (x) {
return [];
}
}
function tryPermutation(array, others, target) {
if (array.length === 0) return "";
if (array.length === 1) {
try {
return target === array[0].v ? array[0].s : "";
} catch (x) {
return "";
}
}
for (var a = 0; a < array.length; a++) {
if (array.length >= 2) {
for (var b = a + 1; b < array.length; b++) {
for (var f in funcsCom) {
var z = tryPermutation(rework2(funcsCom[f], array, a, b), others, target);
if (z !== "") return z;
}
for (var f in funcsNonCom) {
z = tryPermutation(rework2(funcsNonCom[f], array, a, b), others, target);
if (z !== "") return z;
z = tryPermutation(rework2(funcsNonCom[f], array, b, a), others, target);
if (z !== "") return z;
}
}
}
if (others > 0) {
for (var f in funcs1) {
var z = tryPermutation(rework1(funcs1[f], array, a), others - 1, target);
if (z !== "") return z;
}
}
}
return "";
}
function tryPermutationAll(array, target) {
for (var s = 0; s <= MAX_ROOTS_AND_FACTORIALS; s++) {
var z = tryPermutation(array, s, target);
if (z !== "") return z;
}
return "";
}
function search(array, i) {
if (i > MAX_RANGE) return;
var z = tryPermutationAll(array, i);
if (z !== "") {
document.write("Found " + i + " = " + z + "<br>");
} else {
document.write("Dunno " + i + "<br>");
}
setTimeout(function() { search(array, i + 1); }, 10);
}
function format(a) {
var s = [];
for (var i = 0; i < a.length; i++) {
s[i] = {v: a[i], s: "" + a[i]};
}
return s;
}
setTimeout(function() {
search(format([0, 1, 2, 9]), MIN_RANGE);
}, 10);
That MAX_ROOTS_AND_FACTORIALS
is the number of arbitrarily inserted square roots and factorials. You could make this number arbitrarily higher, but then the time that it will take to calculate will increase exponentially, so you would prefer to keep it as low as possible.
This is the output:
Found 1 = ((2 - (0 + 1)) ^ 9)
Found 2 = (((0 + 1) ^ 9) * 2)
Found 3 = (9 / ((0 + 1) + 2))
Found 4 = ((9 - (0 + 1)) / 2)
Found 5 = (((0 + 1) + 9) / 2)
Found 6 = (9 - ((0 + 1) + 2))
Found 7 = (9 - ((0 + 1) * 2))
Found 8 = (((0 + 1) - 2) + 9)
Found 9 = ((2 - (0 + 1)) * 9)
Found 10 = (9 - ((0 + 1) - 2))
Found 11 = (((0 + 1) * 2) + 9)
Found 12 = (((0 + 1) + 2) + 9)
Found 13 = ((((0)! + 1) + 2) + 9)
Found 14 = ((9 - ((0)! + 1)) * 2)
Found 15 = ((((0 + 1) + 2))! + 9)
Found 16 = ((9 - (0 + 1)) * 2)
Found 17 = ((2 * 9) - (0 + 1))
Found 18 = (((0 + 1) * 2) * 9)
Found 19 = ((2 * 9) + (0 + 1))
Found 20 = (((0 + 1) + 9) * 2)
Found 21 = ((((0)! + 9) * 2) + 1)
Found 22 = ((((0)! + 1) + 9) * 2)
Found 23 = ((((2 ^ 0) + sqrt(9)))! - 1)
Found 24 = ((9 - 1) * ((0)! + 2))
Found 25 = (((0 + 1) - (sqrt(9))!) ^ 2)
Found 26 = ((((0)! + 2) * 9) - 1)
Found 27 = (((0 + 1) + 2) * 9)
Found 28 = ((((0)! + 2) * 9) + 1)
Dunno 29
Found 30 = ((1 + 9) * ((0)! + 2))
Found 31 = (sqrt((2 ^ ((0)! + 9))) - 1)
So, what about 29?
The program takes some long time to complete, and > 99% of that time, it is trying to solve the number 29. For all the others, it can find a solution using MAX_ROOTS_AND_FACTORIALS
= 2 in a few seconds. So, I'm pretty sure that 29 is unsolvable.
I'm using MAX_ROOTS_AND_FACTORIALS
as 4 here. I tried it with 5 and it was taking a too long time, and I gave up waiting.
Does the professor have a solution?
Only if the current month is February, 2019!