Арифметические прогрессии


11

Ваша задача состоит в том, чтобы проанализировать ввод и вывод формулы для n-го члена, если это арифметическая последовательность, в противном случае она должна вывести «NAAP».


вход

Ввод (из STDIN) будет состоять из нескольких чисел, от 4 до 10 чисел, где каждое число будет в диапазоне от -1000 до 1000 включительно, разделенных разделителем (пробел, запятая или точка с запятой [в зависимости от того, что ваши предпочтения]). Вот несколько примеров ввода.

12,14,16,18       //valid
-3 4 5 1 -2 -4    //valid
45;35;-35         //invalid (only three numbers are present instead of the minimum of 4 numbers)
2,32;21,321       //invalid (it uses two different delimiters: `,` and `;`)

Выход

Программа должна сначала проверить, является ли ввод арифметической прогрессией или нет.

Арифметические прогрессии (AP) в двух словах: у каждого AP будет общая разница. В этом разница между $ n $ и $ {n-1} $ th членами (в основном $ a (n + 1) - a (n) $ где a- функция для последовательности). Эта разница остается неизменной для любого значения $ n $ в точке доступа. Если нет общей разницы, то это не арифметическая последовательность. Чтобы вычислить значение n-го члена, используйте эту формулу $ a (n) = a (1) + (n-1) d $, где $ a (1) $ - первое слагаемое, а $ d $ - общее разница.

Если это не арифметическая прогрессия, то программа должна напечатать сообщение об ошибке «NAAP» (сокращение от «Not An Arithmetic Progression»).

Если это является арифметической прогрессией, то программа должна напечатать упрощенную п-й член последовательности к STDOUT.

Пример:

> 1,3,5,7,9
2n-1

Пояснение: Это AP, потому что есть общая разница ($ 3 - 1 = 2 $). Тогда вы используете формулу $ a (n) = a (1) + (n-1) d $

aNзнак равноa1+(N-1)d

aNзнак равно1+(N-1)2

aNзнак равно1+2N-2

aNзнак равно2N-1

Поэтому вывод есть 2n-1(обратите внимание на отсутствие пробелов)


Стандартные лазейки по умолчанию запрещены.

Вы можете создать функцию, если хотите (с массивом чисел в качестве параметра). Если нет, то вы должны создать полную программу, которая принимает входные данные в виде строки или массива и выводит соответственно.

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

1.

1,3,5,7,9
2n-1

2.

1 3 12312 7 9
NAAP

3.

-6;8;22;36;50
14n-20

4.

5,1,-3,-7,-11,-15
-4n+9

5.

-5,-7,-9,-11,-13,-15
-2n-3

6.

3,3,3,3,3,3,3,3,3
0n+3

7.

-4,-5,-6,-7
-1n-3

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

Любые предложения приветствуются!


4
Вы, вероятно, должны держать свой пост в песочнице более часа ...
Мего

3
Один час - действительно короткое время. Не все проверяют песочницу постоянно. 24 часа - это хороший минимум.
Мего

8
Извините, но хотя MathJax работает на Meta, он не работает на основном сайте PPCG ...
ETHproductions

1
Вы должны добавить тестовые случаи с убывающими последовательностями.
lirtosiast

2
Есть 0,0,0,0и 3,1,-1,-3,-5арифметические прогрессии? Если так, то я думаю, что они были бы хорошими тестовыми примерами, поскольку они нарушили метод, который я пробовал.
xnor

Ответы:


5

Pyth, 30 байт

?tJ{-VtQQ"NAAP"+hJ%"n%+d"-hQhJ

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

Чтобы проверить, является ли это арифметическим процессом, используется векторизованное вычитание между каждым элементом и предыдущим -VtQQ. Троичный проверяет наличие нескольких значений в result ( ?tJ{) и печатает, NAAPесли так. Затем, чтобы получить +или -правильно, используется форматирование %+d.


3

Haskell, 103 байта

z=(tail>>=).zipWith
f l@(a:b:_:_:_)|and$z(==)$z(-)l=show(b-a)++'n':['+'|b-a<=a]++show(a+a-b)
f _="NAAP"

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

f [-6,8,22,36,50]   ->   "14n-20"
f [60,70,80,90]     ->   "10n+50"
f [2,3,4,6,7,8]     ->   "NAAP"

Как всегда в Haskell, необычное форматирование вывода (например, смешивание чисел со строками) потребляет много байтов (около 40). Логика программы довольно компактна:

f l@(a:b:_:_:_)           -- pattern match an input list with at least 4 elements,
                          -- call the whole list l, the first two elements a and b
z=(tail>>=).zipWith       -- the helper function z takes a function f and a list l
                          -- and applies f element wise to the tail of l and l

           z(-)l          -- make a list of neighbor differences
     z(==)                -- then compare these differences for equality
 and                      -- and see if only True values occur

       show ...           -- if so format output string

f _="NAAP"                -- in all other cases ( < 4 elements or False values)
                          -- return "NAAP"

2

TI-BASIC, 70 байтов

Input X
ΔList(∟X->Y
If variance(Ans
Then
∟X(1)-min(Ans
Text(0,0,min(∟Y),"n",sub("+-",(Ans<0)+1,1),abs(Ans
Else
"NAAP

Чтобы исправить отсутствие преобразования чисел в строку в TI-BASIC, используется вывод на graphscreen ( Text(), если последовательность является арифметической, которая автоматически объединяет аргументы вместе.

Это предполагает, что отрицательные числа вводятся с использованием символа высокого минуса TI-BASIC (который выглядит немного похоже ), а не двоичного знака минуса. Однако вывод использует двоичный знак минус.


2

Japt , 60 52 51 байт

V=N¤£X-NgY+1};W=Vg;Ve_¥W} ?W+'n+'+sU<W +(U-W :"NAAP

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

Ввод может быть сделан с любым разделителем, который вам нравится, так как именно так устроен переводчик;)

Неуправляемый и объяснение

V=N¤  £    X-NgY+1};W=Vg;Ve_  ¥ W} ?W+'n+'+sU<W +(U-W :"NAAP
V=Ns2 mXYZ{X-NgY+1};W=Vg;VeZ{Z==W} ?W+'n+'+sU<W +(U-W :"NAAP

            // Implicit: N = list of inputs, U = first input
V=Ns2       // Set variable V to N, with the first 2 items sliced off,
mXYZ{       // with each item X and index Y mapped to:
X-NgY+1}    //  X minus the item at index Y+1 in N.
            // This results in a list of the differences (but the first item is NaN).
W=Vg;       // Set W to the first item in V (the multiplication part).
VeZ{Z==W}   // Check if every item in V is equal to W.
?W+'n+      // If true, return W + "n" +
'+sU<W      //  "+".slice(U<W) (this is "+" if U >= W, and "" otherwise)
+(U-W       //  + (U minus W [the addition part]).
:"NAAP      // Otherwise, return "NAAP".
            // Implicit: output last expression


1

CJam, 38 байт

{:T2ew::-):U-"NAAP"UW*"n%+d"T0=U+e%+?}

Это анонимная функция, которая принимает массив в стеке в качестве входных данных и оставляет строку в стеке в качестве выходных данных. Попробуйте онлайн с дополнительным кодом ввода / вывода для тестирования.

Объяснение:

:T      Save a copy of input in variable T for output generation.
2ew     Generate list of pairs of sequential elements.
::-     Reduce all pairs with subtraction operator.
)       Pop last value from list of differences.
:U      Save difference value in variable U for output generation.
-       Set difference. This will leave an empty list (falsy) if all values are the same.
"NAAP"  First value for ternary operator, for case where not all values are the same.
UW*     Start generating output for success case. Need to flip sign of difference saved
        in variable U, since it was 1st value minus 2nd, and we need the opposite.
"n%+d"  Push format string for printf operator. The + sign in the format specifies that
        the sign is always generated, saving us from needing different cases for the
        value being negative or positive.
T0=     Extract first value from original input saved in variable T.
U+      Add the difference (with the "wrong" sign) to it.
e%      "printf" operator.
+       Concatenate two parts of result.
?       Ternary operator for picking one of the two output cases.

1

JavaScript (ES6), 91 байт

x=>(s=x.split`,`,m=s[1]-s[0],a=s[0]-m,s.some((n,i)=>n!=m*i+m+a)?"NAAP":m+"n"+(a<0?a:"+"+a))

объяснение

x=>(
  s=x.split`,`,       // s = array of input numbers
  m=s[1]-s[0],        // m = the multiplication part of the formula
  a=s[0]-m,           // a = the addition part of the formula
  s.some((n,i)=>      // check if the rest of the numbers follow this sequence
    n!=m*i+m+a
  )?"NAAP":
  m+"n"+(a<0?a:"+"+a) // output the formula
)

Тест

<input type="text" id="input" value="5,1,-3,-7,-11,-15" /><button onclick='result.innerHTML=(

x=>(s=x.split`,`,m=s[1]-s[0],a=s[0]-m,s.some((n,i)=>n!=m*i+m+a)?"NAAP":m+"n"+(a<0?a:"+"+a))

)(input.value)'>Go</button><pre id="result"></pre>


1

Perl 6, 123 102 101 байт

РЕДАКТИРОВАТЬ: не отрицать разницу

РЕДАКТИРОВАТЬ: использовать анонимные суб, логические операторы и интерполяцию строк. Спасибо Брэд Гилберт b2gills

sub{my@b=@_.rotor(2=>-1).map({[-] $_}).squish;$_=@_[0]+@b[0];@b.end&&"NAAP"||"@b[0]n{'+'x($_>=0)}$_"}

Тестовая программа (читает со стандартного ввода):

my $f = <the code above>
$f(split(/<[;,]>/, slurp)).say

Объяснение:

my @b =
  @_.rotor(2=>-1)  # sliding window of 2: (1,2,3,4) => ((1,2),(2,3),(3,4))
  .map({[-] $_})  # calculate difference (subtract all elements and negate)
  .squish;         # remove adjacent elements that are equal

@b.end        # @b.end is last index, @b.end = 0 means @b has only 1 element
&& "NAAP"     # true branch
|| "@b[0]n{'+'x($_>=0)}$_" # string for an+b, 
        # {'+'x($_>=0)} inserts a plus sign using the repetition operator x

Обычно вы используете одну из форм лямбда-выражения, чтобы вы могли удалить sub f. Также, если бы вы использовали @_вместо @aвас, вы бы сохранили несколько байтов. {my@b=@_.rotor..., Кроме того, вы не должны ставить скобки вокруг условия ifоператора, это не Perl 5. Если вы измените это ifзначение, @b.end&&"NAAP"||$_=...вы сэкономите еще несколько байтов. Вы также можете покончить с последним ifоператором, если используете "@b[0]n{'+'x($_>=0)}$_"вместо этого, сохранив 4 байта.
Брэд Гилберт b2gills

Вам не нужно subв начале, без этого он становится анонимным блоком. Кроме того, чтобы вы знали, я бы не подумал об использовании, которое .map({[-] $_})я, вероятно, использовал бы ».map(*-*).flatдольше, теперь я должен просмотреть свои собственные записи, чтобы посмотреть, смогу ли я сократить его с помощью вашего трюка.
Брэд Гилберт b2gills

1

Рубин, 95 78 76 байт

->s{i,j=s;puts s.reduce(:+)==s.size*(s[-1]+i)/2?"%dn%+d"%[v=j-i,i-v]:"NAAP"}

78 байт

->s{puts s.reduce(:+)==s.size*(s[-1]+i=s[0])/2?"%dn%+d"%[v=s[1]-i,i-v]:"NAAP"}

95 байт

->s{puts s.reduce(:+)==s.size*(s[0]+s[-1])/2?"#{v=s[1]-s[0]}n#{"+"if (i=s[0]-v)>0}#{i}":"NAAP"}

Ungolfed:

-> s {
  i,j=s
  puts s.reduce(:+)==s.size*(s[-1]+i)/2?"%dn%+d"%[v=j-i,i-v]:"NAAP"
}

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

->s{i,j=s;puts s.reduce(:+)==s.size*(s[-1]+i)/2?"%dn%+d"%[v=j-i,i-v]:"NAAP"}[[-6,8,22,36,50]]

=> 14n-20

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