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

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

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


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

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

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 #


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.


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!


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ġ±Ẋ-

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


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!


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.



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

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.


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


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

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.


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


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.