Обратные Математические Циклы


18

Вдохновленный этим

В связанном задании нас просят применить дополнение к элементам оригинала и обратное к входному массиву. В этом задании мы немного усложним его, введя другие основные математические операции.

Получив массив целых чисел, переберите +, *, -, //, %, ^, где //есть целочисленное деление и ^экспонента, применяя его к обратной части массива. Или, другими словами, примените одну из вышеперечисленных функций к каждому элементу массива, причем второй аргумент является обратным к массиву, а функция применяется для циклического перемещения по приведенному выше списку. Это все еще может сбивать с толку, поэтому давайте рассмотрим пример.

Input:   [1, 2, 3, 4, 5, 6, 7, 8, 9]
Reverse: [9, 8, 7, 6, 5, 4, 3, 2, 1]

         [ 1,  2,  3,  4,  5,    6,  7,  8,  9]
Operand:   +   *   -   /   %     ^   +   *   -
         [ 9,  8,  7,  6,  5,    4,  3,  2,  1]

Result:  [10, 16, -4,  0,  0, 1296, 10, 16,  8]

поэтому вывод для [1, 2, 3, 4, 5, 6, 7, 8, 9]будет[10, 16, -4, 0, 0, 1296, 10, 16, 8]

Чтобы охватить угловые случаи, ввод никогда не будет содержать 0, но может содержать любое другое целое число в диапазоне от отрицательной бесконечности до положительной бесконечности. Вы можете принять ввод как список строк, представляющих цифры, если хотите.

Контрольные примеры

input => output

[1, 2, 3, 4, 5, 6, 7, 8, 9]     => [10, 16, -4, 0, 0, 1296, 10, 16, 8]
[5, 3, 6, 1, 1]                 => [6, 3, 0, 0, 1]
[2, 1, 8]                       => [10, 1, 6]
[11, 4, -17, 15, 2, 361, 5, 28] => [39, 20, -378, 7, 2, 3.32948887119979e-44, 9, 308]

Это поэтому выигрывает самый короткий код (в байтах)!



@AdmBorkBork Он обращается к этому, я указал это в чате.
г-н Xcoder

@AdmBorkBork исправлено. Я пропустил это в своем тестовом генераторе
caird coinheringaahing

Ваш третий контрольный пример все еще содержит 0>.>
Mr. Xcoder

1
@DigitalTrauma для языков, которые по умолчанию имеют целые числа, я думаю, что вывод 0 приемлем для таких крошечных чисел, как этот.
caird coinheringaahing

Ответы:


6

Желе, 10 байт ( вилка )

+×_:%*6ƭ"Ṛ

Я только что работал над внедрением быстрого для этого на днях, так что довольно удивительно увидеть его применение так скоро. Он по-прежнему существует только как форк, поэтому вы не можете попробовать его онлайн.

Образец вывода

$ ./jelly eun '+×_:%*6ƭ"Ṛ' '[1,2,3,4,5,6,7,8,9]'
[10, 16, -4, 0, 0, 1296, 10, 16, 8]
$ ./jelly eun '+×_:%*6ƭ"Ṛ' '[5,3,6,1,1]'
[6, 3, 0, 0, 1]
$ ./jelly eun '+×_:%*6ƭ"Ṛ' '[2,1,8]'
[10, 1, 6]
$ ./jelly eun '+×_:%*6ƭ"Ṛ' '[11,4,-17,15,2,361,5,28]'
[39, 20, -378, 7, 2, 3.32948887119979e-44, 9, 308]

объяснение

+×_:%*6ƭ"Ṛ  Input: array
      6ƭ    Tie 6 dyads
+             Addition
 ×            Multiplication
  _           Subtraction
   :          Integer division
    %         Modulo
     *        Power
        "   Vectorize with
         Ṛ  Reverse

ну даааааааа давай по-настоящему :( но приятно, этот быстрый кажется весьма полезным: D
HyperNeutrino

Это должно быть потянуто к желе. +1, хотя вы можете расширить ƭподдержку nilads (заменить значение) и monad (применить к левому аргументу)
Erik the Outgolfer

@EriktheOutgolfer Уже работает с монадами. Смотрите примеры, которые я разместил в чате Jelly. Ниладс - это другой случай.
миль

@ Мили, я имею в виду, как то, как здесь ведут себя нилады .
Эрик Outgolfer

@EriktheOutgolfer Хорошо, теперь он поддерживает нилады, но требует, чтобы вы определили их длину и использовали пробел между ними. Пример 2 1”q3ƭ€на [7,4,9,0]возвраты[2, 1, 'q', 2]
милях

4

Шелуха , 16 байт

Эта задача благоприятствует языкам, которые могут создавать бесконечные списки функций. Возможно нет, evalFTW

zF¢+ë+*-÷e%^Ṡze↔

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

Как?

  ¢+ë+*-÷e%^         The infinite list [+,*,-,÷,%,^,+,*,-,...
    ë+*-÷            The list [+,*,-,÷]
         e%^         The list [%,^]
   +                 Concatenated
  ¢                  Then repeated infinitely
               ↔     The input reversed e.g [9,8,7,6,5,4,3,2,1]
            Ṡze      Zipped with itself     [[9,1],[8,2],[7,3],[6,4],[5,5],[4,6],[3,7],[2,8],[1,9]]
zF                   Zipwith reduce, the list of functions and the list of lists.
                     [F+[9,1],F*[8,2],F-[7,3],F÷[6,4],F%[5,5],F^[4,6],F+[3,7],F*[2,8],F-[1,9]]
                     [10     ,16     ,-4     ,0      ,0      ,1296   ,10     ,16     ,8      ]

Альтернативное 17-байтовое решение:

ṠozIzI¢+ë+*-÷e%^↔

Из любопытства, почему ты не можешь этого сделать ë+*-÷%^? Зачем делать eнеобходимое?
Caird Coneheringaahing

@cairdcoinheringaahing ëпринимает 4 аргумента, eпринимает 2. 2 аргумента не существует
H.PWiz

3

05AB1E , 18 байт

Â"+*-÷%m"Ig×)øε`.V

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

объяснение

                    # push a reversed copy of the input
 "+*-÷%m"            # push the list of operators
         Ig×         # repeat it input times
            )ø       # zip together
              ε      # apply to each triplet
               `     # push separately to stack
                .V   # evaluate

Ig∍если вы хотите использовать команду "newish" (здесь не очень много ).
Волшебная Урна Осьминога

3

Утилиты Bash + GNU, 53

tac $1|paste -d, $1 -|tr ',
' '
;'|paste -sd+*-/%^|bc

Этот скрипт принимает имя файла в качестве параметра командной строки.

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

Приятно то, что здесь можно paste -dуказать список разделителей, которые используются циклически. Остальное это просто получение ввода в правильном формате, чтобы сделать это.


Не удалось в последнем тестовом случае :( tio.run/…
Shaggy


3

Желе , 15 байт

żṚj"“+×_:%*”ṁ$V

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

Как?

żṚj"“+×_:%*”ṁ$V - Link: list of numbers, a       e.g. [5, 3, 6, 1, 1]
 Ṛ              - reverse a                           [1, 1, 6, 3, 5]
ż               - interleave                          [[5,1],[3,1],[6,6],[1,3],[1,5]
             $  - last two links as a monad:
    “+×_:%*”    -   literal list of characters        ['+','×','_',':','%','*']
            ṁ   -   mould like a                      ['+','×','_',':','%']
   "            - zip with the dyad:
  j             -   join                              ["5+1","3×1","6_6","1:3","1%5"]
              V - evaluate as Jelly code (vectorises) [6, 3, 0, 0, 1]

Сохраните пару байтов сż“+×_:%*”;"ṚV
Эрик Outgolfer

@EriktheOutgolfer, который работает только в том случае, если длина входных данных ровно 6. Я думаю, вам нужно сделать это, ż“+×_:%*”ṁ$;"ṚVчто также составляет 15 байтов.
Джонатан Аллан

хорошо, о чем я думал ... я так скучаю по "галстуку" :(
Эрик Outgolfer


2

JavaScript (ES7), 68 67 байт

a=>[...a].map((v,i)=>(x=a.pop(),o='+*-/%'[i%6])?eval(v+o+x)|0:v**x)


Отличное решение! Возможно, вы можете переместить присваивание oвнутри скобок, .pop()чтобы сэкономить несколько байтов.
Люк

@Luke Присвоение oтакже используется как условие троичного оператора. Это сломало бы эту схему.
Arnauld

@Shaggy. Это был точно такой же первый ответ Арно.

@ThePirateBay: Ах. На мобильном телефоне SE, поэтому не может видеть истории редактирования.
Лохматый

2

Perl 6 ,67 66 байт

Сохранено 1 байт благодаря @nwellnhof.

{map {EVAL ".[0] {<+ * - div % **>[$++%6]} .[1]"},zip $_,.reverse}

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

Очень невообразимое (и, вероятно, плохое) решение. Zips аргумент с собой поменялся местами. Полученный список затем сопоставляется с блоком, в котором EVALнаходится строка a (operator) b. Оператор выбирается из списка строк, <+ * - div % **>используя переменную free state(например, staticC - значение сохраняется в вызовах блока) $. Он создается для каждого блока в отдельности и устанавливается на 0. Вы можете делать с ним все, что вам нравится, но вы можете ссылаться на него только один раз ( $фактически, каждый случай обращения к другой переменной). Так $++%6что на самом деле это 0 во время первого звонка, 1 во время второго, ... 5 во время 6-го, 0 во время 7-го и так далее.

Я сначала пытался обойтись без EVAL. Операторы на самом деле просто подпрограммы (= функции), но их имена настолько ужасны ( &infix:<+>и так далее), что мне пришлось отказаться от такого подхода.


map {EVAL ".[0] ... .[1]"},zip $_,.reverseна 1 байт короче.
nwellnhof

@nwellnhof, спасибо!
Ramillies

2

Haskell , 74 117 105 байт

x#y=fromIntegral.floor$x/y
x%y=x-x#y
f u=[o a b|(o,a,b)<-zip3(cycle[(+),(*),(-),(#),(%),(**)])u(reverse u)]

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

Сохранено 12 байт благодаря @nimi

Конечно, есть лучший способ добиться этого.

РЕДАКТИРОВАТЬ 1. Исправлена ​​экспонента для целых чисел; 2. Определенно есть лучший способ, см. Комментарий ниже: 95 91 байт

x#y=fromIntegral.floor$x/y
x%y=x-x#y
f=zipWith3($)(cycle[(+),(*),(-),(#),(%),(**)])<*>reverse

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


zipWith3($)(cycle[(+),(*),(-),div,mod,(^)])<*>reverseКороче, сейчас удалена твоя версия.
H.PWiz

@ H.PWiz Я искал что-то подобное, но у меня не было времени искать дальше. Почему вы удалили это? Я полагаю, что не запрещено иметь два разных решения на одном языке, особенно когда одно намного лучше, чем другое ...
jferard

@ H.PWiz Фиксированная экспонента.
jferard

Нет необходимости hв вызове o: o a bи без этого вы можете встроить h( TIO ).
Ними


1

J, 44 42 байта

Вычеркнул 44, Яда Яда ...

-2 байта благодаря @ ConorO'Brien

_2+/`(*/)`(-/)`(<.@%/)`(|~/)`(^/)\[:,],.|.

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

Так много паренов и вставок ... Конечно, есть лучший способ сделать это (возможно, используя вставку, а не инфикс?)

объяснение

_2(+/)`(*/)`(-/)`(<.@%/)`(|~/)`(^/)\[:,],.|.  Input: a
                                       ],.|.  Join a with reverse(a)
                                      ,       Ravel (zip a with reverse(a))
_2                                 \          To non-overlapping intervals of 2
  (+/)`(*/)`(-/)`(<.@%/)`(|~/)`(^/)           Apply the cyclic gerund
   +/                                           Insert addition
        */                                      Insert subtraction
             -/                                 Insert division 
                  <.@%/                         Insert integer division
                          |~/                   Insert mod
                                ^/              Insert exponentiation

Некоторые заметки:

У J нет целочисленного деления, поэтому мы составляем- %деление с >.-floor. J's mod ( |) выполняет порядок, обратный тому, что мы ожидали, поэтому мы должны инвертировать его порядок с помощью ~-reflexive.

Несмотря на то, что мы перемещаемся с интервалами в 2, мы должны использовать /-insert, чтобы вставить глаголы, чтобы их можно было использовать двоично, поскольку именно \так работает -infix.


Я также хотел бы знать, как избежать всего этого ()и повторить /- я не смог понять это ...
Иона

@Jonah, лучшее, что я могу придумать, это что-то вроде /обращенного массива (так как он работает в обратном направлении ...) с глаголами вроде, (,+)`(,*)но это не очень помогает ... (также это не работает)
Коул

1
Gerund может быть+/`(*/)`...
Конор О'Брайен

1

Рубин , 63 57 байт

->a{t=0;a.map{|x|eval [x,a[t-=1]]*%w(** % / - * +)[t%6]}}

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

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


1

к , 40 байт

{_((#x)#(+;*;-;%;{y!x};{*/y#x})).'x,'|x}

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

{                                      } /function(x)
                                     |x  /reverse x
                                  x,'    /zip concat with x
        ( ; ; ; ;     ;       )          /list of operations
         + * - %                         /add, mult, sub, div
                 {y!x}                   /mod (arguments need to be reversed)
                       {*/y#x}           /pow (repeat and fold multiply)
  ((#x)#                       )         /resize operations to length of x
                                .'       /zip apply
 _                                       /floor result

1

MATL ,27 23 байта

-4 байта благодаря @LuisMendo

tP+1M*1M-IM&\w1M^v"@X@)

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

Объяснение:

tP         % duplicate and flip elements
+          % push array of sums (element-wise)
1M*        % push array of products (element-wise)
1M-        % push array of subtractions (element-wise)
IM&\w      % push array of divisions and modulo (element-wise)
1M^        % push array of power (element-wise)
v          % vertically concatenate all arrays
"@X@)    % push to stack values with the correct index based on operator
           % (implicit) convert to string and display


0

R , 74 байта

function(l)Map(Map,c(`+`, `*`, `-`, `%/%`, `%%`,`^`),l,rev(l))[1:sum(l|1)]

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

Это последний ответ, который я придумал. Возвращает список длины, length(l)где каждый элемент является списком, содержащим соответствующий элемент. Вроде дерьмо, но они все там. Если это неприемлемо, любой из них Mapможет быть заменен mapplyна +3 байта.

Поскольку все операторы R являются функциями (инфиксная нотация просто синтаксический сахар), я попытался выбрать один из списка; например, решение 94 байтов ниже.

Чтобы попытаться избавиться от цикла, я пытался sapply, но это работает только с одной функцией и списком ввода. Затем я вспомнил многомерную форму, mapplyкоторая принимает n-aryфункцию FUNи nпоследующие аргументы, применяя FUNк первому, второму, ..., элементам каждого из аргументов, перерабатывая при необходимости . Существует также функция-обёртка mapply, Mapкоторая «не пытается упростить результат» . Поскольку он на три байта короче, это хорошая возможность для игры в гольф.

Итак, я определил тройную функцию (как в 80-байтовом решении ниже), которая принимает функцию в качестве первого аргумента и применяет ее ко второму и третьему. Однако я понял, что Mapэто функция, которая берет функцию в качестве первого аргумента и применяет ее к последующим. Ухоженная!

Наконец, в конце мы устанавливаем подмножество, чтобы гарантировать, что мы возвращаем только первые length(l)значения.

R , 80 байт

function(l)Map(function(x,y,z)x(y,z),c(`+`, `*`, `-`, `%/%`, `%%`,`^`),l,rev(l))

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

Этот не работает, так как он возвращает 6 значений для списков, содержащих менее 6 элементов.

R , 94 байта

function(l){for(i in 1:sum(l|1))T[i]=switch(i%%6+1,`^`,`+`,`*`,`-`,`%/%`,`%%`)(l,rev(l))[i]
T}

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

Объяснение (мягко не одураченное):

function(l){
 for(i in 1:length(l)){
  fun <- switch(i%%6+1,`^`,`+`,`*`,`-`,`%/%`,`%%`) # select a function
  res <- fun(l,rev(l))                             # apply to l and its reverse
  T[i] <- res[i]                                   # get the i'th thing in the result
 }
 T                                                 # return the values
}

Поскольку каждая из функций векторизована, мы можем индексировать в конце ( res[i]). Это лучше, чем evalподход ниже.

R , 100 байт

function(l)eval(parse(t=paste("c(",paste(l,c("+","*","-","%/%","%%","^"),rev(l),collapse=","),")")))

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

Это самый короткий evalподход, который я мог найти; потому что мы должны собрать результаты в один вектор, нам нужно pasteчерез c( )вокруг всех выражений, который добавляет массу ненужных байтов


0

Casio-Basic, 108 байт

{x+y,x*y,x-y,int(x/y),x-int(x/y)y,x^y}⇒o
dim(l)⇒e
Print seq(o[i-int(i/6)6+1]|{x=l[i+1],y=l[e-i]},i,0,e-1)

Это было больно. Особенно потому, что mod(x,y)возвращается, xкогда это действительно не должно, что означало, что я должен был сделать свою собственную функцию мода: следовательно x-int(x/y)y.

Циклы iот 0 до length(l)-1, принимая последовательные элементы в oсписке и применяя l[i]для xи l[-i]для y. (отрицательные индексы не работают, поэтому вместо этого я вычитаю iдлину списка и беру этот индекс.)

107 байт для функции, +1 байт для добавления lв поле параметров.


0

Java 8, 336 байт

import java.math.*;a->{int b[]=a.clone(),i=0,l=b.length,s,t;for(;i<l/2;b[i]=b[l+~i],b[l+~i++]=t)t=b[i];BigInteger r[]=new BigInteger[l],u,v;for(i=-1;++i<l;t=b[i],v=new BigInteger(t+""),r[i]=(s=i%6)<1?u.add(v):s<2?u.multiply(v):s<3?u.subtract(v):s<4?u.divide(v):s<5?u.remainder(v):t<0?u.ZERO:u.pow(t))u=new BigInteger(a[i]+"");return r;}

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

Вздох ..
Вход как int[], вывод как java.math.BigInteger[].

Без правила « Чтобы охватить угловые случаи, ввод никогда не будет содержать 0, но может содержать любое другое целое число в диапазоне от отрицательной бесконечности до положительной бесконечности. », Используя целые числа в диапазоне -2147483648до 2147483647, это будет 186 байт (вход as int[], и нет выходных данных, потому что он изменяет этот массив ввода вместо сохранения байтов):

a->{int b[]=a.clone(),i=0,l=b.length,t,u,v;for(;i<l/2;b[i]=b[l+~i],b[l+~i++]=t)t=b[i];for(i=-1;++i<l;v=b[i],a[i]=(t=i%6)<1?u+v:t<2?u*v:t<3?u-v:t<4?u/v:t<5?u%v:(int)Math.pow(u,v))u=a[i];}

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

Объяснение:

import java.math.*;            // Required import for BigInteger

a->{                           // Method with int[] parameter and BigInteger[] return-type
  int b[]=a.clone(),           //  Make a copy of the input-array
      i=0,                     //  Index-integer
      l=b.length,              //  Length of the input
      s,t;                     //  Temp integers
  for(;i<l/2;b[i]=b[l+~i],b[l+~i++]=t)t=b[i];
                               //  Reverse the input-array and store it in `b`
  BigInteger r[]=new BigInteger[l],
                               //  Result-array
             u,v;              //  Temp BigIntegers
  for(i=-1;                    //  Reset `i` to -1
      ++i<l;                   //  Loop over the array(s):
                               //    After every iteration:
      t=b[i],                  //     Set the current item of `b` in `t`
      v=new BigInteger(t+""),  //     And also set it in `v` as BigInteger
      r[i]=(s=i%6)<1?          //   If the index `i` modulo-6 is 0:
            u.add(v)           //    Add the items with each other
           :s<2?               //   Else-if index `i` modulo-6 is 1:
            u.multiply(v)      //    Multiply the items with each other
           :s<3?               //   Else-if index `i` modulo-6 is 2:
            u.subtract(v)      //    Subtract the items with each other
           :s<4?               //   Else-if index `i` modulo-6 is 3:
            u.divide(v)        //    Divide the items with each other
           :s<5?               //   Else-if index `i` modulo-6 is 4:
            u.remainder(v)     //    Use modulo for the items
           :                   //   Else (index `i` modulo-6 is 5):
            t<0?               //    If `t` is negative:
             u.ZERO            //     Simply use 0
            :                  //    Else:
             u.pow(t))         //     Use the power of the items
    u=new BigInteger(a[i]+""); //  Set the current item of `a` to `u` as BigInteger
                               //  End of loop (implicit / single-line body)
  return r;                    //  Return the result BigInteger-array
}                              // End of method
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.