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 x
present
absent
在哪些 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
,48字节
lambda L,*k:all(m*k!=(k:=l)for l,m in sorted(L))
获取一对列表(名称,is_mutable)。
\endgroup
|
,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
–
|
,28 字节
x=>/t (.).*\1.*\1/.test(x+x)
通过 2 份副本处理两个方向
\endgroup
1
-
\begingroup
真聪明!我想出了一个基于正则表达式的解决方案,但不是这个特定的解决方案。您可能能够通过使用以更好的方式表示&x
和&mut x
引用的输入格式来减少一个字节。(当前格式似乎类似于逗号分隔的"&x"
和"&mut x"
字符串列表。)
\endgroup
–
|
,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
–
|
,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
|
+ -e
,5字节
ĕ∏Hᵗf
将输入作为一串对的列表[variable, is_mutable]
,其中variable
是字符串,is_mutable
是整数(0
或1
)。
True
和present
的输出。False
absent
ĕ∏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
–
|
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
–
|
字节
#;~:a`j@4k:0g1+\0p1g&+\1p0g'!`\1g' `*2j@._;
输入为字母 (ag) 和二进制数字对,例如a1
,每个字母对后面都必须跟一个换行符。这些字母对后面必须跟另一个换行符。1
如果引用可变,则数字为 ,0
否则为 。
如果发生可变别名则输出0
,否则不输出。
\endgroup
|
,15字节
一个 dfn,以 [mut,not mut …] 布尔数组作为其左参数,以变量名称作为其右参数。
可变引用和出现多次的变量之间的∪
交集的唯一性。∩
(⍺⌿⍵)
⍵⌿⍨~≠⍵
{∪(⍺⌿⍵)∩⍵⌿⍨~≠⍵}
\endgroup
|
,12字节
ay cr<xqB st
解释
xqB
删除具有唯一性的元素…st
第一个元素(变量名)ay
剩余值是否具有真实值?cr
最终元素(可变性)
反射
这非常可靠。我并不认为 hgl 中有什么需要改进的地方。但是我应该检查是否曾经使用过ay cr
或ay st
,如果其中任何一个都使用过,我认为添加这两个都是合理的。
\endgroup
1
-
\begingroup
该语言是 Haskell + hgl,对吗?
\endgroup
–
|
|