Controlla i miei array di tunnel


18

Immagina di avere un array di numeri interi, i cui valori non negativi sono puntatori ad altre posizioni nello stesso array, solo che quei valori rappresentano tunnel, quindi se il valore in posizione A è positivo e punta in posizione B, quindi il valore in posizione B deve anche essere positivo e puntare alla posizione A per rappresentare entrambe le estremità del tunnel. Così:

Sfida

  • Dato un array di numeri interi, controlla se l'array è conforme alla restrizione per essere un array tunneling e restituisce due valori distinti e coerenti per verità e falsità.
  • I valori nella matrice saranno inferiori a zero per le posizioni non tunnel e zero o superiore per le posizioni tunnel. Se l'array è 1 indicizzato, il valore zero rappresenta una posizione non tunnel. Non è necessario verificare i valori non tunnel.
  • Se un valore positivo in una cella punta a se stesso, questa è una falsità. Se A indica B, da B a C e da C a A, è un falso. Se un valore positivo punta oltre i limiti dell'array, si tratta di un falso.

Esempi

I seguenti esempi sono indicizzati 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)

Questo è , quindi può vincere il codice più breve per ogni lingua!


3
per cosa dovremmo tornare [0]?
ngn,

1
Espandendo la domanda di ngn, sono ammessi gli auto tunnel? Quali sarebbero i casi [0,1]e [0,-1,2]dare?
dylnan,

1
@dylnan [0,1]è negli esempi. "Se un valore positivo in una cella indica se stesso, è un falso"
ngn

1
prova suggerita:[2,3,0,1]
ngn

1
@JonathanAllan i valori del tunnel sono valori che indicano le possibili posizioni dell'array. Se l'array è indicizzato 0, ogni valore inferiore a 0 non è un valore tunnel. Se è 1 indicizzato, ogni valore inferiore a 1 non è un valore tunnel.
Charlie,

Risposte:


8

R , 47 byte

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

Provalo online!


Codice non spiegato e spiegazione:

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
}

Gradirei davvero una spiegazione per questa risposta. :-)
Charlie

3
@ Charlie: spiegazione aggiunta
digEmAll


5

APL (Dyalog Unicode) , 19 24 byte

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

Provalo online!

Prefisso lambda anonimo, che restituisce 1 per verità e 0 per falsità. Il collegamento TIO contiene una versione "predefinita" dell'output per i casi di test.

Shoutouts su @ngn e @ Adám per il salvataggio di circa un milione di byte.

Un ulteriore ringraziamento a @ngn per l'aiuto nel fissare la risposta per alcuni casi di test e nel renderlo un treno.

La risposta aggiornata utilizza ⎕IO←0, impostando I ndex O rigin su 0.

Come:

×/<∘≢⍨×≠∘⍳∘≢⍨×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)

Penso che questo non funzioni per (1), (3 2 1), (5 4 3 2 1).
nwellnhof,

0<×Penso
Uriel il

4

JavaScript (ES6), 35 byte

Salvato 1 byte grazie a @Shaggy

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

Provalo online!

Commentate

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

Per fortuna ho controllato le soluzioni prima di pubblicare un port della mia soluzione Japt, che è quasi identico a questo. È possibile salvare un byte con a=>a.every((v,i)=>v<0|v!=i&a[v]==i).
Shaggy,



3

Perl 6 , 36 byte

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

Provalo online!

L'idea di base è verificare se l'insieme { i, a[i], a[a[i]] }contiene esattamente due elementi distinti per ciascun indice icon a[i] >= 0. Se un elemento punta a se stesso, l'insieme contiene solo un singolo elemento distinto. Se l'altra estremità non punta a i, il set contiene tre elementi distinti. Se a[i] < 0, il xxfattore è zero o negativo, quindi l'insieme è { i, a[i] }, anche con due elementi distinti.


3

MATL , 19 18 byte

-1 Byte grazie a Luis

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

Provalo online! , solo per il primo, perché non so come fare tutti!

Fornisce 0if truey, un numero intero diverso da zero se falsey, ad es. per test case 6 dà 4.

Ricorda che come MATLAB, MATL è 1 indicizzato, quindi 1 deve essere aggiunto ai casi di test!

Non ho mai giocato a golf in un Esolang prima, quindi il consiglio è stato molto apprezzato!

Ha spiegato:

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                 

La mia spiegazione è troppo prolissa? Voglio renderlo ovvio senza esagerare.
Lui,

3

05AB1E , 16 15 14 byte

εèNQyNÊ*y0‹~}P

-1 byte grazie a @Dorian .

Provalo online o verifica tutti i casi di test .

Spiegazione:

ε               # 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)

Il mio tentativo è stato lo stesso tranne che con il filtro. Non vedo un modo per migliorare su questo.
Emigna,

1
14 byte . È possibile spingere il valore corrente di εcon y. Quindi non c'è bisogno di ©, e ciascuno ®sostituito day
Dorian

@Dorian Ah, certo .. Questo non era possibile nell'eredità quando ho pubblicato questa risposta, ma avrei dovuto pensarci quando ho fatto il mio golf oggi. Grazie! :)
Kevin Cruijssen,


2

Python, 112 97 96 86 byte

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

Provalo online!

Restituisce Trueo False.

-10 byte grazie a @Rod e @TFeld.



2

Haskell , 48 byte

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

Verifica tutti i test!

Spiegazione

Per prima cosa ungolf un po 'il codice. Come f =<< gè lo stesso \x -> f (g x) x, il codice è equivalente a

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

che è un po 'più chiaro.

(\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)

Questa soluzione si basa su una semplice osservazione: lascia che asia l'array di input e ul'elenco di coppie in (i, a[i])cui iè presente un indice. Quindi aè un array valido se e solo se per ogni (x, y)in ucon y >= 0, anche la coppia (y, x)appartiene u.


2

Java (JDK) , 89 byte

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

Provalo online!

Titoli di coda


Avrebbero potuto essere 87 byte se non fosse stato per quel fastidioso IndexOutOfBoundsException. Forse vedi qualcosa per risolverlo facilmente?
Kevin Cruijssen,

@KevinCruijssen Vedo come risolverlo per 102 byte . Niente di più breve :(
Olivier Grégoire,

1
-3 byte - ometti re interrompi il ciclo analogo a qui
AlexRacer

1

Carbone , 22 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Uscite -per truthy e nulla per falsy. Nota: l'immissione di un array vuoto sembra causare l'arresto anomalo del carbone, ma per ora è possibile inserire uno spazio abbastanza vicino. Spiegazione:

  θ                     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

Questa non sembra essere una sfida molto carbone ... :-)
Charlie

1

Pascal (FPC) , 165 155 153 byte

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;

Provalo online!

Questa volta ha funzionato perché l'input è array. Ritorna 1per la verità e 0per la falsità.


1

Pulito , 60 byte

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

Provalo online!

Pulito , 142 byte

Versione monster mostruosamente complicata:

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

Provalo online!

Ha spiegato:

$ 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


1

Pyth , 17 16 byte

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

Provalo online qui o verifica tutti i casi di test contemporaneamente qui .

.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

Modifica: realizzato che anche il k finale era inutile





0

Mathematica, 42 byte

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

Funzione pura. Prende un elenco di numeri 1 indicizzato come input e restituisce Trueo Falsecome output. Segue solo i tunnel, assicurando che non esistano 0mappe per 01 ciclo e tutti i cicli sono 2 cicli. (Non sono del tutto sicuro se questo fallisce su tutti i casi limite, ma fornisce i risultati corretti per gli esempi.)


0

Questa risposta non funziona. Qui solo a scopo illustrativo.

Questa risposta supera tutti i casi di test (attualmente) pubblicati. Tuttavia, non riesce (genera un errore) su altri input validi, come [1, 2]o [1, 0, 3, 7].

Come potrebbe passare [1, 0, 3]e fallire [1, 0, 3, 7]? Bene, procede attraverso l'elenco, proprio come ti aspetteresti. Quando legge un elemento xdell'elenco a, controlla innanzitutto se xè inferiore a len(a), e restituisce immediatamente False, in tal caso. Quindi restituisce correttamente Falsesu [1, 0, 3], perché 3non è inferiore len(a).

Ma supponendo che xsuperi quel controllo, il codice continuerà a fare altri controlli e ad un certo punto capita di valutare a[a[x]]. Abbiamo già garantito che la valutazione a[x]sarà OK ... ma non a[a[x]], che si risolve a a[7]quando xè 3in [1, 0, 3, 7]esempio. A questo punto Python solleva un IndexError, piuttosto che tornare False.

Per completezza, ecco la risposta.

Python 2 , 59 byte

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

Provalo online!

Volevo farlo x<len(a)and-1<a[x]..., ma ovviamente lo len(a)è sempre >-1, quindi quanto sopra è equivalente. Questo controllo è un totale di 5 rapporti concatenati ( <, >, <, !=, e ==), oltre a un controllo separato -1<xin ifcondizione.

Python (convenientemente) cortocircuita le relazioni in questo modo, quindi ad esempio se x>=len(a)il controllo ritorna Falseprima che arrivi a[x](che altrimenti solleverebbe un IndexError).

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.