reddit编程题-詹妮的水果篮

问题描述


小詹妮拿着 5 美元去超市买东西, 为新搬来的邻居买水果篮礼物。因为她是个勤奋并缺乏想象力的孩纸, 她打算正好花 5 美元, 不多也不少。

事实上超市里水果的价格并非整数, 正好花光 5 美元并不容易。 - 但是詹妮已经准备好了。她从背包里拿出上网本, 输入她看到过的水果的单价, 并且开启了一个程序为她收集 — 就是这样, 5 美元能买的水果的组合就出现在屏幕上。

挑战 : 用你选择的语言展示詹妮的程序是什么样子。

  • 目标就是 500 美分 (等于 5 美元)
  • 解决方法可以包含多种同类型的水果 - 假设它们数量没有限制
  • 解决方法没有必要包含所有水果类型
  • 对给定的输入检测所有可能的方法

输入描述


每行一种水果 — 规定了水果的名字(不含空格的单词)和水果的单价(单位为美分, 整数)

输出描述


每个解决方法一行 — 用以逗号分割的数量+名字对儿, 描述了那种类型要买的水果数。

不要列出数量为 0 的水果。 如果为复数就给名字加 s

输入样本


banana 32
kiwi 41
mango 97
papaya 254
pineapple 399

输出样本


6 kiwis, 1 papaya
7 bananas, 2 kiwis, 2 mangos

有挑战的输入


apple 59
banana 32
coconut 155
grapefruit 128
jackfruit 1100
kiwi 41
lemon 70
mango 97
orange 73
papaya 254
pear 37
pineapple 399
watermelon 500

注意, 这种输入有 180 种解决方法。

my (@names, @prices) := ($_»[0], $_»[1]».Int given lines».words);

for find-coefficients(500, @prices) -> @quantities {
    say (@names Z @quantities)
        .map(-> [$name, $qty] { "$qty $name"~("s" if $qty > 1) if $qty })
        .join(", ");
}

sub find-coefficients ($goal, @terms) {
    gather {
        my @coefficients;

        loop (my $i = 0; $i < @terms; @coefficients[$i]++) {
            given [+](@coefficients Z* @terms) <=> $goal {
                when Less { $i = 0                      }
                when More { @coefficients[$i] = 0; $i++ }
                when Same { take @coefficients.values   }
            }
        }
    }
}

For each iteration of the loop, the array @coefficients is "incremented by one" as if its elements were the digits of a number - but not one with a fixed base: instead, it overflows the "digits" whenever the search condition has been exceeded (sum > goal).

The same could possibly be done more elegantly with recursion. And for those who don't like naive bruteforce solutions, this challenge could also be a nice opportunity to try some dynamic programming techniques.

my @fruits = lines».split(" ").sort(-*[1]);
my @names  = @fruits»[0];
my @prices = @fruits»[1]».Int;

for find-coefficients(500, @prices) -> @quantities {
    say (@names Z @quantities)
        .map(-> [$name, $qty] { "$qty $name"~("s" if $qty > 1) if $qty })
        .join(", ");
}

sub find-coefficients ($goal, @terms) {
    gather {
        my @initial = 0 xx @terms;

        my %partials = (0 => [@initial,]);
        my @todo = (@initial,);
        my %seen-partials := SetHash.new;
        my %seen-solutions := SetHash.new;

        while @todo {
            my @current := @todo.shift;
            my $sum = [+] @current Z* @terms;

            next if $sum > $goal;

            %partials{$sum}.push: @current;

            # Find solutions by adding known partials to the current partial
            for %partials{$goal - $sum}[*] -> @known {
                .take if !%seen-solutions{~$_}++ given list @current Z+ @known;
            }

            # Schedule additional iterations
            if $sum <= $goal div 2 {
                for @terms.keys {
                    my @next = @current;
                    @next[$_]++;
                    @todo.push: @next if !%seen-partials{~@next}++;
                }
            }
        }
    }
}

Note:

  • For the challenge input (solution space = 1,127,153,664) it needs only 4296 iterations, at the cost of several hash lookups per iteration.

Perl 5 的解决方案。

#可以求解三元以上的,只是个思路,可以推广。

use strict;
use warnings;
#计算二元方程组
#2x+3y=21

my @number;

while(<DATA>) {
    chomp;
    my ($name, $number) = split;
    push @number,$number;
}

print "@number\n";
 $_="1" x 500;
my %seen;
my $num = 31;
my $count = 0;



$_=~m{
  (.*)\1{$num}
  (.*)\2{40}
  (.*)\3{96}
  (.*)\4{253}
  (.*)\5{398}

  (?{
  my $a=split //,$1;
  my $b=split //,$2;
  my $x=split //,$3;
  my $y=split //,$4;
  my $d=split //,$5;
  $seen{"x=$a,y=$b,a=$x,b=$y,d=$d"}=1 if ($1 x $number[0]) . ($2 x $number[1]) . ($3 x $number[2]) . ($4 x $number[3]) . ($5 x $number[4]) eq $_ ;
  })
  (?!)}x;

foreach my $result (sort keys %seen) {
  print "$result\n";
}

__DATA__
banana 32
kiwi 41
mango 97
papaya 254
pineapple 399
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容

  • 介绍 先前的教程展示了一个简单的线性模型,对MNIST数据集中手写数字的识别率达到了91%。 在这个教程中,我们会...
    Kimichen7764阅读 1,620评论 0 7
  • 声明:作者翻译论文仅为学习,如有侵权请联系作者删除博文,谢谢! 翻译论文汇总:https://github.com...
    SnailTyan阅读 12,269评论 1 27
  • 一个人的日子,短了会精彩,久了会疲累。每到大姨妈来临,整个人的精神状态都变了,多疑敏感,脾气暴躁,像个脆弱不堪的老...
    三脚猫WW阅读 245评论 0 0
  • java编程思想第12章笔记 1.概念 异常指的是在程序运行过程中发生的异常事件,通常是由硬件问题或者程序设计问题...
    DongBold阅读 394评论 0 2
  • 想在开篇先不负责任的说一句,我永远十七岁。 自打室友四月初过完生日后,我总是对自己的二十岁感到一阵阵恐慌,可一直也...
    口渴雪碧阅读 263评论 1 1