如何在Perl 6中查找列表的正确最小/最大值

4

我是Perl6的新手,试图弄清楚我在这里做错了什么。问题是一个简单的校验和,它获取csv中每一行的最大值和最小值之间的差异。

它返回的最大值和最小值完全错误。对于csv中的第一行,它将最大值返回为71,将最小值返回为104,这是不正确的。

这里是用于参考的链接到存储库,以及相应问题的链接

#!/usr/bin/env perl6

use Text::CSV;

sub checksum {
    my $sum = 0;
    my @data = csv(in => "input.csv");
    for @data -> @value {
        $sum += (max @value) - (min @value);
    }
    say $sum;
}

checksum

1
未经测试的代码:sub checksum($in) { [+] (+<<csv :$in).map(*.minmax.bounds.reduce(&[R-])) }; say checksum 'input.csv' - Christoph
1
大家好,AoC的编程朋友们!你们可能想要访问AoC的子版块,特别是解决方案超级贴。在那里有一些人(包括我在内)发布了Perl 6的解决方案;你可能会从中获得一些技巧。 - mscha
1个回答

12

我假设您的输入包含数字,但由于CSV是一种文本格式,因此输入被读取为字符串。minmax基于字符串排序进行操作,因此max("4", "10")4,但max("04", "10")10。为了解决这个问题,您可以在获取最小/最大值之前将每个元素转换为Numeric(整数、浮点数等):

@input.map(*.Numeric).max

或者向minmax传递一个转换函数,以便在比较每个元素时将其解析为数字:

@input.max(*.Numeric)

对于您的情况,第一个解决方案更好,因为第二个解决方案是临时转换,内部转换但仍返回字符串。最后说明一下:在普通代码中,我会写 +*{ +$_ } 来表示“将X视为数字”,但在这种情况下,我更喜欢明确指出:.Numeric


2
我会使用 +* (*.Numeric) 而不是 {.Int} (或 *.Int),这样如果输入小数值,它仍然可以正常工作。 - Brad Gilbert
@BradGilbert 你说得很对,我已经做出了更改。谢谢! - piojo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接