Antsy permutações


37

Introdução

Suponha que você tenha uma régua com números de 0 a r-1 . Você coloca uma formiga entre dois números e ela começa a engatinhar erraticamente na régua. A régua é tão estreita que a formiga não pode andar de uma posição para outra sem andar em todos os números intermediários. Quando a formiga anda em um número pela primeira vez, você o grava, e isso permite uma permutação dos números r . Dizemos que uma permutação é antipática se puder ser gerada por uma formiga dessa maneira. Alternativamente, uma permutação p é antipática se todas as entradas p [i], exceto a primeira, estiverem a uma distância de uma entrada anterior.

Exemplos

A permutação comprimento-6

4, 3, 5, 2, 1, 0

é impaciente, porque 3 está à distância 1 de 4 , 5 está à distância 1 de 4 , 2 está à distância 1 de 3 , 1 está à distância 1 de 2 e 0 está à distância 1 de 1 . A permutação

3, 2, 5, 4, 1, 0

não é impaciente, porque 5 não está à distância 1 de 3 ou 2 ; a formiga teria que passar por 4 para chegar a 5 .

A tarefa

Dada uma permutação dos números de 0 a r-1 por cerca de 1 ≤ r ≤ 100 em qualquer formato razoável, produza um valor verdadeiro se a permutação for antsy e um valor false se não.

Casos de teste

[0] -> True
[0, 1] -> True
[1, 0] -> True
[0, 1, 2] -> True
[0, 2, 1] -> False
[2, 1, 3, 0] -> True
[3, 1, 0, 2] -> False
[1, 2, 0, 3] -> True
[2, 3, 1, 4, 0] -> True
[2, 3, 0, 4, 1] -> False
[0, 5, 1, 3, 2, 4] -> False
[6, 5, 4, 7, 3, 8, 9, 2, 1, 0] -> True
[4, 3, 5, 6, 7, 2, 9, 1, 0, 8] -> False
[5, 2, 7, 9, 6, 8, 0, 4, 1, 3] -> False
[20, 13, 7, 0, 14, 16, 10, 24, 21, 1, 8, 23, 17, 18, 11, 2, 6, 22, 4, 5, 9, 12, 3, 15, 19] -> False
[34, 36, 99, 94, 77, 93, 31, 90, 21, 88, 30, 66, 92, 83, 42, 5, 86, 11, 15, 78, 40, 48, 22, 29, 95, 64, 97, 43, 14, 33, 69, 49, 50, 35, 74, 46, 26, 51, 75, 87, 23, 85, 41, 98, 82, 79, 59, 56, 37, 96, 45, 17, 32, 91, 62, 20, 4, 9, 2, 18, 27, 60, 63, 25, 61, 76, 1, 55, 16, 8, 6, 38, 54, 47, 73, 67, 53, 57, 7, 72, 84, 39, 52, 58, 0, 89, 12, 68, 70, 24, 80, 3, 44, 13, 28, 10, 71, 65, 81, 19] -> False
[47, 48, 46, 45, 44, 49, 43, 42, 41, 50, 40, 39, 38, 51, 37, 36, 52, 35, 34, 33, 32, 53, 54, 31, 30, 55, 56, 29, 28, 57, 58, 59, 60, 27, 26, 61, 25, 62, 63, 64, 65, 66, 67, 24, 23, 22, 21, 68, 69, 20, 19, 18, 17, 70, 71, 16, 15, 72, 73, 74, 75, 76, 14, 13, 12, 77, 11, 10, 9, 8, 78, 7, 79, 80, 6, 81, 5, 4, 3, 82, 2, 83, 84, 1, 85, 86, 87, 0, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99] -> True

Curiosidade: para r ≥ 1 , existem exatamente 2 r-1 permutações de comprimento r .


7
Este é um desafio muito interessante, com muitas soluções diferentes: conto pelo menos 7 estratégias únicas sendo usadas até agora.
ETHproductions

11
A forma de entrada estruturada de permutações está contribuindo muito para a variedade de abordagens. A condição de ser impaciente pode ser expressa de diferentes maneiras que são diferentes nas listas gerais.
Xnor

11
Estou decepcionado por ainda não haver uma solução ANTSI C.
NoSeatbelts,

Respostas:


18

Pitão, 7 bytes

/y+_QQS

Experimente online. (Apenas casos de teste pequenos são incluídos devido ao tempo de execução exponencial.) Saídas 2 para Truthy, 0 para Falsey.

/          Count the number of occurences of
      S     the sorted input (implicit Q)
 y          in the order-preserved power set
  +_QQ       of the input prepended by its reverse

Em outras palavras,

lambda l: subseq(sorted(l), concat(reverse(l), l))

onde subseqgera se os elementos da primeira lista aparecem em ordem na segunda lista, não necessariamente adjacentes. A subseqé feito em Pyth tomando todos os subgrupos da segunda lista, que mantêm a ordem dos elementos, e contando o número de ocorrências da primeira lista. Isso leva tempo exponencial.

Por que isso funciona? Para que uma permutação seja impaciente, passar de 0 a n-1 deve consistir em ir apenas para a esquerda e depois apenas para a direita. Isso ocorre porque os elementos maiores que o primeiro devem aumentar da esquerda para a direita e os menores que devem diminuir da esquerda para a direita.

[2, 3, 1, 4, 0]
             ^
       ^     0
 ^     1      
 2  ^        
    3     ^
          4

Se espelharmos a lista colocando uma cópia invertida à sua esquerda, essa caminhada agora só dá certo.

[0, 4, 1, 3, 2, 2, 3, 1, 4, 0]
 ^            |             
 0     ^      |             
       1      | ^           
              | 2  ^        
              |    3     ^  
              |          4                                  

Por outro lado, qualquer parte direita da lista de espelhos corresponde a uma caminhada esquerda-direita da lista original. Este à direita é apenas uma subsequência classificada de 0 a n-1. Em uma lista impulsiva, essa subsequência classificada é única, exceto por uma escolha arbitrária entre as duas cópias adjacentes do primeiro elemento original.


7
Você pode reduzir para 6 bytes usando ... brincando.
Jwg # 24/16

2
Há algo de hediondo no uso de uma abordagem de tempo exponencial para um problema com uma solução óbvia de tempo linear, mesmo que ela diminua bastante.
David Conrad

@jwg Eu acreditaria, na verdade. Se a contagem da lista usar argumentos na ordem oposta, você poderá obter 6 bytes inserindo duas entradas implícitamente.
Xnor

ayyyyy, voltando-se para o lado pyth: D
Maltysen 25/10

11

Haskell, 46 bytes

(%)=scanl1
f l=zipWith(+)(min%l)[0..]==max%l

Verifica se a diferença do vetor dos máximos em execução e dos mínimos em execução é [0,1,2,3 ...].

l =             [2, 3, 1, 4, 0]

scanl1 max l =  [2, 3, 3, 4, 0]
scanl1 min l =  [2, 2, 1, 1, 0]  
difference =    [0, 1, 2, 3, 4]

O Zgarb salvou 2 bytes com (%)=scanl1.


Isso é tão inteligente! +1
Gabriel Benamy

11
Você poderia salvar alguns bytes definindo (#)=scanl1?
Zgarb

11
@ Zgarb Obrigado, eu esqueci que você poderia fazer isso.
Xnor

9

JavaScript (ES6), 45

a=>a.every((v,i)=>a[v]=!i|a[v-1]|a[v+1],a=[])

Eu pensei que era muito simples precisar de explicação, mas há um truque e, por precaução, aqui está minha primeira versão, pré-golfe

a => {
  k = []; // I'll put a 1 in this array at position of each value 
          // that I find scanning the input list
  return a.every((v,i) => { // execute for each element v at position i
    // the index i is needed to manage the first iteration
    // return 1/true if ok, 0/false if not valid
    // .every will stop and return false if any iteration return falsy
    k[v] = 1; // mark the current position
    if ( i == 0 )
    {  // the first element is always valid
       return true;
    }
    else
    {
       return k[v-1] == 1 // valid if near a lesser value
              || k[v+1] == 1; // or valid if near a greater value
    }
  })
}

Nota: no código golfed aé usado em vez de k, pois não preciso de referência à matriz original dentro da everychamada. Portanto, evito poluir o espaço para nome global reutilizando o parâmetro

Teste

antsy=
a=>a.every((v,i)=>a[v]=!i|a[v-1]|a[v+1],a=[])

var OkAll=true
;`[0] -> True
[0, 1] -> True
[1, 0] -> True
[0, 1, 2] -> True
[0, 2, 1] -> False
[2, 1, 3, 0] -> True
[3, 1, 0, 2] -> False
[1, 2, 0, 3] -> True
[2, 3, 1, 4, 0] -> True
[2, 3, 0, 4, 1] -> False
[0, 5, 1, 3, 2, 4] -> False
[6, 5, 4, 7, 3, 8, 9, 2, 1, 0] -> True
[4, 3, 5, 6, 7, 2, 9, 1, 0, 8] -> False
[5, 2, 7, 9, 6, 8, 0, 4, 1, 3] -> False
[20, 13, 7, 0, 14, 16, 10, 24, 21, 1, 8, 23, 17, 18, 11, 2, 6, 22, 4, 5, 9, 12, 3, 15, 19] -> False
[34, 36, 99, 94, 77, 93, 31, 90, 21, 88, 30, 66, 92, 83, 42, 5, 86, 11, 15, 78, 40, 48, 22, 29, 95, 64, 97, 43, 14, 33, 69, 49, 50, 35, 74, 46, 26, 51, 75, 87, 23, 85, 41, 98, 82, 79, 59, 56, 37, 96, 45, 17, 32, 91, 62, 20, 4, 9, 2, 18, 27, 60, 63, 25, 61, 76, 1, 55, 16, 8, 6, 38, 54, 47, 73, 67, 53, 57, 7, 72, 84, 39, 52, 58, 0, 89, 12, 68, 70, 24, 80, 3, 44, 13, 28, 10, 71, 65, 81, 19] -> False
[47, 48, 46, 45, 44, 49, 43, 42, 41, 50, 40, 39, 38, 51, 37, 36, 52, 35, 34, 33, 32, 53, 54, 31, 30, 55, 56, 29, 28, 57, 58, 59, 60, 27, 26, 61, 25, 62, 63, 64, 65, 66, 67, 24, 23, 22, 21, 68, 69, 20, 19, 18, 17, 70, 71, 16, 15, 72, 73, 74, 75, 76, 14, 13, 12, 77, 11, 10, 9, 8, 78, 7, 79, 80, 6, 81, 5, 4, 3, 82, 2, 83, 84, 1, 85, 86, 87, 0, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99] -> True`
.split`\n`.forEach(row => {
  var rowElements = row.match(/\w+/g), 
      expected = rowElements.pop()=='True',
      input = rowElements.map(x => +x),
      result = antsy(input),
      ok = result == expected;
  OkAll = OkAll && ok;
  console.log(ok?'OK':'KO', input+' -> '+result)
})
console.log(OkAll ? 'All passed' : 'Failed')


Muito legal. Eu tentei essa abordagem com recursão, mas não consigo obtê-la abaixo de 65:f=([q,...a],x=[])=>x&&(x[q]=!(x+x)|x[q+1]|x[q-1])&&(a+a?f(a,x):1)
ETHproductions

Como é que isso funciona? Você está usando alguma mágica de lista mutável?
Zgarb

@Zgarb explanation added
edc65

6

Python 2, 49 bytes

f=lambda l:l==[]or max(l)-min(l)<len(l)*f(l[:-1])

Verifica se cada prefixo da lista contém todos os números entre o mínimo e o máximo, inclusive. Isso é feito verificando se a diferença entre max e min é menor que seu comprimento.


54 bytes:

f=lambda l:1/len(l)or-~l.pop()in[min(l),max(l)+2]*f(l)

Verifica se o último elemento é um a menos que o mínimo dos outros elementos ou um a mais que o máximo. Em seguida, remove o último elemento e se repete. Em uma lista de elemento único, gera True.

Isso também pode ser verificado através de uma compreensão de lista divertida, mas mais longa.

lambda l:all(l.pop()in[min(l)-1,max(l)+1]for _ in l[1:])

Eu gostaria de usar a desigualdade min(l)-2<l.pop()<max(l)+2, mas as popnecessidades precisam acontecer primeiro. Usar um programa para produzir via código de erro provavelmente seria mais curto.


6

Mathematica, 42 bytes

!MatchQ[#,{a__,b_,___}/;Min@Abs[{a}-b]>1]&

Usa a correspondência de padrões para tentar encontrar um prefixo acuja diferença máxima do próximo elemento bseja maior que 1(e negue o resultado de MatchQ).


6

Perl, 39 38 35 bytes

Inclui +1 para -p

Dê sequência em STDIN:

antsy.pl <<< "2 1 3 0"

antsy.pl:

#!/usr/bin/perl -p
s%\d+%--$a[$&]x"@a"=~/1  /%eg;$_++

2
Estou tendo dificuldade em entender esse ... Importa-se de explicar um pouco? obrigado :-) (apenas a idéia principal deve ser suficiente) #
Dada

4

MATL , 11 bytes

&-|R1=a4L)A

Experimente online! Ou verifique todos os casos de teste .

Explicação

Isso calcula uma matriz de todas as diferenças absolutas aos pares e mantém a parte triangular superior. O resultado é verdadeiro se houver pelo menos um valor 1 em todas as colunas, exceto a primeira.

&-     % All pairwise differences
|      % Absolute value
R      % Upper triangular part
1=     % Does each entry equal 1?
a      % Logical "or" along each column
4L)    % Remove first value
A      % Logical "and" of all results

4

R, 72 64 60 bytes

v=scan();for(i in seq(v))T=c(T,diff(sort(v[1:i])));all(T==1)

Uma permutação é irritante se, e somente se, todas as suas subpermutações esquerdas forem contínuas (ou seja, tiverem uma diferença quando classificadas).

Se é garantido que a entrada tem comprimento superior a um, podemos substituí-lo 1:sum(1|v)por seq(v), o que salva quatro bytes.

A seq(v)condição if se comporta de maneira diferente quando a entrada tem um comprimento --- gera a sequência em 1:vvez de seq_along(v). No entanto, felizmente, a saída acaba sendo TRUEnesse caso, que é o comportamento desejado. O mesmo acontece com a entrada de comprimento zero.

Em R, Té uma variável predefinida igual a TRUE(mas R permite redefini-la). TRUEtambém é considerado igual a 1.

Agradecemos a @Billywob por algumas melhorias úteis na solução original.


11
A leitura da entrada usando scanpouparia dois bytes. Nesse caso, é exatamente o mesmo número de bytes da forabordagem de loop: v=scan();c=c();for(i in 1:sum(1|v))c=c(c,diff(sort(v[1:i])));all(c==1)que seria 2 bytes mais curto que a sua abordagem vetorizada.
Billywob

Boa idéia, e eu posso ir melhor, abusando T. Irá editar.
JDL #


3

Perl, 63 bytes

Observe que @ Gabriel Banamy apresentou uma resposta mais curta (55 bytes) . Mas acho que essa solução ainda é interessante, por isso estou publicando.

A contagem de bytes inclui 62 bytes de código e -nsinalizador.

s/\d+/1x($&+1)/ge;/ 1(1*)\b(?{$.&=$`=~m%\b(11)?$1\b%})^/;say$.

Para executá-lo:

perl -nE 's/\d+/1x($&+1)/ge;/ 1(1*)\b(?{$.&=$`=~m%\b(11)?$1\b%})^/;say$.' <<< "3 2 5 4 1 0"

Explicações breves : converte cada número kna representação unária de k+1(isso +1é necessário para que os 0s não sejam ignorados). Então, para cada número k+1(expresso em unário como 1(1*)), verificamos se k( $1espera k) ou k+2(que é então 11$1) está presente na string anterior (referenciada por $-backtick). Se não, então definimos $.como zero. No final, imprimimos o $.que será 1se nunca o definirmos como zero, ou zero caso contrário.


3

Brain-Flak 302 264 256 bytes

Agradecimentos ao Assistente de Trigo por salvar 46 bytes

([]){{}({}<>)<>([])}{}<>(({}))([]){{}({}<>)<>([])}{}<>(({}<>))<>(()){{}(({})<(({})<>[({})]<>(())){((<{}{}>))}{}{{}({}<><{}>)(<>)}{}<>({}<<>(({})<>[({})<>(())]){((<{}{}>))}{}{{}({}<><{}>)(<>)}{}<>>)<>>[({})](<()>)){{}{}(<(())>)}{}}([][()(())]){((<{}{}>))}{}

O topo da pilha será 1 para verdade e 0 para falsidade.

Truthy: Experimente online!
Falsy: Experimente on-line!

A idéia é manter o número mínimo e máximo que a formiga visitou na pilha off. Em seguida, compare cada número com os dois e atualize o número apropriado. Se o próximo número não for 1 a menos que o mínimo ou 1 a mais que o máximo, saia do loop e retorne false.


Breve explicação:

([])                             # duplicate the bottom element by
{{}({}<>)<>([])}{}<>             # reversing everything onto the other stack 
(({}))([])                       # duplicating the top element
{{}({}<>)<>([])}{}<>             # and reversing everything back

(({}<>))<>                       # copy the top element to the other stack (push twice)
(()){{}                          # push a 1 so the loop starts, and repeat until the top
                                 # two elements are equal
(({})<                           # hold onto the top element to compare later
(({})<>[({})]<>(()))             # push a 0 if diff with the top of the other stack is +1
{{}({}<><{}>)(<>)}{}             # logical not (the previous line pushed a 1 as the second
                                 # element already)
{{}({}<><{}>)<>(<()>)}{}         # replace the top of the other stack with this element if
                                 # the logical not gave us 1
<>({}<<>                         # take the minimum off the other stack temporarily 
(({})<>[({})<>(())])             # push a 0 if diff with the top of the other stack is -1
{((<{}{}>))}{}                   # logical not (the previous line pushed a 1 as the second
                                 # element already)
{{}({}<><{}>)(<>)}{}             # replace the top of the other stack with this element if
                                 # the logical not gave us 1
<>>)<>                           # put the minimum on back on
>)                               # put the element you were comparing back on
[({})](<()>)){{}{}(<(())>)}{}    # push 1 or 0 for not equal to the element we held earlier
                                 # (push the second number back on)
}                                # repeat the loop if the top 2 weren't equal
([][()(())]){((<{}{}>))}{}       # logical not of the height of the stack

Eu verificaria reduções push pop. Já vejo alguns lugares em que você pode usar essa estratégia.
Assistente de trigo

@WheatWizard Tenho certeza de que existem alguns, mas ainda não tive tempo de resolvê-los. Obrigado pela lembrança.
Riley #

Fico feliz que isso, pelo menos, faz sentido para você O_O
Gabriel Benamy

Você também pode substituir instâncias de ([]){({}[()]<({}<>)<>>)}{}com ([]){{}({}<>)<>([])}{}para salvar um casal mais bytes
Assistente de trigo

3

Geléia , 9 8 7 bytes

;@UŒPċṢ

Experimente Online!

Uma tradução em geléia da resposta do xnor.

Soluções antigas:

;\Ṣ€IỊȦ
;\Ṣ€IE€P

Experimente online!

Funciona de maneira muito semelhante à minha resposta Pyth abaixo:

;\          All prefixes (Accumulate (\) over concatenation (;))
  Ṣ€        (Ṣ)ort each (€) prefix
    I       (I)ncrements of each prefix (differences between consecutive elements).  Implicit vectorization.
     E€     Check if all elements are (E)qual (they will be iff the permutation is antsy,
               and all elements will be 1) for each (€) prefix
       P    Is this true for all prefixes?
     ỊȦ     For the other answer, are (Ȧ)ll elements 1 or less (Ị)?

A conversão de outro método de xnor para Jelly é também 7 bytes »\_«\⁼Ṣ, mas muito mais eficientes
milhas

ŒBŒPċṢe ;\Ṣ€IỊȦdeve salvar um byte em cada abordagem.
Dennis

Infelizmente, o primeiro não funciona porque eu precisaria que a entrada reversa fosse devolvida, como a UŒBŒPċṢque não salva bytes. O é bom, no entanto; Eu tinha interpretado mal esse átomo para gerar o NÃO lógico do que ele realmente fez.
Steven H.

Não sei por que você precisaria do U(ou do @agora que penso nisso). Se uma matriz é impaciente, então é a matriz invertida, não?
Dennis

11
Não necessariamente: [2, 1, 3, 0]é impaciente, mas [0, 3, 1, 2]não é.
Steven H.

3

CJam ( 21 20 bytes)

{:A,{_)A<$2*)@-#},!}

Conjunto de testes online

Dissecação

Isso usa a observação de xnor em sua resposta de Haskell de que a diferença entre o máximo e o mínimo dos primeiros nelementos deve ser n-1.

{         e# Define a block. Stack: array
  :A,     e#   Store the array in A and get its length
  {       e#   Filter (with implicit , so over the array [0 ... len-1])
    _)A<  e#     Get the first i+1 elements of A (so we iterate over prefixes)
    $2*)  e#     Extract the last element without leaving an empty array if the
          e#     prefix is of length 1 by first duplicating the contents of the
          e#     prefix and then popping the last element
    @-#   e#     Search the prefix for max(prefix)-i, which should be min(prefix)
          e#     giving index 0
  },      e#   So the filter finds values of i for which the prefix of length i+1
          e#   doesn't have max(prefix) - min(prefix) = i
  !       e#   Negate, giving truthy iff there was no i matching the filter
}

Abordagem alternativa (também 20 bytes)

{_{a+_)f-:z1&,*}*^!}

Conjunto de testes online

Isso verifica diretamente se cada elemento após o primeiro está à distância 1 de um elemento anterior. Como a entrada é uma permutação e, portanto, não repete valores, este é um teste suficiente. Agradecemos a Martin por economizar 1 byte.

Dissecação

{_{a+_)f-:z1&,*}*^!}

{         e# Declare a block. Stack: array
  _       e#   Work with a copy of the array
  {       e#   Fold...
    a+    e#     Add to the accumulator.
    _)f-  e#     Dup, pop last, map subtraction to get distance of this element from
          e#     each of the previous ones
    :z1&, e#     Check whether the absolute values include 1
    *     e#     If not, replace the accumulator with an empty array
  }*
  ^!      e#   Test whether the accumulator is equal to the original array
          e#   Note that this can't just be = because if the array is of length 1
          e#   the accumulator will be 0 rather than [0]
}

Eu acho que isso salva um? {_{a+_)f-:z1&,*}*^!}
Martin Ender

@MartinEnder, very nice. Curiosamente, você postou isso assim como eu estava postando uma abordagem completamente diferente com a mesma contagem de bytes.
Peter Taylor

3

Java, 100 98 79 75 bytes

a->{int n=a[0],m=n-1;for(int i:a)n-=i==m+1?m-m++:i==n-1?1:n+1;return n==0;}

Anteriormente:

a->{int m,n;m=n=a[0];--m;for(int i:a)if(i==m+1)m=i;else if(i==n-1)n=i;else return 0>1;return 1>0;}

Economizou 3 bytes substituindo truee falsecom 1>0e 0>1.

Economizou 23 bytes graças às excelentes sugestões de Peter Taylor!

Ungolfed:

a -> {
    int n = a[0], m = n - 1;
    for (int i : a)
        n -= i == m + 1? m - m++ : i == n - 1? 1 : n + 1;
    return n == 0;
}

Acompanhe os valores mais altos e mais baixos vistos até me n; aceite apenas um novo valor se este for, m + 1ou n - 1seja, o próximo valor mais alto ou mais baixo; inicialize o valor alto,, mpara um a menos que o primeiro elemento, para que ele "corresponda" na primeira vez no loop. Nota: este é um algoritmo online de tempo linear. Requer apenas três palavras de memória, para os valores atuais, mais alto até agora e mais baixo até agora, ao contrário de muitas outras soluções.

Se o próximo valor errar as extremidades alta e baixa da faixa, o valor mais baixo até agora é definido como -1e a extremidade baixa nunca pode prosseguir e chegar a zero. Em seguida, detectamos uma sequência antipática, verificando se o valor baixo natingiu zero.

(Infelizmente, isso é menos eficiente, porque sempre precisamos olhar para toda a sequência, em vez de resgatar o primeiro número errado , mas é difícil argumentar com uma economia de 23 bytes (!) Quando outras soluções estão usando O (n ^ 2 ) e abordagens de tempo exponencial.)

Uso:

import java.util.function.Predicate;

public class Antsy {
    public static void main(String[] args) {
        int[] values = { 6, 5, 4, 7, 3, 8, 9, 2, 1, 0 };
        System.out.println(test(values,
            a -> {
                int n = a[0], m = n - 1;
                for (int i : a)
                    n -= i == m + 1? m - m++ : i == n - 1? 1 : n + 1;
                return n == 0;
            }
        ));
    }

    public static boolean test(int[] values, Predicate<int[]> pred) {
        return pred.test(values);
    }
}

Nota: isso também pode ser escrito sem tirar proveito do Java 8 lambdas:

Java 7, 89 bytes

boolean c(int[]a){int n=a[0],m=n-1;for(int i:a)n-=i==m+1?m-m++:i==n-1?1:n+1;return n==0;}

Bom manuseio do caso especial. int m,n;m=n=a[0];--m;poderia ser int n=a[0],m=n-1;, e o caro returne elsepoderia ser reduzido com i==m+1?m++:n=(i==n-1)?i:-1;return n==0;(ou algo semelhante - eu não testei isso).
Peter Taylor

@PeterTaylor Fantastic! Infelizmente, o Java não permite efeitos colaterais como m++ou m+=1ali, então eu ainda preciso de um ife um else, e ele perde o aspecto de um curto-circuito no primeiro valor ruim, mas isso é uma grande melhoria. Obrigado!
David Conrad

Permitirá efeitos colaterais em uma expressão complexa. O que pode não gostar é usar uma expressão geral como uma declaração. Na pior das hipóteses, você precisa criar uma variável dummy je atribuir o resultado a ela, mas suspeite que haveria uma maneira melhor de fazê-lo.
Peter Taylor

@ PeterTaylor Bem, tentei algumas variações, incluindo atribuí-lo a uma variável dummy g, e não consegui fazê-lo funcionar. (Estou usando o Java 9-ea + 138, talvez seja uma diferença entre o Java 8 e o Java 9?). Posso tentar novamente amanhã.
David Conrad

Consegui. n-=i==m+1?m-m++:i==n-1?1:n+1;
Peter Taylor

2

Pitão ( bifurcação ), 13 bytes

!sstMM.+MSM._

Não há link Try It Online para este fork do Pyth. A bifurcação inclui a função deltas .+, que não faz parte da biblioteca Pyth padrão.

Explicação:

           ._  For each of the prefixes:
         SM    Sort it
      .+M      Get deltas (differences between consecutive elements), which for antsy
                 permutations would all be 1s
   tMM         Decrement each of the elements (all 0s for antsy permutations)
 ss            Sum all the results from the above together, 0 for antsy and >0 for non-antsy
!              Logical negation.

3
Vendo isso me convence a mesclar isso em Pyth.
Isaacg

2

Perl, 66 54 +1 = 55 bytes

+1 byte para -n.

s/\d+/$.&=!@a||1~~[map{abs$_-$&}@a];push@a,$&/eg;say$.

Explicação:

s/\d+/$.&=!@a||1~~[map{abs$_-$&}@a];push@a,$&/eg;say$.
#input is automatically read into $_.
#regex automatically is performed on $_.
s/   /                                       /eg;
    #Substitution regex.
    #/g means to keep searching after the first match
    #/e evaluates the replacement as code instead of regex.
  \d+  #Match of at least 1 digit.  Match automatically gets stored in $&
      $.&=  #$. is initially 1.  This basically says $. = $. & (code)
           !@a  #Since @a is uninitialized, this returns !0, or 1
                #We don't want to check anything for the first match
              || #logical or
                1~~
                   #~~ is the smartmatch operator.  When RHS is scalar and LHS is array reference,
                   #it returns 1 iff RHS is equal to at least one value in de-referenced LHS.
                   [map{abs$_-$&}@a];
                       #Return an array reference to the array calculated by |$_ - $&|
                       #where $_ iterates over @a.  Remember $& is the stored digit capture.
                                     push@a,$& #pushes $& at the end of @a.
                                                 say$. #output the result

Imprime 0 se falso, 1 se verdadeiro.

-11 bytes graças a @Dada


11
Essa é realmente legal. Você pode jogar até 55 bytes perl -nE 's/\d+/$.&=!@a||1~~[map{abs$_-$&}@a];push@a,$&/eg;say$.':: em -nvez de <>=~permitir que você se livre do /rmodificador. use \d+e depois em $&vez de (\d+)e $1. !@aem vez de 0>$#a. $.&=em vez de $.&&=. push@a,$&em vez de@a=(@a,$&)
Dada

Por alguma razão, meu sistema me diz que o novo arquivo tem 55 bytes de comprimento, o que obviamente está errado porque tem apenas 54 caracteres, então ???
Gabriel Benamy

Hmm isso é estranho. (e não tenho ideia de onde isso vem). Mas tenho certeza de que são apenas 54 (o script PPCG-Design me diz 54, e meu aplicativo bytecount me diz 54 também).
Dada

2
É possível que a contagem de bytes tenha expirado devido ao arquivo ter uma nova linha desnecessária no final?
Trichoplax

2

Brainfuck, 60 bytes

,+[>+>+<<-]
,+
[
  [>->->+<<<-]
  >-
  [
    +>+
    [
      <<<
    ]
  ]
  >[>]
  <[<+<+>>-]
  <<<,+
]
>.

A permutação é fornecida como bytes sem separadores e sem nova linha final. Como \x00ocorre na entrada, isso foi projetado para implementações com EOF = -1. A saída é \x00para false e \x01true.

Se uma permutação de \x01até chr(r)é permitido, então podemos substituir todas as instâncias ,+com ,uma pontuação de 57 com uma EOF = 0implementação.

Experimente on-line (versão de 57 bytes): A entrada pode ser fornecida como uma permutação de qualquer faixa contígua de bytes \x00, exceto , e a saída será \x00falsa e o mínimo da faixa verdadeira.

Acompanhamos o mínimo e o máximo vistos até agora e, para cada personagem após o primeiro, verificamos se é min-1 ou max + 1 ou nenhum. No caso de nenhum deles, mova o ponteiro para fora do espaço de trabalho normal para que as células locais se tornem zero.

O layout da memória do espaço de trabalho normal no início do loop principal é

c a b 0 0

onde cé o caractere atual, aé min e bé max. (Para a versão de 60 bytes, tudo é tratado com um deslocamento de 1 por causa de ,+.)


1

Braquilog , 22 bytes

:@[fb:{oLtT,Lh:T:efL}a

Experimente online!

Explicação

Não encontrei uma maneira concisa de verificar se uma lista contém números inteiros consecutivos ou não. O mais curto que encontrei é gerar um intervalo entre o primeiro e o último elemento dessa lista e verificar se esse intervalo é a lista original.

:@[fb                       Take all but the first prefixes of the Input
     :{             }a      This predicate is true for all those prefixes
       oLtT,                Sort the prefix, call it L, its last element is T
            Lh:T            The list [First element of L, T]
                :efL        Find all integers between the First element of L and T. It must
                              result in L

O alcance do primeiro ao último é uma abordagem que me ocorreu no CJam. O outro era tipo, diferenças aos pares, verifique se são todas 1. Não sei como isso é fácil em Brachylog.
Peter Taylor

@PeterTaylor Não existe uma maneira curta de gerar pares consecutivos (ou calcular diretamente diferenças por pares) infelizmente (por enquanto).
Fatalize 24/10/16

1

Lote, 133 bytes

@set/au=%1,l=%1-1,a=0
@for %%n in (%*)do @call:l %%n
@exit/b%a%
:l
@if %1==%u% (set/au+=1)else if %1==%l% (set/al-=1)else set a=1

Recebe entrada como argumentos da linha de comando. Sai com o nível de erro 0 para êxito, 1 para falha.


1

J, 14 bytes

/:~-:>./\-<./\

Isso é baseado no método do @ xnor .

Explicação

/:~-:>./\-<./\  Input: array P
        \       For each prefix of P
     >./          Reduce using the maximum
          <./\  Get the minimum of each prefix of p
         -      Subtract between each
   -:           Test if it matches
/:~               P sorted

1

Java, 170 bytes

boolean f(int[]a){int l=a.length,i=0,b=0,e=l-1;int[]x=new int[l];for(;i<l;i++)x[i]=i;for(i--;i>0;i--)if(a[i]==x[b])b++;else if(a[i]==x[e])e--;else return 0>1;return 1>0;}

Matriz xtem valores de 0 a número máximo em ordem (Python seria muito melhor aqui ...). O loop retrocede tentando corresponder ao número mais baixo ( x[b]) ou mais alto ( x[e]) ainda não encontrado; se isso acontecer, esse número pode ser alcançado nessa etapa.

Teste o código aqui .


0

Mathematica, 47 bytes

Um pouco mais do que a solução de Martin Ender (surpresa surpresa!). Mas é um dos meus esforços mais ilegíveis, então é bom: D

#=={}||{Max@#,Min@#}~MemberQ~Last@#&&#0@Most@#&

Explicação:

#=={}                         empty lists are antsy (function halts with True)
 ||                            or
{Max@#,Min@#}~MemberQ~Last@#  lists where the last number is largest or smallest
                              are possibly antsy (else function halts with False)
 &&                            and
#0@Most@#&                    recursively call this function after dropping the
                              last element of the list

0

Java 7, 170 169 bytes

import java.util.*;Object c(int[]a){List l=new ArrayList();l.add(a[0]);for(int i:a){if(l.indexOf(i)<0&l.indexOf(i-1)<0&l.indexOf(i+1)<0)return 0>1;l.add(i);}return 1>0;}

Ungolfed & código de teste:

Experimente aqui.

import java.util.*;
class M{
  static Object c(int[] a){
    List l = new ArrayList();
    l.add(a[0]);
    for(int i : a){
      if(l.indexOf(i) < 0 & l.indexOf(i-1) < 0 & l.indexOf(i+1) < 0){
        return 0>1; //false
      }
      l.add(i);
    }
    return 1>0; //true
  }

  public static void main(String[] a){
    System.out.println(c(new int[]{ 0 }));
    System.out.println(c(new int[]{ 0, 1 }));
    System.out.println(c(new int[]{ 1, 0 }));
    System.out.println(c(new int[]{ 0, 1, 2 }));
    System.out.println(c(new int[]{ 0, 2, 1 }));
    System.out.println(c(new int[]{ 2, 1, 3, 0 }));
    System.out.println(c(new int[]{ 3, 1, 0, 2 }));
    System.out.println(c(new int[]{ 1, 2, 0, 3 }));
    System.out.println(c(new int[]{ 2, 3, 1, 4, 0 }));
    System.out.println(c(new int[]{ 0, 5, 1, 3, 2, 4 }));
    System.out.println(c(new int[]{ 6, 5, 4, 7, 3, 8, 9, 2, 1, 0 }));
    System.out.println(c(new int[]{ 4, 3, 5, 6, 7, 2, 9, 1, 0, 8 }));
    System.out.println(c(new int[]{ 5, 2, 7, 9, 6, 8, 0, 4, 1, 3 }));
    System.out.println(c(new int[]{ 20, 13, 7, 0, 14, 16, 10, 24, 21, 1, 8, 23, 17, 18, 11, 2, 6, 22, 4, 5, 9, 12, 3, 15, 19 }));
    System.out.println(c(new int[]{ 34, 36, 99, 94, 77, 93, 31, 90, 21, 88, 30, 66, 92, 83, 42, 5, 86, 11, 15, 78, 40, 48, 22, 29, 95, 64, 97, 43, 14, 33, 69, 49, 50, 35, 74, 46, 26, 51, 75, 87, 23, 85, 41, 98, 82, 79, 59, 56, 37, 96, 45, 17, 32, 91, 62, 20, 4, 9, 2, 18, 27, 60, 63, 25, 61, 76, 1, 55, 16, 8, 6, 38, 54, 47, 73, 67, 53, 57, 7, 72, 84, 39, 52, 58, 0, 89, 12, 68, 70, 24, 80, 3, 44, 13, 28, 10, 71, 65, 81, 19 }));
    System.out.println(c(new int[]{ 47, 48, 46, 45, 44, 49, 43, 42, 41, 50, 40, 39, 38, 51, 37, 36, 52, 35, 34, 33, 32, 53, 54, 31, 30, 55, 56, 29, 28, 57, 58, 59, 60, 27, 26, 61, 25, 62, 63, 64, 65, 66, 67, 24, 23, 22, 21, 68, 69, 20, 19, 18, 17, 70, 71, 16, 15, 72, 73, 74, 75, 76, 14, 13, 12, 77, 11, 10, 9, 8, 78, 7, 79, 80, 6, 81, 5, 4, 3, 82, 2, 83, 84, 1, 85, 86, 87, 0, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 }));
  }
}

Saída:

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