Знайдіть операції, необхідні для отримання результату


10

Отож завдання просте, задавши масив чисел і результат, вам потрібно знайти, які операції потрібно використовувати на числах з масиву, щоб отримати запитуваний результат.

Давайте зробимо його простим для початку та дозвольмо лише основні операції, такі як: додавання, віднімання, множення та ділення.

Приклад:

Input  : [5,5,5,5,5] 100
Output : 5*5*5-5*5

Щоб надати певну перевагу таким мовам, як Java, запитом є реалізація функції, а не всієї програми, а результат можна повернути за допомогою параметра або надрукувати на консоль.

Код оцінюється на основі кількості байтів, а оскільки це завдання для гольфу, виграє найнижчий бал.

Ще одна вимога: Ви можете отримати додаткові -10 балів, якщо масив містить лише цифри, підтримуючі рішення, де ви можете побудувати числа з наступних цифр. Тобто

Input  : [1,2,3,4,5] 0
Output : 12-3-4-5

Зауважте, що за умови запропонованих результатів виводи, деякі випадки можуть мати більше одного рішення. Ви вирішуєте, чи надасте одне або декілька рішень для даної задачі.

EDIT: Результат повинен бути дійсним з математичної точки зору, отже, ділення є раціональним поділом, а не цілим числом, а пріоритет операції такий же, як у класичній математиці (спочатку множення та ділення, потім додавання та віднімання).


4
Чи є *і /має перевагу над +і -? Ваші два приклади суперечать один одному.
Leaky Nun

1
В майбутньому переконайтеся, що ви створюєте банти на основі відсотків для такої мови, як java, -10 байт - це не так добре, як для желе
Bálint


4
Чи потрібно використовувати цифри для того, щоб? Крім того, для майбутніх проблем я від душі рекомендую використовувати « Пісочницю», де подібні проблеми можна випрасувати перед публікацією в Main.
AdmBorkBork

2
@ mbomb007 це не дублікат жодного з цих. Це довільні числові входи, і допускаються лише основні математичні операції, вони не повинні виводити фактичні програми.
Патрік Робертс

Відповіді:



4

Oracle SQL 11.2, 322 304 270 байт

SELECT o FROM(SELECT REPLACE(SUBSTR(:1,1,1)||REPLACE(SYS_CONNECT_BY_PATH(a||SUBSTR(:1,LEVEL*2+1,1),','),','),'_')o,LEVEL l FROM(SELECT SUBSTR('+-*/_',LEVEL,1)a FROM DUAL CONNECT BY LEVEL<6)CONNECT BY LEVEL<LENGTH(:1)/2)WHERE:2=dbms_aw.eval_number(o)AND l>LENGTH(:1)/2-1;

: 1 - це список цифр
: 2 - це результат пошуку

Без гольфу:

SELECT o
FROM   (
         SELECT REPLACE(SUBSTR(:1,1,1)||REPLACE(SYS_CONNECT_BY_PATH(a||SUBSTR(:1,LEVEL*2+1,1),','),','),'_')o,LEVEL l 
         FROM ( -- Create one row per operator 
                SELECT SUBSTR('+-*/_',LEVEL,1)a FROM DUAL CONNECT BY LEVEL<6
              ) CONNECT BY LEVEL<LENGTH(:1)/2  -- Create every combination of operators, one per ','
)
WHERE :2=dbms_aw.eval_number(o)  -- filter on result = evaluation
  AND l>LENGTH(:1)/2-1           -- keep only expressions using every digits

4

TSQL (sqlserver 2016) 310 294 280 байт

Яка чудова можливість написати некрасивий код:

Гольф:

DECLARE @ varchar(max)= '5,5,5'
DECLARE @a varchar(20) = '125'

,@ varchar(max)='';WITH D as(SELECT @a a UNION ALL SELECT STUFF(a,charindex(',',a),1,value)FROM STRING_SPLIT('*,+,./,-,',',')x,d WHERE a like'%,%')SELECT @+=a+','''+REPLACE(a,'.','')+'''),('FROM D WHERE a not like'%,%'EXEC('SELECT y FROM(values('+@+'null,null))g(x,y)WHERE x='+@b)

Спробуйте в Інтернеті

Читабельний: (вставлення десяткової крапки (.) Та видалення того ж необхідне для того, щоб sql прийняв, що 4/5 не 0 - вилучення добре для людей, які тестують його)

DECLARE @a varchar(max)= '5,5,5'
DECLARE @b varchar(20) = '5'

,@ varchar(max)=''
;WITH D as
(
  SELECT @a a
  UNION ALL
  SELECT STUFF(a,charindex(',',a),1,value)
  FROM STRING_SPLIT('*,+,./,-,',',')x,d
  WHERE a like'%,%'
)
SELECT @+=a+','''+REPLACE(a,',','')+'''),('
FROM D
WHERE a not like'%,%'

EXEC('SELECT y FROM(values('+@+'null,null))g(x,y)WHERE x='+@b)

Це рішення також може обробляти такі типи введення:

Вхід: [1,2,3,4,5] 0 Вихід: 12-3-4-5


3

JavaScript (ES6), 165 147 байт

a=>o=>(c=[],i=c=>{for(j=0;!((c[j]?++c[j]:c[j]=1)%5);)c[j++]=0},eval(`while(eval(e=(a+'').replace(/,/g,(_,j)=>'+-*/'.charAt(c[~-j/2])))!=o)i(c);e`))

Вкладений eval... милий.

f=a=>o=>(c=[],i=c=>{for(j=0;!((c[j]?++c[j]:c[j]=1)%5);)c[j++]=0},eval(`while(eval(e=(a+'').replace(/,/g,(_,j)=>'+-*/'.charAt(c[~-j/2])))!=o)i(c);e`))
console.log(f([5,5,5,5,5])(100))
console.log(f([1,2,3,4,5])(0))
console.log(f([3,4])(0.75))
console.log(f([3,4,5,6])(339))


3

Python 3, 170 155 байт

from itertools import*
def f(n,o):print({k for k in[''.join(map(str,sum(j,())))[1:]for j in[zip(x,n)for x in product('+-*/',repeat=len(n))]]if eval(k)==o})

Створіть генератор з усіма можливими замовленнями операторів, поєднайте це з числами, а потім оцініть, поки ми не отримаємо відповідь.

https://repl.it/C2F5


2
Ви можете зберегти кілька символів, замінивши ['+','-','*','/']на '+-*/'; оскільки strings є ітерабельним, він буде трактувати його так само, як і arrayкожен елемент, що є кожним символом у string- так він буде діяти так, як ви надали йому масив, який у вас є.
nasonfish

2

Пітон, 195 186 байт

Ось такий жорстокий спосіб зробити це.

def x(i,r):
 t=""
 from random import choice as c
 while True:
  for j in i:
   t+=str(j)
   if c([0,1]):t+="."+c("+-/*")
  t=t.strip("+-*/.")+"."
  v=eval(t)
  if v == r:print t
  t=""

Функція xприймає аргументи a listі a result- x([1,2,3,4,5], 15)наприклад.

Програма починає цикл, коли ми починаємо випадковим чином вибирати, чи слід додавати "+", "-", "*", or "/"між кожним числом чи ми повинні об'єднати їх разом. Це виглядало як більш стислий варіант, ніж насправді переживати перестановки та намагатися кожну комбінацію, щоб знайти кожен результат, і хоча це потрібно більше часу, і це набагато менш ефективно. (На щастя, це не хвилює у цьому контексті!)

Він також додає "". до кожного числа, щоб уникнути виконання цілочисельних операцій на зразок 6/4 = 1. Потім це evalнаше вираження і визначає, чи результат дорівнює тому, що ми очікуємо, і якщо так, виводить вираз.

Ця програма ніколи не виходить - вона буде постійно виводити результати, поки не буде вбита.

EDIT 1 : Видаліть зайві нові рядки, де ifможна використовувати однорядкові оператори.


дійсно смішна реалізація. але легко зберегти ще кілька байт Спробуйте в Інтернеті! (176 байт)
bobrobbob

2

Матлаб, 234 238 258 байт

Я припускаю, що виходячи з обмежень інших відповідей, що порядок чисел вхідного масиву підтримується fiat.

n=length(x)-1
k=n*2+2
p=unique(nchoosek(repmat('*-+/',1,n),n),'rows')
p=[p char(' '*~~p(:,1))]'
c=char(x'*~~p(1,:))
o=p(:,r==cellfun(@eval,mat2cell(reshape([c(:) p(:)]',k,[]),k,0|p(1,:))))
reshape([repmat(x',size(o,2),1) o(:)]',k,[])'

Цей код бере рядок чисел x, скажімо , x = '12345'і в результаті r, скажімо , r = 15і повертає всі рядки з виразів , які ви можете оцінити , щоб отримати rвід xвикористання чотирьох операторів.

Я використовував два різні еквівалентні за довжиною способи уникнення використання виразів ones(length())-type або repmat(length())-type: ~~p(1,:)який повертає значення not-not у p(тобто, список 1s такої ж довжини, як і перший вимір p) і 0|p(:,1)який повертає 0 або є-є -a-value-in- p(тобто список 1s такої ж довжини, як і другий вимір p).

Matlab не має методу nchoosek заміни , тому я дублював операторів правильну кількість разів, обчислював весь простір nchoosekдля цього більшого вибору операторів, а потім використовував uniqueвиклик, щоб зрівняти результат до того, яким він повинен бути (видалення еквівалентних комбінацій, таких як "*** +" та "*** +"). Я додаю пробіл, що відповідає довжині вхідного вектора для цілей конкатенації, а потім складаю рядки оператора зі вхідними рядками в стовпці матриці. Потім я оцінюю вирази в стовпцях для отримання результатів і знаходжу порядок операторів, який відповідає цим стовпцям з результатами, які відповідають нашому введенню r.

Тест: x = '12345', r = 15:

1*2*3+4+5 
1+2+3+4+5 
1-2*3+4*5 

Якби мені довелося взяти масив подвійних значень точності, мені знадобиться x = num2str(x,'%d');для перетворення цифр у рядок, додавши ;до моєї оцінки 21 (20 без значень ). * Додатковий байт був крапкою з комою, яку я залишив суто для того, щоб той, хто працює з цим кодом, не побачив, як їх командний рядок підірветься довгими масивами. Оскільки моя редакція так чи інакше створює гігантську купу попереджень про логіки та операнди двокрапки, я видалив крапки з комою в новій версії.

Змінити 2: Забула замініть 2*n+2з k.

Стара відповідь:

n=length(x)-1;
p=unique(nchoosek(repmat(['*','-','+','/'],1,n),n),'rows');
l=length(p);
p=[p repmat(' ',l,1)]';
c=reshape([repmat(x',l,1) p(:)]',n*2+2,[]);
o = p(:,r == cellfun(@eval, mat2cell(c,n*2+2,ones(l,1))));
reshape([repmat(x',size(o,2),1) o(:)]',n*2+2,[])'

2

JavaScript (ES6), 88 байт

a=>o=>eval(`while(eval(e=(a+'').replace(/,/g,_=>'+-*/'.charAt(Math.random()*5)))!=o);e`)

Кинув трохи випадково до суміші. Набагато простіше, ніж систематично повторювати комбінації.

Тестовий сюїт

f=a=>o=>eval(`while(eval(e=(a+'').replace(/,/g,_=>'+-*/'.charAt(Math.random()*5)))!=o);e`)
console.log(f([5,5,5,5,5])(100))
console.log(f([1,2,3,4,5])(0))
console.log(f([3,4])(0.75))
console.log(f([3,4,5,6])(339))


1

PHP, 108 байт

for(;$i=$argc;eval("$s-$argv[1]?:die(\$s);"))for($s="",$x=$p++;--$i>1;$x/=4)$s.="+-*/"[$s?$x&3:4].$argv[$i];

приймає введення аргументів командного рядка у зворотному порядку. Бігайте з -r.

зламатися

for(;                   # infinite loop:
    $i=$argc;               # 1. init $i to argument count
    eval("$s-$argv[1]?:"    # 3. if first argument equals expression value,
        ."die(\$s);")       #    print expression and exit
    )
    for($s="",              # 2. create expression:
        $x=$p++;            #    init map
        --$i>1;                 # loop from last to second argument
        $x/=4)                  # C: shift map by two bits
        $s.="+-*/"[$s?$x&3:4]   # A: append operator (none for first operand)
            .$argv[$i];         # B: append operand

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