Deadfish是一种深奥的“编程”语言(创建为一个笑话,而不是完整的)。在其中,有一个变量 - 一个初始化为0的整数 - 有4个操作:
Counter += 1
= i Counter += -1
= d Counter = Counter * Counter
= s print(counter)
= o 尽管Deadfish通常将变量设为一个字节,但就我的目的而言,它将是python中的整数。我的程序试图找到打印出任何给定数字的最快方法,即最少的命令。以下是一些例子
达到10,
0> 1> 2> 3> 9> 10 = iiisi
达到15,
0> 1> 2> 4> 16> 15 = iissd
我写了一个简单的暴力程序,通过检查i,d和s的组合来解决这个问题。这是代码:
#!/usr/bin/python
# -*- coding: utf-8 -*-
def baseN(num, base, numerals='0123456789abcdefghijklmnopqrstuvwxyz'):
return num == 0 and numerals[0] or baseN(num // base, base,
numerals).lstrip(numerals[0]) + numerals[num % base]
def validCode(code):
for k in range(0, len(code)):
if code[k] == '!':
return False
return True
def deadFish(code):
counter = 0
for l in range(0, len(code)):
cmd = code[l]
if cmd == 'i':
counter += 1
if cmd == 'd':
counter += -1
if cmd == 's':
counter = counter * counter
return counter
def format(code):
counter = 0
chain = "0"
for m in range(0, len(code)):
cmd = code[m]
if cmd == 'i':
counter += 1
if cmd == 'd':
counter += -1
if cmd == 's':
counter = counter * counter
chain += " -> " + str(counter)
return(chain)
codeChars = '!ids'
i = 0
solutions = [0]
while True:
i += 1
codeInt = baseN(i, 4)
codeStr = ''
for j in range(0, len(str(codeInt))):
codeStr += codeChars[int(str(codeInt)[j])]
if validCode(codeStr) and deadFish(codeStr) < 1000 and deadFish(codeStr) > -1:
if deadFish(codeStr) > len(solutions) - 1:
solutions += [0] * (deadFish(codeStr) - len(solutions) + 1)
if solutions[deadFish(codeStr)] == 0:
solutions[deadFish(codeStr)] = codeStr
print(codeStr, ':', format(codeStr))
else:
print(codeStr)
此代码按预期工作,应该是不言自明的。但是,这非常非常低效。任何改进或优化的建议都将不胜感激。
答案 0 :(得分:1)
这是我的看法。
您希望找到仅包含i
ncrement,d
ecrement和s
quare的最小代码段。由于s
是一个字符,并且创建了所有字符中的最大数字,因此您希望找到最接近的平方数,并使用递归来生成将您带到其根目录的代码。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import math
def nearest_square(n):
root = math.sqrt(n)
lower = math.floor(root)
higher = math.ceil(root)
if n - lower**2 < higher**2 - n:
return lower, n - lower**2
else:
return higher, n - higher**2 # we want a negative error here
def produce_code_for(n):
# squaring doesn't make sense for n < 0, as it always returns positive numbers.
# you can leave this part out if you don't want support for negative numbers.
if n < 0:
return "d" * (-n)
# 2^2 = 4 is the first square that is greater than its square root
# -> for n < 4, the solution is "i" repeated n times
if n < 4:
return "i" * n
else:
root, error = nearest_square(n)
if error < 0:
return produce_code_for(root) + "s" + "d"*(-error)
else:
return produce_code_for(root) + "s" + "i"*error