Oscila periodicamente?

19

Desafio

Em uma lista, determine se o agrupamento da lista em execuções de elementos crescentes e decrescentes resultará em uma lista de listas de tamanhos iguais.

Em outras palavras, os "pontos de virada" da lista são espaçados uniformemente.

Exemplo

Aqui está um exemplo: 0, 3, 7, 5, 2, 3, 6

0, 3, 7aumenta, 7, 5, 2diminui e 2, 3, 6aumenta. Portanto, isso é verdade.

Outro exemplo: 1, 4, 6, 8, 5, 3, 5, 7, 9

1, 4, 6, 8aumenta, 8, 5, 3diminui e 3, 5, 7, 9aumenta. Portanto, isso é falso.

Regras e especificações

  • Nenhum elemento adjacente será igual
  • Todos os números podem estar dentro do intervalo razoável de números do seu idioma
  • Você pode assumir que todos os números são números inteiros, se isso o ajudar a enviar seu envio
  • Isso é , então a resposta mais curta ganha
  • Entrada como uma lista em qualquer representação razoável e saída como qualquer valor de verdade / falsidade. Os dois valores devem ser consistentes.

Casos de teste

Input -> Output
1, 3, 5, 8, 6, 4, 2, 3, 5, 7, 6, 4, 2, 5, 7, 9, 6, 4, 2 -> True
1, 3, 5, 7, 6, 4, 5, 7, 9, 8, 6, 4, 2, 3, 5 -> False
2, 3, 6, 4, 2, 3, 7, 5, 3, 4, 6 -> True
3, 6, 4, 8, 5, 7, 3, 5, 2 -> True
8 -> True
1, 3, 5, 7 -> True
4, 5, 7, 6, 8, 9 -> False
6, 4, 2, 3, 5, 4, 2 -> True
8, 5, 3, 2, 4, 6, 5, 3, 2, 5, 7 -> False

Nota : Você não pode presumir que todos os números são de um dígito (a menos que esse seja todo o seu idioma capaz de lidar); os casos de teste refletem isso apenas porque é mais fácil digitar os casos da seguinte maneira: P Aqui estão alguns casos de teste com números fora desse intervalo:

1, 5, 10, 19, 15, 13, 8, 13, 18, 23, 19, 18, 14 -> True
15, 14, 17, 16, 19, 18 -> True
12, 16, 19, 15, 18, 19 -> False
HyperNeutrino
fonte
A primeira execução sempre aumentará ou a entrada poderá começar com uma execução decrescente?
Jordan
@ Jordan Pode começar a diminuir. Vou adicionar um caso de teste para isso.
HyperNeutrino
Os grupos estão sempre completos? Por exemplo, seria 1, 2, 3, 2uma entrada válida e, se for considerado verdadeiro ou falso? Nesse exemplo, o próximo valor sendo 1 tornaria verdadeiro, mas 3 tornaria falso.
Tom Carpenter
11
@ TomCarpenter Isso é considerado falso. Eles devem ter o mesmo comprimento (e, portanto, todos completos).
HyperNeutrino

Respostas:

9

MATL , 10 9 bytes

dZS&Y'da~

Experimente online!

Guardado um byte graças a Luis Mendo!

Explicação:

Suponha que a entrada seja [0, 3, 7, 5, 2, 3, 6]::

            % Implicit input:                                [0, 3, 7, 5, 2, 3, 6]
d           % Difference between adjacent elements:          [3, 4, -2, -3,  1,  3]
 ZS         % Sign of the differences:                       [1, 1, -1, -1, 1, 1]
   &Y'      % Length of runs of consecutive elements:        [2, 2, 2]
     d      % Difference between the lengths:                [0, 0]
      a     % Any non-zero elements:                         False
       ~    % Negate, to get a truthy value if all are zero: True
Stewie Griffin
fonte
8

Gelatina , 6 bytes

IṠŒgAE

Experimente online!

Guardado 1 byte graças a Adnan !

Como funciona

IṠŒgAE - Programa completo.

I - Incrementos (Deltas).
 Sign - Sinal de cada um. -1 se negativo, 0 se nulo, 1 se positivo.
  Œg - execuções em grupo de elementos adjacentes.
    A - valor absoluto. Vectorizes. Isso mapeia -1 e 1 para o mesmo valor.
     E - são todos iguais?

Enquanto jogava golfe, descobri algumas alternativas legais e mais longas:, (em vez disso IṠŒgL€E, IṠŒrṪ€Eusa codificação de comprimento de execução).

Mr. Xcoder
fonte
Eu acho que IṠŒgḂEdeve salvar um byte
Adnan
@Adnan Pode A(valor absoluto) substituir ou existe algum truque que eu não entendo ?
Xcoder 26/10
Qualquer função que unifica 1 e -1 para o mesmo número deve ser suficiente
Adnan
7

Oitava , 54 50 bytes

@(x)nnz(unique(diff(find([diff(diff(x)>0) 1]))))<2

Experimente online!

Explicação

@(x)nnz(unique(diff(find([diff(diff(x)>0) 1]))))<2

@(x)                                                % Define anonymous function    
                               diff(x)              % Deltas (consecutive differences)
                                      >0            % Positive? Gives signs
                          diff(         )           % Deltas between signs
                         [                1]        % Append 1 to "close" last group
                    find(                   )       % Indices of nonzeros
               diff(                         )      % Deltas. Gives group lengths
        unique(                               )     % Remove duplicates
    nnz(                                       )    % Number of nonzeros. Gives length
                                                <2  % If 1 or 0: input is periodic
Luis Mendo
fonte
6

Wolfram Language (Mathematica) , 38 bytes

Equal@@(1^Differences@#~SplitBy~Sign)&

Experimente online!

Explicação

Equal@@(1^Differences@#~SplitBy~Sign)&  (* Input:                {3, 6, 4, 8, 5, 7, 3, 5, 2} *)

          Differences@#                 (* Take differences:     {3, -2, 4, -3, 2, -4, 2, -3} *)
                       ~SplitBy~Sign    (* Split by sign:        {{3}, {-2}, {4}, {-3}, {2}, {-4}, {2}, {-3}} *)
        1^                              (* Raise to power of 1:  {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}} *)
Equal@@                                 (* Check equal:          True *)
JungHwan Min
fonte
Equal@@(1^Split@Sign@Differences@#)&é 2 bytes mais curto e Equal@@Im@Split@Sign@Differences@#&1 byte mais curto que isso.
Misha Lavrov #
E agora que estou pensando em números complexos, usar em Argvez de Signsalvar outro byte.
Misha Lavrov #
5

05AB1E , 8 7 bytes

¥0.SγaË

Experimente online!

-1 graças a Adnan.

Urna de polvo mágico
fonte
¥0.SγaËdeve salvar um byte
Adnan
O que é aque não consigo encontrar nos documentos. is_letter(a)???
Urna Mágica de Polvo
Sim, isso é correto
Adnan
@ Adnan ahhh ... idéia estranha, boa idéia.
Urna Mágica do Polvo
4

C (gcc) , 143 140 138 136 135 132 bytes

  • Salva três bytes; usando uma variável rpara armazenar o retorno booleano da função em vez de terminar usandoreturn .
  • Salvou dois bytes; golfe int A[]para int*A(usando um ponteiro em vez de uma matriz).
  • Economizou dois bytes graças ao Steadybox ; golfe f(int*A,int a)para f(A,a)int*A;.
  • Salva um byte; golfeif(d!=... para if(d-....
  • Salva três bytes; golfe ;j++...j+1para ;...++j.
j,d,e,l,m,r;f(A,a)int*A;{for(d=A[0]>A[1],r=1,j=m=l=0;j-~-a;){l++;if(d-(e=A[j]>A[++j]))d=e,j--,r*=l>=(m=!m?l:m),l=0;}r*=-~l==m||m<1;}

Experimente online!

Define uma função fque examina todos os elementos da lista, exceto o último, e determina a relação desse elemento com o próximo elemento da lista. O número de comparações iguais consecutivas é armazenado na primeira vez em que a relação é invertida, qualquer execução após a execução inicial que diferir no comprimento do comprimento armazenado resulta em uma saída falsa. No final, a relação do penúltimo elemento com o último é analisada para que corresponda ao restante da lista.

Jonathan Frech
fonte
Você pode usar em f(A,a)int*A;vez de f(int*A,int a).
Steadybox
3

Python 2 , 107 105 103 97 96 94 91 bytes

lambda l:len({sum(g)**2for k,g in groupby(map(cmp,l[:-1],l[1:]))})<2
from itertools import*

Experimente online!

Python 3 , 102 100 97 bytes

lambda l:len({len([*g])for k,g in groupby(x>y for x,y in zip(l,l[1:]))})<2
from itertools import*

Experimente online!

TFeld
fonte
você pode usar {...}em vez set(...)de salvar 3 bytes
Rod
3

Casca , 7 bytes

EmLġ±Ẋ-

Experimente online!

Como isso funciona

EmLġ ± Ẋ- ~ Programa completo.

     Map ~ Mapeie sobre pares de elementos adjacentes.
      - ~ Com subtração (calcula os deltas)
   using ~ Agrupe usando o predicado de igualdade.
    ± ~ Sinal.
 mL ~ Obtenha os comprimentos.
E ~ são todos iguais?

Algumas alternativas fofas:

εġLġ±Ẋ-
εüLġ±Ẋ-
Mr. Xcoder
fonte
2

JavaScript (ES6), 81 bytes

Isso parece muito longo. Provavelmente estou perdendo alguma coisa aqui ... Retorna um trueou outro undefined.

f=(a,p=1)=>a.every((n,i)=>!i|!(1/(y=a[i+1]))|!(i%p)^y>n^a[i-1]>n)||a[p]&&f(a,p+1)

Procura um período 0 <p <a.length de modo que todas as mudanças de direção ocorram a cada p elementos.

Casos de teste

Arnauld
fonte
2

Python 2 , 96 bytes

import re
def f(x):exec"x=map(cmp,x[1:],x[:-1]);"*2;re.match('.([^1]*)(-?1, \\1)*9',`x+[9]`)<0<_

Experimente online! Saída via código de saída: acidente (1) é falsey, saída limpa (0) é verdade.

Python 2 , 106 bytes

def f(x):d=map(cmp,x[1:],x[:-1]);l=len(d);s=(d+[0])[0];k=(d+[-s]).index(-s);print((k*[s]+k*[-s])*l)[:l]==d

Experimente online!

Lynn
fonte
Não tenho certeza, embora (...)[:l]<dpossa ser o inverso de (...)[:l]==d.
Jonathan Frech
2

Haskell , 79 78 77 bytes

import Data.List
g s|h:t<-(1<$)<$>group(zipWith(<)s$tail s)=all(==h)t
g _=1<3

Experimente online!

Dada uma lista s, zipWith(<)s$tail stesta para cada elemento se ele é menor que seu sucessor, por exemplo, s=[2,3,6,4,2,3,7,5,3]rendimento [True,True,False,False,True,True,False,False]. Então groupcorre dos mesmos elementos em conjunto: [[True,True],[False,False],[True,True],[False,False]]. Para verificar se todas essas listas têm o mesmo comprimento, substituir seus elementos com 1( veja esta dica ) produzindo [[1,1],[1,1],[1,1],[1,1]]e verifique se todos os elementos na cauda tda lista igual à cabeça h: all(==h)t.

Esta abordagem não funciona para listas únicas, mas porque aqueles são sempre verdadeiras, podemos lidar com eles em seu próprio caso: g[_]=1<3.

Laikoni
fonte
1

Japonês , 15 bytes

ä- mg ò¦ mÊä¥ e

Experimente online!

Explicação

ä- mg ò¦ mÊä¥ e                                                  [0,3,7,5,2,3,6]
ä-                // Difference between neighboring elements     [-3,-4,2,3,-1,-3]
   mg             // Get the sign of each element                [-1,-1,1,1,-1,-1]
      ò¦          // Partition between different elements        [[-1,-1],[1,1],[-1,-1]]
         mÊ       // Get the length of each element              [2,2,2]
           ä¥     // Check for uniqueness                        [true,true]
              e   // Return true if all elements are truthy      true
Oliver
fonte
1

R, 36 bytes

function(n)!sd(rle(sign(diff(n)))$l)

diffcalcula as diferenças sucessivas e depois signreduz para ± 1. rleentão o comprimento da execução os codifica. Todos os elementos disso rledevem ser os mesmos, ou seja, o vetor tem desvio padrão zero. !então produz a saída lógica correta.

JDL
fonte
1

Haskell (Lambdabot), 59 bytes

g(map(1<$).group.ap(zipWith(<))tail->h:t)=all(==h)t;g _=1<3

Com base na resposta de @ Laikoni

BlackCap
fonte
Bom, eu não sabia que o Lamdabot tinha o ViewPatterns ativado. Falta um espaço g_=1<3.
Laikoni
@Laikoni nem me, mas eu realmente fui para #haskell e testei
Cabeção
0

Java (OpenJDK 8) , 437 302 256 188 bytes

a->{int i=0,g=0,x=0,l=0;String d="";for(;i<~-a.length;d+=a[0].compare(a[i+1],a[i++])+1);for(String s:d.split("(?<=(.))(?!\\1)"))if(g++<1)x=s.length();else if(s.length()!=x)l++;return l<1;}

Experimente online!

Roberto Graham
fonte
0

Clojure, 70 bytes

#({0 1 1 1}(count(set(map count(partition-by pos?(map -(rest %)%))))))

Retorna 1como verdade e nil(AKA nulo) como falso.

NikoNyrh
fonte
0

Java (OpenJDK 8) , 135 bytes

a->{Integer i=0,c,d=0,p=0,r=0;for(;++i<a.length;)d+=(i<2|(c=i.signum(a[i-1]-a[i]))<0?d<0:d>0)?c:p==0|p==-d?c-(p=d):1-(r=1);return r<1;}

Experimente online!

Explicações

a->{                    // int array
 Integer i=0,c,d=0,p=0,r=0;
                        // variable definitions, use Integer to abuse static calls
 for(;++i<a.length;)    // Loop from 1 till length - 1
  d+=                   // Change d
   (i<2                 // First iteration?
     |(c=i.signum(a[i-1]-a[i]))<0?d<0:d>0
   )                    // Or do c and d have the same sign?
    ?c                  // then increase the magnitude of d.
    :p==0|p==-d         // else we're in a u-turn. Is it the first? Or is the magnitude the same as previously?
     ?c-(p=d)           // assign the new magnitude with sign to p and reset d to -1 (if was positive) or 1 (if was negative)
     :1-(r=1);          // else just do r=1 (technically: "add 1-1=0 to d" as well)
 return r<1;            // return whether there were wrong amplitudes.
}
Olivier Grégoire
fonte
0

Python 2 , 110 99 bytes

-11 bytes graças a @Lynn

d=input()
exec"d=map(cmp,d[:-1],d[1:]);"*2
x=[i+1for i,e in enumerate(d)if e]
for i in x:i%x[0]>0<q

Experimente online!

ovs
fonte
Você pode salvar alguns bytes calculando as diferenças duplas como:exec"d=map(cmp,d[:-1],d[1:]);"*2
Lynn