书店

书店

中等

说明

为了鼓励人们更多地购买某套热门系列丛书(该系列共有 5 本)中的不同书籍,一家书店决定,对一次购买多本书的顾客提供折扣。

五本书中任意一本的单价都是 $8。

不过,如果你买两本不同的书,这两本能享受 5% 的折扣。

如果买 3 本不同的书,能享受 10% 的折扣。

如果买 4 本不同的书,能享受 20% 的折扣。

如果 5 本全买,能享受 25% 的折扣。

注意,如果你买了 4 本,其中 3 本是不同的书名,那么能组成一个套组的这 3 本可以享受 10% 的折扣,但第四本仍然是 $8。

你的任务是编写代码,计算任意一个可能出现的购物篮的价格(其中只包含同一系列的书籍),并尽可能给出最大的折扣。

例如,下面这个购物篮里的书要多少钱?

  • 第一本 2 册
  • 第二本 2 册
  • 第三本 2 册
  • 第四本 1 册
  • 第五本 1 册

对这 8 本书的一种分组方式是:

  • 1 组 5 本(第 1、2、3、4、5 本)
  • 1 组 3 本(第 1、2、3 本)

这样总共是:

  • 5 本书享受 25% 的折扣
  • 3 本书享受 10% 的折扣

结果是:

  • 5 × (100% - 25%) × $8 = 5 × $6.00 = $30.00,加上
  • 3 × (100% - 10%) × $8 = 3 × $7.20 = $21.60

总计 $51.60。

不过,这 8 本书还有另一种分组方式:

  • 1 组 4 本(第 1、2、3、4 本)
  • 1 组 4 本(第 1、2、3、5 本)

这样总共是:

  • 4 本书享受 20% 的折扣
  • 4 本书享受 20% 的折扣

结果是:

  • 4 × (100% - 20%) × $8 = 4 × $6.40 = $25.60,加上
  • 4 × (100% - 20%) × $8 = 4 × $6.40 = $25.60

总计 $51.20。

而 $51.20 就是折扣最大的价格。

WebAssembly 专属说明

WebAssembly 导出的total函数的签名如下:

(func (export "total")
    (param $basketOffset i32)
    (param $basketLength i32)
    (result i32)
)

两个参数$basketOffset和$basketLength分别表示一个 32 位整数数组的起始偏移量和长度。长度参数以数组中元素的个数为单位,而不是字节数。在调用这个函数之前,调用方需要先把这个数组写入 WebAssembly 线性内存,从偏移量$basketOffset开始。WebAssembly 线性内存一律采用小端序表示。

例如,调用方会把购物篮[1,2]编码为下面这个八字节序列。

| 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 |
| --- basket[0] --- | --- basket[1] --- |
,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
WebAssembly Exercism

准备好开始 书店 了吗?

注册 Exercism,借助 87 个练习 和真人导师指导,学习并掌握 WebAssembly,全部免费。