Permutazioni di Antsy


37

introduzione

Supponiamo di avere un righello con numeri da 0 a r-1 . Metti una formica tra due numeri qualsiasi e inizia a strisciare in modo irregolare sul righello. Il righello è così stretto che la formica non può camminare da una posizione all'altra senza camminare su tutti i numeri in mezzo. Quando la formica cammina su un numero per la prima volta, lo registri e questo ti dà una permutazione dei numeri r . Diciamo che una permutazione è ansiosa se può essere generata da una formica in questo modo. In alternativa, una permutazione p è ansiosa se ogni voce p [i] eccetto la prima è entro la distanza 1 da una voce precedente.

Esempi

La permutazione lunghezza-6

4, 3, 5, 2, 1, 0

è ansioso, perché 3 è a distanza 1 di 4 , 5 è a distanza 1 di 4 , 2 è a distanza 1 da 3 , 1 è a distanza 1 da 2 e 0 è a distanza 1 da 1 . La permutazione

3, 2, 5, 4, 1, 0

non è ansioso, perché 5 non è entro la distanza di 3 o 2 ; la formica dovrebbe passare attraverso 4 per arrivare a 5 .

L'obiettivo

Data una permutazione dei numeri da 0 a r-1 per circa 1 ≤ r ≤ 100 in qualsiasi formato ragionevole, emettere un valore di verità se la permutazione è ansiosa e un valore di falsa in caso contrario.

Casi test

[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

Curiosità: per r ≥ 1 , ci sono esattamente 2 r-1 permutazioni antsy di lunghezza r .


7
Questa è una sfida molto interessante con molte soluzioni diverse: conto almeno 7 strategie uniche utilizzate finora.
ETHproductions

1
La forma strutturata di input delle permutazioni sta contribuendo molto alla varietà di approcci. La condizione per essere ansiosi può essere espressa in diversi modi che non sono equivalenti negli elenchi generali.
xnor

1
Sono deluso dal fatto che non esiste ancora una soluzione ANTSI C.
NoSeatbelts,

Risposte:


18

Pyth, 7 byte

/y+_QQS

Provalo online.(Sono inclusi solo piccoli casi di test a causa del tempo di esecuzione esponenziale.) Output 2 per Truthy, 0 per 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

In altre parole,

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

dove subseqgenera se gli elementi del primo elenco appaiono in ordine nel secondo elenco, non necessariamente adiacenti. Questo subseqviene fatto in Pyth prendendo tutti i sottoinsiemi del secondo elenco, che mantengono l'ordine degli elementi e contando il numero di occorrenze del primo elenco. Questo richiede tempo esponenziale.

Perché funziona? Perché una permutazione sia ansiosa, passare da 0 a n-1 deve consistere nell'andare solo a sinistra, quindi nell'andare solo a destra. Questo perché gli elementi maggiori del primo elemento devono aumentare da sinistra a destra e quelli inferiori devono diminuire da sinistra a destra.

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

Se rispecchiamo l'elenco mettendo una copia invertita alla sua sinistra, questa passeggiata ora va solo a destra.

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

Al contrario, qualsiasi verso destra di questo elenco di mirror corrisponde a una camminata sinistra-destra-destra dell'elenco originale. Questo verso destra è solo una sottosequenza ordinata da 0 a n-1. In un elenco antsy, questa sottosequenza ordinata è unica, fatta eccezione per una scelta arbitraria tra le due copie adiacenti del primo elemento originale.


7
Puoi ridurlo a 6 byte usando ... scherzando.
jwg

2
C'è qualcosa di orribile nell'usare un approccio a tempo esponenziale a un problema con un'ovvia soluzione a tempo lineare anche se si gioca bene.
David Conrad,

@jwg Ci credo, in realtà. Se il conteggio degli elenchi prendesse argomenti nell'ordine opposto, potresti ottenere 6 byte prendendo due input in modo implacabile.
xnor

ayyyyy, volgendosi al lato pitone: D
Maltysen,

11

Haskell, 46 byte

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

Verifica se la differenza di vettore tra i massimi e i minimi correnti è [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 ha salvato 2 byte con (%)=scanl1.


È così intelligente! +1
Gabriel Benamy,

1
Potresti salvare alcuni byte definendo (#)=scanl1?
Zgarb

1
@Zgarb Grazie, ho dimenticato che potresti farlo.
xnor

9

JavaScript (ES6), 45

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

Ho pensato che fosse troppo semplice per essere spiegato, ma c'è un trucco e, nel caso, ecco la mia prima versione, 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: nel codice golf a viene utilizzato k, in quanto non è necessario alcun riferimento all'array originale all'interno della everychiamata. Quindi evito di inquinare lo spazio dei nomi globale riutilizzando il parametro

Test

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


Davvero carino. Ho provato questo approccio con la ricorsione, ma non riesco a ottenerlo al di sotto di 65:f=([q,...a],x=[])=>x&&(x[q]=!(x+x)|x[q+1]|x[q-1])&&(a+a?f(a,x):1)
ETHproductions

Come funziona? Stai usando un po 'di magia dell'elenco mutabile?
Zgarb,

Aggiunta la spiegazione di @Zgarb
edc65,

6

Python 2, 49 byte

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

Verifica se ciascun prefisso dell'elenco contiene tutti i numeri compresi tra minimo e massimo inclusi. Lo fa controllando se la differenza tra massimo e minimo è inferiore alla sua lunghezza.


54 byte:

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

Verifica se l'ultimo elemento è uno in meno del minimo degli altri elementi o uno in più del loro massimo. Quindi, rimuove l'ultimo elemento e ricorre. In un elenco a singolo elemento, genera True.

Questo può anche essere verificato attraverso una comprensione dell'elenco divertente ma più lunga.

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

Vorrei usare la disuguaglianza min(l)-2<l.pop()<max(l)+2, ma i popbisogni devono accadere per primi. L'uso di un programma per l'output tramite codice di errore sarebbe probabilmente più breve.


6

Mathematica, 42 byte

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

Utilizza la corrispondenza dei modelli per cercare di trovare un prefisso la acui differenza massima dall'elemento successivo bè maggiore di 1(e negando il risultato di MatchQ).


6

Perl, 39 38 35 byte

Include +1 per -p

Dai la sequenza su STDIN:

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

antsy.pl:

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

2
Sto facendo fatica a capire questo ... Ti va di spiegare un po '? grazie :-) (l'idea dovrebbe essere sufficiente)
Dada,

4

MATL , 11 byte

&-|R1=a4L)A

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

Questo calcola una matrice di tutte le differenze assolute a coppie e mantiene la parte triangolare superiore. Il risultato è vero se c'è almeno un valore 1 in tutte le colonne tranne la prima.

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

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

Una permutazione è ansiosa se e solo se tutte le sue subpermutazioni di sinistra sono continue (cioè hanno una differenza quando vengono ordinate).

Se si garantisce che l'input abbia una lunghezza maggiore di uno, allora possiamo sostituirlo 1:sum(1|v)con seq(v), risparmiando quattro byte.

La seq(v)condizione in if si comporta diversamente quando l'ingresso è di lunghezza uno --- genera la sequenza 1:vinvece di seq_along(v). Tuttavia, per fortuna, l'output risulta essereTRUE in questo caso, che è il comportamento desiderato. Lo stesso accade anche per input di lunghezza zero.

In R, Tuna variabile preimpostata è uguale a TRUE(ma R consente di ridefinirla). TRUEè anche considerato uguale a 1.

Grazie a @Billywob per alcuni utili miglioramenti alla soluzione originale.


1
La lettura dell'input usando ti scanfarebbe risparmiare due byte. In quel caso è esattamente lo stesso numero di byte dell'approccio forloop: v=scan();c=c();for(i in 1:sum(1|v))c=c(c,diff(sort(v[1:i])));all(c==1)che sarebbe 2 byte più corto dell'approccio vettorializzato.
Billywob,

Bella idea, e posso andare ancora meglio, penso abusando T. Modifica.
JDL,


3

Perl, 63 byte

Si noti che @Gabriel Banamy ha fornito una risposta più breve (55 byte) . Ma penso che questa soluzione sia ancora interessante, quindi la sto pubblicando.

Il conteggio dei byte include 62 byte di codice e -nflag.

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

Per eseguirlo:

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

Brevi spiegazioni : converte ogni numerok nella rappresentazione unaria di k+1(che +1è necessario in modo che gli 0s non vengano ignorati). Quindi per ogni numero k+1(espresso in unario come 1(1*)), osserviamo se k( $1hold k) o k+2(che è allora 11$1) sono presenti nella stringa precedente (a cui fa riferimento $-backtick). Se no, allora impostiamo $.a zero. Alla fine stampiamo ciò $.che sarà 1se non lo impostiamo mai su zero o su zero altrimenti.


3

Brain-Flak 302 264 256 byte

Grazie a Wheat Wizard per aver salvato 46 byte

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

La parte superiore della pila sarà un 1 per la verità e uno 0 per la falsità.

Verità: provalo online!
Falsy: provalo online!

L'idea è quella di contenere il numero minimo e massimo che la formica ha visitato nello stack. Quindi confrontare ciascun numero con entrambi e aggiornare quello appropriato. Se il numero successivo non è 1 in meno del minimo o 1 in più del massimo, uscire dal loop e restituire false.


Breve spiegazione:

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

Vorrei verificare le riduzioni push pop . Vedo già alcuni posti dove è possibile utilizzare questa strategia.
Wheat Wizard

@WheatWizard Sono sicuro che ce ne sono alcuni, non ho ancora avuto il tempo di risolverli. Grazie per il promemoria.
Riley,

Sono contento che questo abbia almeno senso per te O_O
Gabriel Benamy,

Puoi anche sostituire le istanze di ([]){({}[()]<({}<>)<>>)}{}con ([]){{}({}<>)<>([])}{}per salvare un altro paio di byte
Wheat Wizard,

3

Gelatina , 9 8 7 byte

;@UŒPċṢ

Provalo online!

Una traduzione gelatina della risposta di xnor.

Vecchie soluzioni:

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

Provalo online!

Funziona in modo molto simile alla mia risposta Pyth di seguito:

;\          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 conversione dell'altro metodo di xnor in Jelly è anche di 7 byte »\_«\⁼Ṣma molto più efficiente
miglia

ŒBŒPċṢe ;\Ṣ€IỊȦdovrebbe salvare un byte in ogni approccio.
Dennis,

Sfortunatamente, il primo non funziona perché avrei bisogno che l'input invertito venisse rimbalzato, come UŒBŒPċṢse non salvassi alcun byte. Il è bello, però; Avevo letto male quell'atomo per emettere il NOT logico di ciò che effettivamente ha fatto.
Steven H.

Non sono sicuro del motivo per cui avresti bisogno del U(o del @momento che ci penso). Se una matrice è ansiosa, lo è anche la matrice invertita, no?
Dennis,

1
Non necessariamente: [2, 1, 3, 0]è ansioso ma [0, 3, 1, 2]non lo è.
Steven H.,

3

CJam ( 21 20 byte)

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

Suite di test online

Dissezione

Questo utilizza l'osservazione di xnor nella sua risposta di Haskell che ndovrebbe essere la differenza tra il massimo e il minimo dei primi elementi 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
}

Approccio alternativo (anche 20 byte)

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

Suite di test online

Questo controlla direttamente che ogni elemento dopo il primo sia a distanza 1 da un elemento precedente. Poiché l'input è una permutazione e quindi non ripete i valori, questo è un test sufficiente. Grazie a Martin per un risparmio di 1 byte.

Dissezione

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

Penso che questo lo salvi? {_{a+_)f-:z1&,*}*^!}
Martin Ender,

@MartinEnder, molto carino. Curiosamente, l'hai pubblicato proprio mentre stavo pubblicando un approccio completamente diverso con lo stesso numero di byte.
Peter Taylor,

3

Java, 100 98 79 75 byte

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

In precedenza:

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

Salvato 3 byte sostituendo truee falsecon 1>0e 0>1.

Salvato 23 byte grazie agli eccellenti suggerimenti di 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;
}

Tieni traccia dei valori più alti e più bassi visti fino a me n; accetta un nuovo valore solo se lo è m + 1on - 1 cioè il valore successivo più alto o più basso; inizializzare l'alto valore,m , a uno in meno rispetto al primo elemento in modo che "corrisponda" la prima volta attorno al ciclo. Nota: questo è un algoritmo online a tempo lineare. Richiede solo tre parole di memoria, per i valori attuali, il più alto finora e il più basso finora, a differenza di molte altre soluzioni.

Se il valore successivo non raggiunge né le estremità alte né quelle basse dell'intervallo, il valore più basso finora è impostato su -1e quindi l'estremità inferiore non può mai procedere e raggiungere lo zero. Quindi rileviamo una sequenza antsy controllando se il valore basso n, ha raggiunto lo zero.

(Sfortunatamente questo è meno efficiente perché dobbiamo sempre guardare l'intera sequenza piuttosto che salvare dopo la prima numero sbagliato , ma è difficile discutere con un risparmio di 23 byte (!) Quando altre soluzioni usano O (n ^ 2 ) e approcci esponenziali.)

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: questo può anche essere scritto senza sfruttare Java 8 lambdas:

Java 7, 89 byte

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

Buona gestione del caso speciale. int m,n;m=n=a[0];--m;potrebbe essere int n=a[0],m=n-1;, e il costoso returne elsepotrebbe essere ridotto con i==m+1?m++:n=(i==n-1)?i:-1;return n==0;(o qualcosa di simile - non l'ho provato).
Peter Taylor,

@PeterTaylor Fantastico! Sfortunatamente, Java non consentirà alcun effetto collaterale come m++o m+=1lì, quindi ho ancora bisogno di un ife un else, e perde l'aspetto del corto circuito sul primo valore negativo, ma questo è un grande miglioramento. Grazie!
David Conrad,

Consentirà effetti collaterali in un'espressione complessa. Ciò che potrebbe non piacere è usare un'espressione generale come un'istruzione. Nel peggiore dei casi devi creare una variabile fittizia je assegnargli il risultato, ma sospetti che ci sarebbe un modo migliore per farlo.
Peter Taylor,

@PeterTaylor Beh, ho provato alcune varianti su di esso, inclusa l'assegnazione a una variabile fittizia g, e non sono riuscito a farlo funzionare. (Sto usando Java 9-ea + 138, forse è una differenza tra Java 8 e Java 9?) Potrei riprovare domani.
David Conrad,

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

2

Pyth ( fork ), 13 byte

!sstMM.+MSM._

No Provalo Link online per questo fork di Pyth. Il fork include la funzione delta .+, che non fa parte della libreria Pyth standard.

Spiegazione:

           ._  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
Vedere questo mi convince a fondere questo in Pyth.
isaacg,

2

Perl, 66 54 +1 = 55 byte

+1 byte per -n.

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

Spiegazione:

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

Stampa 0 se falso, 1 se vero.

-11 byte grazie a @Dada


1
Quello è davvero carino. Puoi giocarci fino a 55 byte perl -nE 's/\d+/$.&=!@a||1~~[map{abs$_-$&}@a];push@a,$&/eg;say$.':: -ninvece di <>=~quale ti permette di sbarazzarti del /rmodificatore. usa \d+e poi $&invece di (\d+)e $1. !@ainvece di 0>$#a. $.&=invece di $.&&=. push@a,$&invece di@a=(@a,$&)
Dada,

Per qualche ragione, il mio sistema mi dice che il nuovo file è lungo 55 byte, il che è ovviamente sbagliato perché ha solo 54 caratteri, quindi ???
Gabriel Benamy,

Hmm, è strano. (e non ho idea da dove provenga). Ma sono abbastanza sicuro che sono solo 54 (lo script PPCG-Design mi dice 54 e anche la mia app bytecount mi dice 54).
Dada,

2
È possibile che il conteggio dei byte sia stato eliminato a causa della fine del file con una nuova riga non necessaria?
trichoplax,

2

Brainfuck, 60 byte

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

La permutazione è data come byte senza separatori e senza newline di chiusura. Poiché si \x00verifica nell'input, questo è progettato per implementazioni con EOF = -1. L'output è \x00per false e \x01per true.

Se è consentita una permutazione \x01fino a chr(r), allora possiamo sostituire tutte le istanze di ,+con ,un punteggio di 57 con EOF = 0un'implementazione.

Provalo online (versione a 57 byte): l'input può essere dato come permutazione di qualsiasi intervallo contiguo di byte escluso \x00, e l'output sarà \x00per false e il minimo dell'intervallo per true.

Teniamo traccia del minimo e massimo visti finora, e per ogni personaggio dopo il primo, controlliamo se è min-1 o max + 1 o nessuno dei due. In nessuno dei due casi, spostare il puntatore fuori dallo spazio di lavoro normale in modo che le celle locali diventino zero.

Il layout di memoria dello spazio di lavoro normale all'inizio del loop principale è

c a b 0 0

dove cè il personaggio corrente, aè min e bè max. (Per la versione a 60 byte, tutto è gestito con un offset di 1 a causa di ,+.)


1

Brachylog , 22 byte

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

Provalo online!

Spiegazione

Non ho trovato un modo conciso di verificare se un elenco contiene numeri interi consecutivi o meno. Il più breve che ho trovato è generare un intervallo tra il primo e l'ultimo elemento di tale elenco e verificare che tale intervallo sia l'elenco originale.

:@[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

Il range dal primo all'ultimo è un approccio che mi era venuto in mente in CJam. L'altro era una specie, differenze a coppie, controlla che siano tutte 1. Non so quanto sia facile in Brachylog.
Peter Taylor,

@PeterTaylor Purtroppo non esiste un modo breve per generare coppie consecutive (o calcolare direttamente le differenze di coppia) (per ora).
Fatalizza il

1

Lotto, 133 byte

@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

Accetta input come argomenti della riga di comando. Esce con livello di errore 0 per esito positivo, 1 per errore.


1

J, 14 byte

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

Questo si basa su @ xnor's metodo di .

Spiegazione

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

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

L'array xha valori compresi tra 0 e il numero massimo in ordine (Python sarebbe molto meglio qui ...). Il ciclo va indietro cercando di trovare il numero più basso ( x[b]) o il più alto ( x[e]) non ancora raggiunto; in tal caso, quel numero potrebbe essere raggiunto in quel passaggio.

Codice di prova qui .


0

Mathematica, 47 byte

Un po 'più a lungo della soluzione di Martin Ender (sorpresa sorpresa!). Ma è uno dei miei sforzi più illeggibili, quindi va bene: D

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

Spiegazione:

#=={}                         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 byte

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

Codice non testato e test:

Provalo qui.

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

Produzione:

true
true
true
true
false
true
false
true
true
false
true
false
false
false
false
true
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.