简体   繁体   中英

Algorithm to map letters to digit such that number formed is largest square possible having distinct digits

For a given string of distinct letters map each letter to a digit such that number formed is largest square possible having distinct digits.

eg:

  1. c – 9, a – 8, r – 0, e – 1: 9801
  2. h – 9, a – 6, b – 7, i – 2, t – 1: 96721

This is my code:

from math import sqrt

def sqr(n):
  i = int(sqrt(n))**2
  if len(set(str(i))) == len(str(i)):
    return i
  else:
    return sqr(i-1)

s = input()
n = 10**len(s)
r = sqr(n)

for i,j in zip(s,str(r)): 
  print(i,j)

It takes 3-4 seconds to solve for strings of length upto 8. But after that it shows this error:

RecursionError: maximum recursion depth exceeded while getting the str of an object

Is there a better solution so that it can be done for longer strings as well?

You want a function that returns the largest square smaller than a given number and having distinct digits. Let's break this down and have some helper functions

from math import sqrt, floor

def number_to_digits(n):
  return list(str(n))

def has_distinct_digits(n):
  digits = number_to_digits(n)
  return len(digits) == len(set(digits))

def largest_square_less_than_n(n):
  return floor(sqrt(n))**2

def largest_distinct_square_less_than_n(n):
  largest_square = largest_square_less_than_n(n):
  if has_distinct_digits(largest_square):
    return largest_square
  else:
    return largest_distinct_square_less_than_n(largest_square - 1)  

Then just find n for your string, which is 10**(len(s)) - 1 :

def string_to_largest_square(s):
    return largest_distinct_square_less_than_n(10**len(s) - 1)
>>> string_to_largest_square('care')
9801
>>> string_to_largest_square('habit')
96721
>>> string_to_largest_square('answer')
937024
>>> string_to_largest_square('largest')
9872164
>>> string_to_largest_square('clothing')
98327056
>>> string_to_largest_square('platforms')
923187456
>>> string_to_largest_square('chortlings')
9814072356

Those all come back instantly for me. Of course you won't have any longer than 10 since there aren't more than 10 digits and your question specified the strings are made of distinct letters.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM