Арифметичні прогресії


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} $ го (в основному $ a (n + 1) - a (n) $, де aфункція для послідовності). Ця різниця залишається однаковою для будь-якого значення $ n $ в AP. Якщо немає загальної різниці, то це не арифметична послідовність. Щоб обчислити значення n-го терміна, використовуйте цю формулу $ a (n) = a (1) + (n-1) d $, де $ a (1) $ - перший член, а $ d $ - загальний різниця.

Якщо це не арифметична прогресія, то програма повинна надрукувати повідомлення про помилку "NAAP" (скорочення "Не арифметична прогресія").

Якщо це є арифметичною прогресією, то програма повинна надрукувати спрощену п-й член послідовності до STDOUT.

Приклад:

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

Пояснення: Це AP, оскільки існує загальна різниця ($ 3 - 1 = 2 $). Тоді ви використовуєте формулу $ a (n) = a (1) + (n-1) d $

ан=а1+(н-1)г

ан=1+(н-1)2

ан=1+2н-2

ан=2н-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
Ви, ймовірно, повинні зберігати свою посаду в пісочниці більше години ...
Mego

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. Потрійний перевіряє, чи є в результаті ( ?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 перетворення числа в рядок, для цього використовується вихід на графічному екрані ( 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

Матлаб, 103 байти

x=str2num(input('','s'));y=diff(x);if range(y) disp('NAAP'),else fprintf('%gn%+g\n',y(1),x(1)-y(1)),end

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 байт

EDIT: Не заперечуйте різницю

EDIT: використовувати анонімні підпункти, логічні оператори та інтерполяцію рядків. Дякую Бреду Гілберту b2gills

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

Тестова програма (читається з stdin):

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"}

Безголівки:

-> 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.