Розрахунок відстаней мод N


13

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

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

Виклик

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

Зміна між кожною парою чисел завжди меншаN/2 , тому для кожного тестового випадку буде лише одна дійсна відповідь.

Вам буде введено ціле число N> 2 та список значень у форматі на ваш вибір. Введення може бути надано через STDIN або аргументи командного рядка або функції.

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

Правила

  • Ваша програма повинна працювати на будь-яку відстань і модуль менше, ніж 2^20.
  • Ви можете припустити, що:
    • Nпринаймні 3.
    • Список має щонайменше 2 значення.
    • Усі значення у списку принаймні 0 та менше N.
    • Усі зміни чисел менше, ніж N/2.
  • Все інше недійсне введення, і ваша програма може робити все, що завгодно.
  • Стандартні лазівки, будь-які нестандартні бібліотеки та вбудовані функції для цієї мети заборонені.
  • Це , тому виграє найкоротша програма в байтах.

Приклади тестових випадків

Вхід:

3
0 1 2 2 0 1 0 2 1 2 0 1 2 1 1

Вихід:

4

Пояснення (із прикладом значення):

Value mod 3: 0 1 2 2 0 1 0 2 1 2 0 1 2 1 1
Value:       0 1 2 2 3 4 3 2 1 2 3 4 5 4 4

Вхід:

10
5 2 8 9 5

Вихід:

-10

Пояснення (із прикладом значення):

Value mod 10:  5  2  8  9  5
Value:        15 12  8  9  5

Недійсні входи:

2
0 0 0 0 0

(занадто малий модуль)

6
2 5 4 2

(занадто велика зміна між 2 і 5)


Формат на ваш вибір - слизький схил. Чи може моє рішення GolfScript розраховувати на такий список вхідних даних :^;[5 2 8 9 5](\ ?
Лін

3
@Mauris Як правило, ні ... "формат на ваш вибір", як правило, означає "звичайне представлення на вашій мові вибору".
Мартін Ендер

Однак ви можете розраховувати на список входів, який виглядає як "10 5 2 8 9 5" або "10,5 2 8 9 5" або "10 5,2,8,9,5".
Спарр

Відповіді:


2

TI-BASIC, 15 байт

Input N
sum(N/πtan⁻¹(tan(ΔList(πAns/N

Бере список від Ansта модуль від Input.

                       πAns/N    ; Normalize the list to [0,π)
                 ΔList(          ; Take differences, which are in the range (-π,π)
       tan⁻¹(tan(                ; Modulo, but shorter. Now elements are in (-π/2,π/2)
    N/π                          ; Multiply by N/π. These are displacements at each step.
sum(                             ; Add up all the displacements

9

Python 2, 53 байти

lambda n,l:sum((b-a+n/2)%n-n/2for a,b in zip(l,l[1:]))

Супер пряма відповідь вперед. Цікаво, чи існує коротший шлях.


Я пропустив цей шматочок. Спасибі.
Лін

@Jakube Я вже це робив - я не знав, .:_2щоб генерувати пари, поки не побачив вашу відповідь - я використовував zip.
orlp

1
@Jakube Я отримав це до 19 :)
orlp

7

Математика, 30 байт

Tr@Mod[Differences@#2,#,-#/2]&

Це анонімна функція, яка бере два аргументи. Приклад використання:

Tr@Mod[Differences@#2,#,-#/2]&[3, {0, 1, 2, 2, 0, 1, 0, 2, 1, 2, 0, 1, 2, 1, 1}]
(* 4 *)
Tr@Mod[Differences@#2,#,-#/2]&[10, {5, 2, 8, 9, 5}]
(* -10 *)

Це працює шлях прийняття Differencesміж послідовними елементами, упаковка їх в діапазон , -n/2щоб +n/2з Modі його зміщення параметра, а потім приймає спільне з Tr(слід матриці, сума діагональних елементів).


Зауважте, що навіть у безгольових це лише 43 байти!

f[n_, l_] := Total[Mod[Differences[l], n, -n/2]]

@непотрібно, коли ви вже викликаєте функцію квадратними дужками. Наявність обох - синтаксична помилка.
Девід Чжан

@DavidZhang Уотс, не знаю, про що я думав. Служить мені правильним, намагаючись відповісти, не відкриваючи Mathematica!
2012р. Кемпіон


4

Pyth, 20 19 байт

sm-J/Q2%+-FdJQ.:vw2

Вкрав .:_2з Jakube, ідеї від Mauris.


3

R, 38 байт

function(n,v)sum((diff(v)+n/2)%%n-n/2)

Це створює неназвану функцію, яка приймає ціле число та вектор як вхідні дані та повертає одне ціле число. Щоб зателефонувати, дайте ім’я, наприклад f=function(n,v)....

Недоліковані + пояснення:

f <- function(n, v) {
    # Compute the differences between sequential elements of v
    d <- diff(v)

    # Add n/2 to the differences and get the result modulo n
    m <- (d + n/2) %% n

    # Subtract n/2 then sum the vector
    sum(m - n/2)
}

Приклади:

> f(3, c(0, 1, 2, 2, 0, 1, 0, 2, 1, 2, 0, 1, 2, 1, 1))
[1] 4

> f(10, c(5, 2, 8, 9, 5))
[1] -10

3

MatLab, 33 байти

@(x,y)sum(mod(diff(y)+x/2,x)-x/2)

Вибачте, це моя перша відповідь на цьому веб-сайті. Ввівши це в MatLab, тоді за допомогою введення ans(modulus_value, [intermediate_values])повернеться запитуване значення, де 'modulus_value' - це значення модуля, а 'intermediate_values' - список проміжних значень, розділених або пробілами, або комами.

Приклад:

ans(3, [0 1 2 2 0 1 0 2 1 2 0 1 2 1 1])

Анонімна функція має перевагу від Matlab mod, diffі sumфункції для обчислення відповіді. Спочатку обчислюється різниця між кожним з проміжних значень. Потім результат компенсується модулем, розділеним на два, в результаті чого набір значень різниці пов'язаний з [-модулем / 2 модулем / 2]. Потім результат компенсується та підсумовується знову.

Я думаю, що це може бути більше гольфу, я незабаром повернусь із оновленням. Особлива подяка @ 2012rcampion за ідею.

Редагувати:unwrap Функція Matlab майже працює тут, але це важко для гольфу. Наступний код повертає масив, де останнє значення - це сума, яку змінило перше значення: @(x,y)unwrap(y/x*2*pi)/2/pi*x-y(1)

Проміжні значення масштабуються до діапазону [-pi pi], потім "розгортаються" таким чином, що жодне послідовне значення не перевищує pi один від одного. Ці значення потім повторно масштабуються та зміщуються, що призводить до масиву відстаней від вихідного значення.

Цікавий, але не дуже практичний для цього виклик: D


2

Pyth, 29 байт

+sm**._K-Fdvz>y.aKvz.:Q2-eQhQ

Спробуйте в Інтернеті: компілятор / виконавець Pyth


Введення розділено пробілом, а не розділене комами; ваша програма, схоже, не справляється з цим.
Лінн

2
@Mauris "список значень у форматі на ваш вибір"
Jakube

Ой, мій поганий! Я повністю пропустив цю частину специфікації.
Лін


2

Піп , 39 байт

Qn$+({a>n/2?a-na<-n/2?a+na}Mg@>1-g@<-1)

Потрібен список даних як аргументи командного рядка та модуль на STDIN. Якщо це занадто велике розтягнення, у мене є версія, яка займає два аргументи командного рядка на 5 байт більше.

Пояснення:

                                         g is list of cmdline args (implicit)
Qn                                       Read n from stdin
                            g@>1         All but the first of the cmdline args
                                -g@<-1   ...minus all but the last of the cmdline args
                                         (i.e. a list of the differences of adjacent items)
     {                    }M             ...to which, map the following function:
      a>n/2?a-n                            If diff is too big, subtract n;
               a<-n/2?a+n                  else if too small, add n;
                         a                 else return unchanged
  $+(                                 )  Sum; print (implicit)

І лише щоб довести, що цей не дуже конкурентоспроможний бал більше відображає мої навички гри в гольф, ніж мою мову, ось порт Маріса Python в 30 байтах :

Qn$+({(n/2-$-a)%n-n/2}MgZg@>1)

2

Желе , не конкуруючий

6 байт Ця відповідь є неконкурентоспроможною, оскільки виклик передує створенню желе.

Iæ%H}S

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

Як це працює

Iæ%H}S    Main link. Left input: A (list). Right input: N (integer).

I         Compute the increments (deltas of consecutive elements) of A.
   H}     Halve the right input (N).
 æ%       Mod the increments into (-N/2, N/2].
     S    Take the sum of all results.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.