Не только четыре четверки

11

В этом варианте головоломки « Четыре четверки» вы должны использовать до x x's(и никакое другое число) и определенный набор операций для достижения каждого числа от 0 до 100. Если x = 4тогда вы можете использовать до четырех, 4sи этот вопрос становится классической четверкой головоломка (за исключением того, что вы можете использовать до четырех четверок вместо того, чтобы использовать ровно четыре из них). Мы предполагаем 1 < x <= 9.

В этой версии разрешены только следующие операторы:

  • Сложение ( +), вычитание ( -), умножение ( *), деление ( /). Обратите внимание, что это реальное разделение, так что 5/2 = 2.5.
  • Возведение в степень (например, 4 ^ 4), поскольку это не будет включать в себя никаких дополнительных символов, если написано обычно вручную.
  • Вы можете сделать новые целые числа путем объединения xs. Например, вы можете сделать целые числа 4, 44, 444, 4444.

Вы также можете использовать скобки для группировки номеров просто для того, чтобы контролировать порядок оценки операторов. Вы не можете, например, объединить скобки с конкатенацией, как в (4/4)(4/4) = (1)(1) = 11.

Никакие другие символы не могут быть использованы, и применяется стандартный порядок операций.

Ваша программа должна сгенерировать, учитывая xв определенном диапазоне и nмежду 0и 100включительно, правильное решение для этого ввода, если оно существует. В противном случае ваш код должен что-то выводить, чтобы указать, что такого решения не существует.

Вы должны иметь возможность запустить отправку до завершения на своем компьютере для любых входных значений xи nв допустимом диапазоне. Это код гольф, поэтому выигрывает самое короткое решение.

Этот старый связанный вопрос использует больше операторов (и только 4), и, следовательно, все числа от 0 до 100 разрешимы, что не будет верно для этой задачи.

Вход и выход

Ваш код принимает два целых числа xи в nкачестве входных данных и должен выводить решение (или указание на отсутствие решения) в любом удобочитаемом для человека формате. Ввод 4 6будет означать «Использование до четырех 4, например, число 6». Так что, если вход является 4 6выходом, может быть (4+4)/4+4.

Ануш
источник
1
Полезный справочник
Тост инженера
2
Можно ли сочетать паренны с конкатенацией? например, `(4/4) (4/4) = (1) (1) = 11?
Цифровая травма
1
Добавление скобок (и запрещение скобок + конкатенация) делает это значительно сложнее
Draconis
2
Добавление оператора возведения в степень и внешнего цикла для числа раз, когда используется цифра, не добавляйте в IMO ничего нетривиального по сравнению с codegolf.stackexchange.com/q/82884/194
Питер Тейлор,
2
@PeterTaylor Скобки, кажется, имеют большое значение. Я бы проголосовал за открытие, если бы мог.
Фелипа

Ответы:

4

Python 3 , 265 байт

def f(x,n):
 for e in g(x,x-(x>7)):
  try:
   if eval(e)==n:return e
  except:1
g=lambda x,d:{str(x)*-~i for i in range(d)}|{s%(a,b)for a in g(x,d-1)for b in g(x,d-a.count(str(x)))for s in'%s**%s (%s/%s) (%s+%s) (%s-%s) %s*%s %s/%s'.split()['**'in a+b:]}if d else{}

Попробуйте онлайн!

Работает для всех номеров в ссылке, связанной Engineer Toast.

Подбегает x=8на тио, x=9занимает пару минут на моей машине.


Функция gвозвращает набор всех комбинаций с не более чем xчислом x. fзатем перебирает их и возвращает первое, которое оценивает число n.

Количество возможных значений, которые я нашел для каждого x:

x  possible numbers
------
2  5
3  17
4  35
5  56
6  83
7  101
8  101
9  101

Все номера выше , могут быть получены из (a+b), (a-b), (a+b), a*b, a/b, (a/b), и a^b. a+bи a-bне давайте больше цифр.

a^b также используется только один раз, так как в противном случае создаются огромные числа (это также подтверждается в справочном документе выше)


Альтернативная версия, которая замыкает накоротко, как только находит решение (не как игра в гольф):

Это намного быстрее, поскольку для x=7..9всех чисел может быть создано.

Python 3 , 338 289 байт

def f(x,n,d=-1):
 d=[d,x][d<0];X=str(x);r=set()
 for E in{X*-~i for i in range(d)}|{s%(a,b)for a in[0]*d and f(x,n,d-1)for b in f(x,n,d-a.count(X))for s in'%s**%s (%s/%s) (%s+%s) (%s-%s) %s*%s %s/%s'.split()['**'in a+b:]}:
  try:e=eval(E)
  except:e=-1
  if e==n:exit(E)
  r|={E}
 return r

Попробуйте онлайн!

TFeld
источник
Это очень хороший ответ! Я думал, что вы всегда использовали точно (в отличие от до) х х (например, (4/4**(4-4))для 4), но оказывается, что это не так.
Ануш
exit(e)корочеreturn e
mbomb007