Permutaciones ansiosas


37

Introducción

Supongamos que tiene una regla con números del 0 al r-1 . Coloca una hormiga entre dos de los números, y comienza a gatear erráticamente en la regla. La regla es tan estrecha que la hormiga no puede caminar de una posición a otra sin caminar sobre todos los números intermedios. A medida que la hormiga camina sobre un número por primera vez, lo registras, y esto te da una permutación de los números r . Decimos que una permutación es inquieta si puede ser generada por una hormiga de esta manera. Alternativamente, una permutación p es inquieta si cada entrada p [i] excepto la primera está dentro de la distancia 1 de alguna entrada anterior.

Ejemplos

La permutación de longitud 6

4, 3, 5, 2, 1, 0

es inquietante, porque 3 está dentro de la distancia 1 de 4 , 5 está dentro de la distancia 1 de 4 , 2 está dentro de la distancia 1 de 3 , 1 está dentro de la distancia 1 de 2 y 0 está dentro de la distancia 1 de 1 . La permutación

3, 2, 5, 4, 1, 0

no está inquieto, porque 5 no está dentro de la distancia 1 de 3 o 2 ; la hormiga tendría que pasar por 4 para llegar a 5 .

La tarea

Dada una permutación de los números de 0 a r-1 para aproximadamente 1 ≤ r ≤ 100 en cualquier formato razonable, generar un valor verdadero si la permutación es inquietante, y un valor falso si no.

Casos de prueba

[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

Dato curioso: para r ≥ 1 , hay exactamente 2 permutaciones ansiosas r-1 de longitud r .


77
Este es un desafío muy interesante con muchas soluciones diferentes: cuento con al menos 7 estrategias únicas que se han utilizado hasta ahora.
ETHproductions

1
La forma de entrada estructurada de permutaciones está contribuyendo mucho a la variedad de enfoques. La condición para estar ansioso se puede expresar de diferentes maneras que no son equivalentes en las listas generales.
xnor

1
Estoy decepcionado de que todavía no haya una solución ANTSI C.
NoSeatbelts

Respuestas:


18

Pyth, 7 bytes

/y+_QQS

Pruébalo en línea. (Solo se incluyen casos de prueba pequeños debido al tiempo de ejecución exponencial). Salidas 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

En otras palabras,

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

donde subseqmuestra si los elementos de la primera lista aparecen en orden en la segunda lista, no necesariamente adyacentes. Esto subseqse realiza en Pyth tomando todos los subconjuntos de la segunda lista, que mantienen el orden de los elementos, y contando el número de ocurrencias de la primera lista. Esto lleva tiempo exponencial.

¿Por qué funciona esto? Para que una permutación sea inquieta, pasar de 0 a n-1 debe consistir en ir solo a la izquierda y luego a la derecha. Esto se debe a que los elementos mayores que el primer elemento deben aumentar de izquierda a derecha, y los menores que deben disminuir de izquierda a derecha.

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

Si duplicamos la lista colocando una copia invertida a su izquierda, este recorrido ahora solo va a la derecha.

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

Por el contrario, cualquier derecha de esta lista espejo corresponde a un recorrido de izquierda a derecha de la lista original. Esta derecha solo es una subsecuencia ordenada de 0 a n-1. En una lista inquieta, esta subsecuencia ordenada es única, excepto por una elección arbitraria entre las dos copias adyacentes del primer elemento original.


77
Puede reducirlo a 6 bytes usando ... solo bromeando.
jwg

2
Hay algo horrible en usar un enfoque de tiempo exponencial para un problema con una solución obvia de tiempo lineal, incluso si se juega muy bien.
David Conrad

@jwg Lo creería, en realidad. Si el recuento de la lista tomaba argumentos en el orden opuesto, podría obtener 6 bytes tomando dos entradas implícitamente.
xnor

ayyyyy, girando hacia el lado pyth: D
Maltysen

11

Haskell, 46 bytes

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

Comprueba si la diferencia de vectores de los máximos y mínimos de ejecución es [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]

Zgarb guardó 2 bytes con (%)=scanl1.


Eso es muy inteligente! +1
Gabriel Benamy

1
¿Podría guardar algunos bytes definiendo (#)=scanl1?
Zgarb

1
@ Zgarb Gracias, olvidé que podías hacer eso.
xnor

9

JavaScript (ES6), 45

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

Pensé que era demasiado simple como explicación, pero hay un truco, y por si acaso, aquí está mi primera versión, pre-golf

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: en el código de golf ase utiliza en lugar de k, ya que no necesito ninguna referencia a la matriz original dentro de la everyllamada. Así que evito contaminar el espacio de nombres global reutilizando el parámetro

Prueba

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


Realmente agradable. Intenté este enfoque con recurrencia, pero no puedo obtenerlo por debajo 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 funciona esto? ¿Estás usando alguna magia de lista mutable?
Zgarb

Explicación de @Zgarb agregada
edc65

6

Python 2, 49 bytes

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

Comprueba si cada prefijo de la lista contiene todos los números entre su mínimo y máximo inclusive. Lo hace comprobando si la diferencia entre el máximo y el mínimo es menor que su longitud.


54 bytes:

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

Comprueba si el último elemento es uno menos que el mínimo de los otros elementos, o uno más que su máximo. Luego, elimina el último elemento y vuelve a aparecer. En una lista de un solo elemento, genera True.

Esto también se puede verificar a través de una comprensión de la lista divertida pero más larga.

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

Me gustaría usar la desigualdad min(l)-2<l.pop()<max(l)+2, pero las popnecesidades deben suceder primero. Usar un programa para generar un código de error probablemente sea más corto.


6

Mathematica, 42 bytes

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

Utiliza la coincidencia de patrones para intentar encontrar un prefijo acuya diferencia máxima con respecto al siguiente elemento bsea ​​mayor que 1(y negar el resultado de MatchQ).


6

Perl, 39 38 35 bytes

Incluye +1 para -p

Dar secuencia en STDIN:

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

antsy.pl:

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

2
Me está costando mucho entender esto ... ¿Te importa explicar un poco? gracias :-) (solo la idea principal debería ser suficiente)
Dada

4

MATL , 11 bytes

&-|R1=a4L)A

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

Esto calcula una matriz de todas las diferencias absolutas por pares y mantiene la parte triangular superior. El resultado es verdadero si hay al menos un valor 1 en todas las columnas, excepto en la primera.

&-     % 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)

Una permutación es inquieta si y solo si todas sus subpermutaciones izquierdas son continuas (es decir, tienen una diferencia cuando están ordenadas).

Si se garantiza que la entrada tiene una longitud de más de uno, entonces podemos reemplazar 1:sum(1|v)con seq(v), lo que ahorra cuatro bytes.

La seq(v)condición en el if se comporta de manera diferente cuando la entrada es de longitud uno --- genera la secuencia en 1:vlugar de seq_along(v). Sin embargo, afortunadamente, la salida resulta ser TRUEen este caso, que es el comportamiento deseado. Lo mismo también sucede para la entrada de longitud cero.

En R, Tes una variable predeterminada igual a TRUE(pero R le permite redefinirla). TRUEtambién se considera igual a 1.

Gracias a @Billywob por algunas mejoras útiles a la solución original.


1
Leer la entrada usando scanle ahorraría dos bytes. En ese caso, es exactamente el mismo número de bytes que el forenfoque de bucle: v=scan();c=c();for(i in 1:sum(1|v))c=c(c,diff(sort(v[1:i])));all(c==1)que sería 2 bytes más corto que su enfoque vectorizado.
Billywob

Buena idea, y puedo ir mejor creo, abusando T. Se editará
JDL


3

Perl, 63 bytes

Tenga en cuenta que a @Gabriel Banamy se le ocurrió una respuesta más corta (55 bytes) . Pero creo que esta solución sigue siendo interesante, así que la estoy publicando.

El recuento de bytes incluye 62 bytes de código y -nbandera.

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

Para ejecutarlo:

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

Explicaciones breves : convierte cada número ken la representación unaria de k+1(eso +1es necesario para 0que no se ignore la s). Luego, para cada número k+1(expresado en unario como 1(1*)), observamos si k( $1retenciones k) o k+2(que es entonces 11$1) están presentes en la cadena anterior (referenciada por $-backtick). Si no, entonces lo ponemos $.a cero. Al final imprimimos $.cuál será 1si nunca lo ponemos a cero, o cero de lo contrario.


3

Brain-Flak 302 264 256 Bytes

Gracias a Wheat Wizard por guardar 46 bytes

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

La parte superior de la pila será un 1 para la verdad y un 0 para la falsedad.

Verdad: ¡ Pruébelo en línea!
Falsy: ¡ Pruébalo en línea!

La idea es mantener el número mínimo y máximo que la hormiga ha visitado en la pila. Luego compare cada número con ambos y actualice el apropiado. Si el siguiente número no es 1 menos que el mínimo o 1 más que el máximo, salga del bucle y devuelva falso.


Breve explicacion:

([])                             # 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

Verificaría las reducciones de push pop . Veo algunos lugares donde puedes usar esta estrategia.
Wheat Wizard

@WheatWizard Estoy seguro de que hay algunos, pero aún no tuve tiempo de resolverlos. Gracias por el recordatorio.
Riley

Me alegra que esto al menos tenga sentido para ti O_O
Gabriel Benamy

También puede reemplazar las instancias de ([]){({}[()]<({}<>)<>>)}{}con ([]){{}({}<>)<>([])}{}para guardar un par de bytes más
Wheat Wizard

3

Gelatina , 9 8 7 bytes

;@UŒPċṢ

¡Pruébelo en línea!

Una traducción Jelly de la respuesta de xnor.

Viejas soluciones:

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

Pruébalo en línea!

Funciona de manera muy similar a mi respuesta Pyth a continuación:

;\          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 (Ị)?

La conversión del otro método de xnor a Jelly también es de 7 bytes »\_«\⁼Ṣpero mucho más eficiente
millas del

ŒBŒPċṢy ;\Ṣ€IỊȦdebe guardar un byte en cada enfoque.
Dennis

Desafortunadamente, el primero no funciona porque necesitaría que la entrada invertida se devuelva, como la UŒBŒPċṢcual no guarda ningún byte. El es agradable, sin embargo; Había leído mal ese átomo para generar el NOT lógico de lo que realmente hizo.
Steven H.

No estoy seguro de por qué necesitarías el U(o el @ahora que lo pienso). Si una matriz es inquieta, también lo es la matriz invertida, ¿no?
Dennis

1
No necesariamente: [2, 1, 3, 0]está inquieto pero [0, 3, 1, 2]no lo es.
Steven H.

3

CJam ( 21 20 bytes)

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

Conjunto de pruebas en línea

Disección

Esto utiliza la observación de xnor en su respuesta de Haskell de que la diferencia entre el máximo y el mínimo de los primeros nelementos debería 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
}

Enfoque alternativo (también 20 bytes)

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

Conjunto de pruebas en línea

Esto comprueba directamente que cada elemento después del primero está a la distancia 1 de un elemento anterior. Dado que la entrada es una permutación y, por lo tanto, no repite valores, esta es una prueba suficiente. Gracias a Martin por un ahorro de 1 byte.

Disección

{_{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]
}

Creo que esto salva a uno? {_{a+_)f-:z1&,*}*^!}
Martin Ender

@ MartinEnder, muy agradable. Curiosamente publicaste eso justo cuando estaba publicando un enfoque completamente diferente con el mismo conteo 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;}

Antes:

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

Guardado 3 bytes reemplazando truey falsecon 1>0y 0>1.

¡Ahorré 23 bytes gracias a las excelentes sugerencias de Peter Taylor!

Sin golf:

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

Mantenga un registro de los valores más altos y más bajos vistos hasta ahora my n; solo acepte un nuevo valor si es m + 1o n - 1es el siguiente valor más alto o más bajo; inicialice el valor alto,, ma uno menos que el primer elemento para que "coincida" la primera vez alrededor del ciclo. Nota: este es un algoritmo en línea de tiempo lineal. Requiere solo tres palabras de memoria, para los valores actuales, más alto hasta ahora y más bajo hasta ahora, a diferencia de muchas de las otras soluciones.

Si el siguiente valor no alcanza los extremos alto y bajo del rango, el valor más bajo hasta ahora se establece en -1y luego el extremo bajo nunca puede continuar y llegar a cero. Luego detectamos una secuencia inquieta verificando si el valor bajo n, alcanzó cero.

(Desafortunadamente, esto es menos eficiente porque siempre tenemos que mirar la secuencia completa en lugar de rescatar después del primer número incorrecto , pero es difícil discutir con un ahorro de 23 bytes (!) Cuando otras soluciones están usando O (n ^ 2 ) y enfoques de tiempo 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: esto también se puede escribir sin aprovechar las lambdas de Java 8:

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

Buen manejo del caso especial. int m,n;m=n=a[0];--m;podría ser int n=a[0],m=n-1;, y lo costoso returny elsepodría reducirse con i==m+1?m++:n=(i==n-1)?i:-1;return n==0;(o algo similar, no he probado esto).
Peter Taylor

@PeterTaylor ¡Fantástico! Desafortunadamente, Java no permitirá ningún efecto secundario como m++o m+=1allí, por lo que todavía necesito un ify un else, y pierde el aspecto de cortocircuito en el primer valor malo, pero eso es una gran mejora. ¡Gracias!
David Conrad

Permitirá efectos secundarios en una expresión compleja. Lo que no le gustaría es usar una expresión general como una declaración. En el peor de los casos, debe crear una variable ficticia jy asignarle el resultado, pero sospecha que habría una mejor manera de hacerlo.
Peter Taylor

@PeterTaylor Bueno, probé algunas variaciones, incluida la asignación a una variable ficticia g, y no pude hacer que funcionara. (Estoy usando Java 9-ea + 138, ¿tal vez sea una diferencia entre Java 8 y Java 9?) Puedo intentarlo de nuevo mañana.
David Conrad

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

2

Pyth ( fork ), 13 bytes

!sstMM.+MSM._

No intente en línea enlace para esta bifurcación de Pyth. La bifurcación incluye la función deltas .+, que no forma parte de la biblioteca Pyth estándar.

Explicación:

           ._  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
Ver esto me convence de fusionar esto en Pyth.
isaacg

2

Perl, 66 54 +1 = 55 bytes

+1 byte para -n.

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

Explicación:

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 si es falso, 1 si es verdadero.

-11 bytes gracias a @Dada


1
Ese es realmente lindo. Sin embargo, puede reducirlo a 55 bytes perl -nE 's/\d+/$.&=!@a||1~~[map{abs$_-$&}@a];push@a,$&/eg;say$.': en -nlugar de lo <>=~que le permite deshacerse del /rmodificador. use \d+y luego en $&lugar de (\d+)y $1. !@aen lugar de 0>$#a. $.&=en lugar de $.&&=. push@a,$&en lugar de@a=(@a,$&)
Dada

Por alguna razón, mi sistema me dice que el nuevo archivo tiene 55 bytes de longitud, lo que obviamente es incorrecto porque solo tiene 54 caracteres, ¿entonces?
Gabriel Benamy

Hmm eso es extraño. (y no tengo idea de dónde viene esto). Pero estoy bastante seguro de que solo es 54 (el script PPCG-Design me dice 54, y mi aplicación bytecount también me dice 54).
Dada

2
¿Es posible que el recuento de bytes estuviera fuera debido a que el archivo tenía una nueva línea innecesaria al final?
Trichoplax

2

Brainfuck, 60 bytes

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

La permutación se da como bytes sin separadores y sin nueva línea de terminación. Como \x00ocurre en la entrada, esto está diseñado para implementaciones con EOF = -1. La salida es \x00para falso y \x01para verdadero.

Si se permite una permutación de \x01hasta chr(r), entonces podemos reemplazar todas las instancias de ,+con, una puntuación de 57 con unaEOF = 0 aplicación.

Pruébelo en línea (versión de 57 bytes): la entrada se puede dar como una permutación de cualquier rango contiguo de bytes excluyendo \x00, y la salida será \x00falsa y el mínimo del rango verdadero.

Llevamos un registro de los mínimos y máximos vistos hasta ahora, y para cada personaje después del primero, verificamos si es min-1 o max + 1 o ninguno. En el caso de ninguno de los dos, mueva el puntero fuera del espacio de trabajo normal para que las celdas locales se vuelvan cero.

El diseño de memoria del espacio de trabajo normal al comienzo del bucle principal es

c a b 0 0

donde ces el caracter actual, aes min y bes max. (Para la versión de 60 bytes, todo se maneja con un desplazamiento de 1 debido a ,+).


1

Brachylog , 22 bytes

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

Pruébalo en línea!

Explicación

No he encontrado una manera concisa de verificar si una lista contiene enteros consecutivos o no. Lo más corto que encontré es generar un rango entre el primer y el último elemento de esa lista y verificar que ese rango sea la 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

El rango del primero al último es un enfoque que se me ocurrió en CJam. El otro era ordenar, diferencias por pares, verifique que estén todas 1. No sé lo fácil que es en Brachylog.
Peter Taylor

@PeterTaylor No hay una forma corta de generar pares consecutivos (o calcular directamente las diferencias por pares) desafortunadamente (por ahora).
Fatalize

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

Toma datos como argumentos de línea de comandos. Sale con nivel de error 0 para éxito, 1 para falla.


1

J, 14 bytes

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

Esto se basa en @ xnor's método de .

Explicación

/:~-:>./\-<./\  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;}

La matriz xtiene valores del 0 al número máximo en orden (Python sería mucho mejor aquí ...). El ciclo va hacia atrás tratando de hacer coincidir el número más bajo ( x[b]) o el más alto ( x[e]) que aún no se ha encontrado; si lo hace, ese número podría alcanzarse en ese paso.

Prueba el código aquí .


0

Mathematica, 47 bytes

Un poco más que la solución de Martin Ender (¡sorpresa sorpresa!). Pero es uno de mis esfuerzos más ilegibles, así que eso es bueno: D

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

Explicación:

#=={}                         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 y código de prueba:

Pruébalo aquí

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 }));
  }
}

Salida:

true
true
true
true
false
true
false
true
true
false
true
false
false
false
false
true
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.