Получить последовательность шагов


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 Man!
НГМЫ

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 изначально установлено в нечисловое значение (функция обратного вызова map () ), первая итерация дает 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<-здесь тоже не нужен
Джузеппе

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 байта благодаря Кевину Круйссену .

¥.œʒË}нн

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


05AB1E , 11 байт

āεI¥ô}ʒË}нн

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

āεI ¥ ô} ʒË} нн Полная программа.
Длина диапазона. Нажмите [1 ... len (inp)].
 ε} Для каждого ...
  Я ¥ ô ... Нарезать дельты на кусочки соответствующего размера
      Keep} Оставьте только те, у которых все элементы равны.
         нн И сначала извлеките первый элемент из первого.

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функцию ('gallery') с 5опцией ('circulant'). Создает матрицу с заданным вектором в качестве первой строки, затем в последовательных строках один и тот же вектор смещается по кругу, пока не будет развернут.

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—#

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

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

-1 байт после подсказки @Emigna для удаления регистров global_variable ( ©и 2x ®) и использования взамен Duplicate ( 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

@ Грими, ладно, в этом есть смысл. :)
Кевин Круйссен

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)

х - входной массив.


Добро пожаловать в PPCG и Haskell в гольф в частности! Вы не можете предполагать, что входные данные присутствуют в определенной переменной, хотя это легко исправить, предварительно добавив f x=. Также использование initsтребует import Data.List, поскольку это не является частью Prelude: попробуйте онлайн!
Лайкони

Однако вы можете сохранить довольно много байтов: это (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")

Expanded:

{      # 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

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