Enésimas diferenças


26

Em matemática, uma maneira de descobrir qual é o tipo de uma determinada relação (linear, quadrática etc.) para calcular as diferenças. Para fazer isso, você pega uma lista de valores y para os quais a diferença entre os valores correspondentes x é a mesma e subtrai cada um do número acima, criando uma lista de números um menor que a lista anterior. Se a lista resultante for completamente composta por números idênticos, a relação terá uma diferença de 1 (é linear). Se eles não forem idênticos, repita o processo na nova lista. Se eles agora são idênticos, a relação tem uma diferença de 2 (é quadrática). Se eles não forem idênticos, você simplesmente continua esse processo até que sejam. Por exemplo, se você tiver a lista de valores y [1,6,15,28,45,66] para aumentar incrementalmente os valores x:

First Differences:

1
6   1-6  =-5
15  6-15 =-9
28  15-28=-13
45  28-45=-17
66  45-66=-21

Second differences:

-5 
-9  -5+9  =4
-13 -9+13 =4
-17 -13+17=4
-21 -17+21=4

As these results are identical, this relation has a difference of 2

Sua tarefa:

Escreva um programa ou função que, ao receber uma matriz de números inteiros como entrada, retorne a diferença da relação descrita pela matriz, conforme explicado acima.

Entrada:

Uma matriz de números inteiros, que pode ter qualquer tamanho> 1.

Saída:

Um número inteiro que representa a diferença da relação descrita pela entrada.

Casos de teste:

Input                            => Output
[1,2,3,4,5,6,7,8,9,10]           => 1
[1,4,9,16,25,36]                 => 2
[1,2,1]                          => 2 (when there is only one value left, all values are automatically identical, so the largest difference an array can have is equal to the length of the array-1)
"Hello World"                    => undefined behavior (invalid input)
[1,1,1,1,1,1,1,1,1]              => 0 (all elements are already identical)
[1, 3, 9, 26, 66, 150, 313, 610] => 6

Pontuação:

Isso é , a menor pontuação em bytes em cada idioma ganha para esse idioma. A pontuação mais baixa geral recebe a marca de seleção verde.


A entrada pode ser "inválida" como em, se a entrada NÃO estiver em conformidade com as especificações fornecidas, devemos errar? Forneça -1 como a saída?
Magic Octopus Urn

O comportamento é indefinido para entrada inválida (não me importo com o que o seu código faz)
Gryphon - Reinstate Monica

Não deveria [1,2,1]dar 2? [1,2,1] -> [1,-1] -> [-2]
HyperNeutrino

@HyperNeutrino, sim, desculpe. Eu tive um peido cerebral lá
Gryphon - Reinstate Monica

Adicione este caso de teste [1,3,9,26,66,150,313,610]-> 6se desejar
J42161217

Respostas:


10

Casca , 6 bytes

Obrigado Leo por me deixar usar sua versão que funciona para[1,1,1,1,1,1]

←VE¡Ẋ-

Experimente online!

Explicação

   ¡     Repeatedly apply function, collecting results in a list
    Ẋ-     Differences
 VE      Get the index of the first place in the list where all the elements are equal
←        Decrement

2
Sempre que alguém dizia que Husk é a nova geléia, eles estavam muito certos. > _ <
Zacharý

Porra, eu ia postar isso . Bom trabalho, +1!
Leo

@ Leo, caso de teste que não vi [1,1,1,1], posso usar o seu?
H.PWiz

@ H.PWiz certeza, continue!
Leo

7

JavaScript (ES6), 47 bytes

f=a=>-a.every(x=>i=!x)||1+f(a.map(n=>n-a[++i]))

Casos de teste


7

MATL , 8 bytes

`dta}x@q

Experimente online! Ou verifique todos os casos de teste .

Explicação

Isso compara diferenças consecutivas iterativamente até que o resultado seja todos os zeros ou vazios. A saída é o número necessário de iterações menos 1.

`      % Do... while
  d    %   Consecutive diffferences. Takes input (implicitly) the first time
  t    %   Duplicate
  a    %   True if any element is nonzero. This is the loop condition
}      % Finally (execute before exiting the loop)
  x    %   Delete. This removes the array of all zeros
  @    %   Push iteration index
  q    %   Subtract 1. Implicitly display
       % End (implicit). Proceed with next iteration if top of the stack is true


5

Mathematica, 49 bytes

(s=#;t=0;While[!SameQ@@s,s=Differences@s;t++];t)&  

thanx @alephalpa para -6 bytes e @hftf -1 byte

e aqui está outra abordagem do @hftf

Mathematica, 49 bytes

Length@NestWhileList[Differences,#,!SameQ@@#&]-1&

(s=#;t=0;While[UnsameQ@@s,s=Differences@s;t++];t)&
alephalpha

1
UnsameQ[1,2,1]é falso; !SameQ[1,2,1]é verdade. Eu também não acho que o loop manual salva caracteres: Length@NestWhileList[Differences,#,!SameQ@@#&]-1&já é do mesmo tamanho que o seu depois de substituir UnsameQpor !SameQ.
Hftf


4

Japonês , 10 7 bytes

è@=ä-)d

Experimente online!

Confia no fato de que o resultado é garantido dentro do comprimento da matriz de entrada.

Explicação

è@=ä-)d     Implcit input of array U
 @          For each value in U...
  =ä-)      Update U to be equal to its subsections, each reduced by subtraction
      d     Check if any values in that are truthy
è           Count how many items in that mapping are true

No final, isso mapeará a matriz
[1, 3, 9, 26, 66, 150, 313, 610]para [true, true, true, true, true, true, false, false],
que contém 6 trues.

Versão anterior de 10 bytes

@=ä-)e¥0}a

Experimente online!


4

Perl 6 , 37 bytes

{($_,{@(.[] Z- .[1..*])}...*.none)-2}

Experimente online!

Explicação: A função aceita a entrada como uma lista. Em seguida, ele cria uma sequência recursiva como esta: o primeiro elemento é a lista original ( $_), os próximos elementos são retornados ao {@(@$_ Z- .[1..*])}serem chamados no elemento anterior e são iterados até que a condição *.noneseja verdadeira, o que acontece apenas quando a lista é vazio ou contém apenas zeros (ou, tecnicamente, outros valores de falsey). Em seguida, pegamos a lista e subtraímos 2, o que a força primeiro ao contexto numérico (e as listas no contexto numérico são iguais ao número de seus elementos) e, no final, retorna 2 menor que o número de elementos no Lista.

O bloco estranho {@(@$_ Z- .[1..*])}apenas pega a lista fornecida ( .[]- chamada fatia Zen - a indexação com colchetes vazios gera a lista inteira), fecha o zíper usando o operador menos ( Z-) com a mesma lista sem o primeiro elemento ( .[1..*]) e o força a uma lista ( @(...)- precisamos disso porque o zip retorna apenas uma Seq, que é basicamente uma lista unidirecional que pode ser iterada apenas uma vez. É algo que não gostamos.) E é isso.


Mudar @(.[] Z- .[1..*])para [.[] Z-.[1..*]]deve salvar dois bytes.
Nwellnhof 12/09

4

Java 8, 191 + 58 = 249 198 140 bytes.

Obrigado PunPun1000 por 51 bytes.
Obrigado Nevay por 58 bytes.

int f(int[]a){int x=a.length-1,b[]=new int[x];for(;x-->0;)b[x]=a[x+1]-a[x];return java.util.Arrays.stream(a).distinct().count()<2?0:1+f(b);}

Experimente Online!

Experimente Online (versão de 198 bytes)

Portanto, esta é minha primeira vez postando aqui no PPCG (e a primeira vez em um desafio de código de golfe). Qualquer crítica construtiva é bem-vinda e apreciada. Tentei seguir as diretrizes para publicação, se algo não estiver certo, fique à vontade para apontar.

Versão embelezada:

int f(int[] a) {
    int x = a.length - 1, b[] = new int[x];
    for (; x-- > 0;) {
        b[x] = a[x + 1] - a[x];
    }
    return java.util.Arrays.stream(a).distinct().count() < 2 ? 0 : 1 + f(b);
}

3
Bem vindo ao site!
DJMcMayhem

Em vez de importar esses módulos você pode apenas usarjava.util.stream.IntStream k = java.util.Arrays.stream(a);
PunPun1000

De fato, existem algumas alterações que você pode fazer gratuitamente. 1) publicnão precisa ser incluído na contagem de bytes. 2) Você não deve aceitar um segundo parâmetro, mas removê-lo pode realmente salvar bytes. 3) você pode remover alguns suportes desnecessários lá
PunPun1000

4) Não é um saver mas você deve incluir uma TIO se possível, aqui está um exemplo com essas sugestões em 198 bytes TIO
PunPun1000


3

Haskell, 46 bytes

g l|all(==l!!0)l=0|0<1=1+g(zipWith(-)l$tail l)

isso simplesmente se repete - zipWith(-)l$last lé a lista de diferenças de l. e gé a função que responde à pergunta.


a solução recursiva foi a boa.
jferard

@jferard isso é muito verdadeiro
proud haskeller 13/09/17

3

Kotlin , 77 bytes

primeiro post, tentou editar a última resposta no kotlin 2 vezes; D

{var z=it;while(z.any{it!=z[0]})z=z.zip(z.drop(1),{a,b->a-b});it.size-z.size}

fez parte do teste de @jrtapsell

TryItOnline


Bem-vindo ao PPCG! Ótima primeira resposta, um outgolf também.
H.PWiz

3

APL (Dyalog Classic) , 22 17 bytes

{1=≢∪⍵:01+∇2-/⍵}

Experimente online!

Graças a @ngn por -5 bytes!

Quão?

  • { ... }, a função
  • 1=≢∪⍵:0, se todo elemento for igual no argumento, retorne 0
  • 1+∇2-/⍵caso contrário, retorne 1 + ndas diferenças (ou seja n-1, adicionar uma delas fornece n)

é mais curto se você sacrificar a recursividade da cauda:{1=≢∪⍵:0⋄1+∇2-/⍵}
ngn

2

Geléia , 7 bytes

IÐĿEÐḟL

Experimente online!

Explicação

IÐĿEÐḟL  Main link
 ÐĿ      While results are unique (which is never so it stops at [])
I        Take the increments, collecting intermediate values # this computes all n-th differences
    Ðḟ   Filter out
   E     Lists that have all values equal (the first n-th difference list that is all equal will be removed and all difference lists after will be all 0s)
      L  Take the length (this is the number of iterations required before the differences become equal)

-1 byte graças a Jonathan Allan


1
@Gryphon Done! :)
HyperNeutrino

IÐĿEÐḟLpor sete (vejo Miles também encontrou sete usando recursão).
Jonathan Allan

@JonathanAllan Cool thanks!
HyperNeutrino

2

05AB1E , 7 bytes

[DË#¥]N

Experimente online!

Explicação

[         # start loop
 D        # duplicate current list
  Ë       # are all elements equal?
   #      # if so, break
    ¥     # calculate delta's
     ]    # end loop
      N   # push iteration counter

2

JavaScript (ES6), 58 bytes

f=a=>+(b=a.slice(1).map((e,i)=>e-a[i])).some(e=>e)&&1+f(b)

+0, Jquery insuficiente: p. Realmente, +1, bom trabalho, eu sei que nunca seria capaz de jogar golfe no JS.
Zacharý 11/09/17

2

Python 2 , 65 bytes

-7 bytes graças a Jonathan Allan.

f=lambda l,c=1:any(l)and f([j-i for i,j in zip(l,l[1:])],c-1)or-c

Experimente online!


Salve um byte inicializando cem 1, decrementando e depois usando print-c.
Jonathan Allan

Economize mais seis transformando-a em uma função recursiva:f=lambda l,c=1:any(l)and f([j-i for i,j in zip(l,l[1:])],c-1)or-c
Jonathan Allan

Sou apenas eu ou a mudança para um lambda recursivo não está salvando bytes suficientes? : P Obrigado!
totallyhuman

Eu acho que isso precisa max(...,0)passar nos [1, 1, 1, 1, ...]casos de teste.
Yonatan N

2

Dyalog APL, 19 bytes

≢-1+(≢2-/⍣{1=≢∪⍵}⊢)

Explicação:

≢                      length of input
 -1+(             )    minus 1+
     ≢                 length of
      2-/              differences between elements
         ⍣             while
          {1=≢∪⍵}      there is more than 1 unique element
                 ⊢     starting with the input

1
Isto funciona? ≢-1+∘≢2-/⍣{1=≢∪⍵}⊢
Zachary

2

k , 21 bytes

#1_(~&/1_=':)(1_-':)\

Isso funciona em k, mas não em OK, porque o loop while de OK é executado antes de verificar a condição (em vez de primeiro verificar a condição e depois executar o código). Portanto, em OK, o 1 1 1 1 1exemplo não funcionará corretamente.

Experimente oK online!

Executando o exemplo k com 1 1 1 1 1 1 no interpretador k.

Explicação:

   (        )       \ /while(
    ~&/               /      not(min(
       1_=':          /              check equality of all pairs))) {
             (1_-':)  /    generate difference list
                      /    append to output }
#1_                   /(length of output) - 1

~&/1_=':->1<#?
NGN

2

Haskell , 66 61 60 bytes

z=(=<<tail).zipWith
f=length.takeWhile(or.z(/=)).iterate(z(-))

Experimente online!

Economizou 5 bytes graças a Christian Sievers

Guardado 1 byte graças a proud-haskeller

iterate(z(-)) calcula as listas de diferenças.

or.z(/=) testa se há elementos não iguais nessas listas.

length.takeWhile conta as listas de diferenças com elementos não iguais.


Eu acho que você pode testar para elementos não-igualdade comor.z(/=)
Christian Sievers

@ChristianSievers thanks! Isso era óbvio, mas eu não vê-lo ...
jferard

Você também pode usar z=(=<<tail).zipWith, um byte mais curto
proud haskeller

@proudhaskeller e mais elegante, como sempre com definições sem pontos. Obrigado!
jferard


2

Japonês , 7 bytes

A mesma abordagem (mas derivada de forma independente) que Justin com uma implementação diferente.

£=äaÃèx

Teste-o


Explicação

Entrada implícita da matriz U.

£   Ã

Mapa sobre cada elemento.

äa

Pegue cada par sequencial ( ä) de elementos Ue reduza-o pela diferença absoluta ( a).

=

Reatribua essa matriz para U.

èx

Count ( è) o número de sub-matrizes que retornam verdade (ou seja, diferentes de zero) quando reduzidas pela adição.


1

TI-Basic, 19 bytes

While max(abs(ΔList(Ans
ΔList(Ans
IS>(A,9
End
A

Por padrão, as variáveis ​​começam em zero. Além disso, nunca pensei que eu estaria usando IS>(para algo útil.


1

C # (.NET Core) , 70 69 + 18 bytes

-1 byte graças a Kevin Cruijssen

g=a=>i=>a.Distinct().Count()>1?g(a.Zip(a.Skip(1),(y,z)=>y-z))(i+1):i;

Deve ser atribuído 0 ao chamar para operar corretamente. Também incluído na contagem de bytes:

using System.Linq;

Experimente online!

Explicação:

g = a => i =>                      // Function taking two arguments (collection of ints and an int)
    a.Distinct()                   // Filter to unique elements
    .Count() > 1 ?                 // If there's more than one element
        g(                         //     Then recursively call the function with
            a.Zip(                 //     Take the collection and perform an action on corresponding elements with another one
                a.Skip(1),         //         Take our collection starting at second element
                (y, z) => y - z    //         Perform the subtraction
            )
        )(i + 1)                   //     With added counter
        : i;                       // Otherwise return counter

Versão iterativa 84 + 18 bytes:

a=>{int i=0;for(;a.Distinct().Count()>1;i++)a=a.Zip(a.Skip(1),(y,z)=>y-z);return i;}

Experimente online!


1
Você pode remover o espaço redundante em (y,z)=>y-z. Mas boa resposta, +1 de mim.
Kevin Cruijssen

@KevinCruijssen thank you! Além disso, oops.
Grzegorz Puławski

1

Clojure, 62 bytes

#(loop[c % i 0](if(apply = c)i(recur(map -(rest c)c)(inc i))))

Bem =pode aceitar qualquer número de argumentos, e um único argumento é idêntico a "ele mesmo". (apply = [1 2 3])é executado como (= 1 2 3).


Bom, exatamente o que eu estava tentando fazer, mas estava lutando por uma comparação compacta de pares. Isso é brilhante, vou ter que lembrar disso para o futuro.
MattPutnam

1

Pitão , 15 bytes

W.E.+Q=.+Q=hZ)Z

Verifique todos os casos de teste.

Quão?

Explicação nº 1

W.E.+Q=hZ=.+Q)Z   ~ Full program.

W                 ~ While...
 .E.+Q            ~ ... The deltas of Q contain a truthy element.
      =hZ         ~ Increment a variable Z, which has the initial value of 0.
         =        ~ Transform the variable to the result of a function applied to itself...
          .+Q     ~ ... Operate on the current list and deltas.
             )Z   ~ Close the loop and output Z.

-1 byteWtl{Q=hZ=.+Q)Z
Dave

@ Dave Ainda melhor: WP{Q=hZ=.+Q)Z. Obrigado!
Mr. Xcoder

0

Perl 5 , 83 + 1 (-a) = 84 bytes

sub c{$r=0;$r||=$_-$F[0]for@F;$r}for(;c;$i=0){$_-=$F[++$i]for@F;$#F--}say y/ //-$#F

Experimente online!

Insira como uma lista de números separados por um espaço.



0

Pitão, 10 bytes

tf!t{.+FQt

Se conseguirmos indexar a partir de 1, podemos salvar um byte removendo o líder t.

Experimente Online

Explicação

tf!t{.+FQt
 f        T  Find the first (1-indexed) value T...
     .+FQt   ... such that taking the difference T - 1 times...
  !t{        ... gives a set with more than one value in it.
t            0-index.

0

Kotlin , 83 bytes

{var z=it
var c=0
while(z.any{it!=z[0]}){c++
z=(0..z.size-2).map{z[it+1]-z[it]}}
c}

Embelezado

{
    // Make input mutable
    var z=it
    // Count for returning
    var c=0
    // While the array is not identical
    while (z.any { it != z[0] }) {
        // Increment count
        c++
        // Update list to differences
        z = (0..z.size-2).map { z[it+1] - z[it] }
    }
    // Return count
    c
}

Teste

var n:(List<Int>)->Int =
{var z=it
var c=0
while(z.any{it!=z[0]}){c++
z=(0..z.size-2).map{z[it+1]-z[it]}}
c}

data class TestData(var input: List<Int>, var output: Int)

fun main(args: Array<String>) {
    val items = listOf(
        TestData(listOf(1,2,3,4,5,6,7,8,9,10), 1),
        TestData(listOf(1,4,9,16,25,36), 2),
        TestData(listOf(1,2,1), 2),
        TestData(listOf(1,1,1,1,1,1,1,1,1), 0),
        TestData(listOf(1, 3, 9, 26, 66, 150, 313, 610), 6)
    )

    val fails = items.map { it to n(it.input) }.filter { it.first.output != it.second }

    if (fails.isEmpty()) {
        println("Test passed")
    } else {
        fails.forEach {println("FAILED: $it")}
    }
}

TryItOnline


Se alguém poderia editar para corrigir minhas dicas idioma, por favor, eu não consigo fazê-los trabalhar
jrtapsell

Não é lang-kotlinsimplesmente kotlinnas dicas do marcador.
Ruslan

0

Swift 4 , 90 bytes

func f(_ a:[Int])->Int{return a.contains{$0 != a[0]} ?f(zip(a, a.dropFirst()).map(-))+1:0}

Implementação alternativa baseada em fechamento:

var f: ((_ input: [Int]) -> Int)!
f = {a in a.contains{$0 != a[0]} ?f(zip(a, a.dropFirst()).map(-))+1:0}

casos de teste:

let testcases: [(input: [Int], expected: Int)] = [
    (input: [1,2,3,4,5,6,7,8,9,10],           expected: 1),
    (input: [1,4,9,16,25,36],                 expected: 2),
    (input: [1,2,1],                          expected: 2),
    (input: [1,1,1,1,1,1,1,1,1],              expected: 0),
    (input: [1, 3, 9, 26, 66, 150, 313, 610], expected: 6),
]

for (caseNumber, testcase) in testcases.enumerated() {
    let actual = f(testcase.input)
    assert(actual == testcase.expected,
        "Testcase #\(caseNumber) \(testcase.input) failed. Got \(actual), but expected \(testcase.expected)!")
    print("Testcase #\(caseNumber) passed!")
}
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.