15
$\begingroup$

The alphametic

MANY + MANY = THANKS

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

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

4 Answers 4

10
$\begingroup$

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

17 (3 solution already given in another answer: (8567, 8569, 8576))

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:

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

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

$\endgroup$
15
  • 5
    $\begingroup$ Can you justify this? $\endgroup$ Aug 27, 2019 at 2:14
  • 7
    $\begingroup$ That wasn't the necessary justification. Anyone can do arithmetic. The real question is, do you have a proof of minimality? $\endgroup$ Aug 27, 2019 at 3:20
  • 3
    $\begingroup$ @greenturtle3141 How should I prove it? Won't the OP know the answer and check it? $\endgroup$
    – Duck
    Aug 27, 2019 at 4:46
  • 2
    $\begingroup$ @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. $\endgroup$ Aug 27, 2019 at 11:06
  • 1
    $\begingroup$ @WeatherVane Exactly! If the question implies a minimum, then a fully correct answer must prove that it's the minimum. $\endgroup$ Aug 27, 2019 at 11:11
4
$\begingroup$

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[10];
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;
}

So the answer is

15

$\endgroup$
2
$\begingroup$

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[0]):
        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[0] = word_to_num(first_coding,word[0])#aka get word 0 as a num (num 0)
    if len(str(num[0])) != len(word[0]):
        return ""
    num[1] = num[0]*(multi_number)#word 1, as a num (num 1)
    if len(str(num[1])) != len(word[1]):
        return ""

    second_coding = {}
    for i,char in enumerate(str(num[1])):#build second coding by matching letters in word 1 to num 1
        second_coding[word[1][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[0] = "MANY"
word[1] = "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[0],word_to_num(coding,word[0])))
            print("{} becomes :: {}".format(word[1],word_to_num(coding,word[1])))
            print("{} * {} = {}".format(word_to_num(coding,word[0]),j,word_to_num(coding,word[1])))
            sys.exit("Solution found")

```
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.