# Many many thanks

The alphametic

MANY + MANY = THANKS

has no solutions in base 10. How many more "MANYs" must I add before it has a solution?

• I am new here and with puzzles but if you use T=0, you can find a solution with 2 "MANYs". is that valid? – gustavovelascoh Aug 27 at 10:43
• @gustavovelascoh I believe we usually assume that leading zeroes are not permitted as they are rather improper. – greenturtle3141 Aug 27 at 14:52
• This would make a great codegolf. Take two inputs (like "MANY" and "THANKS" and output the minimum number of "MANY"s to make "THANKS". – Keeta Aug 27 at 18:37

From

1814400

possible permutations of letters AHKMNSTY and digits 0-9 (P(10,8)), just

759

are valid for the problem n * MANY = THANKS. This is, just those were THANKS/MANY is an integer.

After removing those solutions where T=0 (THANKS <= 99999), there are 727 left from which the minimum n is

BONUS:

The maximum n is 7815 for MANY=0123. If M=0 or MANY <= 999 is not valid, the maximum will be n=935 for MANY=1027

csv files with solutions:

• Do you have any proof for all these assertions? I'm guessing you used a machine to get them? – Rand al'Thor Aug 27 at 11:11
• I did it. Isn't that valid? – gustavovelascoh Aug 27 at 11:14
• Well, it's hard for anyone else to judge if this answer is correct or not. – Rand al'Thor Aug 27 at 11:15
• ok, I will try to detail on the process – gustavovelascoh Aug 27 at 11:16

I think you need (in base ten):

15 more manys (17 all together)

There are three solutions:

A=5 H=4 K=3 M=8 N=6 S=9 T=1 Y=7 because $$8567\times17=145639$$,
A=5 H=4 K=7 M=8 N=6 S=3 T=1 Y=9 because $$8569\times17=145673$$, and
A=5 H=4 K=9 M=8 N=7 S=2 T=1 Y=6 because $$8576\times17=145792$$.

Or

Zero more:
$$7493\times2=014986$$
A=4 H=1 K=8 M=7 N=9 S=6 Y=3 T=0
$$8746\times2=17492$$
A=7 H=1 K=9 M=8 N=4 S=2 Y=6

• Can you justify this? – greenturtle3141 Aug 27 at 2:14
• That wasn't the necessary justification. Anyone can do arithmetic. The real question is, do you have a proof of minimality? – greenturtle3141 Aug 27 at 3:20
• @greenturtle3141 How should I prove it? Won't the OP know the answer and check it? – Duck Aug 27 at 4:46
• @WeatherVane Poor analogy. Would you say the same if someone posted an answer with 7815 "many"s? In mathematics problems, proving minimality is often an important aspect. – Rand al'Thor Aug 27 at 11:06
• @WeatherVane Exactly! If the question implies a minimum, then a fully correct answer must prove that it's the minimum. – Rand al'Thor Aug 27 at 11:11

The question was already answered by @Duck, but here is a (not very well-crafted or efficient) C program which tests increasing numbers of MANY until a solution (in fact three) is found.

Program output:

x * MANY = THANKS
17 * 8567 = 145639
17 * 8569 = 145673
17 * 8576 = 145792
3 results found
Took ~ 0.37 seconds

#include <stdio.h>
#include <time.h>

int used;
int result;
int rep = 2;
int M, A, N, Y, T, H, K, S, AN;

void check(int many)
{
for(T=1; T<10; T++) {
if(used[T] == 0) {
used[T] = 1;
int Tval = T * 100000;
for(H=0; H<10; H++) {
if(used[H] == 0) {
used[H] = 1;
int Hval = Tval + H * 10000;
for(K=0; K<10; K++) {
if(used[K] == 0) {
used[K] = 1;
int Kval = Hval + K * 10;
for(S=0; S<10; S++) {
if(used[S] == 0) {
if(Kval + AN + S == many) {
printf("%d * %d%d%d%d = %d%d%d%d%d%d\n", rep,
M,A,N,Y,  T,H,A,N,K,S);
result++;
}

}
}
used[K] = 0;
}
}
used[H] = 0;
}
}
used[T] = 0;
}
}
}

int main(void)
{
clock_t tstart = clock();
printf("x  * MANY = THANKS\n");

while(result == 0) {
for(M=1; M<10; M++) {
used[M] = 1;
int Mval = M * 1000;
for(A=0; A<10; A++) {
if(used[A] == 0) {
used[A] = 1;
int Aval = Mval + A * 100;
for(N=0; N<10; N++) {
if(used[N] == 0) {
used[N] = 1;
int Nval = Aval + N * 10;
AN = (A * 10 + N) * 100;    // for "thanks"
for(Y=0; Y<10; Y++) {
if(used[Y] == 0) {
used[Y] = 1;
check((Nval + Y) * rep);
used[Y] = 0;
}
}
used[N] = 0;
}
}
used[A] = 0;
}
}
used[M] = 0;
}
rep++;
}
printf("%d results found\n", result);
double elapse = (double)(clock() - tstart) / CLOCKS_PER_SEC;
printf("Took ~ %.2f seconds\n", elapse);
return 0;
}


15

I also coded this out, running it in python (you can even use change the words for other similar puzzles, they're global variables, I used "CAT" and "DOG" to test the logic worked for trivial examples.

I would be very interested in a rigorous proof, but given how complex the setup is to express in mathematical logic I suspect there isn't an easy one.

import math as maths
import sys

def build_coding(iter_num):
return_coding = {}
for i,char in enumerate(word):
return_coding[char] = iter_num%10
iter_num -= iter_num%10
iter_num = int(iter_num/10)
return return_coding

def attempt_codings(iteration_number,multi_number):
first_coding = build_coding(iteration_number)
num = word_to_num(first_coding,word)#aka get word 0 as a num (num 0)
if len(str(num)) != len(word):
return ""
num = num*(multi_number)#word 1, as a num (num 1)
if len(str(num)) != len(word):
return ""

second_coding = {}
for i,char in enumerate(str(num)):#build second coding by matching letters in word 1 to num 1
second_coding[word[i]] = int(char)
for quay in first_coding.keys():
if quay in second_coding.keys():
if first_coding[quay] != second_coding[quay]:#if a key in one exists in either
return ""
end_coding = {}
for quay in first_coding.keys():
if quay in end_coding:#if this key is double-coded
if end_coding[quay] != first_coding[quay]:#and the double doesn't match
return ""
end_coding[quay] = first_coding[quay]

for quay in second_coding.keys():
if quay in end_coding:#if this key is double-coded
if end_coding[quay] != second_coding[quay]:#and the double doesn't match
return ""
end_coding[quay] = second_coding[quay]
uniquevals = []
for quay in end_coding.keys():
if end_coding[quay] in uniquevals:#if we already have a match for this value
return ""
else:
uniquevals.append(end_coding[quay])
return end_coding

def word_to_num(coding,word):
num = 0
for i,char in enumerate(word):
num += maths.pow(10,len(word)-i-1)*coding[char]
return int(num)

word = ["",""]
word = "MANY"
word = "THANKS"
num = ["",""]
for i in range(10000):#ways of coding the first word, including invalid ones like '00010'
for j in range(20):#number of the first word to add (aka multiplication)
coding = attempt_codings(i,j)
if coding != "":
print("~~~A SOLUTION:")
print("CODING IS :: {}".format(coding))
print("{} becomes :: {}".format(word,word_to_num(coding,word)))
print("{} becomes :: {}".format(word,word_to_num(coding,word)))
print("{} * {} = {}".format(word_to_num(coding,word),j,word_to_num(coding,word)))
sys.exit("Solution found")

$$$$
`