Tünel dizilerimi kontrol et


18

Negatif olmayan değerleri aynı dizideki diğer konumlara işaret eden bir tamsayı diziniz olduğunu düşünün, yalnızca bu değerler tünelleri temsil eder, bu nedenle A konumundaki değer pozitifse ve B konumuna işaret ediyorsa, konumdaki değer B ayrıca pozitif olmalı ve tünelin her iki ucunu temsil etmek için A konumunu göstermelidir. Yani:

Meydan okuma

  • Bir tamsayı dizisi verildiğinde, dizinin bir tünel dizisi olma kısıtlamasına uyup uymadığını kontrol edin ve doğruluk ve falsey için iki ayrı, tutarlı değer döndürün.
  • Dizideki değerler, tünel dışı konumlar için sıfırın altında ve tünel konumları için sıfırın veya üzerinde olacaktır. Diziniz 1 dizinli ise, sıfır değeri tünel dışı bir konumu temsil eder. Tünel dışı değerlerin kontrol edilmesi gerekmez.
  • Bir hücredeki pozitif bir değer kendini gösteriyorsa, bu bir falseydir. A, B'yi, B'yi C'yi ve C'yi A'yı gösteriyorsa, bu bir falseydir. Pozitif bir değer dizinin sınırlarını aşarsa, bu bir falseydir.

Örnekler

Aşağıdaki örnekler 0 dizinlidir:

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

Bu , bu yüzden her dil için en kısa kod kazanabilir!


3
ne için dönmeliyiz [0]?
ngn

1
Ngn'in sorusunu genişleterek, kendi tünellerine izin veriliyor mu? Davalar ne olacak [0,1]ve [0,-1,2]verecek?
dylnan

1
@dylnan [0,1]örneklerde bulunmaktadır. "Eğer bir hücredeki pozitif bir değer kendini gösteriyorsa, bu bir
falseydir

1
önerilen test:[2,3,0,1]
ngn

1
@JonathanAllan tünel değerleri olası dizi konumlarını gösteren değerlerdir. Diziniz 0 dizinli ise, 0'ın altındaki her değer bir tünel değeri değildir. 1 dizinli ise, 1'in altındaki her değer bir tünel değeri değildir.
Charlie

Yanıtlar:


8

R , 47 bayt

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

Çevrimiçi deneyin!


Kaydedilmemiş kod ve açıklama:

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
}

Bu cevap için bir açıklama gerçekten takdir ediyorum. :-)
Charlie

3
@Charlie: açıklama eklendi
digEmAll


5

APL (Dyalog Unicode) , 19 24 bayt

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

Çevrimiçi deneyin!

Anonim lambda öneki, doğruluk için 1 ve yanlış için 0 döndürür. TIO bağlantısı, test senaryoları için çıktının "önceden hazırlanmış" bir versiyonunu içerir.

@Ngn ve @ Adám'a yapılan yaklaşık bazilyon baytı kaydettiği için yapılan alışverişler

Bazı test durumlarının cevabını düzeltmek ve bir tren yapmak için yardım için @ngn'a ekstra bir çekilme.

Güncellenmiş cevap ⎕IO←0, I ndex O rigin değerini 0 olarak ayarlayarak kullanır .

Nasıl:

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

Bunun (1), (3 2 1), (5 4 3 2 1) için işe yaramadığını düşünüyorum.
nwellnhof

0<×Sanırım
Uriel

4

JavaScript (ES6), 35 bayt

@Shaggy sayesinde 1 bayt kaydedildi

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

Çevrimiçi deneyin!

Yorumlananlar

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

İyi bir şey, Japt çözümümün bir portunu göndermeden önce çözümleri kontrol ettim, bu neredeyse aynı. İle bir bayt kaydedebilirsiniz a=>a.every((v,i)=>v<0|v!=i&a[v]==i).
Shaggy



3

Perl 6 , 36 bayt

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

Çevrimiçi deneyin!

Temel fikir seti olup olmadığını kontrol etmektir { i, a[i], a[a[i]] }her endeksi için tam olarak iki ayrı öğeleri içerir iile a[i] >= 0. Bir öğe kendini gösteriyorsa, kümede yalnızca tek bir ayrı öğe bulunur. Diğer uç geri dönmezse i, set üç ayrı öğe içerir. Eğer a[i] < 0, xxfaktör sıfır ya da negatif olması, yani dizi { i, a[i] }iki ayrı elemanlarla da.


3

MATL , 19 18 Bayt

-1 Luis sayesinde bayt

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

Çevrimiçi deneyin! , sadece ilki için, çünkü hepsini nasıl yapacağımı bilmiyorum!

0Doğruysa verir , falsey ise sıfırdan farklı bir tamsayı, örn. test durumu 6 için verir 4.

MATLAB gibi MATL'nin de 1 endekslendiğini ve bu nedenle test senaryolarına 1 ekleneceğini unutmayın!

Asla bir Esolang golf, tavsiye büyük aldı!

Açıklaması:

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                 

Açıklamam çok mu garip? Tamamen denize girmeden bunu belirginleştirmek istiyorum.
Lui

3

05AB1E , 16 15 14 bayt

εèNQyNÊ*y0‹~}P

@Dorian sayesinde -1 bayt .

Çevrimiçi deneyin veya tüm test senaryolarını doğrulayın .

Açıklama:

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

Denemem filtre dışında aynıydı. Bunu geliştirmek için bir yol göremiyorum.
Emigna

1
14 bayt . Sen mevcut değerini zorlayabilir εile y. Yani gerek yok ©ve her biri ile ®değiştirildiy
Dorian

@Dorian Ah, elbette .. Bu yanıtı yayınladığımda mirasta bu mümkün değildi, ama bugün golfü yaptığımda bunu düşünmeliydim. Teşekkürler! :)
Kevin Cruijssen


2

Python, 112 97 96 86 bayt

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

Çevrimiçi deneyin!

TrueVeya döndürür False.

@Rod ve @TFeld sayesinde -10 bayt.



2

Haskell , 48 bayt

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

Tüm test vakalarını doğrulayın!

açıklama

Önce kodu biraz çözelim. Olduğu f =<< ggibi\x -> f (g x) x kod eşdeğerdir

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

ki bu biraz daha net.

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

Bu çözelti, basit bir gözleme dayanmaktadır: let agiriş dizi ve olmak uçiftlerinin listesi bir indekstir. Sonra ve sadece her için eğer geçerli bir dizidir içinde olan , çift aittir yanı.(i, a[i])ia(x, y)uy >= 0(y, x)u


2

Java (JDK) , 89 bayt

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

Çevrimiçi deneyin!

Kredi


Olabilirdi 87 byte o sinir bozucu IndexOutOfBoundsException olmasaydı. Belki kolayca düzeltmek için bir şey görüyorsunuz?
Kevin Cruijssen

@KevinCruijssen 102 bayt için nasıl düzeltileceğini görebilirim . Henüz kısa bir şey yok :(
Olivier Grégoire

1
-3 bayt - burayar benzer döngü atlayın ve
koparın

1

Kömür , 22 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. Çıkışlar -falsy için truthy ve hiçbir şey için. Not: Boş bir dizi girmek Kömürü çökertiyor gibi görünüyor, ancak şimdilik bunun yerine yeterince yakın bir boşluk girebilirsiniz. Açıklama:

  θ                     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

Bu çok Charcoalable bir meydan okuma gibi görünmüyor ... :-)
Charlie

1

Pascal (FPC) , 165 155 153 bayt

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;

Çevrimiçi deneyin!

Girdi dizi olduğu için bu kez işlev yapıldı. İade 1truthy için ve 0Falsey için.


1

Temiz , 60 bayt

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

Çevrimiçi deneyin!

Temiz , 142 bayt

Büyük ölçüde aşırı karmaşık canavar versiyonu:

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

Çevrimiçi deneyin!

Açıklaması:

$ 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 bayt

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

Buradan çevrimiçi olarak deneyin veya tüm test senaryolarını burada bir kerede doğrulayın .

.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

Düzenleme: sondaki k'nin de gereksiz olduğunu fark etti





0

Mathematica, 42 bayt

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

Saf fonksiyon. Girdi ve döndürme Trueya Falseda çıktı olarak 1 dizinli sayılar listesini alır . Sadece tünelleri takip ederek, 0haritaların 01 döngü olmadığından ve tüm döngülerin 2 döngü olduğundan emin olun. (Bunun herhangi bir kenar durumunda başarısız olup olmadığından tamamen emin değilim, ancak örnekler için doğru sonuçları veriyor.)


0

Bu cevap işe yaramıyor. Burada sadece gösterim amaçlıdır.

Bu cevap (şu anda) yayınlanan tüm test senaryolarını geçer. Ancak, [1, 2]veya gibi diğer geçerli girdilerde başarısız olur (bir hata oluşturur)[1, 0, 3, 7] .

Nasıl geçip [1, 0, 3]başarısız olabilir [1, 0, 3, 7]? Tam da beklediğiniz gibi listede ilerliyor. Bir eleman okuduğunda xlistenin a, ilk olmadığını denetler xazdır len(a)derhal ve döner False, eğer öyleyse. Bu yüzden doğru döndürür Falseüzerinde [1, 0, 3]çünkü, 3az değildir len(a).

Ancak xbu kontrolü geçtiğini varsayarsak , kod daha sonra başka kontroller yapmaya devam eder ve belirli bir noktada değerlendirir a[a[x]]. Biz zaten değerlendirerek garanti ettik a[x]değil Tamam olacak ... ama a[a[x]]hiç giderir, hangi a[7]zaman xolduğu 3içinde [1, 0, 3, 7]örneğin. Bu noktada Python IndexErrorgeri dönmek yerine birFalse .

Bütünlük için, işte cevap.

Python 2 , 59 bayt

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

Çevrimiçi deneyin!

Yapmak istedim x<len(a)and-1<a[x]..., ama elbette len(a)her zaman >-1, bu yüzden yukarıdaki eşdeğerdir. Bu kontrol 5 zincirli ilişkilerin (yani toplam <, >, <, !=, ve ==), ve ayrı bir kontrol -1<xolarakif durum.

Python (uygun olarak) kısa devreler bu gibi ilişkileri zincirledi, örneğin, eğer x>=len(a)o zaman kontrol Falsegelmeden önce geri dönerse a[x](aksi takdirde bir an yükseltir IndexError).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.