Progressões aritméticas


11

Sua tarefa é analisar a entrada e gerar a fórmula para o n-ésimo termo, se for uma sequência aritmética, caso contrário, deverá imprimir "NAAP".


Entrada

A entrada (do STDIN) consistirá em poucos números, entre 4 e 10 números em que cada número estará no intervalo entre -1000 e 1000, inclusive, separados por um delimitador (um espaço ou vírgula ou ponto e vírgula [o que for sua preferencia]). Aqui estão alguns exemplos de entradas.

12,14,16,18       //valid
-3 4 5 1 -2 -4    //valid
45;35;-35         //invalid (only three numbers are present instead of the minimum of 4 numbers)
2,32;21,321       //invalid (it uses two different delimiters: `,` and `;`)

Resultado

O programa deve primeiro verificar se a entrada é uma progressão aritmética ou não.

Progressões aritméticas (PA) em poucas palavras: todo PA terá uma diferença comum. Essa é a diferença entre os termos $ n $ e $ {n-1} $ th (basicamente $ a (n + 1) - a (n) $, onde aé a função da sequência). Essa diferença permanece a mesma para qualquer valor de $ n $ em um AP. Se não houver diferença comum, então é não uma sequência de aritmética. Para calcular o valor do n-ésimo termo, use esta fórmula $ a (n) = a (1) + (n-1) d $ em que $ a (1) $ é o primeiro termo e $ d $ é o comum diferença.

Se não for uma progressão aritmética, o programa deverá imprimir a mensagem de erro "NAAP" (abreviação de "Não é uma progressão aritmética").

Se for uma progressão aritmética, o programa deverá imprimir o n-ésimo termo simplificado da sequência em STDOUT.

Exemplo:

> 1,3,5,7,9
2n-1

Explicação: Este é um AP porque existe uma diferença comum ($ 3 - 1 = 2 $). Então você usa a fórmula $ a (n) = a (1) + (n-1) d $

uman=uma1+(n-1)d

uman=1+(n-1)2

uman=1+2n-2

uman=2n-1

Portanto, a saída é 2n-1(observe a ausência de espaços)


As brechas padrão não são permitidas por padrão.

Você pode criar uma função se desejar (com a matriz de números como seu parâmetro). Caso contrário, você deve criar um programa completo que aceite a entrada como uma sequência de caracteres ou uma matriz e produza adequadamente.

Casos de teste:

1

1,3,5,7,9
2n-1

2)

1 3 12312 7 9
NAAP

3)

-6;8;22;36;50
14n-20

4)

5,1,-3,-7,-11,-15
-4n+9

5)

-5,-7,-9,-11,-13,-15
-2n-3

6

3,3,3,3,3,3,3,3,3
0n+3

7)

-4,-5,-6,-7
-1n-3

Isso é então o código mais curto em bytes vence! (desculpe pelo mau math-jax)

Todas as sugestões são bem-vindas!


4
Você provavelmente deve manter sua postagem na sandbox por mais de uma hora ...
Mego

3
Uma hora é um tempo muito curto. Nem todo mundo verifica a caixa de areia constantemente. 24 horas é um bom mínimo.
Mego

8
Desculpe, mas embora o MathJax funcione no Meta, ele não funciona no site principal do PPCG ...
ETHproductions

1
Você deve adicionar casos de teste com sequências decrescentes.
lirtosiast

2
São 0,0,0,0e 3,1,-1,-3,-5progressões aritméticas? Nesse caso, acho que seriam bons casos de teste, pois quebraram um método que eu estava tentando.
Xnor

Respostas:


5

Pitão, 30 bytes

?tJ{-VtQQ"NAAP"+hJ%"n%+d"-hQhJ

Suíte de teste

Para verificar se é uma procissão aritmética, isso usa uma subtração vetorizada entre cada elemento e o anterior -VtQQ. Um ternário verifica se há vários valores no resultado ( ?tJ{) e imprime NAAPse houver. Então, para acertar +ou -acertar, a formatação mod %+dé usada.


3

Haskell, 103 bytes

z=(tail>>=).zipWith
f l@(a:b:_:_:_)|and$z(==)$z(-)l=show(b-a)++'n':['+'|b-a<=a]++show(a+a-b)
f _="NAAP"

Exemplo de uso:

f [-6,8,22,36,50]   ->   "14n-20"
f [60,70,80,90]     ->   "10n+50"
f [2,3,4,6,7,8]     ->   "NAAP"

Como sempre em Haskell, a formatação de saída sofisticada (por exemplo, misturando números com seqüências de caracteres) consome muitos bytes (cerca de 40). A lógica do programa é bastante compacta:

f l@(a:b:_:_:_)           -- pattern match an input list with at least 4 elements,
                          -- call the whole list l, the first two elements a and b
z=(tail>>=).zipWith       -- the helper function z takes a function f and a list l
                          -- and applies f element wise to the tail of l and l

           z(-)l          -- make a list of neighbor differences
     z(==)                -- then compare these differences for equality
 and                      -- and see if only True values occur

       show ...           -- if so format output string

f _="NAAP"                -- in all other cases ( < 4 elements or False values)
                          -- return "NAAP"

2

TI-BASIC, 70 bytes

Input X
ΔList(∟X->Y
If variance(Ans
Then
∟X(1)-min(Ans
Text(0,0,min(∟Y),"n",sub("+-",(Ans<0)+1,1),abs(Ans
Else
"NAAP

Para remediar a falta de conversão de número em string do TI-BASIC, ele usa a saída na tela de gráfico ( Text() se a progressão for aritmética, que concatena automaticamente os argumentos.

Isso pressupõe que os números negativos sejam inseridos usando o caractere de menos-alto do TI-BASIC (que parece um pouco ), e não o sinal de menos-binário. No entanto, a saída usa o sinal de menos binário.


2

Japt , 60 52 51 bytes

V=N¤£X-NgY+1};W=Vg;Ve_¥W} ?W+'n+'+sU<W +(U-W :"NAAP

Experimente online!

A entrada pode ser fornecida com o separador que você quiser, pois é assim que o intérprete é projetado;)

Ungolfed e explicação

V=N¤  £    X-NgY+1};W=Vg;Ve_  ¥ W} ?W+'n+'+sU<W +(U-W :"NAAP
V=Ns2 mXYZ{X-NgY+1};W=Vg;VeZ{Z==W} ?W+'n+'+sU<W +(U-W :"NAAP

            // Implicit: N = list of inputs, U = first input
V=Ns2       // Set variable V to N, with the first 2 items sliced off,
mXYZ{       // with each item X and index Y mapped to:
X-NgY+1}    //  X minus the item at index Y+1 in N.
            // This results in a list of the differences (but the first item is NaN).
W=Vg;       // Set W to the first item in V (the multiplication part).
VeZ{Z==W}   // Check if every item in V is equal to W.
?W+'n+      // If true, return W + "n" +
'+sU<W      //  "+".slice(U<W) (this is "+" if U >= W, and "" otherwise)
+(U-W       //  + (U minus W [the addition part]).
:"NAAP      // Otherwise, return "NAAP".
            // Implicit: output last expression

1

Matlab, 103 bytes

x=str2num(input('','s'));y=diff(x);if range(y) disp('NAAP'),else fprintf('%gn%+g\n',y(1),x(1)-y(1)),end

1

CJam, 38 bytes

{:T2ew::-):U-"NAAP"UW*"n%+d"T0=U+e%+?}

Essa é uma função anônima que pega uma matriz na pilha como entrada e deixa uma string na pilha como saída. Experimente online com código de E / S adicional para teste.

Explicação:

:T      Save a copy of input in variable T for output generation.
2ew     Generate list of pairs of sequential elements.
::-     Reduce all pairs with subtraction operator.
)       Pop last value from list of differences.
:U      Save difference value in variable U for output generation.
-       Set difference. This will leave an empty list (falsy) if all values are the same.
"NAAP"  First value for ternary operator, for case where not all values are the same.
UW*     Start generating output for success case. Need to flip sign of difference saved
        in variable U, since it was 1st value minus 2nd, and we need the opposite.
"n%+d"  Push format string for printf operator. The + sign in the format specifies that
        the sign is always generated, saving us from needing different cases for the
        value being negative or positive.
T0=     Extract first value from original input saved in variable T.
U+      Add the difference (with the "wrong" sign) to it.
e%      "printf" operator.
+       Concatenate two parts of result.
?       Ternary operator for picking one of the two output cases.

1

JavaScript (ES6), 91 bytes

x=>(s=x.split`,`,m=s[1]-s[0],a=s[0]-m,s.some((n,i)=>n!=m*i+m+a)?"NAAP":m+"n"+(a<0?a:"+"+a))

Explicação

x=>(
  s=x.split`,`,       // s = array of input numbers
  m=s[1]-s[0],        // m = the multiplication part of the formula
  a=s[0]-m,           // a = the addition part of the formula
  s.some((n,i)=>      // check if the rest of the numbers follow this sequence
    n!=m*i+m+a
  )?"NAAP":
  m+"n"+(a<0?a:"+"+a) // output the formula
)

Teste

<input type="text" id="input" value="5,1,-3,-7,-11,-15" /><button onclick='result.innerHTML=(

x=>(s=x.split`,`,m=s[1]-s[0],a=s[0]-m,s.some((n,i)=>n!=m*i+m+a)?"NAAP":m+"n"+(a<0?a:"+"+a))

)(input.value)'>Go</button><pre id="result"></pre>


1

Perl 6, 123 102 101 bytes

EDIT: Não negue a diferença

EDIT: use sub anônimos, operadores lógicos e interpolação de strings. Obrigado Brad Gilbert b2gills

sub{my@b=@_.rotor(2=>-1).map({[-] $_}).squish;$_=@_[0]+@b[0];@b.end&&"NAAP"||"@b[0]n{'+'x($_>=0)}$_"}

Programa de teste (leituras de stdin):

my $f = <the code above>
$f(split(/<[;,]>/, slurp)).say

Explicação:

my @b =
  @_.rotor(2=>-1)  # sliding window of 2: (1,2,3,4) => ((1,2),(2,3),(3,4))
  .map({[-] $_})  # calculate difference (subtract all elements and negate)
  .squish;         # remove adjacent elements that are equal

@b.end        # @b.end is last index, @b.end = 0 means @b has only 1 element
&& "NAAP"     # true branch
|| "@b[0]n{'+'x($_>=0)}$_" # string for an+b, 
        # {'+'x($_>=0)} inserts a plus sign using the repetition operator x

Normalmente, você usaria um dos formulários de expressão lambda para remover o sub f. Além disso, se você usou em @_vez de @asalvar vários bytes. {my@b=@_.rotor.... Além disso, você não deve colocar parênteses em torno da condição de uma ifinstrução, isso não é o Perl 5. Se você alterou isso ifpara @b.end&&"NAAP"||$_=...salvar mais alguns bytes. Você também pode acabar com essa última ifinstrução se tiver usado "@b[0]n{'+'x($_>=0)}$_", salvando 4 bytes.
Brad Gilbert b2gills

Você não precisa subno começo, sem que isso se torne um bloco anônimo. Além disso, só para você saber, eu não teria pensado em usá- .map({[-] $_})lo. Provavelmente usaria ».map(*-*).flatmais, agora tenho que passar por minhas próprias entradas para ver se consigo reduzi-lo com seu truque.
Brad Gilbert b2gills

1

Ruby, 95 78 76 bytes

->s{i,j=s;puts s.reduce(:+)==s.size*(s[-1]+i)/2?"%dn%+d"%[v=j-i,i-v]:"NAAP"}

78 bytes

->s{puts s.reduce(:+)==s.size*(s[-1]+i=s[0])/2?"%dn%+d"%[v=s[1]-i,i-v]:"NAAP"}

95 bytes

->s{puts s.reduce(:+)==s.size*(s[0]+s[-1])/2?"#{v=s[1]-s[0]}n#{"+"if (i=s[0]-v)>0}#{i}":"NAAP"}

Ungolfed:

-> s {
  i,j=s
  puts s.reduce(:+)==s.size*(s[-1]+i)/2?"%dn%+d"%[v=j-i,i-v]:"NAAP"
}

Uso:

->s{i,j=s;puts s.reduce(:+)==s.size*(s[-1]+i)/2?"%dn%+d"%[v=j-i,i-v]:"NAAP"}[[-6,8,22,36,50]]

=> 14n-20

0

Python 3, 92 bytes
Com base na minha resposta de Find the Sequence

def m(t):s=str;a=t[0];b=t[1];q=b-a;return((s(q)+'n'+'+'*(0<a-q)+s(a-q)),'NAAP')[t[2]/b==b/a]

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.