受我亲爱的朋友和同事的启发,并为之缅怀,
Dan Baronet,1956年-2016年。RIP
他为该任务找到了最短的APL解决方案:
任务
给定一个布尔列表,计算尾随真值的数量。
案例案例
{}
→ 0
{0}
→ 0
{1}
→ 1
{0, 1, 1, 0, 0}
→ 0
{1, 1, 1, 0, 1}
→ 1
{1, 1, 0, 1, 1}
→ 2
{0, 0, 1, 1, 1}
→ 3
{1, 1, 1, 1, 1, 1}
→ 6
他为该任务找到了最短的APL解决方案:
给定一个布尔列表,计算尾随真值的数量。
{}
→ 0
{0}
→ 0
{1}
→ 1
{0, 1, 1, 0, 0}
→ 0
{1, 1, 1, 0, 1}
→ 1
{1, 1, 0, 1, 1}
→ 2
{0, 0, 1, 1, 1}
→ 3
{1, 1, 1, 1, 1, 1}
→ 6
Answers:
⊥⍨
⊥(uptack,dyadic:decode)执行基本转换。如果左操作数是向量,它将执行混合基数转换,非常适合此任务。
对于基本向量b = b n,⋯,b 0和一个数字向量a = a n,⋯,a 0,b⊥a将a转换为混合基b,即,计算b 0 ⋯b n-1 a n +⋯+ b 0 b 1 a 2 + b 0 a 1 + a 0。
现在,⍨(波浪号降噪,上下班)将操作符修改为左侧,如下所示。在单子上下文中,它使用相等的左右参数调用运算符。
例如,⊥⍨一个被定义为一个⊥一个,它计算一个0 ⋯一个Ñ +⋯+一个0一个1一2 +α 0一个1 +α 0,所有累积的产品从向左右侧的总和。
对于k个尾随的乘积,k个最右边的乘积为1,所有其他乘积为0,因此它们的总和等于k。
b⊥b
并⊥⍨b
放弃了无限的提速。
ŒrṪP
对于列表为空的情况,有一些奇怪的发现。首先,对空列表进行游程编码会[]
返回另一个空列表[]
。然后retreiving从使用尾部的最后一个元素Ṫ
返回0
,而不是一对[value, count]
,其是一个游程长度编码的阵列中的常规元件。然后产品在被调用时P
返回0
,0
这是预期的结果。
ŒrṪP Main link. Input: list M
Œr Run-length encode
Ṫ Tail, get the last value
P Product, multiply the values together
ŒgṪS
,也可以!
Ṫ
Jelly中的@PeterTaylor 实现为:lambda z: iterable(z).pop() if iterable(z) else 0
。iterable
当在列表上调用时,仅返回列表,而空列表当然是虚假的。
a%b|b=1+a|0<3=0
foldl(%)0
用法:
Prelude> foldl(%)0 [True,False,True,True]
2
无点版本(26字节):
length.fst.span id.reverse
使用整数列表而不是布尔列表(21个字节,感谢Christian Sievers):
a%b=b*(a+1)
foldl(%)0
用法:
Prelude> foldl(%)0 [1,0,1,1]
2
无点版本(25字节)
sum.fst.span(==1).reverse
foldl
想法适用于a%b=b*(a+1)
r`1\G
在线尝试!(第一行启用换行分隔的测试套件。)
定义Retina的输入格式并非一模一样。由于视网膜除字符串外没有任何类型的概念(也没有可用于我们对真假的常规定义的值),因此我通常使用0
和1
(或通常是肯定的东西)来表示真假的,因为它们代表零或一些匹配项。
使用单字符表示形式时,我们也不需要列表的分隔符(从某种意义上说,对于只包含字符串的语言,列表分隔符更自然)。Adám确认这是可接受的输入格式。
至于正则表达式本身,它r
从右到左\G
匹配,并将每个匹配锚定到前一个。因此,这计算了1
我们可以从字符串末尾匹配多少个s。
由于使用了carusocomputing,因此节省了1个字节。
Î0¡¤g
说明
Î # push 0 and input
0¡ # split on 0
¤ # take last item in list
g # get length
0¡¤g
是四个字节。
J0¡¤g
还更短;)。
Î
处理空的输入,但是仍然节省了一个字节,谢谢:)
lambda a:(a[::-1]+[0]).index(0)
Fold[If[#2,#+1,0]&,0,#]&
FromDigits[b=Boole@#,MixedRadix@b]&
(35个字节)。
r;main(c,v)int**v;{while(0<--c&*v[c])r++;c=r;}
输入是通过命令行参数(每个参数一个整数),输出是通过退出代码。
r是全局变量。它的类型默认为int,并且是全局的,它的值默认为0。
函数参数c也默认为int。对于n个布尔数组,它将保存整数n +1。main的第一个参数始终是可执行文件的路径。
函数参数v声明为int**
。的实际类型v会char**
,但由于我们只检查每个参数的最低显著位告诉字符0(代码点48)和1(代码点49)分开,这并不重要的小尾数机器。
while循环递减c并将其与0比较。一旦c达到0,我们就会跳出循环。仅当数组不包含0时才需要。
只要0<--c
返回1,我们就使用第c 个命令行参数(v[c]
),并通过取消引用指针(*
)来提取其第一个字符。我们采取的按位与布尔的0<--c
和字符(和随后的三项垃圾字节)的代码点,这样的情况会返回0一旦0遇到,打破循环。
在剩余的情况下,在命令行参数是1,r++
递增- [R由1,从而计算后的次数1的。
最后,c=r
将r的计算值存储在c中。使用默认设置,编译器将优化并删除分配。它实际上会生成movl %eax, -4(%rbp)
指令。由于ret
返回EAX寄存器的值,因此会生成所需的输出。
请注意,此代码并不能与C99,返回工作0从主如果年底主要到达。
argc
至少1
(与argv[0]
包含文件名)?您可以用--c&&
代替保存一个字节0<--c&
。gcc的退出代码来自argc
?整齐。
*v[c]
是1或0的代码点,所以它是49或48,因此始终是真实的。
#.~
这是自反的混合碱基转换。因为这与混合基准转换相同。 再次。
v =: #.~
]t =: '';0;1;0 1 1 0 0;1 1 1 0 1;1 1 0 1 1;0 0 1 1 1;1 1 1 1 1 1
++-+-+---------+---------+---------+---------+-----------+
||0|1|0 1 1 0 0|1 1 1 0 1|1 1 0 1 1|0 0 1 1 1|1 1 1 1 1 1|
++-+-+---------+---------+---------+---------+-----------+
v&.> t
+-+-+-+-+-+-+-+-+
|0|0|1|0|1|2|3|6|
+-+-+-+-+-+-+-+-+
(,. v&.>) t
+-----------+-+
| |0|
+-----------+-+
|0 |0|
+-----------+-+
|1 |1|
+-----------+-+
|0 1 1 0 0 |0|
+-----------+-+
|1 1 1 0 1 |1|
+-----------+-+
|1 1 0 1 1 |2|
+-----------+-+
|0 0 1 1 1 |3|
+-----------+-+
|1 1 1 1 1 1|6|
+-----------+-+
using System.Linq;
int a(bool[] l)=>l.Reverse().TakeWhile(x=>x).Count();
使用非通用列表比通用列表快1字节大声笑
-31字节感谢Scott
int
s 数组,则可以int a(int[] l)=>l.Reverse().TakeWhile(i=>i>0).Sum();
Func<bool[], int>
为57个字节的a ,即using System.Linq;l=>l.Reverse().TakeWhile(x=>x).Count();
l=>l.reverse:+0 indexOf 0
取消高尔夫:
l=>(l.reverse :+ 0).indexOf(0)
反转列表,追加一个0并找到第一个索引0,即第一个0之前的元素数
n=>n.V().O(F);
int c(boolean[]a){int r=0;for(boolean b:a)r=b?r+1:0;return r;}
取消测试代码:
class M{
static int c(boolean[] a){
int r = 0;
for (boolean b : a){
r = b ? r+1 : 0;
}
return r;
}
public static void main(String[] a){
System.out.print(c(new boolean[]{}) + ", ");
System.out.print(c(new boolean[]{ false }) + ", ");
System.out.print(c(new boolean[]{ true }) + ", ");
System.out.print(c(new boolean[]{ false, true, true, false, false }) + ", ");
System.out.print(c(new boolean[]{ true, true, true, false, true }) + ", ");
System.out.print(c(new boolean[]{ true, true, false, true, true }) + ", ");
System.out.print(c(new boolean[]{ false, false, true, true, true }) + ", ");
System.out.print(c(new boolean[]{ true, true, true, true, true, true }));
}
}
输出:
0, 0, 1, 0, 1, 2, 3, 6
perl -E '$_++while pop;say' 0 1 1 0 1 1 1
但这不会输出任何信息0
(虽然不确定这是否有问题!)
21个字节的代码+ 1个字节的-p
标志。
s/.(?=.*0)//g;$_=y;1;
运行它:
perl -pE 's/.(?=.*0)//g;$_=y;1;' <<< "0 1 1 0 1 1 1"
(实际上,输入的格式并不重要了很多:0110111
,0 1 1 0 1 1 1
,[0,1,1,0,1,1,1]
等一切都能解决)
perl -pE '/1*$/;$_=length$&' <<< '0110111'
;
把戏:)如果格式是一个连续的字符串:perl -pE '/1*$/;$_=length$&' <<< '0110111'
对于18,不确定是否违反了规则……
->n{n.size-1-(n.rindex(!0)||-1)}
创建一个匿名函数,该函数查找错误值的最右边实例,并计算从该值开始的子数组的大小。
它使用!0
false,因为Ruby中的true值为0。rindex
查找数组中值的最后一个索引。
用法:
boolean_list = [true, false, false, true]
->n{n.size-1-(n.rindex(!0)||-1)}[boolean_list]
返回 1
如果允许我将0和1的字符串作为命令行参数传递(这不是ruby表示布尔值列表的方式),我可以将其降低到24:
$*[0]=~/(1*)\z/;p$1.size
这使用正则表达式和打印由正则表达式返回字符串的长度/(1*)\z/
,其中,\z
是字符串的结尾。$*[0]
是传递的第一个参数,是0和1的字符串。
用法:
trailing_truths.rb 011101
返回1。
01100
?