Инструкция по оружию математики


44

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

Входные данные:

Массив / список с целыми числами / десятичными числами. (Или строка, представляющая массив с целыми числами / десятичными числами.)

Выход:

Переберите числа и примените следующие пять математических операндов в следующем порядке:

  • Дополнение ( +);
  • Вычитание ( );
  • Умножение ( *или ×или ·);
  • Real / Calculator Division ( /или ÷);
  • Возведение в степень ( ^или **).

(ПРИМЕЧАНИЕ. Символы между круглыми скобками просто добавляются в качестве пояснения. Если ваш язык программирования использует для математической операции совершенно другой символ, чем примеры, то это, конечно, вполне приемлемо.)

Продолжайте, пока не дойдете до конца списка, а затем дайте результат суммы.

Правила соревнований:

  • Возведение в степень 0 ( n ^ 0) должно привести к 1 (это также относится к 0 ^ 0 = 1).
  • Для деления на 0 ( n / 0) нет тестовых случаев , поэтому вам не нужно беспокоиться об этом пограничном случае.
  • Если массив содержит только одно число, мы возвращаем его как результат.

Основные правила:

  • Это , поэтому выигрывает самый короткий ответ в байтах.
    Не позволяйте языкам кода-гольфа отговаривать вас от публикации ответов на языках, не относящихся к кодексу. Попробуйте придумать как можно более короткий ответ для «любого» языка программирования.
  • К вашему ответу применяются стандартные правила , поэтому вы можете использовать STDIN / STDOUT, функции / метод с правильными параметрами, полные программы. Ваш звонок.
  • По умолчанию лазейки запрещены.
  • Если возможно, добавьте ссылку с тестом для вашего кода.

Тестовые случаи:

[1,2,3,4,5] -> 0
-> 1 + 2 = 3
  -> 3 - 3 = 0
    -> 0 * 4 = 0
      -> 0 / 5 = 0 

[5,12,23,2,4,4,2,6,7] -> 539
-> 5 + 12 = 17
  -> 17 - 23 = -6
    -> -6 * 2 = -12
      -> -12 / 4 = -3
        -> -3 ^ 4 = 81
          -> 81 + 2 = 83
            -> 83 - 6 = 77
              -> 77 * 7 -> 539

[-8,50,3,3,-123,4,17,99,13] -> -1055.356...
-> -8 + 50 = 42
  -> 42 - 3 = 39
    -> 39 * 3 = 117
      -> 117 / -123 = -0.9512...
        -> -0.9512... ^ 4 = 0.818...
          -> 0.818... + 17 = 17.818...
            -> 17.818... - 99 -> -81.181...
              -> -81.181... * 13 = -1055.356...

[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2] -> 256
-> 2 + 2 = 4
  -> 4 - 2 = 2
    -> 2 * 2 = 4
      -> 4 / 2 = 2
        -> 2 ^ 2 = 4
          -> 4 + 2 = 6
            -> 6 - 2 = 4
              -> 4 * 2 = 8
                -> 8 / 2 = 4
                  -> 4 ^ 2 = 16
                    -> 16 + 2 = 18
                      -> 18 - 2 = 16
                        -> 16 * 2 = 32
                          -> 32 / 2 = 16
                            -> 16 ^ 2 = 256

[1,0,1,0,1,0] -> 1
-> 1 + 0 = 1
  -> 1 - 1 = 0
    -> 0 * 0 = 0
      -> 0 / 1 = 0
        -> 0 ^ 0 = 1

[-9,-8,-1] -> -16
  -> -9 + -8 = -17
    -> -17 - -1 = -16

[0,-3] -> -3
  -> 0 + -3 = -3

[-99] -> -99

Не целочисленное деление?
Утренняя монахиня

@LeakyNun Нет. Возможно, мне следует изменить ввод в список с десятичными числами вместо целых чисел из-за деления (и контрольного примера 3)?
Кевин Круйссен

Это было в песочнице?
Балинт

9
В математике есть два противоречивых «правила»:, n ^ 0 = 1но 0 ^ n = 0. Конфликт разрешается путем установки n != 0обоих правил, но затем он остается 0 ^ 0неопределенным. Однако в математике есть много вещей, которые хорошо подходят для математики, если 0 ^ 0она определена 1. Посмотрите Википедию для некоторых деталей.
Mego

1
@ Bálint Правила гласят, что никогда не будет действительного ввода с делением на ноль. Вам не нужно беспокоиться об этом крайнем случае.
Mego

Ответы:


7

Желе , 13 байт

“+_×÷*”ṁṖ⁸żFV

Попробуйте онлайн! или проверьте все контрольные примеры .

Как это работает

“+_×÷*”ṁṖ⁸żFV  Main link. Argument: A (list of integers)

“+_×÷*”        Yield the list of operations as a string.
        Ṗ      Yield A popped, i.e., with its last element removed.
       ṁ       Mold; reshape the string as popped A.
               This repeats the characters of the string until it contains
               length(A)-1 characters.
         ⁸ż    Zipwith; pairs the integers of A with the corresponding characters.
           F   Flatten the result.
            V  Eval the resulting Jelly code.
               Jelly always evaluates left-to-right (with blatant disregard towards
               the order of operations), so this returns the desired result.

Хорошо, это на 8 байт меньше , чем у Пайка , который в настоящее время лидировал.
Кевин Круйссен

3
Никто не обгоняет Денниса. Никогда.
Blue

1
Просто вопрос: действительно ли он считается как 13 байтов со всеми этими не-ASCII символами?
Ксавье Дури

3
@XavierDury Да. В байтах ссылка в заголовке приводит к собственной кодовой странице Jelly, который кодирует 256 символов Jelly понимают , как один байт каждого.
Деннис

@Dennis Спасибо за точность!
Ксавье Дури

19

Javascript ES7 49 байтов

a=>a.reduce((c,d,e)=>[c**d,c+d,c-d,c*d,c/d][e%5])

Сохранено 9 байтов благодаря Dom Hastings, сохранено еще 6 благодаря Leaky Nun

Использует новый оператор возведения в степень.


@ LeakyNun это не просто производит Infinity, а не ошибка?
Дом Гастингс

Попробуйте использовать eval, это может быть короче
Downgoat

@Upgoat Сначала он использовал eval, затем Leaky Nun показала мне, что лучше делать это так
Bálint

@ Блин, ты используешь так много запятых?
Rɪᴋᴇʀ

1
@ EᴀsᴛᴇʀʟʏIʀᴋ Неродной. Балинт часто так делает. Английская грамматика глупа в лучшие времена.
wizzwizz4

11

Haskell, 76 65 64 62 байта

Спасибо @Damien за удаление еще двух байтов =)

f(u:v)=foldl(\x(f,y)->f x y)u(zip(v>>[(+),(-),(*),(/),(**)])v)

Это использует, >>который здесь просто добавляет список [(+),...]к себе length vраз. Остальное все еще работает так же, как старые версии.

Старые версии:

Эти решения используют бесконечные списки, так как cycle[...]просто повторяют данный список бесконечно. Затем он в основном редактируется zipсо списком чисел, и мы просто fold( сокращаем на других языках) сжатый список через лямбду, который применяет операторы к элементу аккумулятора / текущего списка.

f(u:v)=foldl(\x(f,y)->f x y)u(zip(cycle[(+),(-),(*),(/),(**)])v)

f(u:v)=foldl(\x(y,f)->f x y)u(zip v(cycle[(+),(-),(*),(/),(**)]))

f l=foldl(\x(y,f)->f x y)(head l)(zip(drop 1l)(cycle[(+),(-),(*),(/),(**)]))

Вы можете заменить цикл на: v >>
Дэмиен

@Damien Спасибо большое!
flawr

Хм foldl(&)u$zipWith(&)v(flip<$>v>>[…])?
Берги

@ Bergi Я, честно говоря, больше не могу читать, что это делает =) В любом случае, нам нужен importfor &, так что это снова будет дольше, но все равно спасибо!
flawr

@flawr: На самом деле моя идея была такой же, как и то, что Lazersmoke опубликовал в качестве ответа , я просто не читал ее. Я понял это, пытаясь упростить эту твою лямду чем-то вроде uncurry. Не сработало, но я заметил, что вы должны быть в состоянии сохранить другой байт, используя $вместо скобок.
Берги


7

Haskell, 61 байт

foldl(flip id)0.zipWith flip((+):cycle[(+),(-),(*),(/),(**)])

Создает серию преобразований в списке, как в [сложить 1, сложить 2, вычесть 3, ...], начиная с 2 сложений, потому что мы начинаем с 0 в сгибе. Далее мы делаем то, что я называю сложением списка приложений, или foldl (flip id), который применяет список гомоморфизмов в серии. Это начинается с нуля, добавляет начальное значение, затем выполняет все вышеуказанные преобразования, чтобы получить окончательный результат.

Обратите внимание, что (flip id) такой же, как (\ x y-> yx), только короче.

Пример использования:

f = foldl(flip id)0.zipWith flip((+):cycle[(+),(-),(*),(/),(**)])
f [1,2,3,4,5] -- Is 0.0

Вместо этого flip idвы можете просто использовать &. Или flip($). Вау, я так и не понял($) = id
Берги

1
@Bergi: &определено в Data.Function, так что вам importтоже нужно . Может быть, какой-то онлайн-переводчик импортирует его по умолчанию, но тогда вам нужно указать, какой из них вы используете.
Ними

7

TSQL 116 115 88 байт

Благодаря предложению Росса Прессера я смог сыграть в гольф до 88 символов

-- In Try-it code, this must be DECLARE @y TABLE 
CREATE TABLE T(a real, i int identity)
INSERT T values(5),(12),(23),(2),(4),(4),(2),(6),(7)

DECLARE @ REAL SELECT @=CHOOSE(i%5+1,@/a,ISNULL(POWER(@,a),a),@+a,@-a,@*a)FROM T
PRINT @

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


1
На 1 байт меньше: требуется, чтобы входная таблица называлась T вместо @y. Решение PL / SQL имело это, так почему бы не TSQL.
Росс Прессер

@RossPresser да, конечно. как я это пропустил Это невозможно в тестовой ссылке, нет прав на создание таблиц, и она будет правильно работать только в первый раз в базе данных. Но какое это имеет значение, когда персонаж может играть в гольф. Спасибо за подсказку, ваше улучшение было добавлено
t-clausen.dk

Вычеркнуто еще 12 байтов: используйте CHOOSE вместо вложенного IIF, оставляя один IIF для случая i = 1. С вашего разрешения я отредактирую ответ.
Росс Прессер

ответ отредактирован. Вот ссылка на пробную версию
Ross Presser

1
@RossPresser Я не знал, ВЫБЕРИТЕ. включил ваше предложение и поиграл в гольф немного дальше
t-clausen.dk

6

Pyth, 27 26 25 байт

.v+>tlQ*lQ"^c*-+":jdQ\-\_

Тестирование.

Pyth использует префиксную нотацию: 1+2записывается как +1 2(пространство, необходимое для разделения чисел).

Поэтому для первого тестового примера выражение будет таким (((1+2)-3)*4)/5, которое в префиксной записи будет записано как /*-+ 1 2 3 4 5.

В Pyth cвместо деления делится поплавок /, поэтому он становится c*-+ 1 2 3 4 5.

Также в Pyth -100написано как _100вместо.

Таким образом, для третьего случая испытания, которое ((((((((-8+50)-3)*3)/-123)^4)+17)-99)*13), она становится: *-+^c*-+ _8 50 3 3 _123 4 17 99 13.

.v+>tlQ*lQ"^c*-+":jdQ\-\_
                  jdQ       Join input by space.
                 :   \-\_   Replace "-" with "_".
   >tlQ*lQ"^c*-+"           Generate the string "...^c*-+" of suitable length.
  +                         Join the two strings above.
.v                          Evaluate as a Pyth expression.

история


Ты быстрый! Похоже, мне удалось сделать более легкий вызов. Или ты просто ЭТО хорошо. ;)
Кевин Круйссен



6

На самом деле, 23 байта

;l"+-*/ⁿ"*@R':j':+'?o+ƒ

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

На самом деле используется постфиксная нотация для математики, и операторы, которые когда-либо принимают только два аргумента (например, операторы сложения, вычитания, умножения, деления и возведения в степень), ничего не делают, когда в стеке только один элемент. Таким образом, преобразование ввода в код на самом деле так же просто, как изменение ввода, форматирование его в виде чисел и добавление операций. Затем результирующий код может быть выполнен, давая желаемый результат.

Объяснение:

;l"+-*/ⁿ"*@R':j':+'?o+ƒ
;l"+-*/ⁿ"*               repeat the operations a number of times equal to the length of the input
                            (since extraneous operations will be NOPs, there's no harm in overshooting)
          @R             reverse the input
            ':j          join on ":" (make a string, inserting ":" between every pair of elements in the list)
               ':+       prepend a ":" (for the first numeric literal)
                  '?o    append a "?"
                           (this keeps the poor numeric parsing from trying to gobble up the first + as part of the numeric literal, since ? isn't interpreted as part of the literal, and is a NOP)
                     +   append the operations string
                      ƒ  cast as a function and call it

Пример переведенного кода для ввода 1,2,3,4,5:

:5:4:3:2:1?+-*/ⁿ+-*/ⁿ+-*/ⁿ+-*/ⁿ+-*/ⁿ

3
Люблю, как название языка сливается с количеством байтов
user6245072

3
s/Actually uses postfix notation/Actually actually uses postfix notation/
Утренняя монахиня


5

J, 40 байт

^~`(%~)`*`(-~)`+/@(|.@,7#:~#&2)(5-5|4+#)

Находит количество значений, необходимых для использования кратных 5 операторам, чем площадок со значениями идентичности этих операторов. По порядку +: 0, -0, *1, 1, %1 и ^1, что может быть битовым значением 00111, или 7 в базе 10. Затем работает с этим списком при циклическом переключении между операторами.

использование

   f =: ^~`(%~)`*`(-~)`+/@(|.@,7#:~#&2)(5-5|4+#)
   f 1 2 3 4 5
0
   f 5 12 23 2 4 4 2 6 7
539
   f _8 50 3 3 _123 4 17 99 13
_1055.36
   f 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
256
   f 1 0 1 0 1 0
1
   f _9 _8 _1
_16
   f 0 _3
_3
   f _99
_99

объяснение

^~`(%~)`*`(-~)`+/@(|.@,7#:~#&2)(5-5|4+#) Input: A
                                      #  Get length of A
                                    4+   Add four to it
                                  5|     Take it mod 5
                                5-       Find 5 minus its value, call it x
                           #&2           Create x copies of 2
                       7#:~              Convert 7 to base 2 and take the last x digits
                      ,                  Append those x digits to the end of A
                   |.@                   Reverse it, call it A'
^~                                       Power, reversed operators
    %~                                   Division, reversed operators
       *                                 Multiplication
         -~                              Subtraction, reversed operators
            +                            Addition
             /@                          Insert the previous operations, separated by `,
                                         into A' in order and cycle until the end
                                         Then evaluate the equation from right-to-left
                                         and return

5

Python 2, 81 67 64 байта

i=10
for n in input():exec'r%s=n'%'*+-*/*'[i::5];i=-~i%5
print r

Ввод представляет собой массив с плавающей точкой. Проверьте это на Ideone .

Как это работает

'*+-*/*'[i::5]выбирает каждый пятый символ строки, начиная с символа с индексом i , поэтому это дает, **если i = 0 , +если i = 1 , -если i = 2 , *если i = 3 и /если i = 4 . Поскольку строка имеет длину 6 , выражение даст пустую строку, если i> 5 .

Мы инициализируем переменную i до 10 . Для каждого числа n во входном массиве мы строим строку r<op>=n, котораяexec выполняется.

Первоначально, i = 10 , поэтому <op>пустая строка, и он инициализирует r с r+=n. После каждого шага мы увеличиваем i по модулю 5 сi=-~i%5 , так что следующий шаг будет извлечь правильный оператор.

Когда все входные числа были обработаны, и мы печатаем r , который содержит желаемый результат.


5

Матлаб - 95 91 85 байт / октава - 81 байт

Ввод в такой форме: a = ['1' '2' '3' '4' '5']; я надеюсь, что это покрыто "строкой, представляющей массив с целыми числами / десятичными числами", иначе дополнительно требуется 2 num2str.

Каждый промежуточный результат выводится на консоль, потому что это экономит мне несколько точек с запятой. a(1)выполняется, поэтому его значение затем сохраняется в ans. Также, конечно, использование ansв коде - плохая практика.

b='+-*/^'
a(1)
for i=2:length(a)
  ['(',ans,')',b(mod(i-2,5)+1),a(i)]
end
eval(ans)

В Octave '+-*/^'(mod(i+2,5)+1)также работает, что экономит еще 4 байта, спасибо Адаму и Луису Мендо:

a(1)
for i=2:length(a)
  strcat('(',ans,')','+-*/^'(mod(i-2,5)+1),a(i))
end
eval(ans)

Changelog:

  • Удаленные места, где это возможно
  • добавлено решение Octave
  • заменил strcat () на []

Привет, добро пожаловать в PPCG! Ввод хорошо, так как он по-прежнему легко различим, что ввод. Хм, я никогда не использовал Matlab, так что, может быть , я говорю идиотские вещи здесь, но не может b = '+-*/^'быть golfed к b='+-*/^'и for i = 2:length(a)к for i=2:length(a)(удаление пробелов)? Также, возможно, вам будут интересны Советы по игре в гольф в MATLAB . :)
Кевин Круйссен

Является '+-*/^'(mod(i+2,5)+1)действительным?
Адам

@ Adám Нет, но это, вероятно, в Октаве
Луис Мендо

@ Adám: это работает в Октаве, я добавил это.
Лукас К.

4

Mathematica, 67 66 65 байт

Fold[{+##,#-#2,#2#,#/#2,If[#2==0,1,#^#2]}[[i++~Mod~5+1]]&,i=0;#]&

Простой Foldс переменной, iсодержащей индекс.


Байт можно сохранить +##вместо#+#2
LLlAMnYP

4

CJam, 18 байт

q~{"+-*/#"W):W=~}*

Ввод представляет собой массив с плавающей точкой. Попробуйте онлайн!

Как это работает

q~                  Read and evaluate all input.
  {             }*  Reduce:
   "+-*/#"            Push the string of operators.
          W           Push W (initially -1).
           ):W        Increment and save in W.
              =       Retrieve the character at that index.
               ~      Evaluate.

4

R , 87 78 70 байт

i=0
Reduce(function(a,j)get(substr("+-*/^",i<<-i%%5+1,i))(a,j),scan())

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


в какой-то момент мне действительно нужно научиться пользоваться do.call... Я, вероятно, не должен считать себя программистом R, пока не пойду!
Джузеппе

1
@Giuseppe Advanced Rот Hadley Wickam - отличный пляж для чтения :)
JayCe

@Giuseppe спасибо за указание do.call- заставил меня понять, что я искал get.
JayCe

3

Haskell - 74

f(x:xs)=foldl(\x(o,y)->o x y)x(zip(cycle[(+),(-),(*),(/),flip(^).floor])xs)

Тестовые случаи:

λ> f[1,2,3,4,5] -> 0.0
λ> f[5,12,23,2,4,4,2,6,7] -> 539.0
λ> f[-8,50,3,3,-123,4,17,99,13] -> -1055.356943846277
λ> f [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2] -> 256.0

Возможно, это может быть короче; Однако поддержка Хаскеллом бесконечных списков и функций более высокого порядка делает прямое решение довольно приятным. Версия ^ :: Double -> Double -> Doubleбыла бы лучше для игры в гольф, но я не мог найти ее. К счастью, мне не нужна была полная лямбда, поэтому бессмысленный стиль сбрил несколько байтов.


2
Вы можете предварять сингл (+)к списку операторов и начать foldlс 0идти полностью pointfree и сохранить имя функции и параметры: foldl(\x(o,y)->o x y)0.zip((+):cycle[(+),(-),(*),(/),(**)]).
Ними

3

PowerShell v2 +, 124 байта

param($n)$o=$n[0];if($y=$n.count-1){1..$y|%{$o=if(($x=$i++%5)-4){"$o"+'+-*/'[$x]+$n[$_]|iex}else{[math]::pow($o,$n[$_])}}}$o

Долго, потому что PowerShell не имеет оператора ^или **, поэтому мы должны учитывать отдельный случай и использовать вызов .NET.

Принимает ввод $nв виде массива, устанавливает наш вывод $oв качестве первой цифры. Затем мы проверяем .countмассив, и до тех пор, пока он больше единицы, мы входим в if. В противном случае мы пропускаем if.

Внутри ifмы перебираем массив 1..$y|%{...}и каждую итерацию мы сбрасываем $oна новое значение, результат другого if/elseоператора. Пока наш счетчик $i++не равен по модулю 5 4 (т. Е. Мы не в ^операторе), мы просто берем $oи объединяем его с соответствующим символом '+-*/'[$x]и следующим числом во входном массиве $n[$_]. Мы передаем это в iex(псевдоним для Invoke-Expressionи аналогично eval), и это снова сохраняется в $o. Если мы находимся на ^операторе, мы находимся в else, поэтому мы выполняем [math]::Pow()вызов, и этот результат снова сохраняется в$o .

В любом случае мы просто выводим данные $oв конвейер и выходим с неявным выводом.


3

Ржавчина, 123 , 117 байт

Оригинальный ответ:

fn a(v:&[f32])->f32{v.iter().skip(1).enumerate().fold(v[0],|s,(i,&x)|match i%5{0=>s+x,1=>s-x,2=>s*x,3=>s/x,_=>s.powf(x)})}

глупые длинные имена методов ^^ ааа, намного лучше

fn f(v:&[f32])->f32{v[1..].iter().zip(0..).fold(v[0],|s,(&x,i)|match i%5{0=>s+x,1=>s-x,2=>s*x,3=>s/x,_=>s.powf(x)})}

ungolfed

fn f(values : &[f32]) -> f32 {
    values[1..].iter().zip(0..)
    .fold(values[0], |state,(&x,i)|
        match i%5 {
            0=>state+x,
            1=>state-x,
            2=>state*x,
            3=>state/x,
            _=>state.powf(x)
        }
    )
}

3

Perl 6 ,  70 68 65   62 байта

{$/=[(|(&[+],&[-],&[*],&[/],&[**])xx*)];.reduce: {$/.shift.($^a,$^b)}}
{(@_ Z |(&[+],&[-],&[*],&[/],&[**])xx*).flat.reduce: {&^b($^a,$^c)}}
{(@_ Z |(*+*,*-*,&[*],*/*,&[**])xx*).flat.reduce: {&^b($^a,$^c)}}
{reduce {&^b($^a,$^c)},flat @_ Z |(*+*,*-*,&[*],*/*,&[**])xx*}

Объяснение:

-> *@_ {
  reduce
    -> $a, &b, $c { b($a,$c) },

    flat       # flatten list produced from zip
      zip
        @_,    # input

        slip(  # causes the list of operators to flatten into the xx list

          # list of 5 infix operators
          &infix:<+>, &infix:<->, &infix:<*>, &infix:</>, &infix:<**>

        ) xx * # repeat the list of operators infinitely
}

Технически * + *это лямбда-бы то ни было, но фактически она такая же, как &[+]и сокращение для &infix:<+>набора подпрограмм, которые обрабатывают добавление чисел в инфикс.
Я не использовал это для умножения или возведения в степень, поскольку способы написать их таким образом, по крайней мере, столько, сколько у меня есть ( *×*или * * *и * ** *)

Тест:

Протестируйте его на ideone.com
(после того, как они обновятся до версии Rakudo, то есть за полтора года до официального выпуска спецификаций Perl 6 )

#! /usr/bin/env perl6

use v6.c;
use Test;

my @tests = (
  [1,2,3,4,5] => 0,
  [5,12,23,2,4,4,2,6,7] => 539,
  [-8,50,3,3,-123,4,17,99,13] => -1055.35694385, # -2982186493/2825761
  [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2] => 256,
  [1,0,1,0,1,0] => 1,
  [-9,-8,-1] => -16,
  [0,-3] => -3,
  [-99] => -99,
);

plan +@tests;

my &code = {reduce {&^b($^a,$^c)},flat @_ Z |(*+*,*-*,&[*],&[/],&[**])xx*}

for @tests -> $_ ( :key(@input), :value($expected) ) {
  is code(@input), $expected, .gist
}
1..8
ok 1 - [1 2 3 4 5] => 0
ok 2 - [5 12 23 2 4 4 2 6 7] => 539
ok 3 - [-8 50 3 3 -123 4 17 99 13] => -1055.35694385
ok 4 - [2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2] => 256
ok 5 - [1 0 1 0 1 0] => 1
ok 6 - [-9 -8 -1] => -16
ok 7 - [0 -3] => -3
ok 8 - [-99] => -99


3

Python 3, 88 93 байта

f=lambda x:eval('('*(len(x)-1)+'){}'.join(map(str,x)).format(*['+','-','*','/','**']*len(x)))

Сначала все было намного короче, но затем победил оператор, и мне пришлось добавить много скобок ...


3

Oracle PL / SQL, 275 254 байта

declare r number;begin for x in (select n,mod(rownum,5)r from t) loop if r is null then r:=x.n;elsif x.r=2then r:=r+x.n;elsif x.r=3then r:=r-x.n;elsif x.r=4then r:=r*x.n;elsif x.r=0then r:=r/x.n;else r:=r**x.n;end if;end loop;DBMS_OUTPUT.PUT_LINE(r);end;

Данные должны быть вставлены в таблицу с именем Tстолбца NтипаNUMBER

Использование:

drop table t;
create table t (n number);
insert into t values (-8);
insert into t values (50);
insert into t values (3);
insert into t values (3);
insert into t values (-123);
insert into t values (4);
insert into t values (17);
insert into t values (99);
insert into t values (13);

declare r number;begin for x in (select n,mod(rownum,5)r from t) loop if r is null then r:=x.n;elsif x.r=2then r:=r+x.n;elsif x.r=3then r:=r-x.n;elsif x.r=4then r:=r*x.n;elsif x.r=0then r:=r/x.n;else r:=r**x.n;end if;end loop;DBMS_OUTPUT.PUT_LINE(r);end;

Выход:

-1055,356943846277162152071601242992595623

275 байт версия:

declare r number;cursor c is select n,mod(rownum,5) r from t;begin for x in c loop if r is null then r:=x.n;else case x.r when 2 then r:=r+x.n;when 3 then r:=r-x.n;when 4 then r:=r*x.n;when 0 then r:=r/x.n;else r:=r**x.n; end case;end if;end loop;DBMS_OUTPUT.PUT_LINE(r);end;

3

Ява 8, 173 172 167 138 137 118 113 байтов

a->{double r=a[0],t;for(int i=1;i<a.length;r=new double[]{Math.pow(r,t),r+t,r-t,r*t,r/t}[i++%5])t=a[i];return r;}

Объяснение:

Попробуй это здесь.

a->{                     // Method with double-array parameter and double return-type
  double r=a[0],         //  Result-double, starting at the first item of the input
         t;              //  Temp double
  for(int i=1;           //  Index-integer, starting at the second item
      i<a.length;        //  Loop over the input-array
      r=new double[]{    //    After every iteration, change `r` to:
         Math.pow(r,t),  //      If `i%5` is 0: `r^t`
         r+t,            //      Else-if `i%5` is 1: `r+t`
         r-t,            //      Else-if `i%5` is 2: `r-t`
         r*t,            //      Else-if `i%5` is 3: `r*t`
         r/t}[i++%5])    //      Else-if `i%5` is 4: `r/t`
                         //      And increase `i` by 1 afterwards with `i++`
    t=a[i];              //   Change `t` to the next item in the array
  return r;}             //  Return result-double

2
Потому что, вы знаете, java.1.5 раза длиннее текущего самого длинного ответа .... который находится в SQL
Bálint

1
Вы можете изменить , double r=a[0];чтобы double r=a[0],b;сохранить некоторые байты.
Утренняя монахиня

1
@ LeakyNun Первоначально у меня было float, но нет Math.powдля поплавков, следовательно, doubleвместо. Спасибо за ,b. И с i++<a.lengthя получаю ArrayOutOfBoundsException в b=a[i];(если я не делаю i++<a.length-1вместо этого, который на один байт больше, чем короче).
Кевин Круйссен

1
Вы можете изменить == 4на > 3и == 0на < 1. Я не уверен, но я думаю, что вы могли бы немного сэкономить, создав переменную для i % 5.
Frozn

1
Я подумал, что вы можете изменить все это на объединение троичных. Во всех сравнениях вы можете использовать <xхитрость, сократив всю функцию до 137 символов.
Frozn

3

Несколько трюков могут уменьшить подход @ Willmore's на 23–174 байта (требуется php 5.6 или более поздняя версия). Самая экономящая часть - это удаление ненужных скобок (-10 байт).

функция f ($ a) {while (count ($ a)> 1) {$ l = array_shift ($ a); $ r = array_shift ($ a); array_unshift ($ a, ($ j = $ i ++% 5)) ? ($ J == 1 $ l- $ г: ($ J == 2 $ л * $ г: ($ J == 3 $ л / $ г: $ л ** $ г))): $ l + $ r);} return end ($ a);}

Но использование **оператора вместо pow()также позволяет использоватьeval с массивом для операций; и еще с несколькими трюками ...

PHP> = 5,6, 82 байта

while(--$argc)eval('$x'.['/','**','+','-','*'][$i++?$i%5:2]."=$argv[$i];");echo$x;

берет список из параметров командной строки. Запустите php -nr '<code>'или попробуйте онлайн .

старая версия, 161 157 151 145 144 140 137 117 байт

function f($a){while(count($a)>1)eval('$a[0]=array_shift($a)'.['+','-','*','/','**'][$i++%5].'$a[0];');return$a[0];}

Наиболее эффективная игра в гольф пришла от записи промежуточного результата непосредственно к первому элементу - после смещения предыдущего результата из массива.

сломать

function f($a)
{
    while(count($a)>1)  // while array has more than one element ...
        eval('$a[0]='                           // future first element :=
            . 'array_shift($a)'                 // = old first element (removed)
            . ['+','-','*','/','**'][$i++%5]    // (operation)
            .'$a[0];'                           // new first element (after shift)
        );
    return$a[0];        // return last remaining element
}

тестирование

$cases = array (
    0=>[1,2,3,4,5],
    539=>[5,12,23,2,4,4,2,6,7],
    '-1055.356...' => [-8,50,3,3,-123,4,17,99,13],
    256 => [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2],
    1 => [1,0,1,0,1,0],
    -16 => [-9,-8,-1],
    -3 => [0, -3],
    -99 => [-99]
);
echo '<table border=1><tr><th>values</th><th>expected</th><th>actual result</th></tr>';
foreach ($cases as $expect=>$a)
{
    $result=f($a);
    echo "<tr><td>[", implode(',',$a),"]</td><td>$expect</td><td>$result</td></tr>";
}
echo '</table>';

Красиво сделано. Вы можете удалить еще 3 байта, возвращая последнее значение в виде массива (измените «return $ a [0]» на «return $ a»), что я не вижу, это явно противоречит правилам. :)
640KB

@gwaugh Имо If the array contains just a single number, we return that as the result.довольно ясно. Но спасибо, что позволили мне вернуться к этому.
Тит

Можно привести семантический аргумент, что «это» в предложении может относиться к «массиву». В любом случае, ваш ответ - самый короткий PHP. Очень красиво сделано, и еще раз спасибо за указатели на мою более длительную работу.
640KB

3

PHP ,135 130 байт

Спасибо @titus, -5 байт, плюс 0 исправлений!

function f($z){return array_reduce($z,function($c,$x)use(&$i){eval('$c'.['/','**','+','-','*'][$i++?$i%5:5].'=$x;');return$c;});};

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

Меньше гольфа

function f( $t ) {
    return array_reduce( $t,
        function( $c, $x ) use( &$i ) {
            eval('$c'.['/','**','+','-','*'][$i++?$i%5:5].'=$x;');
            return $c;
        }
    );
};

Был действительно болтать за array_reduce (), чтобы работать для этого, но требует слишком много символов, чтобы побить текущий самый низкий счет PHP.

Размещение в любом случае, если у кого-то есть предложения!


1
Хороший подход; но я считаю, что он потерпит неудачу всякий раз, когда $cпопадет 0. Сохраните два байта с анонимной функцией вместо w. eval('$c'.['/','**','+','-','*'][$i++?$i%5:5].'=$x');return$c;на шесть байтов короче и должен решить нулевую проблему.
Тит

Спасибо @Titus! Вы абсолютно правы в случае 0. Я должен был добавить обратно; после = $ x, потому что eval не будет работать без него. Если бы я сделал ее анон-функцией, мне пришлось бы присвоить ей переменную или запустить ее в тестовом коде, верно? Не хотел бы подвергать сомнению количество байтов. : D
640KB

2

Брахилог , 68 байт

hI,?bL,1:+:-:*:/:^b:L:I{bhv?t.|[O:L:I]h$(P,LbM,OhA,Lh:Ir:A&:M:Pr&.}.

Это долго ... но не использует предикат оценки.

объяснение

  • Главный предикат

    hI,                                  Unify I with the first element of the input
       ?bL,                              L is the input minus the first element
           1:+:-:*:/:^b                  Construct the list of predicates [+:-:*:/:^]
                       :L:I{...}.        Call predicate 1 with [[+:-:*:/:^]:L:I] as input
    
  • Предикат 1

    bhv?t.                               If the second element of Input is empty (i.e. L),
                                         unify Output with the last element of Input
    |                                    Or
    [O:L:I]                              Input = [O:L:I]
           h$(P,                         P is O circularly permutated to the left
                LbM,                     M is L minus the first element
                    OhA,                 A is the first element of O
                        Lh:Ir:A&         Call predicate A on [I:First element of L]
                                :M:Pr&.  Call predicate 1 recursively with P:M:
    

Победи тебя на 1̶ ̶b̶y̶t̶e̶ 2 байта;)
LegionMammal978

2

IBM PC 8087 FPU, 66 82 байта

Для вычислений используется только математический сопроцессор Intel 8087 IBM PC.

Попробуйте это в автономном режиме! (в DOSBox или что-то еще). Дайте что-нибудь делать скучающему чипу 8087 вашего старого компьютера, кроме всех тех таблиц Lotus 1-2-3, которые вы использовали в 80-х годах.

9bdf 0783 c302 499b de07 83c3 0249 e342 9bde 2783 c302 49e3 399b de0f 83c3 0249 
e330 9bde 3783 c302 49e3 2751 8b0f 9bd9 e883 f900 7413 9c7f 02f7 d99b d8c9 e2fb 
9d7d 069b d9e8 9bd8 f159 83c3 0249 e302 ebb5 c3

Ungolfed (в разобранном виде):

START: 
    ; RUN TESTS  
    MOV  BX, OFFSET TST     ; 5, 12, 23, 2, 4, 4, 2, 6, 7
    MOV  CX, CTST           ; input array length
    CALL WOMI               ; calculate sequence
    CALL PRINT_FLT          ; output to console

    MOV  BX, OFFSET TST1    ; 5, 12, 23, 2, 4, -4, 2, 6, 7
    MOV  CX, CTST1
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST2    ; -8, 50, 3, 3, -123, 4, 17, 99, 13
    MOV  CX, CTST2
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST3    ; 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
    MOV  CX, CTST3
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST4    ; 1,0,1,0,1,0
    MOV  CX, CTST4
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST5    ; -9, -8, -1
    MOV  CX, CTST5
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST6    ; 0, -3
    MOV  CX, CTST6
    CALL WOMI
    CALL PRINT_FLT

    MOV  AX, 4C00H          ; exit to DOS
    INT  21H

;  TEST DATA

TST   DW  5, 12, 23, 2, 4, 4, 2, 6, 7
CTST  EQU ($-TST)/(SIZE TST)    ; count of items on list

TST1  DW  5, 12, 23, 2, 4, -4, 2, 6, 7
CTST1 EQU ($-TST1)/(SIZE TST1)  ; count of items on list

TST2  DW -8, 50, 3, 3, -123, 4, 17, 99, 13
CTST2 EQU ($-TST2)/(SIZE TST2)  ; count of items on list

TST3  DW 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
CTST3 EQU ($-TST3)/(SIZE TST3)  ; count of items on list

TST4  DW 1,0,1,0,1,0
CTST4 EQU ($-TST4)/(SIZE TST4)  ; count of items on list

TST5  DW -9, -8, -1
CTST5 EQU ($-TST5)/(SIZE TST5)  ; count of items on list

TST6  DW 0, -3
CTST6 EQU ($-TST6)/(SIZE TST6)  ; count of items on list

; 8087 exponent: ST(0) = ST(0) ^ EXP
FIEXP   MACRO   EXP
        LOCAL   REPEAT, DONE
        PUSH CX
        MOV  CX, EXP        ; Exponent is count for loop
        FLD1                ; load 1 into ST
        CMP  CX, 0          ; is exponent pos, neg or 0?
        JZ   DONE           ; exit (with value 1) if exponent is 0
        PUSHF               ; save result flags for later
        JG   REPEAT         ; if exp > 1 start calculation
        NEG  CX             ; make exponent positive for loop
REPEAT:
        FMUL ST(0), ST(1)   ; multiply ST0 = ST0 * ST1
        LOOP REPEAT
        POPF                ; retrieve flags from earlier
        JGE  DONE           ; if exponent was negative, divide 1 by result
        FLD1                ; push 1 into numerator
        FDIV ST(0), ST(1)   ; ST0 = 1 / ST1
DONE:
        POP  CX
        ENDM

; Function WOMI: (Weapons of Math Instruction)
; input: BX - address of start of input array
;       CX - length of input array
; output: ST - result on top of 8087 register stack
WOMI PROC
    FILD WORD PTR [BX]      ; load first item
    ADD  BX, 2              ; move to next
    DEC  CX
CALC:
    FIADD WORD PTR [BX]     ; add
    ADD  BX, 2              ; move to next
    DEC  CX                 ; decrement counter
    JCXZ OUTPUT             ; check if done

    FISUB WORD PTR [BX]     ; subtract
    ADD  BX, 2
    DEC  CX
    JCXZ OUTPUT

    FIMUL WORD PTR [BX]     ; multiply
    ADD  BX, 2
    DEC  CX
    JCXZ OUTPUT

    FIDIV WORD PTR [BX]     ; divide
    ADD  BX, 2
    DEC  CX
    JCXZ OUTPUT

    FIEXP [BX]              ; exponent
    ADD  BX, 2
    DEC  CX
    JCXZ OUTPUT
    JMP CALC                ; start again

OUTPUT:
    RET 
WOMI ENDP

PRINT_FLT PROC
; print top of 8087 stack
; scaling: 14 digits, 4 decimal places
; input: BX = address of a TBYTE (BCD) output buffer
;       ST = value to display on top of 8087 stack  
    LEA   BX, BUFF                  ; set BX to BCD output buffer
    MOV   AH, 2
    MOV   WORD  PTR[BX], 10000      ; ten thousand (scale factor)
    FIMUL WORD  PTR[BX]             ; scale up by 10000
    FBSTP TBYTE PTR[BX]             ; store as BCD
    FWAIT                           ; sync 8088 and 8087
    TEST  BYTE  PTR[BX+9], 80H      ; check sign bit
    JE    PF_1                      ; 0, goto PF_1
    MOV   DL, '-'                   ; output '-'
    INT   21H
PF_1:
    ADD   BX, 8                     ; point to high byte
    MOV   CH, 7                     ; 14 digits before decimal point
    MOV   CL, 4                     ; 4 shifts (8 bytes / 2 = 4 = 1 nibble)
    MOV   DH, 2                     ; 2 times (8 bytes / 4)
PF_LOOP:
    MOV   DL, [BX]                  ; get BCD digits
    SHR   DL, CL                    ; move high digit to low nibble
    OR    DL, 30H                   ; convert to ASCII
    INT   21H
    MOV   DL, [BX]                  ; get byte again
    AND   DL, 0FH                   ; mask out high digit
    OR    DL, 30H                   ; convert to ASCII
    INT   21H                       ; output
    DEC   BX                        ; next byte
    DEC   CH                        ; decrement byte
    JG    PF_LOOP                   ; repeat if more bytes
    DEC   DH                        ; second time?
    JE    PF_DONE                   ; yes, done
    MOV   DL, '.'                   ; no, output decimal point
    INT   21H
    MOV   CH, 2                     ; 4 more digits after decimal point
    JMP   PF_LOOP                   ; go print digits
PF_DONE:
    MOV  DL, 0DH                    ; display newline CRLF
    MOV  AH, 2
    INT  21H
    MOV  DL, 0AH
    INT  21H
    RET 
PRINT_FLT ENDP

BUFF DT 0   ; output buffer for floating point digit string

_TEXT ENDS
END START

Выход:

A>WOMI.COM
00000000000539.0000
-00000000000027.9136
-00000000001055.3569
00000000000256.0000
00000000000001.0000
-00000000000016.0000
-00000000000003.0000

Ввод осуществляется через PROC (x86, наиболее эквивалентный функции), причем BX - это указатель на массив WORD в памяти, а CX - количество элементов в нем и возвращает результат в ST.

* Примечание: фактический код функции 6682 байта. Конечно, код для записи числа с плавающей запятой на консоль (код поваренной книги) составляет 83 байта. Программа тестирования и данные183215 байт, что делает исполняемый файл .COM 305 Всего 380 байт.


1
Это здорово! Я написал подобное решение для x86-64 (linux), но пока еще не играл в гольф, что, вероятно, сильно изменит логику. Для расчета показателя степени, даже если данные тесты не проверяют получение отрицательного показателя, я чувствовал, что это была необходимая часть логики программы, тем более что это так же просто, как нажать 1 на st0, а затем выполнить деление между st0 и st1 (по крайней мере на x86 это две инструкции).
Дэви

Спасибо @davey - очень хороший момент! Я обновил код для обработки отрицательных показателей и добавил для него еще один тест.
640KB

2

APL (Dyalog Unicode) , 29 27 байтов SBCS

Функция аномального молчаливого префикса. Обратите внимание, что *это возведение в степень в APL.

≢{⍎3↓⍕⌽⍵,¨⍨⍺⍴'+-×÷*''⍨'}⊢

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

Поскольку APL выполняется справа налево, мы можем просто изменить порядок аргументов вставленных операций и полностью изменить выражение. Postfix меняет аргументы. После идеального перемешивания чисел и операций нам просто нужно повернуть вспять, сгладить и оценить:

≢{}⊢ Вызвать следующую функцию с количеством и фактическими числами как и :

'⍨' этот персонаж

'+-×÷*',¨ добавьте к этому каждый из этих символов; ["+⍨","-⍨","×⍨","÷⍨","*⍨"]

⍺⍴ использовать левый аргумент (кол - во номеров) циклически г eshape , что

 обратный

 форматировать как плоскую строку

3↓опустить ведущие 3 символа (пробел и символ и )

 выполнить как код APL


2

Japt , 16 байт

r@[XY]r"p+-*/"gZ

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

Объяснение:

r@                  #Reduce the input list:
       "p+-*/"      # The list of functions to apply (offset by one due to the behavior of Z)
              gZ    # Choose the one at the current index, wrapping
  [  ]r             # Apply that function to:
   X                #  The result of the previous step
    Y               #  and the current number
                    #Implicitly return the result of the final step

Ах, черт, я просто работал над этим, пытаясь понять, почему это дало мне неправильные результаты - я пропустил чертову степень! : \
Лохматый

1

c #, 238 , 202 байта

double d(double[]a){Array.Reverse(a);var s=new Stack<double>(a);int i=0,j;while(s.Count>1){double l=s.Pop(),r=s.Pop();j=i++%5;s.Push(j==0?l+r:j==1?l-r:j==2?l*r:j==3?l/r:Math.Pow(l,r));}return s.Peek();}

Я не видел никакого решения C #, поэтому я дам его. Это мой первый Codegolf. Я начал писать на c # «два месяца назад» (хотя я знаю Java до некоторой степени).

Он использует стек

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

Ungolfed и тестовые случаи

using System;
using System.Collections.Generic;

class M 
{
    double d(double[]a) {
        Array.Reverse(a);
        var s = new Stack<double>(a);
        int i=0,j;
        while (s.Count>1)
        {
            double l=s.Pop(),r=s.Pop();
            j=i++%5;
            s.Push(j==0?l+r:j==1?l-r:j==2?l*r:j==3?l/r:Math.Pow(l, r));
        }
        return s.Peek();
    }

    public static void Main()
    {
        int[][] a = new int[][]{
            new int[]{1,2,3,4,5},
            new int[]{5,12,23,2,4,4,2,6,7},
            new int[]{-8,50,3,3,-123,4,17,99,13},
            new int[]{2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
            new int[]{1,0,1,0,1,0},
            new int[]{-9,-8,-1},
            new int[]{0,-3},
            new int[]{-99}
        };

        for (int i = 0; i < a.Length; i++)
        {
            Console.WriteLine(new M().d(Array.ConvertAll(a[i], e => Convert.ToDouble(e))));
        }
        Console.ReadKey();
    }
}

Выход:

0
539
-1055,35694384628
256
1
-16
-3
-99

Привет и добро пожаловать в PPCG! Это может быть хорошей темой для рассмотрения: Советы по игре в гольф на C # . Некоторые вещи, которые могут быть добавлены в ваш код: пробелы ( a, Double.Parse-> a,Double.Parse; while (s.Count-> while(s.Count; Pow(l, r)-> Pow(l,r)). Кроме того, вы можете удалить int перед j=и положить его за int i=0,j;. Отличный первый ответ, и еще раз добро пожаловать. :)
Кевин Круйссен

@KevinCruijssen Привет! Ty! Пробелы удалены, и j переместился, как вы и предлагали :)
display_name

1

PHP, 206 , 198 , 197 байт

function f($a){while(count($a)>1){$l=array_shift($a);$r=array_shift($a);array_unshift($a,($j=$i++%5)==0?($l+$r):($j==1?($l-$r):($j==2?($l*$r):($j==3?($l/$r):(pow($l,$r))))));}return array_pop($a);}

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

Ungolfed

<?php

function f($a)
{
    while(count($a)>1)
    {
        $l = array_shift($a); $r = array_shift($a);
        array_unshift($a,($j=$i++%5)==0?($l+$r):($j==1?($l-$r):($j==2?($l*$r):($j==3?($l/$r):(pow($l,$r))))));
    }
    return array_pop($a);
}

echo f([1,2,3,4,5])."\n";
echo f([5,12,23,2,4,4,2,6,7])."\n";
echo f([-8,50,3,3,-123,4,17,99,13])."\n";
echo f([2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2])."\n";
echo f([1,0,1,0,1,0])."\n";
echo f([-9,-8,-1])."\n";
echo f([0,-3])."\n";
echo f([-99])."\n";

В PHP логика похожа на мою с # ответ ( 202 байта ) :).

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.