今天早上我一看到这个,我就知道这至少会比昨天容易一点。
第一部分
今天的前提是刮刮卡有两组号码:中奖号码和您拥有的号码。前半部分是中奖号码,后半部分是您拥有的号码。
Card 1 : 41 48 83 86 17 | 83 86 6 31 17 9 48 53
从“代码出现”页面:
卡 1 有 5 个中奖号码(41、48、83、86 和 17)和 8 个您拥有的号码(83、86、6、31、17、9、48 和 53)。在您拥有的号码中,其中 4 个(48、83、17 和 86)是中奖号码!
看起来很简单,特别是当使用 PHP 的array_intersect
时,它返回“一个包含所有参数中存在的数组的所有值的数组”。在这种情况下,我们的中奖号码。对于每个中奖号码,分数加倍(从第一个中奖号码开始)。目标是找到所有获胜牌的总分。
$total = 0 ;
$lines = explode ( "\n" , $input ) ;
foreach ( $lines as $line )
{
// explode the string to get only the numbers
[ $card , $data ] = explode ( ': ' , $line ) ;
// get the two strings of numbers
[ $winners , $have ] = explode ( '|' , $data ) ;
// make them an array
$winners = explode ( ' ' , trim ( $winners ) ) ;
$have = explode ( ' ' , trim ( $have ) ) ;
$winningNumbers = array_intersect ( $have , $winners ) ;
$currentTotal = 0 ;
foreach ( $winningNumbers as $win )
{
if ( $currentTotal === 0 ) {
// first number, so start at 1 for the score
$currentTotal = 1 ;
continue ;
}
// each additional winning number doubles the score
$currentTotal = $currentTotal * 2 ;
}
$total += $currentTotal ;
}
echo 'Current total ' . $total . PHP_EOL ;
我对这个解决方案非常有信心,但我没有使用示例输入得到正确的答案。然后我注意到字符串中的空格不一致,因此我的array_intersect
返回了额外的空值。经过快速的array_filter
之后,我得到了正确的答案,所以我进入了第二部分。
- $winningNumbers = array_intersect($have, $winners);
+ $winningNumbers = array_filter(array_intersect($have, $winners));
第二部分
第二部分一如既往地更加复杂:
相反,刮刮卡只会让您赢得更多相当于您中奖号码数量的刮刮卡
卡 1 有四个匹配的数字,因此您将赢得接下来四张卡中的每张:卡 2、3、4 和 5
从第一个部分的代码开始,我在循环每个刮刮卡之前对数据进行了一些处理。
$lines = explode ( "\n" , $input ) ;
$lines = array_map ( function ( $l ) {
[ $_ , $data ] = explode ( ': ' , $l ) ;
[ $winners , $have ] = explode ( '|' , $data ) ;
$winners = explode ( ' ' , trim ( $winners ) ) ;
$have = explode ( ' ' , trim ( $have ) ) ;
return [
'winners' => $winners ,
'have' => $have ,
] ;
} , $lines ) ;
// [['winners' => [4,5,6], 'have' => [1,2,3]], ...]
$multipliers = array_fill ( 1 , count ( $lines ) , 1 ) ;
// [1 => 1, 2 => 2, 3 => 3, ...]
然后我循环浏览刮刮卡,确定中奖号码,然后将每个号码添加到该卡的multipliers
中。例如,第一张牌有四个获胜号码,因此它通过将其设置为2
来“复制”第二张、第三张、第四张和第五张牌。当我在循环中击中卡牌 2 时,添加的数字将是2
而不是 1,因为我有该卡牌的两张副本。
foreach ( $lines as $index => $line ) {
$cardId = $index + 1 ;
// count the winning numbers
$winCount = count ( array_filter ( array_intersect ( $line [ 'have' ] , $line [ 'winners' ] ) ) ) ;
// if there are none, we don't need to make any card copies
if ( $winCount === 0 ) {
continue ;
}
// the card ID of the next card we need to copy
$windex = $cardId + 1 ;
// for each winning number, add the the multipliers to "copy" that card
foreach ( range ( 0 , $winCount - 1 ) as $win ) {
$multipliers [ $windex ] += $multipliers [ $cardId ] ;
$windex ++ ;
}
}
总而言之,第一部分花了我大约 30 分钟,第二部分花了大约 15 分钟——尽管我在工作时确实考虑了第二部分几个小时。
我的解决方案在 GitHub 上。