Obtén los pasos de la secuencia

17

Desafío

Dada una secuencia de números, cree una función que devuelva los pasos de la secuencia.

  • Suponga que una secuencia será N >= 3
  • La secuencia repetirá los pasos al menos una vez
  • La secuencia solo contendrá números naturales
  • Su función o programa debe devolver la secuencia de pasos más corta posible

Ejemplo:

Entrada: [1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17]

Salida: [1, 1, 2]

Explicación: La secuencia inicial va de 1 => 2 (1 step), 2 => 3 (1 step), 3 => 5 (2 steps). Entonces se repite. La salida entonces es[1 step, 1 step, 2 steps] => [1, 1, 2]

Otro ejemplo:

Entrada: [2, 5, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19, 20]

Salida: [3, 1, 1, 1]

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

Casos de prueba

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]


Aclaraciones

  • La longitud de entrada - 1 es divisible por la longitud de salida
  • Suponga que la secuencia siempre va a estar aumentando

Este es el , por lo que gana la respuesta más corta en bytes.

Luis felipe De jesus Munoz
fuente
Desafío relacionado .
AdmBorkBork
66
He visto algunos desafíos que ha publicado recientemente con muchos comentarios aclaratorios, y un par cerró como "poco claro", y posteriormente volvió a abrir después de haber realizado las ediciones apropiadas. ¿Has considerado publicar esto en el sandbox durante unos días / una semana? He disfrutado tus desafíos ya que son bastante accesibles, pero todos los desafíos, sin importar cuán simples o por quién los publiquen, pueden usar el refinamiento.
Giuseppe
2
@Giuseppe Gracias por tus sugerencias. He publicado algunos otros desafíos en la caja de arena (generalmente, si no consigo la forma correcta de crear un desafío con él, lo elimino). Para estos desafíos, pensé que eran lo suficientemente claros y es por eso que publiqué de inmediato, pero primero comenzaré a publicarlos en el sandbox. Gracias
Luis felipe De jesus Munoz
2
@LuisMendo Heretic! ¡0 es un número natural! ¡Billy Joel incluso tenía un álbum completo dedicado al Peano Man!
ngm
1
@AdmBorkBork, esto está más relacionado en virtud de tratar con listas de operaciones de longitud arbitraria.
Peter Taylor

Respuestas:

10

Jalea , 9 7 bytes

IsJEƇḢḢ

Pruébalo en línea!

Cómo funciona

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.
Dennis
fuente
9

JavaScript (ES6), 58 bytes

Emite una cadena separada por comas (con una coma inicial).

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

Pruébalo en línea!

O 56 bytes si usamos ,-como separador y asumimos que la secuencia es siempre aumentando estrictamente .

¿Cómo?

Primero convertimos la matriz de entrada a [] en una lista de diferencias consecutivas con:

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

Debido a que p se establece inicialmente en un valor no numérico (la función de devolución de llamada de map () ), la primera iteración produce NaN .

Ejemplo:

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

Luego coaccionamos el resultado a una cadena:

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

Finalmente, buscamos el patrón 1 más corto de enteros separados por comas ( ,\d+) que comienzan justo después de "NaN" y se repiten hasta el final de la cadena:

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

1: usando el no codicioso *?

Arnauld
fuente
Estoy publicando una solución basada en la misma idea regex, pero muy diferente en la implementación. Por supuesto, no busqué otras soluciones antes de desarrollar la mía, y parece lo suficientemente diferente, y tal vez es la primera vez que logro anotar mejor que usted aquí.
edc65
1
53 Bytes: /(,.+?)\1*$/.
Neil
6

Brachylog , 11 bytes

s₂ᶠ-ᵐṅᵐ~j₍t

Pruébalo en línea!

Sería de 5 bytes si hubiera una función integrada para diferencias consecutivas.

Explicación

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]
Fatalizar
fuente
¿Puedes negar después de la cola para guardar un byte?
Rod
@ Rod Todavía necesitaría mapearlo, por lo que sería de la misma longitud. Negate es un predicado entre dos números, no se vectoriza automáticamente a listas como otros idiomas (de lo contrario, no funcionaría bien con entradas / salidas desconocidas que son comunes en los programas declarativos)
Fatalize
5

Pyth, 11 bytes

<J.+Qf.<IJT

Pruébalo aquí

Explicación

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

fuente
5

Japt , 14 12 bytes

äa
¯@eUéX}aÄ

Intentalo


Explicación

              :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

Original

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

Intentalo

Lanudo
fuente
5

R , 49 46 bytes

Programa completo:

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

Pruébalo en línea!

R , 72 58 54 bytes

Presentación de la función original con todos los casos de prueba en un solo lugar:

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

Pruébalo en línea!

Gracias a JayCe por sugerir la ruta completa del programa y -4 bytes en la función, y a Giuseppe por más -3.

Kirill L.
fuente
@JayCe tampoco necesita a<-aquí
Giuseppe
4

J , 22 19 bytes

¡3 bytes guardados gracias a FrownyFrog!

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

Pruébalo en línea!

[¡Pruébalo en línea!] [TIO-ji2uiwla]

¿Cómo?

                 -      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
Galen Ivanov
fuente
Si en /:lugar de #\, puede 0{"1[:~.guardar 1 byte.
FrownyFrog
Y "0 1es"{
FrownyFrog
@FrownyFrog Gracias, una vez más!
Galen Ivanov
1
esto es hermoso.
Jonás
@ Jonás Sí, gracias a FrownyFrog!
Galen Ivanov
4

05AB1E , 8 bytes

Guardado 3 bytes gracias a Kevin Cruijssen .

¥.œʒË}нн

Pruébalo en línea!


05AB1E , 11 bytes

āεI¥ô}ʒË}нн

Pruébalo en línea!

āεI ¥ ô} ʒË} нн Programa completo.
Rango de longitud. Presione [1 ... len (inp)].
 ε} Para cada ...
  I ¥ ô ... Cortar los deltas en trozos del tamaño correspondiente
      Keep} Mantenga solo aquellos que tengan todos sus elementos iguales.
         нн Y primero recupera el primer elemento del primero.

13 bytes

Una linda alternativa, OMI:

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

Pruébalo en línea!

¥©ηʒ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.
Sr. Xcoder
fuente
1
8 bytes usando.
Kevin Cruijssen
3

Javascript, 49 56 bytes

Editar 7 bytes guardados gracias (¿adivina quién?) Arnauld

La misma idea regex que Arnauld, pero curiosamente tan diferente en la implementación ...

Devolver una cadena con pasos separados por comas (y una coma inicial)

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

Prueba

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

edc65
fuente
Usar matchfue una mala decisión mía. Puedes superarme en golf un poco más . :-)
Arnauld
3

MATL , 14 13 12 bytes

dt5YLFTF#Xu)

Pruébalo en línea!

¡Acabo de descubrir que MATL tiene una función circulante!

Explicación

d - Obtenga las diferencias entre términos sucesivos, como una matriz

t5YL- duplica eso, luego llama a la función YL('galería') con 5la opción ('circulante'). Crea una matriz con el vector dado como primera fila, luego las filas sucesivas son el mismo vector desplazado circularmente, hasta que se envuelve.

FTF#Xu- Busque filas únicas y obtenga sus números de fila (no estoy seguro si hay una forma más corta de hacerlo). Cuando se repiten los pasos de la secuencia, la fila desplazada circularmente será la misma que la primera fila, y las filas posteriores se repetirán. Entonces esto obtiene los índices de la primera ejecución de los pasos de la secuencia antes de que comiencen a repetirse.

) - indexe eso en la matriz de diferencias original, para obtener la respuesta.


Mayor:

d`tt@YS-a}@:)

Pruébalo en línea!

(-1 byte gracias a Giuseppe)

Explicación:

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
sundar - Restablece a Monica
fuente
2

Python 2 , 101 bytes

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]

Pruébalo en línea!

Primero genera los deltas d , luego encuentra el primer prefijo p de d que cuando se repite ⌊len (L) / len (p) ⌋ veces produce L , donde L es la lista de entrada.

Sr. Xcoder
fuente
2

Java 10, 104 100 bytes

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

Expresiones regulares ( ?.+?)\1*$para repetir más corto subcadena de @Neil 's comentario sobre @Arnauld ' JavaScript respuesta s (ES6) .

Pruébalo en línea.

Explicación:

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
Kevin Cruijssen
fuente
1

APL + WIN, 39 bytes

Solicitud de entrada.

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

Pruébalo en línea! Cortesía de Dyalog Classic.

Explicación:

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
Graham
fuente
1

Python 2 , 86 85 bytes

def f(a,n=1):d=[y-x for x,y in zip(a,a[1:])];return d[:-n]==d[n:]and d[:n]or f(a,n+1)

Pruébalo en línea!

Construya las diferencias como d; si se drepite con el tamaño de la unidad nentonces d[n:]==d[:-n]; De lo contrario, recurse.

Chas Brown
fuente
1

Retina 0.8.2 , 42 bytes

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

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

Pruébalo en línea! El enlace incluye casos de prueba. La salida incluye comas iniciales. Explicación:

\d+
$*

Convierte a unario.

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

Calcule las diferencias hacia adelante, excepto el primer número, que se queda atrás.

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

Empareja las diferencias repetitivas.

1+
$.&

Convierte a decimal.

Neil
fuente
1

05AB1E , 14 13 bytes

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

Pruébelo en línea o verifique todos los casos de prueba .

Sé que ya hay dos respuestas 05AB1E más cortas publicadas por @ Mr.Xcoder , pero quería probar este enfoque alternativo utilizando la rotación y la verificación de igualdad.
Podría ser capaz de jugarlo unos pocos bytes sin caerÁ .

-1 byte después de una sugerencia de @Emigna para eliminar los registros global_variable ( ©y 2x ®) y utilizar un Duplicate ( D) y un Triplicate ( Ð) en su lugar.

Explicación:

¥             # 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
Kevin Cruijssen
fuente
1
Aquí hay un 9 (respuesta separada ya que es un algo muy diferente, aunque comparte el ¥ η).
Grimmy
@ Grimy ¿Estás revisando todas mis respuestas 05AB1E y jugando golf cada una de ellas, jaja? ; p Buena respuesta (una vez más), +1 de mi parte.
Kevin Cruijssen
1
No todos, solo estoy revisando los vinculados en esta publicación .
Grimmy
@ Grimy Ah ok, eso tiene sentido. :)
Kevin Cruijssen
1

Haskell, 107 bytes

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

x es la matriz de entrada.

misja111
fuente
¡Bienvenido a PPCG y al golf Haskell en particular! No puede suponer que la entrada está presente en una determinada variable, aunque esto se soluciona fácilmente anteponiendo f x=. Además, el uso de initsrequiere import Data.List, ya que no es parte de Prelude: ¡ Pruébelo en línea!
Laikoni
Sin embargo, puede guardar bastantes bytes: (init x)puede ser xporque se ziptrunca automáticamente si una de las listas es más larga que la otra. Y para map(uncurry(-))$zipexiste una acumulación en: zipWith(-). En lugar de f x=let i=...inque se utilice un protector patrón: f x|i<-...=.
Laikoni
Además, puede utilizar una lista de comprensión en lugar de filter, en !!0lugar de heady en cyclelugar de concat$repeat: ¡ Pruébelo en línea!
Laikoni
@Laikoni ¡Muchas gracias por tus mejoras! Tiene razón, mi código necesita una declaración de función y una importación para Data.List.inits. Pero me preguntaba, ¿debería agregarse eso a la longitud del código? Lo pregunto porque algunos de los otros ejemplos de código también dependen de algún código adicional.
misja111
Sí, es un consenso general que esos bytes están incluidos en la puntuación. Tenemos una guía de reglas de golf en Haskell que cubre la mayoría de estos casos.
Laikoni
1

Stax , 8 6 bytes

░»F\☺»

Ejecutar y depurarlo

Aquí hay una versión anotada desempaquetada para mostrar cómo funciona.

:-  pairwise differences
:(  all leftward rotations of array
u   keep only unique rotations
mh  output the first element from each unique rotation

Ejecute este

recursivo
fuente
1

Perl 6 , 57 bytes

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

Pruébalo

La salida está separada por espacios ( "1 1 2")

Expandido:

{      # 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
}
Brad Gilbert b2gills
fuente
Toda la primera parte puede ser~(.skip Z-$_)
Jo King,
1

05AB1E , 9 bytes

¥©η.ΔÞ®Å?

Explicación:

          # 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

Alternativa de 9 bytes:

¥η.ΔÞ.¥-Ë

Lo mismo, pero en lugar de comparar con la lista de deltas (que debe guardarse / restaurarse), esto usa (undelta) y luego se compara con la entrada (implícita).

Pruébalo en línea!

Mugriento
fuente
0

K4 , 30 bytes

Solución:

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

Ejemplos:

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

Explicación:

Parece considerable para lo que estamos tratando de resolver. Obtenga los deltas de la entrada y luego cree secuencias y determine la más corta que coincida.

(*&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
callejero
fuente
0

Perl 5 -p , 55 bytes

s/\d+ (?=(\d+))/($1-$&).$"/ge;s/\d+$//;s/^(.+?)\1*$/$1/

Pruébalo en línea!

Los números se ingresan como una lista separada por espacios. La salida es el mismo formato.

Xcali
fuente