检查我的隧道阵列


18

假设您有一个整数数组,其非负值是指向同一数组中其他位置的指针,只是这些值表示隧道,因此如果位置A中的值为正并指向位置B,则位置中的值B也必须为正,并指向位置A以代表隧道的两端。所以:

挑战

  • 给定一个整数数组,请检查该数组是否符合作为隧道数组的限制,并为true和false返回两个不同的连贯值。
  • 对于非隧道位置,数组中的值将小于零;对于隧道位置,数组中的值将小于零或大于零。如果您的数组是1索引的,则零值表示非隧道位置。不需要检查非隧道值。
  • 如果单元格中的正值指向自身,那是错误的。如果A指向B,B指向C,C指向A,那是错误的。如果一个正值指向数组的范围之外,那是错误的。

例子

以下示例是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)

这是,因此每种语言的最短代码可能会胜出!


3
我们应该返回[0]什么?
ngn

1
扩展ngn的问题,是否允许自隧道?会是什么情况[0,1],并[0,-1,2]给?
dylnan

1
@dylnan [0,1]在示例中。“如果一个积极的细胞分本身的价值,这是一个falsey”
NGN

1
建议的测试:[2,3,0,1]
ngn

1
@JonathanAllan隧道值是指示可能的数组位置的值。如果您的数组是0索引的,则低于0的每个值都不是隧道值。如果它是1索引的,则每个小于1的值都不是隧道值。
查理

Answers:


8

R,47个字节

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

在线尝试!


展开代码和说明:

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
}

我真的很感谢对此答案的解释。:-)
查理

3
@Charlie:添加了解释
digEmAll


5

APL(Dyalog Unicode)19 24字节

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

在线尝试!

前缀匿名lambda,对于真值返回1,对于伪造值返回0。TIO链接包含测试用例的输出的“预设”版本。

向@ngn和@Adám喊叫以节省大约15亿个字节。

向@ngn额外大喊大叫,以帮助您修复某些测试用例的答案,并使之成为培训。

更新的答案使用⎕IO←0,将I dex O rigin设置为0。

怎么样:

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

我认为这不适用于(1),(3 2 1),(5 4 3 2 1)。
nwellnhof

0<×我认为
Uriel '18

4

JavaScript(ES6),35个字节

@Shaggy节省了1个字节

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

在线尝试!

已评论

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

好东西,我在发布Japt解决方案的端口之前检查了解决方案,这几乎与此相同。您可以使用保存一个字节a=>a.every((v,i)=>v<0|v!=i&a[v]==i)
毛茸茸的



3

Perl 6、36字节

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

在线尝试!

其基本思路是,以检查是否设置{ i, a[i], a[a[i]] }包含了每个索引正好有两个不同的元素ia[i] >= 0。如果一个元素指向自身,则该集合仅包含一个不同的元素。如果另一端不指向i,则该集合包含三个不同的元素。如果为a[i] < 0,则xx因子为零或负,因此集合为{ i, a[i] },也具有两个不同的元素。


3

MATL19 18字节

-1字节感谢Luis

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

在线尝试!,仅适用于第一个,因为我不知道该怎么做!

0如果为真,则给出,如果为假,则给出非零整数,例如。对于测试用例6给出4

请记住,像MATLAB一样,MATL是1索引的,因此必须在测试用例中添加1!

从来没有打过伊索朗(Esolang)高尔夫球,因此得到了很多建议!

解释:

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                 

我的解释太罗word了吗?我想让它变得显而易见而又不完全落伍。
路易斯

3

05AB1E16 15 14 字节

εèNQyNÊ*y0‹~}P

-1个字节感谢@Dorian

在线尝试验证所有测试用例

说明:

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

我的尝试是相同的,除了过滤器。我没有办法对此进行改进。
Emigna

1
14个字节。你可以推的当前值εy。因此,不需要©,每个®都由y
多里安

@Dorian Ah,当然..当我发布这个答案时,这在传统中是不可能的,但是当我今天早些时候打高尔夫球时,应该考虑一下。谢谢!:)
Kevin Cruijssen


2

Python,112 97 96 86字节

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

在线尝试!

返回TrueFalse

-10个字节,感谢@Rod和@TFeld。



2

Haskell,48个字节

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

验证所有测试用例!

说明

首先让我们取消一些代码。由于f =<< g是相同的\x -> f (g x) x,该代码相当于

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

这更清楚了。

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

该解决方案是基于一个简单的观察:让a是输入阵列,并且u对列表(i, a[i]),其中i是一个索引。然后a是当且仅当对于每个有效的阵列(x, y)uy >= 0,一对(y, x)是属于u为好。


2

Java(JDK),89个字节

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

在线尝试!

学分


如果不是那个讨厌的IndexOutOfBoundsException,本来可以是87个字节。也许您看到可以轻松解决的问题?
凯文·克鲁伊森

@KevinCruijssen我可以看到如何将其修复为102个字节。没有比这更短的了:(
OlivierGrégoire18年


1

木炭,22字节

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

在线尝试!链接是详细版本的代码。输出-为真,虚无。注意:输入一个空数组似乎会使Charcoal崩溃,但是现在您可以输入一个足够接近的空格。说明:

  θ                     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

这似乎不是一个非常困难的挑战……:-)
查理(Charlie)

1

帕斯卡(FPC) 165个 155 153字节

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;

在线尝试!

这次执行功能,因为输入是数组。返回1的truthy和0对falsey。


1

干净,60字节

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

在线尝试!

干净,142字节

过于复杂的怪物版本:

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

在线尝试!

解释:

$ 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

Pyth17 16字节

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

在此处在线尝试,或在此处一次验证所有测试用例。

.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

编辑:意识到尾随k也是不必要的





0

Mathematica,42个字节

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

纯功能。将1索引的数字列表作为输入并返回TrueFalse作为输出。仅遵循隧道,确保0映射到0,不存在1个周期,并且所有周期均为2个周期。(我不完全确定这是否在任何极端情况下都会失败,但是可以为示例提供正确的结果。)


0

这个答案不起作用。此处仅用于说明目的。

该答案通过了所有(当前)发布的测试用例。但是,它在其他有效输入(例如[1, 2]或)上失败(引发错误)[1, 0, 3, 7]

它如何通过[1, 0, 3]和失败[1, 0, 3, 7]?好吧,它就像您期望的那样在列表中进行。读取x列表的元素时a,它将首先检查是否x小于,如果是,则len(a)立即返回False。因此,正确地返回False[1, 0, 3],因为3不小于len(a)

但是,假设x通过了该检查,则代码将继续执行其他一些检查,并在某个时刻进行评估a[a[x]]。我们已经保证评估a[x]都会好的......但a[a[x]],它解析为a[7]x3[1, 0, 3, 7]例子。在这一点上,Python引发IndexError,而不是返回False

为了完整起见,这就是答案。

Python 2,59个字节

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

在线尝试!

我想做x<len(a)and-1<a[x]...,但是当然len(a)总是>-1如此,因此以上是等效的。此检查是总共5间链接关系的(<><!=,和==),再加上一个单独检查-1<xif条件。

Python(通常)会像这样使链式关系短路,例如,如果x>=len(a)检查然后在返回False之前就返回了a[x](否则会引发IndexError)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.