Microsoft Excel World Championship 2025-2025EXCEL大赛,折纸

赛事链接
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
在这里插入图片描述
数据准备完毕,计算方法分析完毕,那么开始进行处理

  1. 定位左上角CELL
    LET(
        tlc,
        INDIRECT(
            "'Sheet (of Paper)'!" & H263
        ),1)
  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)
  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
            )
        )
    )
)

第七题

经历过前面的题目就很好理解该题目了,一个纸张经过三次折叠后,对剩余区域求和,其中包含了水平垂直对折和斜向对折
在这里插入图片描述
前面的偷的懒最后只能在这里重新开始,因为前面都没有进行对称变换,都是通过从对称找到原数据位置进行处理,等到现在这种复杂情况,就需要重新开始处理

  1. 定义待处理数据块
    首先定义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)
  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

  2. 处理0值
    上述转换只是进行了位置交换,还需要处理一件事情就是,对折过后,原始位置区域需要修改为0
    上下左右变换只需要通过r或者csize/2的大小比较,即可赋值为0
    4角方向的转换需要通过第六题的类不等式方法进行比较
    同时存在一个问题,如果对折位置数值为0,但当前位置数值不为0,那么就不需要进行数据转换,因此再转换过程中需要加上二次判断

  3. 编写代码
    例子 · 上↑
    外层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

  1. '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))
)
  1. '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
        )
    )
)
  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)))
            )
        )
    )
)
  1. '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列求和,直接选中,获取结果

  2. '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
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值