问题描述
这个面试问题。给定两个n位素数,一次将第一个素数转换为第二个改变的一位。中间数字也必须是质数。这需要以最少的步骤数完成(检查素数和更改数字被认为是步骤)
Came across this interview question. Given two n-digit prime numbers, convert the first prime number to the second changing one digit at a time. The intermediate numbers also need to be prime. This needs to be done in the minimum number of steps (checking for primality and changing a digit are considered steps)
将1033转换为8179(1033-> 1733-> 3733-> .......-> 8179)
E.g. convert 1033 to 8179 (1033->1733->3733->.......->8179)
推荐答案
在一个下雨的星期一晚上(无论如何在这里,这是一个不错的挑战!)。可以使用来完成。第一步是创建一个包含所有4位素数的。然后使用Dijkstra的算法找出开始/结束素数之间的最短路径。这是Python的实现:
Nice challenge for a rainy Monday evening (it is here, anyway!). This can be done using Dijkstra's algorithm. The first step is to create a graph containing all 4-digit primes. Then use Dijkstra's algorithm to find the shortest path between the start/end primes. Here's an implementation in Python:
#! /usr/bin/python -tt
# run as: findpath start end
import sys
(start, end) = map(int, sys.argv[1:3])
# http://primes.utm.edu/lists/small/10000.txt
f = open("10000.txt", "r")
lines = f.readlines()
f.close
lines = lines[4:-1] # remove header/footer
all = "".join(lines) # join lines
all = all.split()
all = map(int, all)
# only want the 4-digit primes
fourdigit = [p for p in all if 1000 <= p and p <= 9999]
# returns digits in a number
digits = lambda x: map(int, str(x))
# cache of digits for each prime
digits_for_nums = {}
# returns digits in a number (using cache)
def digits_for_num(x):
global digits_for_nums
if x not in digits_for_nums:
digits_for_nums[x] = digits(x)
return digits_for_nums[x]
# returns 1 if digits are same, 0 otherwise
diff = lambda pair: 1 if pair[0] == pair[1] else 0
# computes number of identical digits in two numbers
def distance(a, b):
pair = (a, b)
pair = map(digits_for_num, pair)
pair = zip(pair[0], pair[1])
pair = map(diff, pair)
same = sum(pair)
return same
# adjacency list representation of graph of primes
edges = {}
# construct graph
for a in fourdigit:
edges[a] = []
for b in fourdigit:
if distance(a, b) == 3:
edges[a].append(b)
infinity = sys.maxint
def smallest():
global dist, Q
minimum = infinity
which = None
for v in Q:
if dist[v] <= minimum:
which = v
minimum = dist[v]
return which
# Dijkstra's algorithm
dist = {}
previous = {}
Q = edges.keys()
for v in Q:
dist[v] = infinity
previous[v] = None
dist[start] = 0
while len(Q) > 0:
u = smallest()
if dist[u] == infinity:
break
Q.remove(u)
for v in edges[u]:
alt = dist[u] + 1
if alt < dist[v]:
dist[v] = alt
previous[v] = u
# get path between start/end nodes
num = end
path = [num]
while num != start:
num = previous[num]
path.insert(0, num)
print path
这篇关于转换素数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!