Отримайте етапи послідовності


17

Виклик

Давши послідовність чисел, створіть функцію, яка повертає етапи послідовності.

  • Припустимо, послідовність буде N >= 3
  • Послідовність повторить його дії хоча б раз
  • Послідовність міститиме лише натуральні числа
  • Ваша функція або програма повинна повернути найкоротшу можливу послідовність кроків

Приклад:

Вхід: [1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17]

Вихід: [1, 1, 2]

Пояснення: Початкова послідовність йде від 1 => 2 (1 step), 2 => 3 (1 step), 3 => 5 (2 steps). Потім це повторюється. Вихід тоді є[1 step, 1 step, 2 steps] => [1, 1, 2]

Ще один приклад:

Вхід: [2, 5, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19, 20]

Вихід: [3, 1, 1, 1]

[2, 5, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19, 20]
 \  /\ /\ /\ / 
  3   1  1  1  Then it repeats...

Випробування

Input: [1, 4, 8, 9, 10, 13, 17, 18, 19, 22, 26, 27, 28] => Output: [3,4,1,1]

Input: [6, 11, 13, 18, 20, 25, 27, 32, 34, 39, 41] => Output: [5,2]

Input: [2, 6, 10, 13, 17, 21, 25, 28, 32, 36, 40, 43, 47] => Output: [4,4,3,4]

Input: [5, 6, 7] => Output: [1]


Роз'яснення

  • Довжина вводу - 1 ділиться на довжину виходу
  • Припустимо, послідовність завжди буде зростати

Це , тому найкоротша відповідь у байтах виграє.



6
Я бачив кілька викликів, які ви опублікували нещодавно, з великою кількістю уточнюючих коментарів, і пару закрили як "незрозумілі", а згодом знову відкрили після того, як ви внесли відповідні зміни. Чи розглядали ви розміщувати їх у пісочниці кілька днів / тиждень? Мені подобаються ваші виклики, оскільки вони цілком доступні, але всі виклики, незалежно від того, наскільки вони прості та ким вони розміщені, можуть використовувати уточнення.
Джузеппе

2
@Giuseppe Дякуємо за ваші пропозиції. Я розмістив деякі інші проблеми в пісочному ящику (зазвичай, якщо я не знайду правильний спосіб створити виклик з ним, я видаляю його). Для цих викликів я подумав, що вони досить чіткі, і тому я опублікував негайно, але спершу почну публікувати їх у пісочниці. Спасибі
Луїс феліпе Де ісус Муноз

2
@LuisMendo Єретик! 0 - натуральне число! У Біллі Джоеля був навіть цілий альбом, присвячений людині Peano!
ngm

1
@AdmBorkBork, це більше пов’язано з обробкою списків операцій довільної довжини.
Пітер Тейлор

Відповіді:


10

Желе , 9 7 байт

IsJEƇḢḢ

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

Як це працює

IsJEƇḢḢ  Main link. Argument: A (array)

I        Increment; compute D, the array of A's forward differences.
  J      Indices; yield [1, ..., len(A)].
 s       Split D into chunks of length k, for each k in [1, ..., len(A)].
   EƇ    Comb equal; keep only partitions of identical chunks.
     Ḣ   Head; extract the first matching parititon.
      Ḣ  Head; extract the first chunk.

9

JavaScript (ES6), 58 байт

Виводить рядок, розділений комою (з провідною комою).

a=>(a.map(p=x=>-(p-(p=x)))+'').match(/N((,\d+)*?)\1*$/)[1]

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

Або 56 байт, якщо ми використовуємо ,-як роздільник і вважаємо, що послідовність завжди суворо збільшується.

Як?

Спочатку перетворюємо вхідний масив a [] в список послідовних відмінностей за допомогою:

a.map(p = x => -(p - (p = x)))

Тому що p спочатку встановлений на НЕ-числове значення (функцію зворотного виклику відображення () ), перша ітерація дає NaN .

Приклад:

[6, 11, 13, 18, 20, 25, 27, 32, 34, 39, 41]
[ NaN, 5, 2, 5, 2, 5, 2, 5, 2, 5, 2 ]

Потім примушуємо результат до рядка:

"NaN,5,2,5,2,5,2,5,2,5,2"

Нарешті, шукаємо найкоротший 1 візерунок цілих чисел ( ,\d+), що починається відразу після "NaN" і повторюється до кінця рядка:

match(/N((,\d+)*?)\1*$/)

1: використання не жадібних *?


Я розміщую рішення, засноване на тій же ідеї регулярного виразів, але дуже різної в реалізації. Звичайно, я не дивився на інші рішення, перш ніж розробляти шахту, і це здається досить різним, і, можливо, це перший раз, коли мені вдається забити краще, ніж вам тут.
edc65

1
53 байт: /(,.+?)\1*$/.
Ніл

6

Брахілог , 11 байт

s₂ᶠ-ᵐṅᵐ~j₍t

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

Було б 5 байт, якби була вбудована послідовність відмінностей.

Пояснення

Example input: [6, 11, 13, 18, 20, 25, 27, 32, 34, 39, 41] 

s₂ᶠ             Find all substrings of length 2: [[6,11],[11,13],…,[34,39],[39,41]]
   -ᵐ           Map subtraction: [-5,-2,-5,-2,-5,-2,-5,-2,-5,-2]
     ṅᵐ         Map negate: [5,2,5,2,5,2,5,2,5,2]
       ~j₍      Anti-juxtapose the list of differences; the shortest repeated list is found
                  first, with the biggest number of repetitions: [5,[5,2]]
            t   Tail: [5,2]

Чи можете ви заперечити за хвіст, щоб зберегти байт?
Прут

@Rod Мені все-таки потрібно було б його відобразити, щоб воно було однакової довжини. Negate - це предикат між двома числами, він не векторизується автоматично для списків, як інші мови (інакше він не буде добре працювати з невідомими входами / виходами, які є загальними в декларативних програмах)
Fatalize

5

Pyth, 11 байт

<J.+Qf.<IJT

Спробуйте тут

Пояснення

<J.+Qf.<IJT
 J.+Q          Call the sequence of differences in the input J.
     f         Find the first positive integer T...
      .<IJT    ... where rotating J by T doesn't change it.
<J             Take that many elements of J.

5

Japt , 14 12 байт

äa
¯@eUéX}aÄ

Спробуй це


Пояснення

              :Implicit input of array U
äa            :Consecutive absolute differences
\n            :Reassign to U
 @    }aÄ     :Return the first positive integer X that returns true
   UéX        :  Rotate U right X times
  e           :  Check equality with U
¯             :Slice U to that element

Оригінал

äa
@eUîX}a@¯XÄ

Спробуй це


5

R , 49 46 байт

Повна програма:

d=diff(scan());while(any((s=d[1:T])-d))T=T+1;s

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

R , 72 58 54 байт

Оригінальне подання функції з усіма тестовими випадками в одному місці:

function(a,d=diff(a)){while(any((s=d[1:T])-d))T=T+1;s}

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

Дякую JayCe, що запропонував повний маршрут програми та -4 байти на функції, а Джузеппе - ще -3.



@JayCe не потрібно a<-тут або
Giuseppe

4

J , 22 19 байт

3 байти збережено завдяки FrownyFrog!

0{"1[:~./:|."{}.-}:

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

[Спробуйте в Інтернеті!] [TIO-ji2uiwla]

Як?

                 -      find the successive differences by subtracting 
                  }:    the list with last element dropped
               }.       from the list with the first element dropped 
           |."{         rotate the list of differences
         /:             0..length-1 times (the input graded up)
     [:~.               remove duplicating rows
 0{"1                   take the first element of each row

Якщо ви /:замість цього #\, ви можете 0{"1[:~.зберегти 1 байт.
FrownyFrog

І "0 1це"{
FrownyFrog

@FrownyFrog Дякую, ще раз!
Гален Іванов

1
це чудово.
Йона

@Jonah Так, дякую FrownyFrog!
Гален Іванов

4

05AB1E , 8 байт

Збережено 3 байти завдяки Kevin Cruijssen .

¥.œʒË}нн

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


05AB1E , 11 байт

āεI¥ô}ʒË}нн

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

āεI ¥ ô} ʒË} нн Повна програма.
ā Діапазон довжини. Натисніть [1 ... len (inp)].
 ε} Для кожного ...
  I ¥ ô ... Розбийте дельти на шматочки відповідного розміру
      ʒË} Зробіть рівними лише ті, у кого всі їх елементи.
         нн І спочатку витягніть перший елемент першого.

13 байт

Мила альтернатива, ІМО:

¥©ηʒDg®ôÙ˜Q}н

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

¥©ηʒDg®ôÙ˜Q}н   Full program.
¥               Push the deltas.
 ©              Copy them to the register.
  ηʒ       }    And filter the prefixes by...
    D     Q     ... Is the prefix itself equal to...
     g®ô        ... The deltas, split into chunks of its length...
        Ù˜      ... Deduplicated and flattened?
            н   Head.

1
8 байт з використанням.
Кевін Круїссен

3

Javascript, 49 56 байт

Редагуйте 7 байтів, збережених спасибі (здогадайтесь, хто?)

Та сама ідея регулярного вираження, що і Арнольд, але цікаво настільки інша в реалізації ...

Повернення рядка з кроками, розділеними комами (і провідною комою)

p=>/N(.+?)\1+$/.exec(p.map(p=v=>[v-p,p=v][0]))[1]

Тест

var F=
p=>/N(.+?)\1+$/.exec(p.map(p=v=>[v-p,p=v][0]))[1]

;[[1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17]
,[1, 4, 8, 9, 10, 13, 17, 18, 19, 22, 26, 27, 28]
,[6, 11, 13, 18, 20, 25, 27, 32, 34, 39, 41] 
,[2, 6, 10, 13, 17, 21, 25, 28, 32, 36, 40, 43, 47]
,[5, 6, 7]]
.forEach(x=>console.log(x + ' -> ' + F(x)))


Використання matchбуло моїм поганим рішенням. Ви можете перемогти мене ще трохи . :-)
Арнольд

3

MATL , 14 13 12 байт

dt5YLFTF#Xu)

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

Щойно виявив, що MATL має функцію циркуляції!

Пояснення

d - Отримайте відмінності між послідовними термінами, як масив

t5YL- дублювати це, а потім викликати функцію YL('галерея') за допомогою параметра 5('cirlantlant'). Створює матрицю з заданим вектором, як перший рядок, потім послідовні рядки - той самий вектор, зміщений круговим чином, поки він не завернеться.

FTF#Xu- Перевірте унікальні рядки та отримайте їхні рядки (не впевнені, чи існує коротший спосіб цього). Коли етапи послідовності повторюються, круговий зміщений рядок буде таким самим, як і перший ряд, а наступні рядки будуть повторюватися. Таким чином, це отримує показники першого запуску послідовних кроків, перш ніж вони почнуть повторюватися.

) - індекс, використовуючи це в початковому масиві відмінностей, щоб отримати відповідь.


Старіші:

d`tt@YS-a}@:)

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

(-1 байт завдяки Джузеппе)

Пояснення:

d   % Get the differences between successive terms, as an array
`   % Start do-while loop
  tt  % duplicate the difference array twice
  @   % push the current loop index value
  YS  % circularly shift the difference array by that amount
  -   % subtract the shifted diffs from the original diffs
  a   % see if the subtraction resulted in any non-zeros
    % if it did, shifted differences were not equal to original differences, so continue loop 
}@ % if it didn't, then get loop index
:) % get the differences upto the loop index, before they started repeating
   % implicit loop end

2

Python 2 , 101 байт

def f(l):d=[y-x for x,y in zip(l,l[1:])];g=len(l);print[d[:k]for k in range(1,g+1)if g/k*d[:k]==d][0]

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

Спочатку формується дельти d , потім знаходить перший префікс p of d, який при повторенні ⌊len (L) / len (p) ⌋ разів дає L , де L - вхідний список.



2

Java 10, 104 100 байт

a->{var t="";for(int i=a.length;i-->1;t+=a[i]-a[i-1]+" ");return t.replaceAll("( ?.+?)\\1*$","$1");}

Regex ( ?.+?)\1*$для найкоротшого повторення підрядка з @Neil 's коментар на @Arnauld ' JavaScript (ES6) відповідь s .

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

Пояснення:

a->{                        // Method with integer-array parameter and String return-type
  var t="";                 //  Temp-String, starting empty
  for(int i=a.length;i-->1; //  Loop backward over the input-array, skipping the first item
    t+=a[i]-a[i-1]          //   Calculate the difference between two adjacent items
       +" ");               //   And append this with a space to the temp-String
  return t.replaceAll("( ?.+?)\\1*$", 
                            //  Find the shortest repeating substring
                     "$1");}//  And only keep one such substring

1

APL + WIN, 39 байт

Запит на введення.

(↑((⍴v)=+/¨(⊂v)=(⍳⍴v)⌽¨⊂v)/⍳⍴v)↑v←-2-/⎕

Спробуйте в Інтернеті! Надано Dyalog Classic

Пояснення:

v←-2-/⎕ Prompt for input and take successive differences

(⍳⍴v)⌽¨⊂v create a nested vector ans sequentially rotate by one to length of v

+/¨(⊂v)= compare to original v and sum positions where there is match

(⍴v)= identify where all elements match

(↑(....) identify number of rotations giving a first complete match

(↑(...)↑v take first number of elements from above from v as repeated sequence


1

Сітківка 0,8,2 , 42 байти

\d+
$*
(?<=(1+),)\1

1+(.+?)\1*$
$1
1+
$.&

Спробуйте в Інтернеті! Посилання включає тестові випадки. Вихід включає провідну кому. Пояснення:

\d+
$*

Перетворити в одинарне.

(?<=(1+),)\1

Обчисліть різниці вперед, за винятком першого числа, яке залишається позаду.

1+(.+?)\1*$
$1

Збігайте повторювані відмінності.

1+
$.&

Перетворити в десятковий.


1

05AB1E , 14 13 байт

¥DηvÐNƒÁ}QD—#

Спробуйте в Інтернеті або перевірте всі тестові випадки .

Я знаю, що вже є два коротші відповіді 05AB1E, опубліковані @ Mr.Xcoder , але я хотів спробувати цей альтернативний підхід, використовуючи перевірку обертання та рівності.
Можливо, ви зможете переграти його на кілька байтів, не опускаючись Á.

-1 байт після підказки @Emigna, щоб видалити регістри global_variable ( ©і 2x ®) і використовувати замість нього дублікат ( D) і Triplicate ( Ð).

Пояснення:

¥             # Calculate the deltas of the input-array
              #  i.e. [1,2,3,5,6,7,9] → [1,1,2,1,1,2]
 D            # Duplicate it
  η           # Push all its prefixes
              #  [1,1,2,1,1,2] → [[1],[1,1],[1,1,2],[1,1,2,1],[1,1,2,1,1],[1,1,2,1,1,2]]
v             # For-each over these prefixes
 Ð            #  Triplicate the (duplicated) deltas-list
  NƒÁ}        #  Rotate the deltas-list N+1 amount of times,
              #  where N is the prefix index (== prefix_length-1)
              #   i.e. [1,1,2] and [1,1,2,1,1,2] (rotate 3 times) → [1,1,2,1,1,2]
      Q       #  If the rotated deltas and initial deltas are equal
              #   [1,1,2,1,1,2] and [1,1,2,1,1,2] → 1
       D—#    #  Print the current prefix-list, and stop the for-each loop

1
Ось 9 (окрема відповідь, оскільки це зовсім інше альго, хоча воно поділяє ¥ η).
Grimmy

@Grimy Ти перебираєш усі мої відповіді 05AB1E і гольфуєш кожну з них, так? ; p Хороша відповідь, хоча (ще раз), +1 від мене.
Кевін Кройсейсен

1
Не всі вони, я просто переглядаю пов’язані у цій публікації .
Grimmy

@Grimy Ну добре, це має сенс. :)
Кевін Круїссен

1

Haskell, 107 байт

let i=map(uncurry(-))$zip(tail x)(init x)in head$filter(\s->take(length i)(concat$repeat s)==i)(tail$inits i)

x - вхідний масив.


Ласкаво просимо в PPCG та Haskell гольф зокрема! Ви не можете вважати, що вхід присутній у певній змінній, хоча це легко виправити попередньо f x=. Також використання initsвимагає import Data.List, оскільки воно не є частиною Прелюдії: Спробуйте це в Інтернеті!
Лайконі

Однак ви можете зберегти досить багато байтів: (init x)може бути лише xтому, що zipскорочується автоматично, якщо один із списків довший за інший. І map(uncurry(-))$zipіснує Будувати-в: zipWith(-). Замість того , f x=let i=...inви можете використовувати шаблон охоронець: f x|i<-...=.
Лайконі

Крім того , ви можете використовувати список розуміння замість filter, !!0замість того , headі cycleзамість того , щоб concat$repeat: Спробуйте його в Інтернеті!
Лайконі

@Laikoni Дякую за вдосконалення! Ви маєте рацію, мій код потребує декларації функції та імпорту для Data.List.inits. Але мені було цікаво, чи варто додати до довжини коду? Я прошу, бо деякі інші зразки коду також покладаються на якийсь додатковий код.
misja111

Так, є загальним консенсус, що ці байти включаються в бал. У нас є посібник з правил гольфу в Хаскелл, який охоплює більшість цих випадків.
Лайконі


1

Perl 6 , 57 байт

{~(.rotor(2=>-1).map:{.[1]-.[0]})~~/^(.+?){}" $0"+$/;~$0}

Перевірте це

Вихід розділений пробілом ( "1 1 2")

Розширено:

{      # bare block lambda with implicit parameter $_

  ~(   # stringify (space separated)

    .rotor( 2 => -1 )     # from the input take 2 backup 1, repeat
    .map: { .[1] - .[0] } # subtract each pair to find the differences
  )

  ~~   # smartmatch

  /    # regex

    ^  # beginning of string

    ( .+? ) # match at least one character, but as few as possible
    {}      # make sure $0 is set (probably a compiler bug)
    " $0"+  # match $0 one or more times (with a leading space)

    $  # end of string
  /;

  ~$0  # return the stringified $0
}

Перша частина може бути~(.skip Z-$_)
Джо Кінг

1

05AB1E , 9 байт

¥©η.ΔÞ®Å?

Пояснення:

          # take input implicitly
¥         # deltas, eg [4, 5, 7, 8, 10] -> [1, 2, 1, 2]
 ©        # save this to the global register
  η       # prefixes, eg [1, 2, 1, 2] -> [[1], [1, 2], ...]
   .Δ     # find the first one such that
     Þ    # cycled infinitely, eg [1, 2] -> [1, 2, 1, 2, ...]
       Å? # starts with
      ®   # the global register
          # and implicitly print the found element

Альтернативний 9-байт:

¥η.ΔÞ.¥-Ë

Це ж альго, але замість того, щоб порівнювати зі списком дельт (який потрібно зберегти / відновити), це використовує (undelta), а потім порівнює з (неявним) введенням.

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


0

К4 , 30 байт

Рішення:

(*&d~/:c#'(!c:#d)#\:d)#d:1_-':

Приклади:

q)k)(*&d~/:c#'(!c:#d)#\:d)#d:1_-':2, 5, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19, 20
3 1 1 1
q)k)(*&d~/:c#'(!c:#d)#\:d)#d:1_-':1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17
1 1 2
q)k)(*&d~/:c#'(!c:#d)#\:d)#d:1_-':1, 4, 8, 9, 10, 13, 17, 18, 19, 22, 26, 27, 28
3 4 1 1
q)k)(*&d~/:c#'(!c:#d)#\:d)#d:1_-':6, 11, 13, 18, 20, 25, 27, 32, 34, 39, 41
5 2
q)k)(*&d~/:c#'(!c:#d)#\:d)#d:1_-':2, 6, 10, 13, 17, 21, 25, 28, 32, 36, 40, 43, 47
4 4 3 4
q)k)(*&d~/:c#'(!c:#d)#\:d)#d:1_-':5 6 7
,1

Пояснення:

Здається здоровенним для того, що ми намагаємось вирішити. Отримайте дельти введення, а потім побудуйте послідовності та визначте найкоротший, який відповідає йому.

(*&d~/:c#'(!c:#d)#\:d)#d:1_-': / the solution
                           -': / deltas 
                         1_    / drop first
                       d:      / save as d
                      #        / take (#) from
(                    )         / do this together
                 #\:d          / take (#) each-left (\:) from d
          (     )              / do this together
              #d               / count length of d
            c:                 / save as c
           !                   / range 0..c-1
       c#'                     / take c copies of each
   d~/:                        / d equal (~) to each right (/:)
  &                            / where true
 *                             / first one


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.