Я пытаюсь понять, как напечатать слово «привет» 121 раз в python. Мне нужно использовать функцию без условных выражений или циклов, без новых строк и без умножения строки на целое число.
Я думаю что-то вроде:
print_hello():
print('hello')
print_hello()
print_hello()
но я не могу найти способ ограничить рекурсивный вывод без условий. Любая помощь будет принята с благодарностью.
Обновлять Вот все ограничения задачи, возможно, рекурсия - неправильный подход.
try ... except ... разрешено? Разрешены ли and и or? Используя эти операторы, легко подделать условное выражение в Python.
@Стеф, я не согласен. и там не сказано, что их нельзя использовать...
Если вы не можете использовать '\n', вы можете схитрить и заменить его на ''' в одной строке и ''' в следующей строке.






from sys import setrecursionlimit
setrecursionlimit(121)
def phello():
print('hello', end='')
phello()
try:
phello()
except:
print('done')
def print_hello():
print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello'); print('hello');
Это не рекурсивно?
@MaximilianBallard «но я не могу найти способ ограничить рекурсивный вывод без условных выражений». Насколько я понимаю, это не условие задачи.
@MaximilianBallard Кстати, это рекурсивно. Но количество вызовов рекурсии равно нулю.
def print_hello(i):
print('hello', end = "")
i -= 1
a = 42 / i
try:
print_hello(i)
except ZeroDivisionError:
pass
print_hello(121)
На самом деле 42 может быть чем угодно, просто нужно вызвать ошибку деления на 0
ХОРОШО. Просто еще один ответ, просто для удовольствия.
def print_hello121():
print(('\n'.join(['hello']*121)))
Здесь - умножаем список, а не строку.
"нет новых строк" так и должно быть "".join(['hello']*121)
ОП отредактировал вопрос, чтобы запретить использование '\n', хотя с '''<real line break>''' это легко обойти.
def print_single_hello():
print('hello')
def print_hello121():
[print_single_hello()] * 121
Это на самом деле не работает правильно, но может быть идеей.
Ничего из этого "*" не разрешено.
Просто использовать списки довольно просто:
def myr(l=[lambda *a: 0] + 120*[lambda a, b: a(b)]):
print("hello", end = "")
l.pop()(myr, l)
myr()
Мне нравится, как ваш ответ начинается с «это довольно просто», а затем сразу же прибегает к черной магии.
Это какой-то pythonic анти-шаблон: список значений по умолчанию для функции: docs.quantifiedcode.com/python-anti-patterns/correctness/….
Идея.
def loop(x):
try:
next(x)
print("hello", end = "")
loop(x)
except StopaIteration:
pass
def hello(n_repeat):
loop(iter(range(n_repeat)))
...
hello(50)
Используя ленивые операторы and или or, в Python легко подделать условное выражение:
def print_hello(n):
n > 0 and (print('hello') or print_hello(n - 1))
print_hello(3)
# hello
# hello
# hello
print_hello(121)
# ...
Есть неявные условия (без if).
Вы можете использовать свойство короткого замыкания and. Ноль — Ложь, все остальные числа — Истина. Если первая часть выражения ложна, вторая часть не оценивается.
def print_hello(n=121):
print('hello', end=' ')
n and print_hello(n - 1)
print_hello()
Редактировать: я видел, что вы дисквалифицировали другой ответ, потому что у функции был параметр, поэтому вот версия, в которой вместо этого используется глобальная переменная. Это также исправляет проблему с несовпадением в оригинале.
n = 121
def print_hello():
global n
print('hello', end=' ')
n -= 1
n and print_hello()
print_hello()
Есть неявные условия (без if).
@sergzach, если вы проверите часть вопроса «ограничения на вызов», я думаю, вы увидите, что это не нарушает ни одно из них. Утверждение об «условиях» кажется небрежным перефразированием.
Не очень понятно — любое условие можно легко заменить удалением if, смотрите: gist.github.com/sergzach/f613e0035cfe4c753546b210a4a950d0
(Примечание: я отредактировал сообщение. См. лучшее решение в конце)
Если мы не попытаемся найти серебряную пулю, используя трюк, который был бы забыт в ограничениях (переменные global для обхода запрета параметров, and/try для обхода запрета if, список умножения для обхода запрета умножения строки, .. .), насколько я понимаю вопрос, речь идет о поиске правильного разделения функций/подфункций на 20 строк кода (без точки с запятой)
Например, если бы нам нужно было напечатать 32 hello, мы могли бы, как привыкли рассуждать гики в степени 2,
def h2():
print("hello")
print("hello")
def h4():
h2()
h2()
def h8():
h4()
h4()
def h16():
h8()
h8()
h16()
h16()
Которые 14 строк.
Но части def усложняют вещи и усложняют то, что является оптимальным. Например, здесь, поскольку мы не используем h2 нигде, кроме h4, было бы короче напрямую печатать hello 4 раза в h4. Аналогично, для h16
def h4():
print("hello")
print("hello")
print("hello")
print("hello")
def h16():
h4()
h4()
h4()
h4()
h16()
h16()
которых всего 12 строк.
Здесь число 121. Это конкретное число. Именно по этой причине я считаю, что это ожидаемое решение: непросто решить, какую промежуточную функцию нам нужно создать.
Это было бы интересной проблемой само по себе: создать код, который оптимизирует количество необходимых строк, используя такого рода инкапсуляцию подфункций.
Но есть одна комбинация, умещающаяся в 20 строк:
def h3():
print("hello")
print("hello")
print("hello")
def h7():
h3()
h3()
print("hello")
def h15():
h7()
h7()
print("hello")
def h60():
h15()
h15()
h15()
h15()
h60()
h60()
print("hello")
Я знаю, что это гораздо менее умно (и даже «умно»), чем все другие предложенные решения. Но я действительно убежден, что это ожидаемое решение. Это может показаться слишком простым и наивным. Но решить, что h?? написать, не так просто (ну, это не так сложно, если ограничение просто «уместиться в 20 строк». Но мне было бы сложнее, если бы ограничение было «использовать наименьшее число». возможных линий")
Я не мог устоять, поэтому написал код, оптимизирующий это
def size(n, l):
ml=max(k for k in l if k<=n)
nm=n//ml
r=n-nm*ml
if r==0:
return nm
else:
return nm+size(r, l)
def sizefn(l):
return sum(size(k, [x for x in l if x<k])+1 for k in l if k>1)
def totsize(n,l):
return size(n, l) + sizefn(l)
rec=1000
def compute(l, k):
global rec
if k>120: return False
sfn =sizefn(l)
if sfn+2>=rec:
return False
f = size(121, l)
if sfn+f<rec:
rec=sfn+f
print(f'{sfn+f} ({sfn}+{f}) :', l)
compute(l+[k], k+1)
compute(l, k+1)
Что он делает, так это просто пробует все возможные комбинации промежуточных функций. Итак, то есть теоретически 2¹²⁰ комбинаций (все промежуточные функции h? могут существовать или нет), и посчитать, сколько будет строк кода, и оставить лучшую. За исключением того, что я делаю это с помощью Branch&Bound, что позволяет избежать рассмотрения целых подмножеств множества всех комбинаций.
Результат
121 (0+121) : [1]
64 (3+61) : [1, 2]
47 (6+41) : [1, 2, 3]
40 (9+31) : [1, 2, 3, 4]
37 (12+25) : [1, 2, 3, 4, 5]
36 (15+21) : [1, 2, 3, 4, 5, 6]
35 (31+4) : [1, 2, 3, 4, 5, 6, 7, 8, 9, 13, 39]
34 (28+6) : [1, 2, 3, 4, 5, 6, 7, 8, 9, 23]
33 (28+5) : [1, 2, 3, 4, 5, 6, 7, 8, 10, 30]
32 (28+4) : [1, 2, 3, 4, 5, 6, 7, 8, 13, 39]
31 (25+6) : [1, 2, 3, 4, 5, 6, 7, 8, 23]
30 (25+5) : [1, 2, 3, 4, 5, 6, 7, 10, 30]
29 (25+4) : [1, 2, 3, 4, 5, 6, 7, 13, 39]
28 (22+6) : [1, 2, 3, 4, 5, 6, 8, 24]
27 (22+5) : [1, 2, 3, 4, 5, 6, 10, 30]
26 (20+6) : [1, 2, 3, 4, 5, 6, 23]
25 (19+6) : [1, 2, 3, 4, 5, 8, 24]
24 (19+5) : [1, 2, 3, 4, 5, 10, 30]
23 (17+6) : [1, 2, 3, 4, 6, 24]
22 (16+6) : [1, 2, 3, 4, 8, 24]
21 (16+5) : [1, 2, 3, 5, 10, 30]
20 (14+6) : [1, 2, 3, 6, 24]
19 (13+6) : [1, 2, 4, 8, 24]
18 (12+6) : [1, 2, 6, 24]
И это заканчивается там.
Это означает, что нет лучшего решения, чем решение с h2, h6 и h24 (h1 — это просто print(hello))
Всего 18 строк
Который дает
def h2():
print("hello")
print("hello")
def h6():
h2()
h2()
h2()
def h24():
h6()
h6()
h6()
h6()
h24()
h24()
h24()
h24()
h24()
print("hello")
Я убежден, что это то, что они ищут.
@MitchellMatheny Я пошел немного дальше, так как вы приняли ответ (спасибо, кстати). Итак, теперь у меня есть (в том же духе) решение из 18 строк. И код, доказывающий, что 17-строчного решения быть не может (без уловок).
Вы можете использовать «функции более высокого порядка», такие как map, filter, max, min или sorted, чтобы многократно применять функцию к range.
def print_hello_map(n):
any(map(lambda _: print('hello'), range(n)))
def print_hello_filter(n):
next(filter(lambda x: print('hello') or x + 1>= n, range(n)))
def print_hello_max(n):
max(range(n), key=lambda x: bool(print('hello')))
def print_hello_sorted(n):
sorted(range(n), key=lambda x: bool(print('hello')))
Если бы вы разрешили импорт из стандартной библиотеки, то было бы много альтернатив map и filter, например, functools.reduce и itertools.repeat, а также все функции из itertools, выполняющие любой цикл.
from functools import reduce
def print_hello_reduce(n):
reduce(lambda acc,x: print('hello'), range(n+1))
from itertools import repeat
def f(x):
yield bool(print('hello'))
def print_hello_repeat(n):
sum(repeat(f, n))
не могу сделать что-то вроде: print("hello\n"*121)" Это... неконкретно.