Створіть дійсне рівняння, використовуючи вказані користувачем числа


10

Це засновано на грі, яку один із моїх вчителів математики грав у середній школі. Він напише 5 довільних одноцифрових чисел на дошці, а потім випадкове двоцифрове число. Ми спробуємо створити рівняння, яке використовувало б усі 5 одноцифрових чисел для отримання двоцифрового числа. Ось декілька прикладів із рішеннями, щоб пояснити це краще:

Input:           Solution:
7 5 4 8 4 34     5*8-7+4/4 = 34
3 1 5 7 6 54     (7+3)*6-5-1 = 54
3 9 2 1 6 87     9*(2+1)*3+6 = 87
2 1 6 9 7 16     (9-7+6*1)*2 = 16
2 4 5 8 6 96     8*(5+6)+2*4 = 96
3 8 4 5 4 49     8*(4+4)-3*5 = 49

Це завдання полягає в тому, щоб написати програму, яка може генерувати такі рівняння для заданого вводу. Введення даних може бути надано або через командний рядок, або через рядок. П'ять одноцифрових чисел завжди будуть вводитись спочатку (у певному порядку), а потім двоцифрове число. Потім програма роздрукує знайдене рівняння рішення; не потрібно впоратися з ситуаціями, коли немає рішення. Функція повинна бути здатна використовувати в рівнянні такі операції: додавання, віднімання, множення та ділення. Якщо ви хочете дозволити додаткові основні операції, це добре, якщо вони залишаються в дусі виклику (заперечення, експоненція та модуль були б приємними доповненнями). Порядок операцій відповідає стандартним математичним правилам, тому для групування знадобляться дужки.

Програми оцінюються на основі довжини коду (включаючи необхідний пробіл). Примітка: ділення повинно бути точним, а не округленим і не усіченим до найближчого цілого числа.



Це дуже схоже завдання, але я думаю, що додатковий термін і жодне обмеження в групуванні виразів не повинні розширити проблему достатньо, щоб вона була цікавою іншою. Крім того, це проблема в гольфі замість виклику коду, який вимагатиме різних рішень.
Sir_Lagsalot

Що з конкатенацією? наприклад, якщо дано 7 5 4 8 4 34, дозволено вихід 7 + 54/8 * 4?
Патрік Робертс

Відповіді:


7

Python 2.7 (284), Python 3.x (253)

from __future__ import division #(Remove for Python 3.x)
from itertools import *
a=raw_input().split()
for i in permutations(a[:-1],5):
 for j in product('+-*/',repeat=5):
  for k,l in combinations(range(1,12,2),2):
   d=''.join(sum(zip(i,j),()))[:-1];d='('+d[:l]+')'+d[l:]
   if eval(d)==int(a[-1]):print d;b

Це дає помилку (виклик невідомої функції b) на рішенні.

В основному, це гігантська груба сила. Він бере вхід, розбиває його на пробіли ( 1 2 -> [1,2]), а потім перестановлює через цей список. З кожною перестановкою вона повторюватиме всі можливі рядки довжиною 5 за допомогою символів +-*/. З кожною з цих ітерацій вона генерує комбінації довжини 2 списку [1,3,5,7,9,11], переплітає перестановку та рядок разом ( 12345 *-/+- -> 1*2-3/4+5-) та вкладає в дужки. Нарешті, вона оцінить це, і якщо відповідь і рівняння є істинними, то воно друкує рівняння і зупиняється.

Це жахливо неефективно, O(n!/(n-5)!)=O(n^5)але, проте, він працює в розумний час для тестових входів.


1
Ціла математика може спричинити неправильний вихід при використанні поділу. Наприклад, вхід "3 6 8 7 1 29" дає "(3 + 8/6) * 7 + 1", що дорівнює 31 1/3, а не 29. Я оновлюю опис, щоб зробити це явним.
Sir_Lagsalot

Це дає (3/6)*8*7+1для мене.
beary605

Гаразд, я покладу це на замітку як проблему з перекладачем, яким я користувався.
Sir_Lagsalot

3

Scala 368:

2-й g = -Line легше перевірити, перший гнучкий до аргументів команд, і обидва мають однакову довжину, тому я рахую лише з другого - видаліть його, щоб зробити аргументи, що проходять:

val g=(args.map(_.toDouble))
val g=Array(3,9,2, 1, 6, 87)
val k="+*/-DQ"
val i=(0 to 5)
val f:Seq[(Double,Double)=>Double]=Seq(_+_,_*_,_/_,_-_,(a,b)=>b-a,(a,b)=>b/a)
val h=g.init.permutations;
for(j<-h;o<-i;p<-i;q<-i;r<-i;z=try{f(r)(f(q)(f(p)(f(o)(j(0),j(1)),j(2)),j(3)),j(4))}catch{case _ => 0}
if(z==g(5)))printf("(((%d%c%d)%c%d)%c%d)%c%d=%d\n",j(0),k(o),j(1),k(p),j(2),k(q),j(3),k(r),j(4),g(5))

Вибірка зразка (у вас може виникнути питання прямо зараз - лише на мить):

(((5+7)/1)+6)*3=54
(((5-7)D1)*6)*3=54
(((5D7)+1)*6)*3=54
(((5+7)+6)Q1)Q3=54

Що з цією справою 5D7? D1? Це шестигранний? Є Q1, Q3 - що це.

Sir_Lagsalot дозволив нові основні операції в дусі виклику, і так, це базові операції, Delta і Quotient.

Вони відрізняються від a / b і ab тим, що aQb означає b / a, aDb означає ba. Назвемо це українським позначенням.

Тому

(((5-7)D1)*6)*3=54

засоби

((1-(5-7))*6)*3=54
 (1-(-2))*6*3
   3*6*3 = 18*3=54

До більш цікавого питання про те, як і чому: На початку я розсердився щодо можливостей розміщення дужок, і чи (a + b) -c = a + bc = (a + bc) = ((a + b ) -c) = (b + a) -c тощо. Ви можете розлютитися над цим питанням, але якщо ви записуєте можливі комбінації дужок, ви іноді викидаєте лист нуля і стикаєтесь з фактом: Ви завжди виконуєте 4 операції між 5 значеннями, і ви завжди починаєте з одного з них. Якщо шаблон завжди (((_x_)x_)x_)x_ ?= _(x є одним із 4-х операторів) і допускає зворотний напрямок (xb) та (bxa), ви зверталися до кожної можливості.

Тепер для + b і a b не потрібен протилежний напрямок, вони є комутаційними. Тому я винайшов оператор D і Q, який просто перемикає напрямок. Зараз у мене є ще 2 оператори, але не потрібно змінювати напрямок. Ну - це робиться у функції Послідовність:

 (a,b)=>b-a,(a,b)=>b/a

Моє для розуміння приймає значення з масиву g і розподіляє їх на a до e, потім я вибираю 4 індекси для вибору функції, а пізніше (лише за індексом) пов'язаний символ оператора. Мені доводиться вводити помилки div / 0, оскільки віднімання може призвести до нулів, тоді як вибіркові вхідні дані не містять 0.


Оператори Delta і Quotient добре. Якщо ви плануєте займатися гольфом, вам потрібно буде додати дужки до результату.
Sir_Lagsalot

Вихід тепер друкує круглі дужки.
користувач невідомий
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.