console.error(`Unable to load nonexistent manifest entry ‘islands/voting-prompt’. Check that your file path is correct.`)

\begingroup

Rust 的借用检查器强制执行“可变性 XOR 别名”的要求:一段数据可以有多个不可变引用,也可以有一个可变引用。这一挑战围绕着实现借用检查器这一方面的极其简化的版本。

任务:给定一个对变量的不可变和可变引用列表,确定是否违反了可变性 XOR 别名要求,或者换句话说,是否发生可变别名。当变量具有两个或多个引用,其中至少一个是可变的时,就会发生可变别名。

考虑[&c, &mut g, &c, &c],其中&x表示对 的不可变引用x,而&mut x表示对 的可变引用x。此列表不显示可变别名——c只有不可变引用,并且g只有一个可变引用。

另一方面,
[&c, &mut g, &mut c, &c] 确实具有可变别名,因为c有多个引用,其中一个是可变的。

这是—— 每种语言中最短的解决方案获胜。

输入/输出格式

为了增加打高尔夫的可能性,输入列表的最大长度为 7,并且您只需要支持 7 个不同变量的池a, b, c, d, e, f, g

输入和输出可以是任何合理的格式,包括但不限于:

  • 将元组列表(<variable name>, <is mutable>)作为函数参数,并返回表示可变别名是否存在的真值/假值;
  • 取一个整数列表[0..14),每个整数代表引用的 14 个可能值之一(7 个变量 * 2 种引用类型),并返回 0 或 1;
  • 从 STDIN 中获取格式化为&x和 的以空格分隔的引用列表,并打印到 STDOUT。&mut xpresentabsent

在哪些 I/O 格式算作“合理”方面,存在一个相对较大的灰色区域,但此处的意图是高度宽容。如果您不确定某种 I/O 格式是否算作“合理”,欢迎您在评论中讨论它和/或在您的答案中包含同一种方法的多种变体:较长的版本采用更标准的 I/O 格式,而简化的版本采用不太合理的 I/O 格式。

请在您的答案中注明解决方案的 I/O 格式。

测试用例

[] => absent
[&a] => absent
[&mut a] => absent
[&b, &b] => absent
[&mut b, &b] => present (b)
[&b, &mut b] => present (b)
[&mut b, &mut b] => present (b)
[&c, &d] => absent
[&mut c, &mut d] => absent
[&a, &mut d, &mut d] => present (d)
[&mut a, &d, &mut d] => present (d)
[&mut a, &mut d, &mut d, &mut a] => present (a, d)
[&a, &mut d, &d, &a] => present (d)
[&c, &mut g, &c, &c] => absent
[&c, &mut g, &mut c, &c] => present (c)
[&a, &b, &c, &d, &e] => absent
[&mut f, &e, &e, &mut d] => absent
[&f, &e, &mut e, &d] => present (e)
[&a, &mut g, &b, &a, &b, &b, &mut f] => absent
[&mut a, &g, &b, &a, &b, &mut b, &f] => present (a, b)
[&a, &a, &a, &a, &a, &a, &a] => absent
[&a, &a, &a, &mut a, &a, &a, &a] => present (a)
[&mut a, &mut a, &mut a, &mut a, &mut a, &mut a, &mut a] => present (a)
[&mut g, &mut g, &mut g, &mut g, &mut g, &mut g, &mut g] => present (g)
[&a, &b, &mut c, &mut d, &e, &mut f, &g] => absent
[&a, &b, &c, &mut a, &mut b, &mut c] => present (a, b, c)
[&a, &mut a, &a, &mut g, &g, &mut g] => present (a, g)

采用更方便的格式引用(<variable name>, <is mutable>)

缺席的:

[],
[("a", false)],
[("a", true)],
[("b", false), ("b", false)],
[("c", false), ("d", false)],
[("c", true), ("d", true)],
[("c", false), ("g", true), ("c", false), ("c", false)],
[("a", false), ("b", false), ("c", false), ("d", false), ("e", false)],
[("f", true), ("e", false), ("e", false), ("d", true)],
[("a", false), ("g", true), ("b", false), ("a", false), ("b", false), ("b", false), ("f", true)],
[("a", false), ("a", false), ("a", false), ("a", false), ("a", false), ("a", false), ("a", false)],
[("a", false), ("b", false), ("c", true), ("d", true), ("e", false), ("f", true), ("g", false)],

展示:

[("b", true), ("b", false)],
[("b", false), ("b", true)],
[("b", true), ("b", true)],
[("a", false), ("d", true), ("d", true)],
[("a", true), ("d", false), ("d", true)],
[("a", true), ("d", true), ("d", true), ("a", true)],
[("a", false), ("d", true), ("d", false), ("a", false)],
[("c", false), ("g", true), ("c", true), ("c", false)],
[("f", false), ("e", false), ("e", true), ("d", false)],
[("a", true), ("g", false), ("b", false), ("a", false), ("b", false), ("b", true), ("f", false)],
[("a", false), ("a", false), ("a", false), ("a", true), ("a", false), ("a", false), ("a", false)],
[("a", true), ("a", true), ("a", true), ("a", true), ("a", true), ("a", true), ("a", true)],
[("g", true), ("g", true), ("g", true), ("g", true), ("g", true), ("g", true), ("g", true)],
[("a", false), ("b", false), ("c", false), ("a", true), ("b", true), ("c", true)],
[("a", false), ("a", true), ("a", false), ("g", true), ("g", false), ("g", true)],

\endgroup


10 个解决方案
10

\begingroup

,48字节

lambda L,*k:all(m*k!=(k:=l)for l,m in sorted(L))

获取一对列表(名称,is_mutable)。

\endgroup

\begingroup

,40 字节

lambda l:any(l.count(n|1)>n%2for n in l)

输入为“[0..14] 中的整数列表,每个整数代表 14 个可能值中的一个”,最后一位表示可变性(1=可变),其余位表示变量。输出为 True/False。

对于n列表中的每个元素,检查是否n|1设置了可变性位,如果n为偶数(不可变),则至少出现一次,如果n为奇数(可变),则至少出现两次。

带有(variable, is_mutable)

lambda l:any(b<l.count((k,1))for k,b in l)

\endgroup

1

  • \begingroup
    每个元素的低位指示允许的最大可变引用数(对于同一个变量,可能包括元素本身),非常优雅!当然,这不是我在写这个挑战时意识到的事情。
    \endgroup


    – 

\begingroup

,28 字节

x=>/t (.).*\1.*\1/.test(x+x)

通过 2 份副本处理两个方向

\endgroup

1

  • \begingroup
    真聪明!我想出了一个基于正则表达式的解决方案,但不是这个特定的解决方案。您可能能够通过使用以更好的方式表示&x&mut x引用的输入格式来减少一个字节。(当前格式似乎类似于逗号分隔的"&x""&mut x"字符串列表。)
    \endgroup


    – 


\begingroup

,75字节

⁽hġƛvtÞżU₃;A

位串:

111001011100101011110100010010000000011001111000100101100100001011101110111

位串:

111001011100101011110100010010000000110011101001010111100110010

将输入作为[[var: str, mut: bool (0/1)]],返回1表示不存在,0表示存在。标头将示例输入中的元组转换为列表(否则您需要手动执行此操作)。

解释

⁽hġƛvtÞżU₃;A­⁡​‎‎⁡⁠⁡‏⁠‎⁡⁠⁢‏⁠‎⁡⁠⁣‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁤‏⁠‎⁡⁠⁣⁡‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁢⁡‏⁠‎⁡⁠⁢⁢‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁢⁣‏⁠‎⁡⁠⁢⁤‏‏​⁡⁠⁡‌⁢⁡​‎‎⁡⁠⁣⁡‏‏​⁡⁠⁡‌⁢⁢​‎‎⁡⁠⁣⁢‏‏​⁡⁠⁡‌⁢⁣​‎‎⁡⁠⁣⁤‏‏​⁡⁠⁡‌­
⁽hġ           # ‎⁡Group the input based on the variable name
   ƛ    U     # ‎⁢To each group:
    vt        # ‎⁣  Get whether each reference is mutable
      Þż      # ‎⁤  Multiply each item by its 1-based index
        U     # ‎⁢⁡  Uniquify - this ensures that only one immutable reference is kept, while keeping all mutable references. Basically, treat all immutable references as the same.
         ₃    # ‎⁢⁢  Is there only one item in that list?
           A  # ‎⁢⁣Is that true for all possible variables?
💎

的帮助下创建

\endgroup

1

  • \begingroup
    不错,基于 groupby 的方法!1 索引的用法很有趣。
    \endgroup


    – 

\begingroup

,10字节

⊙θ›№θ↥ι№αι

链接为代码的详细版本。将输入作为字母字符串,其中小写字母为不可变引用,大写字母为可变引用,并输出 Charcoal 布尔值,即-表示存在,不存在则不输出。说明:@xnor 的 Python 答案的端口。

 θ          Input string
⊙           Any letter satisfies
   №        Count of
      ι     Current letter
     ↥      Uppercased
    θ       In input string
  ›         Is greater than
       №    Count of
         ι  Current letter in
        α   Predefined variable uppercase alphabet
            Implicitly print

\endgroup

\begingroup

+ -e,5字节

ĕ∏Hᵗf

将输入作为一串对的列表[variable, is_mutable],其中variable是字符串,is_mutable是整数(01)。

Truepresent输出Falseabsent

ĕ∏Hᵗf
ĕ       Take one element out from the input
 ∏      Product; strings are converted to their code points
  H     Convert the code points back to a string
        After these two steps, [v,1] becomes v and [v,0] becomes a null character
   ᵗf   Check that the rest of the input contains this string

-e检查是否有解决方案。

我们举[["f",0],["e",0],["e",1],["d",0]]个例子。在第一步(ĕ)中,我们可以取出,应用 后["e",1]变为。其余输入为,其中包含。因此,输出为"e"∏H[["f",0],["e",0],["d",0]]"e"True

\endgroup

1

  • 1
    \begingroup
    这里对非确定性的运用很有趣!
    \endgroup


    – 

\begingroup

0.8.2,15 13字节

O`.#?
1`(.)\1

将输入作为仅包含字母的列表,其中不可变引用以尾随#但链接为标记,用于将测试用例转换为此格式的测试套件。输出0为缺席和1存在(如果允许不一致的较大数字,则1可以删除以节省两个字节)。说明:

O`.#?

按顺序对所有引用进行排序,因此的可变引用排a在最前面,的不可变引用排g在最后。

1`(.)\1

检查可变引用,然后检查对同一变量的另一个引用。

\endgroup

4

  • \begingroup
    这也是我想到的高尔夫方法之一(虽然不是用这种语言)!如果我正确理解了文档,也许对输入格式进行调整可以帮助消除用于反转排序的字节?
    \endgroup


    – 

  • \begingroup
    @shapewarriort 啊,你的意思是如果我标记不可变引用而不是可变引用?
    \endgroup


    – 

  • \begingroup
    我不确定交换标记的参考是否足以减少字节数,但您可以自由地选择参考的确切格式。
    \endgroup


    – 

  • 1
    \begingroup
    @shapewarriort 事实证明,它为我节省了两个字节,一个用于反向排序,一个用于简化测试。
    \endgroup


    – 

\begingroup

字节

#;~:a`j@4k:0g1+\0p1g&+\1p0g'!`\1g' `*2j@._;

输入为字母 (ag) 和二进制数字对,例如a1,每个字母对后面都必须跟一个换行符。这些字母对后面必须跟另一个换行符。1如果引用可变,则数字为 ,0否则为 。

如果发生可变别名则输出0 ,否则不输出。

\endgroup

\begingroup

15字节

一个 dfn,以 [mut,not mut …] 布尔数组作为其左参数,以变量名称作为其右参数。

可变引用和出现多次的变量之间的交集的唯一性(⍺⌿⍵)⍵⌿⍨~≠⍵

{∪(⍺⌿⍵)∩⍵⌿⍨~≠⍵}

\endgroup

\begingroup

,12字节

ay cr<xqB st

解释

  • xqB删除具有唯一性的元素…
  • st第一个元素(变量名)
  • ay剩余值是否具有真实值?
  • cr最终元素(可变性)

反射

这非常可靠。我并不认为 hgl 中有什么需要改进的地方。但是我应该检查是否曾经使用过ay cray st,如果其中任何一个都使用过,我认为添加这两个都是合理的。

\endgroup

1

  • \begingroup
    该语言是 Haskell + hgl,对吗?
    \endgroup


    –