List words = ''' PIGS SAND MAIL DATE HEAD CLAM PEAK SAND JOYA WELL TOAD CARD WILL TAPE LEGS TREE ROAD MAID SLAB ROCK HAND VASE SAFE CLAY TOES'''.split('\n'); // List numbers = [1000, 200, 11, 2]; // family core // List numbers = [8, 6, 45, 5]; // example // List numbers = [3, 6, 1, 4]; enum Op { plus, minus, times, divide } List> options = [ [Op.plus, Op.minus, Op.times, Op.divide], [Op.plus, Op.minus, Op.divide, Op.times], [Op.plus, Op.times, Op.minus, Op.divide], [Op.plus, Op.divide, Op.minus, Op.times], [Op.plus, Op.times, Op.divide, Op.minus], [Op.plus, Op.divide, Op.times, Op.minus], ]; double compute(List numbers, List ops) { assert(ops.first == Op.plus); assert(ops.length == numbers.length); double value = numbers.first.toDouble(); for (int index = 1; index < ops.length; index += 1) { switch (ops[index]) { case Op.plus: value += numbers[index]; break; case Op.minus: value -= numbers[index]; break; case Op.times: value *= numbers[index]; break; case Op.divide: value /= numbers[index]; break; } } return value; } int findBest(List numbers) { double best = double.infinity; for (List ops in options) { double current = compute(numbers, ops); if ((current.truncateToDouble() == current) && (current >= 0)) { if (current < best) { best = current; } } } if (best.isInfinite) { print('failed to find answer for $numbers'); } return best.round(); } void main() { print(words); List result = []; for (String word in words) { result.add(findBest(word.runes.map((int r) => r - 0x40).toList())); } print(result); print(String.fromCharCodes(result.map((int c) => c + 0x40))); }