赛事链接
B站看到的一个博主张云翼_like,讲了自己参加比赛,提供了题目下载链接,下载下来自己做一下
第一题
通过Reference列的数据来获取右侧对应列表

应该有其他字符串的解析方法,因对正则比较熟悉,对excel的语法不是很懂
现通过REGEXP进行解析
获取到所有的数字字符串
=REGEXP(G61, "\d", 0)
通过INDEX获取到单个数字
=INDEX(REGEXP(G61, "\d", 0), 1)
=INDEX(REGEXP(G61, "\d", 0), 2)
通过INDEX获取到映射表数字
=INDEX(
$K$66:$N$69,
INDEX(REGEXP(G61, "\d", 0), 1),
INDEX(REGEXP(G61, "\d", 0), 2)
)
第二题
在Sheet (of Paper)页获取到以Center Cell列对应为中心,大小为size列的正方形的形状数字的求和

先随意找个cell,点一下获取到单元格的样式
='Sheet (of Paper)'!K7
通过INDIRECT来获取到中心单元格位置
=INDIRECT("'Sheet (of Paper)'!" & H93)
因为是中心,所以size肯定是奇数,因此用减一除以2的方式,就能获取到
通过OFFSET,获取到左上角位置
=OFFSET(
INDIRECT(
"'Sheet (of Paper)'!" & H93
),
(1 - G93) / 2,
(1 - G93) / 2
)
通过OFFSET,获取到右下角位置
OFFSET(
INDIRECT(
"'Sheet (of Paper)'!" &
H93
),
(G93 - 1) / 2,
(G93 - 1) / 2
)
然后求和一下即可获得结果
=SUM(
OFFSET(
INDIRECT(
"'Sheet (of Paper)'!" & H93
),
(1 - G93) / 2,
(1 - G93) / 2
) :
OFFSET(
INDIRECT(
"'Sheet (of Paper)'!" &
H93
),
(G93 - 1) / 2,
(G93 - 1) / 2
)
)
第三题
通过Top Left Cell列对应单元格定位,往右下扩展8x8的一个区域,通过对称的形式,把右边的覆盖左边的

思路很明显还是INDIRECT获取到对应位置,OFFSET获取到8x8的范围,正则解析到Reference列的RC对应行列
因为对称关系,12345678其实对应12344321,这个可以通过MIN(val,9-val)进行判断
定位到左上角
=INDIRECT("'Sheet (of Paper)'!" & G136)
定位到右下角
=OFFSET(INDIRECT("'Sheet (of Paper)'!" & G136),8,8)
定位R
=INDEX(REGEXP(H136, "\d", 0), 1)
定位C,此时观察到所有C都大于4,因此不需要通过MIN进行二次判断,直接用9减去就行了
=9 - INDEX(REGEXP(H136, "\d", 0), 2)
最后结果
=INDEX(
INDIRECT(
"'Sheet (of Paper)'!" & G136
) :
OFFSET(
INDIRECT(
"'Sheet (of Paper)'!" &
G136
),
8,
8
),
INDEX(REGEXP(H136, "\d", 0), 1),
9 - INDEX(REGEXP(H136, "\d", 0), 2)
)
后续学习,通过let定义,类似于编程语言一样写出来答案
=LET(
tlc,
INDIRECT("'Sheet (of Paper)'!" & G136),
data,
OFFSET(tlc, 0, 0) : OFFSET(tlc, 7, 7),
rc,
REGEXP(H136, "\d+", 0),
r,
INDEX(rc, 1),
c,
INDEX(rc, 2),
INDEX(data, r, 9 - c)
)
第四题
看起来很麻烦,通过左上角单元格定位,规定size大小的一个nxn的块,然后通过Direction的方向进行对折,最后获取到Reference列对应的值

size通过offset解决
左上角通过INDIRECT定位
现在问题是对折的方向然后对解析到R或者C进行判断
第一反应是通过IFS进行4向判断单独处理
4向判断
=IFS(
I178 = "↑",
1,
I178 = "↓",
2,
I178 = "←",
3,
I178 = "→",
4
)
再次观察到不应该先判断4向,应该先通过size和左上角定位nxn块
先获取到nxn块
INDIRECT(H178):OFFSET(INDIRECT(H178),G178,G178)
有点复杂,引入辅助列,来获取r,c对应的值

观察到RC已经要超过2位数了,正则改成"\d+"

计算对折后的R或者C,
假设size为8
往上对折,C不变,R映射关系为12345678对应87655678,MAX(val,9-val)
往下对折,C不变,R映射关系为12345678对应12344321,MIN(val,9-val)
同理当左右对折时,R也是如此

R的转换
=IFS(
I178 = "↑",
MAX(
K178,
G178 + 1 - K178
),
I178 = "↓",
MIN(
K178,
G178 + 1 - K178
),
I178 = "←",
K178,
I178 = "→",
K178
)
C的转换
=IFS(
I178 = "←",
MAX(
L178,
G178 + 1 - L178
),
I178 = "→",
MIN(
L178,
G178 + 1 - L178
),
I178 = "↑",
L178,
I178 = "↓",
L178
)
最后获取就简单了
=INDEX(
INDIRECT(
"'Sheet (of Paper)'!"
& H178
) :
OFFSET(
INDIRECT(
"'Sheet (of Paper)'!"
& H178
),
G178,
G178
),
M178,
N178
)
后续学习,通过let定义,类似于编程语言一样写出来答案
=LET(
tlc,
INDIRECT("'Sheet (of Paper)'!" & G136),
data,
OFFSET(tlc, 0, 0) : OFFSET(tlc, 7, 7),
rc,
REGEXP(H136, "\d+", 0),
r,
INDEX(rc, 1),
c,
INDEX(rc, 2),
INDEX(data, r, 9 - c)
)
第五题
和第四题一样就是增加了两次对折

第一印象应该是就是多加一些辅助列即可,解析Directions,然后进行两次转换,观察到这不是传统的对折,而只是简单的对称。因此两个更换顺序是无影响的
引入辅助列直接成功了

第五题、通过REDUCE对操作区域进行真实对折操作
命名细则
tlc:top left cell 左上角定位块
size:操作区域大小
data:初始数据
rowcol:题目获取的行列数组
=LET(
tlc,
INDIRECT("'Sheet (of Paper)'!" & H221),
size,
G221,
data,
OFFSET(tlc, 0, 0) :
OFFSET(tlc, size - 1, size - 1),
ds,
MID(I221, SEQUENCE(LEN(I221)), 1),
r,
SEQUENCE(size),
c,
SEQUENCE(, size),
result,
REDUCE(
data,
ds,
LAMBDA(
arr,
ds,
SWITCH(
ds,
"↑",
IF(
r <= size / 2,
INDEX(
arr,
size + 1 - r,
c
),
0
),
"↓",
IF(
r > size / 2,
INDEX(
arr,
size + 1 - r,
c
),
0
),
"→",
IF(
c > size / 2,
INDEX(
arr,
r,
size + 1 - c
),
0
),
"←",
IF(
c <= size / 2,
INDEX(
arr,
r,
size + 1 - c
),
0
)
)
)
),
rowcol,
REGEXP(J221, "\d+", 0),
INDEX(
result,
INDEX(rowcol, 1),
INDEX(rowcol, 2)
)
)
第六题
通过一个Direction斜向对折,然后获取到对应Quadrant1/4区域的求和

观察当对折方向和取值方向相同时直接取原始块的(n/2)x(n/2)块的求和即可(最简单)
当方向相反时没有意义
当方向垂直时,取1/4块的斜向一半的求和
同向的很容易写出来,就是堆砌条件就行了
=IFS(
I266 = J266,
IFS(
I266 = "↘",
SUM(
INDIRECT("'Sheet (of Paper)'!" & H266) :
OFFSET(
INDIRECT("'Sheet (of Paper)'!" & H266),
G266 / 2 - 1,
G266 / 2 - 1
)
),
I266 = "↙",
SUM(
OFFSET(
INDIRECT("'Sheet (of Paper)'!" & H266),
0,
G266 / 2
) :
OFFSET(
INDIRECT("'Sheet (of Paper)'!" & H266),
G266 / 2 - 1,
G266 - 1
)
),
I266 = "↗",
SUM(
OFFSET(
INDIRECT("'Sheet (of Paper)'!" & H266),
G266 / 2,
0
) :
OFFSET(
INDIRECT("'Sheet (of Paper)'!" & H266),
G266 - 1,
G266 / 2 - 1
)
),
I266 = "↖",
SUM(
OFFSET(
INDIRECT("'Sheet (of Paper)'!" & H266),
G266 / 2,
G266 / 2
) :
OFFSET(
INDIRECT("'Sheet (of Paper)'!" & H266),
G266 - 1,
G266 - 1
)
)
),
I266 <> J266,
2
)

对于垂直方向
情况共有8中情况
例如当“↗↖”这种情况时,其实可以理解为

首先只需要考虑Quadrant列对应的1/4半区即可,其他的不需要考虑,因此只考虑左上半区
因为对折为左下到右上,其实可以表现为取对折起始部分的数据,忽略掉被覆盖区域即可
由此可以理解为
↗↘

↘↗

↘↙

↖↙

↖↗

↙↘

↙↖

总结来说就是
Quadrant用来在一个大的正方形中寻找一个1/4半区
Direction用来决定在这1/4半区中,再寻找一个1/2+对称线
直观理解

通过LET函数对4个半区进行重命名
因此,给左上角定位tlc,意为top left cell
同时把整个正方形进行4向切割
分别是tld:top left data 左上部分
trd:top right data 右上部分
bld:bottom left data 左下部分
brd:bottom right data 右下部分
LET(
tlc,
INDIRECT("'Sheet (of Paper)'!" & H263),
tld,
OFFSET(tlc, 0, 0) :
OFFSET(tlc, G263 / 2 - 1, G263 / 2 - 1),
trd,
OFFSET(tlc, 0, G263 / 2) :
OFFSET(tlc, G263 / 2 - 1, G263 - 1),
bld,
OFFSET(tlc, G263 / 2, 0) :
OFFSET(tlc, G263 - 1, G263 / 2 - 1),
brd,
OFFSET(tlc, G263 / 2, G263 / 2) :
OFFSET(tlc, G263 - 1, G263 - 1),
1
)
接下来处理Direction对应的1/2半区,共2种大情况,4种小情况,其实就是一元一次不等式
此可以理解为C>=R

这种情况就是R>=C

对于这种情况,有些小复杂,为R+C>=对角线的R+C。R+C为一个定值

这是相反的R+C<=对角线R+C

数据准备完毕,计算方法分析完毕,那么开始进行处理
- 定位左上角CELL
LET(
tlc,
INDIRECT(
"'Sheet (of Paper)'!" & H263
),1)
- 对4个方向进行重新编码
LET(
tlc,
INDIRECT(
"'Sheet (of Paper)'!" & H263
),
tld,
OFFSET(tlc, 0, 0) :
OFFSET(
tlc,
G263 / 2 - 1,
G263 / 2 - 1
),
trd,
OFFSET(tlc, 0, G263 / 2) :
OFFSET(
tlc,
G263 / 2 - 1,
G263 - 1
),
bld,
OFFSET(tlc, G263 / 2, 0) :
OFFSET(
tlc,
G263 - 1,
G263 / 2 - 1
),
brd,
OFFSET(tlc, G263 / 2, G263 / 2) :
OFFSET(
tlc,
G263 - 1,
G263 - 1
),1)
- 分情况讨论
LET(
tlc,
INDIRECT(
"'Sheet (of Paper)'!" & H263
),
tld,
OFFSET(tlc, 0, 0) :
OFFSET(
tlc,
G263 / 2 - 1,
G263 / 2 - 1
),
trd,
OFFSET(tlc, 0, G263 / 2) :
OFFSET(
tlc,
G263 / 2 - 1,
G263 - 1
),
bld,
OFFSET(tlc, G263 / 2, 0) :
OFFSET(
tlc,
G263 - 1,
G263 / 2 - 1
),
brd,
OFFSET(tlc, G263 / 2, G263 / 2) :
OFFSET(
tlc,
G263 - 1,
G263 - 1
),
IFS(
I263 & J263 = "↘↙",
LET(
data,
bld,
SUM(
IF(
ROW(data) +
COLUMN(
data
) <=
ROW(
INDEX(
data,
G263
/ 2,
1
)
) +
COLUMN(
INDEX(
data,
G263
/ 2,
1
)
),
data,
0
)
)
),
I263 & J263 = "↘↗",
LET(
data,
trd,
SUM(
IF(
ROW(data) +
COLUMN(
data
) <=
ROW(
INDEX(
data,
G263
/ 2,
1
)
) +
COLUMN(
INDEX(
data,
G263
/ 2,
1
)
),
data,
0
)
)
),
I263 & J263 = "↙↖",
LET(
data,
tld,
SUM(
IF(
ROW(data) -
ROW(tlc) <=
COLUMN(
data
) -
COLUMN(tlc),
data,
0
)
)
),
I263 & J263 = "↙↘",
LET(
data,
brd,
SUM(
IF(
ROW(data) -
ROW(tlc) <=
COLUMN(
data
) -
COLUMN(tlc),
data,
0
)
)
),
I263 & J263 = "↗↘",
LET(
data,
brd,
SUM(
IF(
ROW(data) -
ROW(tlc) >=
COLUMN(
data
) -
COLUMN(tlc),
data,
0
)
)
),
I263 & J263 = "↗↖",
LET(
data,
tld,
SUM(
IF(
ROW(data) -
ROW(tlc) >=
COLUMN(
data
) -
COLUMN(tlc),
data,
0
)
)
),
I263 & J263 = "↖↗",
LET(
data,
trd,
SUM(
IF(
ROW(data) +
COLUMN(
data
) >=
ROW(
INDEX(
data,
G263
/ 2,
1
)
) +
COLUMN(
INDEX(
data,
G263
/ 2,
1
)
),
data,
0
)
)
),
I263 & J263 = "↖↙",
LET(
data,
bld,
SUM(
IF(
ROW(data) +
COLUMN(
data
) >=
ROW(
INDEX(
data,
G263
/ 2,
1
)
) +
COLUMN(
INDEX(
data,
G263
/ 2,
1
)
),
data,
0
)
)
)
)
然后与当两个方向相同时的拼起来,答案就出来了
=IFS(
I263 = J263,
IFS(
I263 = "↘",
SUM(
INDIRECT(
"'Sheet (of Paper)'!" &
H263
) :
OFFSET(
INDIRECT(
"'Sheet (of Paper)'!"
& H263
),
G263 / 2 - 1,
G263 / 2 - 1
)
),
I263 = "↙",
SUM(
OFFSET(
INDIRECT(
"'Sheet (of Paper)'!"
& H263
),
0,
G263 / 2
) :
OFFSET(
INDIRECT(
"'Sheet (of Paper)'!"
& H263
),
G263 / 2 - 1,
G263 - 1
)
),
I263 = "↗",
SUM(
OFFSET(
INDIRECT(
"'Sheet (of Paper)'!"
& H263
),
G263 / 2,
0
) :
OFFSET(
INDIRECT(
"'Sheet (of Paper)'!"
& H263
),
G263 - 1,
G263 / 2 - 1
)
),
I263 = "↖",
SUM(
OFFSET(
INDIRECT(
"'Sheet (of Paper)'!"
& H263
),
G263 / 2,
G263 / 2
) :
OFFSET(
INDIRECT(
"'Sheet (of Paper)'!"
& H263
),
G263 - 1,
G263 - 1
)
)
),
I263 <> J263,
LET(
tlc,
INDIRECT(
"'Sheet (of Paper)'!" & H263
),
tld,
OFFSET(tlc, 0, 0) :
OFFSET(
tlc,
G263 / 2 - 1,
G263 / 2 - 1
),
trd,
OFFSET(tlc, 0, G263 / 2) :
OFFSET(
tlc,
G263 / 2 - 1,
G263 - 1
),
bld,
OFFSET(tlc, G263 / 2, 0) :
OFFSET(
tlc,
G263 - 1,
G263 / 2 - 1
),
brd,
OFFSET(tlc, G263 / 2, G263 / 2) :
OFFSET(
tlc,
G263 - 1,
G263 - 1
),
IFS(
I263 & J263 = "↘↙",
LET(
data,
bld,
SUM(
IF(
ROW(data) +
COLUMN(
data
) <=
ROW(
INDEX(
data,
G263
/ 2,
1
)
) +
COLUMN(
INDEX(
data,
G263
/ 2,
1
)
),
data,
0
)
)
),
I263 & J263 = "↘↗",
LET(
data,
trd,
SUM(
IF(
ROW(data) +
COLUMN(
data
) <=
ROW(
INDEX(
data,
G263
/ 2,
1
)
) +
COLUMN(
INDEX(
data,
G263
/ 2,
1
)
),
data,
0
)
)
),
I263 & J263 = "↙↖",
LET(
data,
tld,
SUM(
IF(
ROW(data) -
ROW(tlc) <=
COLUMN(
data
) -
COLUMN(tlc),
data,
0
)
)
),
I263 & J263 = "↙↘",
LET(
data,
brd,
SUM(
IF(
ROW(data) -
ROW(tlc) <=
COLUMN(
data
) -
COLUMN(tlc),
data,
0
)
)
),
I263 & J263 = "↗↘",
LET(
data,
brd,
SUM(
IF(
ROW(data) -
ROW(tlc) >=
COLUMN(
data
) -
COLUMN(tlc),
data,
0
)
)
),
I263 & J263 = "↗↖",
LET(
data,
tld,
SUM(
IF(
ROW(data) -
ROW(tlc) >=
COLUMN(
data
) -
COLUMN(tlc),
data,
0
)
)
),
I263 & J263 = "↖↗",
LET(
data,
trd,
SUM(
IF(
ROW(data) +
COLUMN(
data
) >=
ROW(
INDEX(
data,
G263
/ 2,
1
)
) +
COLUMN(
INDEX(
data,
G263
/ 2,
1
)
),
data,
0
)
)
),
I263 & J263 = "↖↙",
LET(
data,
bld,
SUM(
IF(
ROW(data) +
COLUMN(
data
) >=
ROW(
INDEX(
data,
G263
/ 2,
1
)
) +
COLUMN(
INDEX(
data,
G263
/ 2,
1
)
),
data,
0
)
)
)
)
)
)
第一次初见题目写的应该是有些略微复杂,
回头重新分析,应该全部采用垂直方向的思路,先判断方向,然后判断求和过程,下为事后改进方法
先定位4向块,通过方向相同直接sum,如果不同,分情况讨论即可获得答案
=LET(
tlc,
INDIRECT("'Sheet (of Paper)'!" & H263),
tld,
OFFSET(tlc, 0, 0) :
OFFSET(tlc, G263 / 2 - 1, G263 / 2 - 1),
trd,
OFFSET(tlc, 0, G263 / 2) :
OFFSET(tlc, G263 / 2 - 1, G263 - 1),
bld,
OFFSET(tlc, G263 / 2, 0) :
OFFSET(tlc, G263 - 1, G263 / 2 - 1),
brd,
OFFSET(tlc, G263 / 2, G263 / 2) :
OFFSET(tlc, G263 - 1, G263 - 1),
IFS(
J263 = I263,
IFS(
J263 = "↙",
SUM(trd),
J263 = "↖",
SUM(brd),
J263 = "↗",
SUM(bld),
J263 = "↘",
SUM(tld)
),
J263 <> I263,
LET(
data,
IFS(
J263 = "↙",
bld,
J263 = "↖",
tld,
J263 = "↗",
trd,
J263 = "↘",
brd
),
IFS(
I263 = "↘",
SUM(
IF(
ROW(data) + COLUMN(data) <=
ROW(INDEX(data, G263 / 2, 1)) +
COLUMN(INDEX(data, G263 / 2, 1)),
data,
0
)
),
I263 = "↖",
SUM(
IF(
ROW(data) + COLUMN(data) >=
ROW(INDEX(data, G263 / 2, 1)) +
COLUMN(INDEX(data, G263 / 2, 1)),
data,
0
)
),
I263 = "↗",
SUM(
IF(
ROW(data) - ROW(tlc) >= COLUMN(data) -
COLUMN(tlc),
data,
0
)
),
I263 = "↙",
SUM(
IF(
ROW(data) - ROW(tlc) <= COLUMN(data) -
COLUMN(tlc),
data,
0
)
)
)
)
)
)
第六题、真实变换,全部进行真实的变换而不使用获取原始值
=LET(
tlc,
INDIRECT("'Sheet (of Paper)'!" & H263),
size,
G263,
data,
OFFSET(tlc, 0, 0) : OFFSET(tlc, size - 1, size - 1),
r,
SEQUENCE(size),
c,
SEQUENCE(, size),
data_trans,
SWITCH(
I263,
"↙",
LET(t, INDEX(data, c, r), IF(r >= c, t, 0)),
"↗",
LET(t, INDEX(data, c, r), IF(r <= c, t, 0)),
"↘",
LET(
t,
INDEX(data, size + 1 - c, size + 1 - r),
IF(r + c >= size + 1, t, 0)
),
"↖",
LET(
t,
INDEX(data, size + 1 - c, size + 1 - r),
IF(r + c <= size + 1, t, 0)
)
),
SWITCH(
J263,
"↙",
SUM(
IF(
(r >= size / 2) * (c <= size / 2),
data_trans,
0
)
),
"↗",
SUM(
IF(
(r <= size / 2) * (c > size / 2),
data_trans,
0
)
),
"↘",
SUM(
IF(
(r > size / 2) * (c > size / 2),
data_trans,
0
)
),
"↖",
SUM(
IF(
(r <= size / 2) * (c <= size / 2),
data_trans,
0
)
)
)
)
第七题
经历过前面的题目就很好理解该题目了,一个纸张经过三次折叠后,对剩余区域求和,其中包含了水平垂直对折和斜向对折

前面的偷的懒最后只能在这里重新开始,因为前面都没有进行对称变换,都是通过从对称找到原数据位置进行处理,等到现在这种复杂情况,就需要重新开始处理
- 定义待处理数据块
首先定义tlc,用来标记左上角cell位置
定义size,用来获取size
定义data,获取到待处理正方形区域
定义df,ds,dt用来确定3次变换的类型,意思为Direction first,Direction second,Direction third
定义r,c用来定位待处理数据
=LET(
tlc,
INDIRECT("'Sheet (of Paper)'!" & H303),
size,
G303,
data,
OFFSET(tlc, 0, 0) : OFFSET(tlc, size - 1, size - 1),
df,
LEFT(I303, 1),
ds,
LEFT(RIGHT(I303, 2), 1),
dt,
RIGHT(I303, 1),
r,
SEQUENCE(ROWS(data)),
c,
SEQUENCE(, COLUMNS(data)),1)
-
处理变换
我没想到有什么优雅的方法,但是能够发现,如果变换写的边界条件足够好,那么3次变换是能复用的,我不知道怎么写Excel的循环,于是通过3次判断进行处理,但是每次变换的代码是一样的不需要二次编写
观察8方向变换规律,
上下变换其实就是r=size+1-r,c=c
左右变换其实就是c=size+1-c,r=r
左下至右上与右上至左下是一个变换,为r=c,c=r
右下至左上与左上至右下是一个变换,为r=size+1-c,c=size+1-r -
处理0值
上述转换只是进行了位置交换,还需要处理一件事情就是,对折过后,原始位置区域需要修改为0
上下左右变换只需要通过r或者c与size/2的大小比较,即可赋值为0
4角方向的转换需要通过第六题的类不等式方法进行比较
同时存在一个问题,如果对折位置数值为0,但当前位置数值不为0,那么就不需要进行数据转换,因此再转换过程中需要加上二次判断 -
编写代码
例子 · 上↑
外层IF判断置0区域,内层IF判断目标位置是否为0,如果为0代表,该位置已经对折过了,当前位置不进行转换
LET(
data1,
IFS(
df = "↑",
LET(
t,
IF(
r <= size / 2,
IF(
INDEX(data, size + 1 - r, c) = 0,
INDEX(data, r, c),
INDEX(data, size + 1 - r, c)
),
0
),
t
),1)
下
df = "↓",
LET(
t,
IF(
r > size / 2,
IF(
INDEX(data, size + 1 - r, c) = 0,
INDEX(data, r, c),
INDEX(data, size + 1 - r, c)
),
0
),
t
)
左
df = "←",
LET(
t,
IF(
c <= size / 2,
IF(
INDEX(data, r, size + 1 - c) = 0,
INDEX(data, r, c),
INDEX(data, r, size + 1 - c)
),
0
),
t
)
右
df = "→",
LET(
t,
IF(
c > size / 2,
IF(
INDEX(data, r, size + 1 - c) = 0,
INDEX(data, r, c),
INDEX(data, r, size + 1 - c)
),
0
),
t
)
左上
df = "↖",
LET(
t,
IF(
INDEX(data, size + 1 - c, size + 1 - r) = 0,
INDEX(data, r, c),
INDEX(data, size + 1 - c, size + 1 - r)
),
IF(r + c <= size + 1, t, 0)
)
右下
df = "↘",
LET(
t,
IF(
INDEX(data, size + 1 - c, size + 1 - r) = 0,
INDEX(data, r, c),
INDEX(data, size + 1 - c, size + 1 - r)
),
IF(r + c >= size + 1, t, 0)
)
右上
df = "↗",
LET(
t,
IF(
INDEX(data, c, r) = 0,
INDEX(data, r, c),
INDEX(data, c, r)
),
IF(r <= c, t, 0)
)
左下
df = "↙",
LET(
t,
IF(
INDEX(data, c, r) = 0,
INDEX(data, r, c),
INDEX(data, c, r)
),
IF(r >= c, t, 0)
)
对于第二层直接复制粘贴即可,但是需要把相对应的data修改为data1.
下面是完整代码
=LET(
tlc,
INDIRECT("'Sheet (of Paper)'!" & H303),
size,
G303,
data,
OFFSET(tlc, 0, 0) : OFFSET(tlc, size - 1, size - 1),
df,
LEFT(I303, 1),
ds,
LEFT(RIGHT(I303, 2), 1),
dt,
RIGHT(I303, 1),
r,
SEQUENCE(ROWS(data)),
c,
SEQUENCE(, COLUMNS(data)),
LET(
data1,
IFS(
df = "↑",
LET(
t,
IF(
r <= size / 2,
IF(
INDEX(data, size + 1 - r, c) = 0,
INDEX(data, r, c),
INDEX(data, size + 1 - r, c)
),
0
),
t
),
df = "↓",
LET(
t,
IF(
r > size / 2,
IF(
INDEX(data, size + 1 - r, c) = 0,
INDEX(data, r, c),
INDEX(data, size + 1 - r, c)
),
0
),
t
),
df = "←",
LET(
t,
IF(
c <= size / 2,
IF(
INDEX(data, r, size + 1 - c) = 0,
INDEX(data, r, c),
INDEX(data, r, size + 1 - c)
),
0
),
t
),
df = "→",
LET(
t,
IF(
c > size / 2,
IF(
INDEX(data, r, size + 1 - c) = 0,
INDEX(data, r, c),
INDEX(data, r, size + 1 - c)
),
0
),
t
),
df = "↖",
LET(
t,
IF(
INDEX(data, size + 1 - c, size + 1 - r) = 0,
INDEX(data, r, c),
INDEX(data, size + 1 - c, size + 1 - r)
),
IF(r + c <= size + 1, t, 0)
),
df = "↗",
LET(
t,
IF(
INDEX(data, c, r) = 0,
INDEX(data, r, c),
INDEX(data, c, r)
),
IF(r <= c, t, 0)
),
df = "↙",
LET(
t,
IF(
INDEX(data, c, r) = 0,
INDEX(data, r, c),
INDEX(data, c, r)
),
IF(r >= c, t, 0)
),
df = "↘",
LET(
t,
IF(
INDEX(data, size + 1 - c, size + 1 - r) = 0,
INDEX(data, r, c),
INDEX(data, size + 1 - c, size + 1 - r)
),
IF(r + c >= size + 1, t, 0)
)
),
data2,
IFS(
ds = "↑",
LET(
t,
IF(
r <= size / 2,
IF(
INDEX(data1, size + 1 - r, c) = 0,
INDEX(data1, r, c),
INDEX(data1, size + 1 - r, c)
),
0
),
t
),
ds = "↓",
LET(
t,
IF(
r > size / 2,
IF(
INDEX(data1, size + 1 - r, c) = 0,
INDEX(data1, r, c),
INDEX(data1, size + 1 - r, c)
),
0
),
t
),
ds = "←",
LET(
t,
IF(
c <= size / 2,
IF(
INDEX(data1, r, size + 1 - c) = 0,
INDEX(data1, r, c),
INDEX(data1, r, size + 1 - c)
),
0
),
t
),
ds = "→",
LET(
t,
IF(
c > size / 2,
IF(
INDEX(data1, r, size + 1 - c) = 0,
INDEX(data1, r, c),
INDEX(data1, r, size + 1 - c)
),
0
),
t
),
ds = "↖",
LET(
t,
IF(
INDEX(data1, size + 1 - c, size + 1 - r) = 0,
INDEX(data1, r, c),
INDEX(data1, size + 1 - c, size + 1 - r)
),
IF(r + c <= size + 1, t, 0)
),
ds = "↗",
LET(
t,
IF(
INDEX(data1, c, r) = 0,
INDEX(data1, r, c),
INDEX(data1, c, r)
),
IF(r <= c, t, 0)
),
ds = "↙",
LET(
t,
IF(
INDEX(data1, c, r) = 0,
INDEX(data1, r, c),
INDEX(data1, c, r)
),
IF(r >= c, t, 0)
),
ds = "↘",
LET(
t,
IF(
INDEX(data1, size + 1 - c, size + 1 - r) = 0,
INDEX(data1, r, c),
INDEX(data1, size + 1 - c, size + 1 - r)
),
IF(r + c >= size + 1, t, 0)
)
),
data3,
IFS(
dt = "↑",
LET(
t,
IF(
r <= size / 2,
IF(
INDEX(data2, size + 1 - r, c) = 0,
INDEX(data2, r, c),
INDEX(data2, size + 1 - r, c)
),
0
),
t
),
dt = "↓",
LET(
t,
IF(
r > size / 2,
IF(
INDEX(data2, size + 1 - r, c) = 0,
INDEX(data2, r, c),
INDEX(data2, size + 1 - r, c)
),
0
),
t
),
dt = "←",
LET(
t,
IF(
c <= size / 2,
IF(
INDEX(data2, r, size + 1 - c) = 0,
INDEX(data2, r, c),
INDEX(data2, r, size + 1 - c)
),
0
),
t
),
dt = "→",
LET(
t,
IF(
c > size / 2,
IF(
INDEX(data2, r, size + 1 - c) = 0,
INDEX(data2, r, c),
INDEX(data2, r, size + 1 - c)
),
0
),
t
),
dt = "↖",
LET(
t,
IF(
INDEX(data2, size + 1 - c, size + 1 - r) = 0,
INDEX(data2, r, c),
INDEX(data2, size + 1 - c, size + 1 - r)
),
IF(r + c <= size + 1, t, 0)
),
dt = "↗",
LET(
t,
IF(
INDEX(data2, c, r) = 0,
INDEX(data2, r, c),
INDEX(data2, c, r)
),
IF(r <= c, t, 0)
),
dt = "↙",
LET(
t,
IF(
INDEX(data2, c, r) = 0,
INDEX(data2, r, c),
INDEX(data2, c, r)
),
IF(r >= c, t, 0)
),
dt = "↘",
LET(
t,
INDEX(data2, size + 1 - c, size + 1 - r),
IF(r + c >= size + 1, t, 0)
)
),
SUM(INDEX(data3, r, c))
)
)
共314行
应该有简单方法,这个只是代码堆砌,找到简单方法后会再次进行编辑
第七题,引入REDUCE定义通用操作函数,109行完成
如果第五题、第六题都采用真实变换的话,第7题将会很简单,直接组合起来就行了
=LET(
tlc,
INDIRECT("'Sheet (of Paper)'!" & H303),
size,
G303,
data,
OFFSET(tlc, 0, 0) : OFFSET(tlc, size - 1, size - 1),
ds,
MID(I303, SEQUENCE(LEN(I303)), 1),
r,
SEQUENCE(size),
c,
SEQUENCE(, size),
result,
REDUCE(
data,
ds,
LAMBDA(
arr,
ds,
SWITCH(
ds,
"↑",
IF(
r <= size / 2,
IF(
INDEX(arr, size + 1 - r, c) = 0,
INDEX(arr, r, c),
INDEX(arr, size + 1 - r, c)
),
0
),
"↓",
IF(
r > size / 2,
IF(
INDEX(arr, size + 1 - r, c) = 0,
INDEX(arr, r, c),
INDEX(arr, size + 1 - r, c)
),
0
),
"→",
IF(
c > size / 2,
IF(
INDEX(arr, r, size + 1 - c) = 0,
INDEX(arr, r, c),
INDEX(arr, r, size + 1 - c)
),
0
),
"←",
IF(
c <= size / 2,
IF(
INDEX(arr, r, size + 1 - c) = 0,
INDEX(arr, r, c),
INDEX(arr, r, size + 1 - c)
),
0
),
"↙",
LET(
t,
IF(
INDEX(arr, c, r) = 0,
INDEX(arr, r, c),
INDEX(arr, c, r)
),
IF(r >= c, t, 0)
),
"↗",
LET(
t,
IF(
INDEX(arr, c, r) = 0,
INDEX(arr, r, c),
INDEX(arr, c, r)
),
IF(r <= c, t, 0)
),
"↘",
LET(
t,
IF(
INDEX(arr, size + 1 - c, size + 1 - r) =
0,
INDEX(arr, r, c),
INDEX(arr, size + 1 - c, size + 1 - r)
),
IF(r + c >= size + 1, t, 0)
),
"↖",
LET(
t,
IF(
INDEX(arr, size + 1 - c, size + 1 - r) =
0,
INDEX(arr, r, c),
INDEX(arr, size + 1 - c, size + 1 - r)
),
IF(r + c <= size + 1, t, 0)
)
)
)
),
SUM(INDEX(result, r, c))
)
题后感
首先学习到了INDIRECT,在该题目之前,完全没有用过该函数,其次学习到了LET函数的用法,能够像编程语言一样写excel的函数.
题目总体上来说还是很简单的相较于编程语言的那种题目,但是用excel来实现该功能太麻烦了
Bonus Questions
- 'What is the sum of the main diagonal “⤡” (top-left, bottom-right) of the “Sheet (of Paper)”?
左上角到右下角求和是多少
=LET(
data,
'Sheet (of Paper)'!B4 : 'Sheet (of Paper)'!IW259,
r,
SEQUENCE(ROWS(data)),
c,
SEQUENCE(, COLUMNS(data)),
SUM(IF(r = c, data, 0))
)
- 'What is the sum of the 4 central cells located in the very middle of the “Sheet (of Paper)”?
最中间的4个数求和是多少,直接过去算就行了,代码写法
=LET(
data,
'Sheet (of Paper)'!B4 : 'Sheet (of Paper)'!IW259,
r,
ROWS(data),
c,
COLUMNS(data),
SUM(
INDEX(data, r / 2, c / 2),
INDEX(data, r / 2 + 1, c / 2),
INDEX(data, r / 2, c / 2 + 1),
INDEX(
data,
r / 2 + 1,
c / 2 + 1
)
)
)
- 'What’s the largest sum of numbers found in any 5x1 vector in the “Sheet (of Paper)”? (vertically or horizontally only, no diagonals (e.g., B4:F4, C4:G4, B4:B8))
最大5x1连续行或者列和是多少

分开计算行列的5x1,然后肉眼比较
=LET(
data,
'Sheet (of Paper)'!B4 : 'Sheet (of Paper)'!IW259,
r,
ROWS(data),
c,
COLUMNS(data),
MAX(
TOCOL(
MAKEARRAY(
r,
c - 4,
LAMBDA(r, c, SUM(INDEX(data, r, c) : INDEX(data, r, c + 4)))
)
)
)
)
=LET(
data,
'Sheet (of Paper)'!B4 : 'Sheet (of Paper)'!IW259,
r,
ROWS(data),
c,
COLUMNS(data),
MAX(
TOCOL(
MAKEARRAY(
r - 4,
c,
LAMBDA(r, c, SUM(INDEX(data, r, c) : INDEX(data, r + 4, c)))
)
)
)
)
-
'Always folding from left to right, and considering that each fold reduces the size of visible cells by half, what’s the sum of the visible cells when the “Sheet (of Paper)” reaches a width of 4 columns?
一直从左向右对折,直到剩下4列,求和是多少
没有写代码
根据推理
初始为 1-256
每次对折都是中间值-开始值
以下变化规律为
1-256
128-1
64-128
96-64
80-96
88-80
84-88
因此就是最初表中85列-88列求和,直接选中,获取结果 -
'What is the center cell of the only 3x3 square that contains all 1 to 9 numbers in the “Sheet (of Paper)”? (e.g., AH100)
有一个3x3的块中恰好包含了1-9的元素
开一个新页面
=LET(
data,
'Sheet (of Paper)'!B4 : 'Sheet (of Paper)'!IW259,
r,
ROWS(data),
c,
COLUMNS(data),
MAKEARRAY(
r - 3,
c - 3,
LAMBDA(
r,
c,
SUM(
INDEX(data, r, c) :
INDEX(
data,
r + 2,
c + 2
)
)
)
)
)
计算所有每个单元格作为左上角的3x3范围的求和
然后定位所有45,
恰好第一个45就是123456789




被折叠的 条评论
为什么被折叠?



