Sprawdź moje tablice tunelowania

18

Wyobraź sobie, że masz tablicę liczb całkowitych, których nieujemne wartości są wskaźnikami do innych pozycji w tej samej tablicy, tyle że te wartości reprezentują tunele, więc jeśli wartość w pozycji A jest dodatnia i wskazuje na pozycję B, to wartość na pozycji B musi być również dodatnie i wskazywać na pozycję A, aby reprezentować oba końce tunelu. Więc:

Wyzwanie

  • Biorąc pod uwagę tablicę liczb całkowitych, sprawdź, czy tablica jest zgodna z ograniczeniem bycia tablicą tunelującą i zwróć dwie różne, spójne wartości dla wartości true i falsey.
  • Wartości w tablicy będą poniżej zera dla pozycji nie tunelowych i zero lub powyżej dla pozycji tunelowych. Jeśli tablica ma indeks 1, wówczas wartość zerowa reprezentuje pozycję nie tunelowaną. Wartości inne niż tunelowe nie muszą być sprawdzane.
  • Jeśli dodatnia wartość w komórce wskazuje na siebie, to falsey. Jeśli A wskazuje na B, B na C i C na A, to falsey. Jeśli dodatnia wartość wskazuje poza granice tablicy, to falsey.

Przykłady

Poniższe przykłady są indeksowane według 0:

[-1, -1, -1, 6, -1, -1, 3, -1, -1]  Truthy (position 3 points to position 6 and vice versa)
[1, 0]                              Truthy (position 0 points to position 1 and vice versa)
[0, 1]                              Falsey (positions 0 and 1 point to themselves)
[4, 2, 1, -1, 0, -1]                Truthy
[2, 3, 0, 1]                        Truthy
[1, 2, 0]                           Falsey (no circular tunnels allowed)
[-1, 2, -1]                         Falsey (tunnel without end)
[]                                  Truthy (no tunnels, that's OK)
[-1, -2, -3]                        Truthy (no tunnels, that's OK)
[1, 0, 3]                           Falsey (tunnel goes beyond limits)
[1]                                 Falsey (tunnel goes beyond limits)
[1, 0, 3, 7]                        Falsey (tunnel goes beyond limits)

To jest , więc może wygrać najkrótszy kod dla każdego języka!

Charlie
źródło
3
po co mamy wracać [0]?
ngn
1
Rozwijając pytanie ngn, czy sam tunele są dozwolone? Co by dały skrzynie [0,1]i jakie [0,-1,2]?
dylnan
1
@dylnan [0,1]jest w przykładach. „Jeśli dodatnia wartość w komórce wskazuje na siebie, to jest falsey”
ngn
1
sugerowany test:[2,3,0,1]
ngn
1
@JonathanAllan wartości tunelu są wartościami wskazującymi możliwe pozycje tablic. Jeśli tablica jest indeksowana 0, to każda wartość poniżej 0 nie jest wartością tunelu. Jeśli jest indeksowany 1, to każda wartość poniżej 1 nie jest wartością tunelu.
Charlie,

Odpowiedzi:

8

R , 47 bajtów

function(v,a=v[v>0],b=sort(a))all(v[a]==b&a!=b)

Wypróbuj online!


Kod i objaśnienie:

f=
function(v){          # v vector of tunnel indexes (1-based) or values <= 0

  a = v[v>0]          # get the tunnel positions

  b = sort(a)         # sort the tunnel positions ascending

  c1 = v[a]==b        # get the values of 'v' at positions 'a'
                      # and check if they're equal to the sorted positions 'b'
                      # (element-wise, returns a vector of TRUE/FALSE)

  c2 = a != b         # check if positions 'a' are different from sorted positions 'b' 
                      # (to exclude tunnels pointing to themselves, element-wise,
                      #  returns a vector of TRUE/FALSE)

  all(c1 & c2)        # if all logical conditions 'c1' and 'c2' are TRUE then
                      # returns TRUE otherwise FALSE
}
digEmAll
źródło
Byłbym naprawdę wdzięczny za wyjaśnienie tej odpowiedzi. :-)
Charlie,
3
@Charlie: dodano wyjaśnienie
digEmAll
6

Python 2 , 66 61 60 bajtów

lambda l:all(len(l)>v!=i==l[v]for i,v in enumerate(l)if-1<v)

Wypróbuj online!

TFeld
źródło
5

APL (Dyalog Unicode) , 19 24 bajtów

×/<∘≢⍨×≠∘⍳∘≢⍨×0∘>∨⊢=⊢⍳⍳⍨

Wypróbuj online!

Prefiks anonimowy lambda, zwracający 1 za prawda i 0 za fałsz. Łącze TIO zawiera „wstępnie potwierdzoną” wersję danych wyjściowych dla przypadków testowych.

Krzyczy do @ngn i @ Adám za zapisanie około bajtów bazillionów.

Dodatkowy krzyk do @ngn za pomoc w ustaleniu odpowiedzi dla niektórych przypadków testowych i uczynieniu go pociągiem.

Zaktualizowana odpowiedź wykorzystuje ⎕IO←0, ustawiając I ndex O rigin na 0.

W jaki sposób:

×/<∘≢⍨×≠∘⍳∘≢⍨×0∘>∨⊢=⊢⍳⍳⍨  Prefix lambda, argument   4 2 1 ¯1 0 ¯1.
                       ⍳⍨  Index of (⍳)  in ⍵. ⍵⍳⍵  0 1 2 3 4 3
                     ⊢⍳    Index of that in  (returns the vector length if not found). 
                           ⍵⍳⍵⍳⍵  4 2 1 6 0 6
                  ⊢=       Compare that with ⍵. ⍵=⍵⍳⍵⍳⍵  1 1 1 0 1 0
                           This checks if positive indices tunnel back and forth correctly.
                          Logical OR with
              0∘>          0>⍵  0 0 0 1 0 11 1 1 0 1 0  1 1 1 1 1 1
                           Removes the zeroes generated by negative indices
             ×             Multiply that vector with
                          (using  as both arguments)
         ⍳∘≢               Generate the range [0..length(⍵)-1]
       ≠∘                  And do ⍵≠range; this checks if any          
                           element in  is tunneling to itself.
                           ⍵≠⍳≢⍵  4 2 1 ¯1 0 ¯10 1 2 3 4 5  1 1 1 1 1 1  
      ×                    Multiply that vector with
                          (using  as both arguments)
  <∘≢                       < length(⍵)  4 2 1 ¯1 0 ¯1 < 6  1 1 1 1 1 1
                           This checks if any index is out of bounds
×/                         Finally, multiply and reduce.
                           ×/1 1 1 1 1 1  1 (truthy)
J. Sallé
źródło
Myślę, że to nie działa dla (1), (3 2 1), (5 4 3 2 1).
nwellnhof
0<×Myślę, że
Uriel
4

JavaScript (ES6), 35 bajtów

Zaoszczędzono 1 bajt dzięki @Shaggy

a=>a.every((v,i)=>v<0|v!=i&a[v]==i)

Wypróbuj online!

Skomentował

a =>                // a[] = input array
  a.every((v, i) => // for each value v at position i in a[]:
    v < 0 |         //   force the test to succeed if v is negative (non-tunnel position)
    v != i &        //   make sure that this cell is not pointing to itself
    a[v] == i       //   check the other end of the tunnel
  )                 // end of every()
Arnauld
źródło
Dobrze, że sprawdziłem rozwiązania przed opublikowaniem portu mojego rozwiązania Japt, które jest prawie identyczne z tym. Możesz zapisać bajt za pomocą a=>a.every((v,i)=>v<0|v!=i&a[v]==i).
Shaggy
3

Perl 6 , 36 bajtów

{!.grep:{2-set $++,$^v,.[$v]xx$v+1}}

Wypróbuj online!

Podstawową ideą jest sprawdzenie, czy zestaw { i, a[i], a[a[i]] }zawiera dokładnie dwa różne elementy dla każdego indeksu za ipomocą a[i] >= 0. Jeśli element wskazuje na siebie, zestaw zawiera tylko jeden odrębny element. Jeśli drugi koniec nie wskazuje i, zestaw zawiera trzy odrębne elementy. Jeśli a[i] < 0The xxczynnikiem jest zerowy lub ujemny, a więc zespół jest { i, a[i] }także z dwóch oddzielnych elementów.

nwellnhof
źródło
3

MATL , 19 18 bajtów

-1 bajtów dzięki Luisowi

n:G=GGG0>f))7M-|hs

Wypróbuj online! , tylko dla pierwszego, ponieważ nie wiem, jak to zrobić!

Podaje, 0jeśli to prawda, niezerową liczbę całkowitą, jeśli falsey, np. dla przypadku testowego 6 daje 4.

Pamiętaj, że podobnie jak MATLAB, MATL ma indeks 1, więc należy dodać 1 do przypadków testowych!

Nigdy wcześniej nie grałem w Esolang, więc bardzo otrzymałem porady!

Wyjaśniono:

n:G=GGG0>f))7M-|hs
                        Implicit - input array
n                       Number of values in array
 :                      Make array 1:n
  G                     Push input
   =                    Equality
n:G=                    Makes non-zero array if any of the tunnels lead to themselves
    GGG                 Push input 3x
       0                Push literal 0
        >               Greater than
      G0>               Makes array of ones where input > 0
         f              Find - returns indeces of non-zero values
                        Implicit - copy this matrix to clipboard
          )             Indeces - returns array of positive integers in order from input
           )            Ditto - Note, implicit non-zero any above maximum
            7M          Paste from clipboard
              -         Subtract
    GGG0>f))7M-         Makes array of zeros if only two-ended tunnels evident
               |        Absolute value (otherwise eg. [3,4,2,1] -> '0')
                h       Horizontal concat (ie. joins check for self tunnels and wrong tunnels)
                 s      Sum; = 0 if truthy, integer otherwise                 
Lui
źródło
Czy moje wyjaśnienie jest zbyt trudne? Chcę, aby stało się to oczywiste bez całkowitego przesadzania.
Lui,
3

05AB1E , 16 15 14 bajtów

εèNQyNÊ*y0‹~}P

-1 bajt dzięki @Dorian .

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

ε               # Map each value `y` of the (implicit) input-list to:
 è              #   If the current value indexed into the (implicit) input-list
  NQ            #   is equal to the index
       *        #   And
    yNÊ         #   If the current value is not equal to the current index
           ~    #  Or if:
        y0     #   The current value is negative
            }P  # After the map: check if everything is truthy
                # (after which the result is output implicitly)
Kevin Cruijssen
źródło
Moja próba była taka sama, z wyjątkiem filtra. Nie widzę sposobu na poprawę tego.
Emigna,
1
14 bajtów . Możesz przesunąć bieżącą wartość za εpomocą y. Więc nie ma potrzeby ©, a każdy ®zastąpiony przezy
Dorian
@Dorian Ah, oczywiście .. Nie było to możliwe w spuściźnie, kiedy opublikowałem tę odpowiedź, ale powinienem o tym pomyśleć, kiedy dzisiaj grałem w golfa. Dzięki! :)
Kevin Cruijssen
2

Python, 112 97 96 86 bajtów

f=lambda l:sum(i==l[i]or len(l)<=l[i]or 0<=l[i]and i!=l[l[i]]for i in range(len(l)))<1

Wypróbuj online!

Zwraca Truelub False.

-10 bajtów dzięki @Rod i @TFeld.

DimChtz
źródło
2

Haskell , 48 bajtów

(all=<< \u(x,y)->y<0||x/=y&&elem(y,x)u).zip[0..]

Zweryfikuj wszystkie przypadki testowe!

Wyjaśnienie

Najpierw trochę poprawmy kod. Podobnie f =<< gjak \x -> f (g x) xkod jest równoważny

(\u->all(\(x,y)->y<0||x/=y&&elem(y,x)u)u).zip[0..]

co jest nieco jaśniejsze.

(\u ->                                  -- given u, return
    all (\(x, y) ->                     -- whether for all elements (x, y) of u
            y < 0 ||                    -- either y < 0, or
            x /= y && elem (y, x) u     -- (x /= y) and ((y, x) is in u)
        )
    u
) . zip [0..]                           -- given the array a (implicitly via point-free style),
                                        -- return the array augmented with indices (it's the u above)

To rozwiązanie opiera się na prostej obserwacji: niech abędzie tablicą wejściową i ulistą par, (i, a[i])gdzie ijest indeks. Potem ajest ważna tablica wtedy i tylko wtedy, gdy dla każdego (x, y)w uz y >= 0, para (y, x)należy do utak dobrze.

Delfad0r
źródło
2

Java (JDK) , 89 bajtów

a->{int l=a.length,i=l;for(;i-->0;)i=a[i]<1||a[i]<l&&a[i]!=i&a[a[i]]==i?i:-2;return-2<i;}

Wypróbuj online!

Kredyty

Olivier Grégoire
źródło
Mógłby być 87 bajtów, gdyby nie ten nieznośny wyjątek IndexOutOfBoundsException. Może widzisz coś, co łatwo to naprawić?
Kevin Cruijssen
@KevinCruijssen Widzę, jak to naprawić dla 102 bajtów . Nic krótszego :(
Olivier Grégoire,
1
-3 bajty - pomiń ri wyjdź z pętli analogicznie jak tutaj
AlexRacer
1

Węgiel drzewny , 22 bajty

¬Φθ∨⁼ικ¬∨‹ι⁰∧‹ιLθ⁼κ§θι

Wypróbuj online! Link jest do pełnej wersji kodu. Wyjścia -dla prawdy i nic dla fałszu. Uwaga: wprowadzenie pustej tablicy wydaje się powodować awarię węgla drzewnego, ale na razie możesz zamiast tego wprowadzić spację, która jest wystarczająco blisko. Wyjaśnienie:

  θ                     Input array
 Φ                      Filter elements
     ι                  Current value
    ⁼                   Equals
      κ                 Current index
   ∨                    Or
       ¬                Not
          ι             Current value
         ‹ ⁰            Is less than zero
        ∨               Or
              ι         Current value
             ‹          Is less than
               L        Length of
                θ       Input array
            ∧           And
                  κ     Current index
                 ⁼      Equals
                   §θι  Indexed value
¬                       Logical Not (i.e. is result empty)
                        Implicitly print
Neil
źródło
To nie wydaje się być wyzwaniem bardzo łatwym do rozpalenia ... :-)
Charlie
1

Pascal (FPC) , 165 155 153 bajtów

function f(a:array of int32):byte;var i:int32;begin f:=1;for i:=0to length(a)-1do if a[i]>-1then if(a[i]=i)or(a[i]>length(a))or(a[a[i]]<>i)then f:=0;end;

Wypróbuj online!

Tym razem wykonano funkcję, ponieważ dane wejściowe to tablica. Zwraca 1za prawdę i 0falsey.

AlexRacer
źródło
1

Czysty , 60 bajtów

import StdEnv
@l=and[v<0||l%(v,v)==[i]&&v<>i\\v<-l&i<-[0..]]

Wypróbuj online!

Czysty , 142 bajty

Ogromnie skomplikowana wersja potworów:

import StdEnv,Data.List,Data.Maybe
$l=and[?i(mapMaybe((!?)l)j)j\\i<-l&j<-map((!?)l)l|i>=0]with?a(Just(Just c))(Just b)=a==c&&b<>c;?_ _ _=False

Wypróbuj online!

Wyjaśniono:

$ l                           // function $ of `l` is
 = and [                      // true when all elements are true
  ?                           // apply ? to
   i                          // the element `i` of `l`
   (mapMaybe                  // and the result of attempting to
    ((!?)l)                   // try gettting an element from `l`
    j)                        // at the potentially invalid index `j`
   j                          // and `j` itself, which may not exist
  \\ i <- l                   // for every element `i` in `l`
  & j <- map                  // and every potential `j` in
    ((!?)l)                   // `l` trying to be indexed by
    l                         // every element in `l`
  | i >= 0                    // where `i` is greater than zero
 ]
with
 ? a (Just (Just c)) (Just b) // function ? when all the arguments exist
  = a==c && b<>c              // `a` equals `c` and not `b`
  ;
 ? _ _ _ = False              // for all other arguments, ? is false
Obrzydliwe
źródło
1

Pyth , 17 16 bajtów

.A.e|>0b&nbkq@Qb

Spróbuj go online tutaj , lub sprawdzić wszystkie przypadki testowe od razu tutaj .

.A.e|>0b&nbkq@QbkQ   Implicit: Q=eval(input())
                     Trailing k, Q inferred
  .e             Q   Map the input with b=element, k=index, using:
     >0b               0>b
    |                  OR (
         nbk           b != k
        &              AND
            q@Qbk      Q[b] == k)
.A                   Check if all elements are truthy

Edycja: zdałem sobie sprawę, że końcowe k również było niepotrzebne

Sok
źródło
1

Groovy , 52 bajty

{o=!(i=0);it.each{e->o&=e<0||(it[e]==i&&i-e);i++};o}

Wypróbuj online!

GolfIsAGoodWalkSpoilt
źródło
1

C (gcc) , 95 bajtów

i(_,o,O,Q,I)int*_;{for(I=O=0;O<o;O++)_[O]<0||(Q=_[O[_]],I|=_[O]>=o|Q<0|Q>=o|O[_]==O|Q!=O);Q=I;}

Wypróbuj online!

Jonathan Frech
źródło
0

Mathematica, 42 bajty

#=={}||(a=0@@#)[[#]]=!=a&&a[[#]][[#]]===a&

Czysta funkcja. Pobiera 1-indeksowaną listę liczb jako dane wejściowe i zwracane Truelub Falsedane wyjściowe. Po prostu podąża tunelami, upewniając się, że 0mapy do 0, nie ma 1-cykli, a wszystkie cykle są 2-cykli. (Nie jestem do końca pewien, czy to się nie powiedzie na żadnym przypadku krawędzi, ale daje prawidłowe wyniki dla przykładów).

LegionMammal978
źródło
0

Ta odpowiedź nie działa. Tutaj tylko w celach ilustracyjnych.

Ta odpowiedź przechodzi przez wszystkie (obecnie) opublikowane przypadki testowe. Jednak nie powiedzie się (wywołuje błąd) na innych prawidłowych danych wejściowych, takich jak [1, 2]lub [1, 0, 3, 7].

Jak to mogło przejść [1, 0, 3]i zawieść [1, 0, 3, 7]? Cóż, przechodzi przez listę, tak jak można się spodziewać. Kiedy czyta element xlisty a, najpierw sprawdza, czy xjest mniejsza niż len(a), i natychmiast zwraca False, jeśli tak jest. Więc to poprawnie powraca Falsena [1, 0, 3], ponieważ 3nie jest mniejsza niż len(a).

Ale zakładając, że xpozytywny wynik testu się powiedzie, kod przejdzie do wykonania innych kontroli i w pewnym momencie zdarzy się, że się oceni a[a[x]]. Mamy już gwarancję, że ocena a[x]będzie w porządku ... ale nie a[a[x]], co rozwiązuje się, a[7]gdy xjest 3w [1, 0, 3, 7]przykładzie. W tym momencie Python podnosi IndexError, a nie zwraca False.

Dla kompletności, oto odpowiedź.

Python 2 , 59 bajtów

lambda a:all(x<len(a)>-1<a[x]!=x==a[a[x]]for x in a if-1<x)

Wypróbuj online!

Chciałem to zrobić x<len(a)and-1<a[x]..., ale oczywiście len(a)zawsze >-1, więc powyższe jest równoważne. Kontrola ta jest w sumie 5 przykuty relations ( <, >, <, !=, i ==) oraz oddzielny check -1<xw ifstanie.

Python (dogodnie) zwiera takie łańcuchowe relacje, więc na przykład, jeśli x>=len(a)wtedy czek wraca Falsezanim do niego dojdzie a[x](co w innym przypadku spowodowałoby an IndexError).

Mathmandan
źródło