Перестановки Анци


37

Вступ

Припустимо, у вас є лінійка з цифрами від 0 до r-1 . Ви розміщуєте мурашник між будь-якими двома числами, і він починає хаотично повзати по лінійці. Лінійка настільки вузька, що мураха не може ходити з однієї позиції в іншу, не переходячи на всі числа між ними. Коли мураха ходить по номеру вперше, ви записуєте його, і це дає вам перестановку r- чисел. Будемо говорити , що перестановка смикатися , якщо вона може бути породжена мураха таким чином. Альтернативно, перестановка p є анци, якщо кожен запис p [i], крім першого, знаходиться в межах відстані 1 від попереднього запису.

Приклади

Довжина-6 перестановок

4, 3, 5, 2, 1, 0

є анци, тому що 3 знаходиться в межах відстані 1 з 4 , 5 знаходиться в межах відстані 1 від 4 , 2 знаходиться в межах відстані 1 від 3 , 1 знаходиться в межах відстані 1 від 2 , а 0 знаходиться в межах відстані 1 від 1 . Перестановка

3, 2, 5, 4, 1, 0

не є мурашкою, тому що 5 не перебуває в межах відстані 1 або 3, або 2 ; мурашник повинен був би пройти через 4, щоб дістатися до 5 .

Завдання

Дано перестановку чисел від 0 до r-1 для якихось 1 ≤ r ≤ 100 у будь-якому розумному форматі, виведіть значення truthy, якщо перестановка є antsy, а значення false - якщо ні.

Тестові справи

[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

Цікавий факт: для г ^ 1 , існує рівно 2 г-1 засмиканою перестановки довжини г .


7
Це дуже цікавий виклик з багатьма різними рішеннями: я нараховую щонайменше 7 унікальних стратегій, що використовуються дотепер.
ETHproductions

1
Структурована форма введення перестановок багато сприяє різноманітності підходів. Умова бути мурашкою може бути виражена різними способами, які не є рівнозначними у загальних списках.
xnor

1
Я розчарований, що ще немає рішення ANTSI C.
NoSeatbelts

Відповіді:


18

Pyth, 7 байт

/y+_QQS

Спробуйте в Інтернеті. (Включаються лише невеликі тестові випадки через експоненціальний час виконання.) Виходи 2 для Truthy, 0 для 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

Іншими словами,

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

де subseq виводиться, чи елементи першого списку відображаються в порядку у другому списку, не обов'язково суміжні. Це subseqробиться в Pyth, беручи всі підмножини другого списку, які зберігають порядок елементів, і підраховують кількість зустрічей першого списку. Це займає експоненціальний час.

Чому це працює? Щоб перестановка була мурашкою, перехід від 0 до n-1 повинен складатися лише зліва, а потім лише праворуч. Це тому, що елементи, що перевищують перший елемент, повинні збільшуватися зліва направо, а ті, які менші за нього, повинні зменшуватися зліва направо.

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

Якщо ми відобразимо дзеркальний список, поставивши звороту копію ліворуч, зараз ця прогулянка йде лише праворуч.

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

І навпаки, будь-яка праворуч від цього списку дзеркал відповідає ходу ліворуч та праворуч від початкового списку. Цей правий якраз є впорядкованим підрядком від 0 до n-1. У списку мурах цей сортований підряд унікальний, за винятком довільного вибору між двома сусідніми копіями оригінального першого елемента.


7
Ви можете скоротити його до 6 байт, використовуючи ... просто жартуючи.
jwg

2
Існує щось огидне в застосуванні експоненціально-часового підходу до проблеми з очевидним рішенням лінійного часу, навіть якщо воно гарно зітхає.
Девід Конрад

@jwg Насправді я вірю. Якщо підрахунок списку брав аргументи у зворотному порядку, ви можете отримати 6 байт, безоплатно взявши два входи.
xnor

ayyyyy, повернувшись в сторону піта: D
Мальтісен

11

Haskell, 46 байт

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

Перевіряє, чи є векторна різниця бігових максимумів та мінімумів бігу [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]

Згарб врятував 2 байти за допомогою (%)=scanl1.


Це так розумно! +1
Габріель Бенамі

1
Не могли б ви зберегти кілька байтів, визначившись (#)=scanl1?
Згарб

1
@ Zgarb Спасибі, я забув, ти можеш це зробити.
xnor

9

JavaScript (ES6), 45

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

Я подумав, що це занадто просто, щоб потребувати пояснення, але є хитрість, і про всяк випадок, ось моя перша версія, перед-гольф

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

Примітка: у коді golfed aвикористовується замість k, оскільки мені не потрібно посилатися на вихідний масив всередині everyвиклику. Тому я уникаю забруднювати глобальний простір імен, використовуючи параметр

Тест

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


Справді приємно. Я спробував цей підхід з рекурсією, але не можу досягти його нижче 65:f=([q,...a],x=[])=>x&&(x[q]=!(x+x)|x[q+1]|x[q-1])&&(a+a?f(a,x):1)
ETHproductions

Як це працює? Ви використовуєте якусь змінну магію списку?
Згарб

@Zgarb пояснення додано
edc65

6

Python 2, 49 байт

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

Перевіряє, чи містить кожен префікс списку всі числа між його min та max. Це робиться, перевіряючи, чи різниця макс і хв менша від його довжини.


54 байти:

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

Перевіряє, чи останній елемент або на один менше, ніж хв інших елементів, або на один більше, ніж їх макс. Потім, видаляє останній елемент і повторюється. У списку одноелементів виводиться True.

Це також можна перевірити за допомогою забавного, але більш тривалого розуміння списку.

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

Я хотів би скористатися нерівністю min(l)-2<l.pop()<max(l)+2, але це popмає відбутися спочатку. Використання програми для виводу за допомогою коду помилки, ймовірно, буде коротшим.


6

Математика, 42 байти

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

Використовує відповідність шаблону, щоб спробувати знайти префікс a, максимальна відмінність якого від наступного елемента bперевищує 1(і заперечує результат MatchQ).


6

Perl, 39 38 35 байт

Включає +1 для -p

Наведіть послідовність на STDIN:

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

antsy.pl:

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

2
Мені важко намагатися зрозуміти це ... Хочете трохи пояснити? спасибі :-) (просто головної ідеї повинно вистачити)
Дада

4

MATL , 11 байт

&-|R1=a4L)A

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Пояснення

This computes a matrix of all pairwise absolute differences and keeps the upper triangular part. The result is true iff there is at least a 1 value in all columns except the first.

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

A permutation is antsy if and only if all its left subpermutations are continuous (i.e. have difference one when sorted).

If input is guaranteed to have length more than one, then we can replace 1:sum(1|v) with seq(v), which saves four bytes.

The seq(v) in the if condition behaves differently when the input is of length one --- it generates the sequence 1:v instead of seq_along(v). However, fortunately, the output turns out to be TRUE in this case, which is the desired behaviour. The same also happens for zero-length input.

In R, T is a preset variable equal to TRUE (but R allows you to redefine it). TRUE is also deemed to be equal to 1.

Thanks to @Billywob for some helpful improvements to the original solution.


1
Reading input using scan would save you two bytes. In that case it's exactly the same number of bytes as the for loop approach: v=scan();c=c();for(i in 1:sum(1|v))c=c(c,diff(sort(v[1:i])));all(c==1) which would be 2 bytes shorter than your vectorized approach.
Billywob

Nice idea, and I can go one better I think by abusing T. Will edit.
JDL


3

Perl, 63 bytes

Note that @Gabriel Banamy came up with a shorter (55 bytes) answer. But I think this solution is still interesting, so I'm posting it.

The bytes count includes 62 bytes of code and -n flag.

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

To run it :

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

Short explanations : converts each number k to the unary representation of k+1 (that +1 is needed so the 0s don't get ignored). Then for each number k+1 (expressed in unary as 1(1*)), we look if either k ($1 holds k) or k+2 (which is then 11$1) are present in the preceding string (referenced by $-backtick). If no, then we set $. to zero. At then end we print $. which will be 1 if we never set it to zero, or zero otherwise.


3

Brain-Flak 302 264 256 Bytes

Thanks to Wheat Wizard for saving 46 bytes

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

The top of the stack will be a 1 for truthy and a 0 for falsy.

Truthy: Try it Online!
Falsy: Try it Online!

The idea is to hold the minimum and maximum number that the ant has visited in the off stack. Then compare each number to both of those and update the appropriate one. If the next number is not 1 less than the min or 1 more than the max, break out of the loop and return false.


Brief Explanation:

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

I would check for push pop reductions I see some already a few places where you could use this strategy.
Wheat Wizard

@WheatWizard I'm sure there are a few, I just didn't have time to work them out yet. Thanks for the reminder.
Riley

I'm glad this at least makes sense to you O_O
Gabriel Benamy

You can also replace instances of ([]){({}[()]<({}<>)<>>)}{} with ([]){{}({}<>)<>([])}{} to save a couple more bytes
Wheat Wizard

3

Jelly, 9 8 7 bytes

;@UŒPċṢ

Try It Online!

A Jelly translation of xnor's answer.

Old solutions:

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

Try it online!

Works very similarly to my Pyth answer below:

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

The conversion of xnor's other method to Jelly is also 7 bytes »\_«\⁼Ṣ but much more efficient
miles

ŒBŒPċṢ and ;\Ṣ€IỊȦ should save one byte in each approach.
Dennis

Unfortunately, the first doesn't work because I would need the reversed input to be bounced, like UŒBŒPċṢ which doesn't save any bytes. The is nice, though; I had misread that atom to output the logical NOT of what it actually did.
Steven H.

I'm not sure why you'd need the U (or the @ now that I think about it). If an array is antsy, so is the reversed array, no?
Dennis

1
Not necessarily: [2, 1, 3, 0] is antsy but [0, 3, 1, 2] is not.
Steven H.

3

CJam (21 20 bytes)

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

Online test suite

Dissection

This uses the observation by xnor in his Haskell answer that the difference between the maximum and minimum of the first n elements should be 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
}

Alternative approach (also 20 bytes)

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

Online test suite

This checks directly that each element after the first is at distance 1 from a previous element. Since the input is a permutation and hence doesn't repeat values, this is a sufficient test. Thanks to Martin for a 1-byte saving.

Dissection

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

I think this saves one? {_{a+_)f-:z1&,*}*^!}
Martin Ender

@MartinEnder, very nice. Curiously you posted that just as I was posting a completely different approach with the same byte count.
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;}

Formerly:

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

Saved 3 bytes by replacing true and false with 1>0 and 0>1.

Saved 23 bytes thanks to excellent suggestions from 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;
}

Keep track of the highest and lowest values seen so far as m and n; only accept a new value if it is m + 1 or n - 1 i.e. the next higher or lower value; initialize the high value, m, to one less than the first element so that it will "match" the first time around the loop. Note: this is a linear-time, online algorithm. It requires only three words of memory, for the current, highest-so-far, and lowest-so-far values, unlike a lot of the other solutions.

If the next value misses both the high and low ends of the range, the lowest-so-far value is set to -1 and then the low end can never proceed and reach zero. We then detect an antsy sequence by checking whether the low value, n, reached zero.

(Unfortunately this is less efficient because we always have to look at the entire sequence rather than bailing out after the first wrong number, but it's hard to argue with a 23-byte savings (!) when other solutions are using O(n^2) and exponential time approaches.)

Usage:

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

Note: this can also be written without taking advantage of 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;}

Good handling of the special case. int m,n;m=n=a[0];--m; could be int n=a[0],m=n-1;, and the expensive return and else could be reduced with i==m+1?m++:n=(i==n-1)?i:-1;return n==0; (or something similar - I haven't tested this).
Peter Taylor

@PeterTaylor Fantastic! Unfortunately, Java won't allow any side effects such as m++ or m+=1 there, so I still need an if and an else, and it loses the aspect of short circuiting on the first bad value, but that is a big improvement. Thank you!
David Conrad

It will allow side-effects in a complex expression. What it might not like is using a general expression as a statement. In the worst case you need to create a dummy variable j and assign the result to it, but suspect there would be a better way of doing it.
Peter Taylor

@PeterTaylor Well, I tried a few variations on it, including assigning it to a dummy variable g, and I couldn't get it to work. (I'm using Java 9-ea+138, maybe it's a difference between Java 8 and Java 9?) I may try again tomorrow.
David Conrad

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

2

Pyth (fork), 13 bytes

!sstMM.+MSM._

No Try It Online link for this fork of Pyth. The fork includes the deltas function .+, which is not part of the standard Pyth library.

Explanation:

           ._  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
Seeing this convinces me to merge this into Pyth.
isaacg

2

Perl, 66 54 +1 = 55 bytes

+1 byte for -n.

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

Explanation:

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

Prints 0 if false, 1 if true.

-11 bytes thanks to @Dada


1
That one is really nice. You can golf it down to 55 bytes though : perl -nE 's/\d+/$.&=!@a||1~~[map{abs$_-$&}@a];push@a,$&/eg;say$.' : -n instead of <>=~ which allows you to get rid of /r modifier. use \d+ and then $& instead of (\d+) and $1. !@a instead of 0>$#a. $.&= instead of $.&&=. push@a,$& instead of @a=(@a,$&)
Dada

For some reason, my system tells me the new file is 55 bytes long, which is obviously wrong because it's only 54 characters, so ???
Gabriel Benamy

Hmm that's strange. (and I have no idea where this comes from). But I'm pretty sure it's only 54 (the PPCG-Design script tells me 54, and my bytecount app tells me 54 aswell).
Dada

2
Is it possible the byte count was out due to the file having an unnecessary newline at the end?
trichoplax

2

Brainfuck, 60 bytes

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

The permutation is given as bytes with no separators and no terminating newline. Since \x00 occurs in the input, this is designed for implementations with EOF = -1. The output is \x00 for false and \x01 for true.

If a permutation of \x01 up to chr(r) is allowed, then we can replace all instances of ,+ with , for a score of 57 with an EOF = 0 implementation.

Try it online (57-byte version): Input can be given as a permutation of any contiguous range of bytes excluding \x00, and the output will be \x00 for false and the minimum of the range for true.

We keep track of the min and max seen so far, and for each character after the first, check whether it is min-1 or max+1 or neither. In the case of neither, move the pointer outside the normal working space so that the local cells become zero.

The memory layout of the normal working space at the beginning of the main loop is

c a b 0 0

where c is the current character, a is min, and b is max. (For the 60-byte version, everything is handled with an offset of 1 because of ,+.)


1

Brachylog, 22 bytes

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

Try it online!

Explanation

I haven't found a concise way of checking whether a list contains consecutive integers or not. The shortest I found is to generate a range between the first and last element of that list and check that that range is the original list.

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

Range from first to last is one approach which had occurred to me in CJam. The other was sort, pairwise differences, check they're all 1. I don't know how easy that is in Brachylog.
Peter Taylor

@PeterTaylor There is no short way of generating consecutive pairs (or directly compute pairwise differences) unfortunately (for now).
Fatalize

1

Batch, 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

Takes input as command-line arguments. Exits with error level 0 for success, 1 for failure.


1

J, 14 bytes

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

This is based on @xnor's method.

Explanation

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

Array x has values from 0 to maximum number in order (Python would be much better here...). The loop goes backwards trying to match the lowest (x[b]) or the highest (x[e]) number not yet encountered; if it does, that number could be reached in that step.

Test code here.


0

Mathematica, 47 bytes

A little longer than Martin Ender's solution (surprise surprise!). But it's one of my more unreadable efforts, so that's good :D

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

Explanation:

#=={}                         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 & test code:

Try it here.

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

Output:

true
true
true
true
false
true
false
true
true
false
true
false
false
false
false
true
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.