RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 892196
Accepted
user192664
user192664
Asked:2020-10-12 19:06:16 +0000 UTC2020-10-12 19:06:16 +0000 UTC 2020-10-12 19:06:16 +0000 UTC

以顺时针螺旋方式遍历二维数组

  • 772

比赛挑战:

我有一个二维数组N x N。我们需要编写一个函数,以顺时针方向围绕二维数组循环,如图所示。

在此处输入图像描述


示例4x4:

输入是一个二维数组:

entryArray = [[1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]

遍历后的输出是一维数组:

exitArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]

语言可以是任何东西。主要条件:函数必须对任何等边二维数组都能正常工作,包括1х1,空数组返回空数组。


获奖者的定义:

获胜者将由以下参数决定:

  1. 最少的代码字符数
  2. 票数
  3. 在第一个给出的答案之后不超过 2 次编辑

选择获胜者时不考虑作者的回答。

获胜者将在 2 周内(10 月 26 日)确定。

请在响应头中注明语言和缩小函数的字符数,用逗号分隔。


我希望看到Ruby、Haskell和Scalaad infinitum 的解决方案。非常感谢您的活动!


获奖者结论:

execute("ru.stackoverflow.com", "892196");
.cssload-container,.cssload-cube{width:97px;height:97px;transform-style:preserve-3d}.cssload-container,.cssload-cube,.cssload-half1,.cssload-half2{transform-style:preserve-3d}.cssload-container{position:relative;margin:23px 84px;perspective:292px}.cssload-cube{animation:cube 11.5s forwards infinite;transform-origin:center 49px}.cssload-half1,.cssload-s1{top:0;transform-origin:50% 100%}.cssload-half1{height:39px;position:absolute;animation:half-fold 11.5s forwards infinite}.cssload-side{width:19px;height:19px;background:#ddd;position:absolute}.cssload-s1{left:39px;animation:s1ani 11.5s forwards infinite}.cssload-s2,.cssload-s3,.cssload-s4{left:39px;transform-origin:50% 0}.cssload-s2{top:19px;animation:s2ani 11.5s forwards infinite}.cssload-s3{top:39px;animation:s3ani 11.5s forwards infinite}.cssload-s4{top:58px;animation:s4ani 11.5s forwards infinite}.cssload-s5{left:19px;top:19px;transform-origin:100% 50%;animation:s5ani 11.5s forwards infinite}.cssload-s6{left:58px;top:39px;transform-origin:0 50%;animation:s6ani 11.5s forwards infinite}@keyframes cube{0%,30%{transform:rotateX(0)}40%{transform:rotateX(45deg) rotateY(0) rotate(45deg)}60%{transform:rotateX(60deg) rotateY(0) rotate(45deg)}65%,70%{transform:rotateX(60deg) rotate(45deg) rotate(180deg)}75%,80%{transform:rotateX(60deg) rotate(45deg) rotate(1turn)}90%{transform:rotateX(0) rotate(0) rotate(0)}}@keyframes s1ani{0%{opacity:1;transform:translateY(0);background:#ddd}40%{transform:rotateX(0);background:#ddd}50%{transform:rotateX(-90deg);background:#ddd}90%{transform:rotateX(-90deg)}}@keyframes s2ani{0%{opacity:0;transform:rotateX(-179deg)}10%{opacity:1;transform:rotateX(0)}40%{background:#ddd}45%,80%{background:#b4b4b4}65%{opacity:1;background:#b4b4b4}90%{opacity:1}to{opacity:0}}@keyframes s3ani{0%,10%{opacity:0;transform:rotateX(-179deg)}20%,90%{opacity:1;transform:rotateX(0)}40%{background:#ddd}45%{background:#969696}to{opacity:0}}@keyframes s4ani{0%,20%{opacity:0;transform:rotateX(-179deg)}10%,to{opacity:0}30%{opacity:1;transform:rotateX(0)}40%{transform:rotateX(0);background:#ddd}50%{transform:rotateX(90deg);background:#b4b4b4}80%{background:#b4b4b4}90%{opacity:1;transform:rotateX(90deg)}}@keyframes s5ani{0%,10%{opacity:0;transform:rotateY(-179deg)}20%{opacity:1;background:#ddd;transform:rotateY(0)}40%{transform:rotateY(0)}50%{transform:rotateY(90deg)}55%{background:#ddd}60%{background:#c8c8c8}90%{transform:rotateY(90deg);opacity:1}to{opacity:0}}@keyframes s6ani{0%,20%{opacity:0;transform:rotateY(179deg)}30%{opacity:1;transform:rotateY(0)}40%{transform:rotateY(0)}50%{transform:rotateY(-90deg);background:#ddd}60%,80%{background:#c8c8c8}90%{opacity:1;transform:rotateY(-90deg)}to{opacity:0}}@keyframes half-fold{0%,50%{transform:rotateX(0)}60%,90%{transform:rotateX(-90deg)}}
<script src="https://mayorovp.github.io/codegolf/table-8c505e68f1349e4c69e7.js"></script>
<div class=cssload-container><div class=cssload-cube><div class=cssload-half1><div class="cssload-side cssload-s1"></div><div class="cssload-side cssload-s2"></div><div class="cssload-side cssload-s5"></div></div><div class=cssload-half2><div class="cssload-side cssload-s3"></div><div class="cssload-side cssload-s4"></div><div class="cssload-side cssload-s6"></div></div></div></div>


比赛结果:

第一名 Andrew NOP用Haskell回答40 字节

第二名 Yauhen的Ruby答案为 59 字节

第三名 比方说81 字节 JavaScript答案的Pie


非常感谢大家的参与,所有的评论都将被考虑到以后的比赛中。

javascript
  • 18 18 个回答
  • 10 Views

18 个回答

  • Voted
  1. Best Answer
    Андрей NOP
    2020-10-22T15:37:29Z2020-10-22T15:37:29Z

    Haskell, 40

    s[]=[];s(h:t)=h++(s$reverse$transpose t)
    

    Решение эксплуатирует всё ту же идею отрезания первой строки от матрицы и поворота оставшегося куска против часовой стрелки.

    https://ideone.com/FHeJAx

    • 18
  2. Андрей NOP
    2020-10-16T15:34:42Z2020-10-16T15:34:42Z

    蟒蛇,88 65 60

    f=lambda m:m and m.pop(0)+f([list(x)for x in zip(*m)][::-1])
    

    这是我第一次用 Python 编写代码,所以我还不知道如何缩短(长度)代码。

    Возникла следующая идея: берем матрицу, отрезаем от нее первую строку, оставшуюся часть поворачиваем против часовой стрелки на 90 градусов и рекурсивно применяем этот же алгоритм. В итоге потребовалось лишь выбрать ЯП, умеющий такие операции из коробки, им оказался Python ¯\_(ツ)_/¯

    https://ideone.com/5qasui

    Бонусом — алгоритм работает с любыми прямоугольными матрицами (не только с квадратными).

    • 13
  3. Harry
    2020-10-13T00:09:35Z2020-10-13T00:09:35Z

    正因为如此,嗯……“谁少”的要求,天生就是这样的怪物……

    C++,155 字节

    232 字节

    #define c(i,j) )std::cout<<m[i][j]<<" ";
    using M=std::vector<std::vector<int>>;void s(M&m,int h){int i,n=m.size(),k=n-h-1;if(n>2*h){for(i=h;i<=k;c(h,i++)for(i=h+1;i<=k;c(i++,k)for(i=k-1;i>=h;c(k,i--)for(i=k-1;i>h;c(i--,h)s(m,h+1);}}
    

    如果我们允许(并无视)公平标准

    using namespace std;
    

    然后我们得到 217 个字节...

    这是偶数和奇数 N 的测试:https ://ideone.com/OEHTLS

    如果您只需要将其推入一个数组 - 14 个字节以上:

    #define c(i,j) )v.push_back(m[i][j]);
    using V=std::vector<int>;
    using M=std::vector<V>;void s(M&m,V&v,int h){int i,n=m.size(),k=n-h-1;if(n>2*h){for(i=h;i<=k;c(h,i++)for(i=h+1;i<=k;c(i++,k)for(i=k-1;i>=h;c(k,i--)for(i=k-1;i>h;c(i--,h)s(m,v,h+1);}}
    

    首先允许的更改:) 用于填充到数组中

    230 字节

    #define c(k,r,c) for(i=0;i<k;++i)v.push_back(m[r][c]);
    using V=std::vector<int>;void s(std::vector<V>&m,V&v,int h){int r=h,c=h,i,n=m.size(),k=n-2*h-1;if(!k)c(1,r,c)else if(k>0){c(k,r,c++)c(k,r++,c)c(k,r,c--)c(k,r--,c)s(m,v,h+1);}}
    

    验证 - https://ideone.com/86YkY4

    第二个允许的变化

    与优化一样 - 有必要更改算法。我们改变……我们得到 196 个字节。

    using V=std::vector<int>;void s(std::vector<V>&m,V&v,int n,int h){int r=h,c=h,i=0,j,l=n-2*h-1;if(l>-1){do{v.push_back(m[r][c]);l?(j=i/l)<1?c++:j<2?r++:j<3?c--:r--:l;}while(++i<4*l);s(m,v,n,h+1);}}
    

    https://ideone.com/rDXdbh

    但是您不仅可以更改算法,还可以更改使用的数据结构!让我们继续讨论int**,因为问题的条件并没有说明应该如何创建数组。然后我们得到155字节的最终解

    void s(int**m,int*v,int n,int h){int r=h,c=h,i=0,j,l=n-2*h-1;if(l>-1){do{*v++=m[r][c];l?(j=i/l)<1?c++:j<2?r++:j<3?c--:r--:l;}while(++i<4*l);s(m,v,n,h+1);}}
    

    https://ideone.com/vukXQG

    您只需要稍微不同地准备输入数组。

    在这一点上,也许,我们会停下来。

    PS 其实,在这样的比赛中,还需要一些其他的规则……因为从头开始写一个算法是一回事,另一个有点夸张的是调用现成的库函数。或者使用更“短”的语言——再次夸大其词,想象一种语言,其中增量看起来完全像summation(a,1),没有别的:(

    • 12
  4. user192664
    2020-10-16T17:14:43Z2020-10-16T17:14:43Z

    Python 2, 60 59 байт

    Решил разбавить немного python'ом.

    Логика как у @Андрей NOP, но код короче:

    def f(a):return list(a[0])+f(zip(*a[1:])[::-1])if a else []
    

    Подтверждение:

    https://ideone.com/4Xmy7W


    Небольшое добавление:

    Пример выше реализован для Python второй версии. Для того чтобы функция работала должным образом в 3 версии нужно обернуть zip в list: list(zip(...)). Разница в том, что во второй версии zip возвращает список, а в третьей возвращает итерируемый объект.

    • 10
  5. user192664
    2020-10-13T14:03:17Z2020-10-13T14:03:17Z

    JS,125 个字符

    function f(a){for(var b=[];a.length;)b.push(...a.shift()),a.map(c=>b.push(c.pop())),a.reverse().map(c=>c.reverse());return b}
    

    正确性证明:

    function spiralRound(entryArray) {
      var exitArray = [];
      //Повторяем действие пока entryArray не останентся пустым
      while (entryArray.length) {
        //Добавление в exitArray первого вложенного массива из entryArray. 
        //shift() возвращает первый вложенный массив и удаляет его из entryArray.
        exitArray.push(...entryArray.shift());
     
        //Добавляем в exitArray каждый последний элемент из каждого оставщегося массива в entryArray.
        //pop() возвращает последний элемент массива и удаляет его из исходного 
        entryArray.map(row => exitArray.push(row.pop()));
     
        //Разворачиваем оставщийся массив на 180 градусов
        entryArray.reverse().map(row => row.reverse());
      }
      //Возвращаем результат
      return exitArray;
    }
    
    let testArray = [];
    console.log("0x0:" + spiralRound(testArray));
    
    testArray = [
      [1]
    ];
    console.log("1x1:" + spiralRound(testArray));
    
    testArray = [
      [1, 2],
      [3, 4]
    ];
    console.log("2x2:" + spiralRound(testArray));
    
    testArray = [
      [1, 2, 3, 4],
      [12, 13, 14, 5],
      [11, 16, 15, 6],
      [10, 9, 8, 7]
    ]
    console.log("4x4:" + spiralRound(testArray));
    
    testArray = [
      [1, 2, 3, 4, 12, 13, 14, 5, 7, 8],
      [1, 2, 3, 4, 12, 13, 14, 5, 7, 8],
      [1, 2, 3, 4, 12, 13, 14, 5, 7, 8],
      [1, 2, 3, 4, 12, 13, 14, 5, 7, 8],
      [1, 2, 3, 4, 12, 13, 14, 5, 7, 8],
      [1, 2, 3, 4, 12, 13, 14, 5, 7, 8],
      [1, 2, 3, 4, 12, 13, 14, 5, 7, 8],
      [1, 2, 3, 4, 12, 13, 14, 5, 7, 8],
      [1, 2, 3, 4, 12, 13, 14, 5, 7, 8],
      [1, 2, 3, 4, 12, 13, 14, 5, 7, 8],
    ]
    console.log("10x10:" + spiralRound(testArray));

    • 9
  6. user285292
    2020-10-18T04:54:52Z2020-10-18T04:54:52Z

    PHP 7.4, 124

    $f=fn($a,$f)=>$a?[...array_shift($a),...$f(array_reverse($a?next($a)?array_map(null,...$a):array_chunk($a[0],1):$a),$f)]:$a;
    

    https://3v4l.org/JDGfH

    • 9
  7. user285292
    2020-10-23T04:27:53Z2020-10-23T04:27:53Z

    JS, 121 107 81

    f=b=>b[0]?[...b.shift(),...f(b[0]?b[0].map((d,e)=>b.map(g=>g[e])).reverse():b)]:b
    

    在不改变算法的情况下进行编辑,考虑到@Andrey NOP 的意见和建议。我将函数更改为 lambda,并将其替换b.length为b[0],并将[]其替换为b.

    演示:

    f = b => b[0] 
        ? [...b.shift(), ...f(b[0] ? b[0].map((d, e) => b.map(g => g[e])).reverse() : b)] 
        : b
    
    console.log([
        [], 
        [[1]], 
        [[1, 2], [4, 3]], 
        [[1, 2, 3], [8, 9, 4], [7, 6, 5]], 
        [[1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]], 
        [[1, 2, 3, 4], [10, 11, 12, 5],[9, 8, 7, 6]] 
    ].map(f))

    • 8
  8. Yauhen
    2020-10-16T21:33:21Z2020-10-16T21:33:21Z

    Ruby, 61 59

    def f(a) a.empty? ? [] : a.shift+f(a.transpose.reverse) end
    

    https://ideone.com/SYmf7W

    • 7
  9. iluxa1810
    2020-10-18T05:14:41Z2020-10-18T05:14:41Z

    C#, 320 280

    static int[]f(int[,]a){var r=new List<int>();var n=a.GetLength(0);int j=-1,i=0;bool h=true;bool d=false;int c=0;int p=n;int max=n;for(var cnt=1;cnt<=a.Length;cnt++){i=h?i:!d?++i:--i;j=!h?j:!d?++j:--j;p--;r.Add(a[i,j]);if(p<=0){h=!h;if((c+1)%2==0){d=!d;}if(cnt==n||c>1&&(c+1)%2!=0){--max;}p=max;c++;}}return r.ToArray();}
    

    Потестить можно вот тут на deck.net


    int[]F(int[,]a){var n=a.GetLength(0);var r=new int[n*n];int j=-1,i=0;var h=true;var d=!h;int o=0;int p=n;intm=n;for(varc=1;c<=a.Length;c++){p--;r[c-1]=a[h?i:!d?++i:--i,!h?j:!d?++j:--j];if(p<=0&&a.Length!=2){h=!h;if((o+1)%2==0)d=!d;if(c==n||o>1&&(o+1)%2!=0)--m;p=m;o++;}}return r;}
    

    Внес небольшие исправления не меняя алгоритм, что бы уменьшить длину кода

    Потестить можно вот тут на deck.net


    Смысл в том, что я делаю реверс булевых флагов, которые показывают какие индексы в какую сторону двигать и на основании этого я обхожу массив.

    Вроде бы, это должно быть эффективно нежеле алгоритмы, через повороты матриц, которые ИМХО будут не так эффективны на больших матрицах.

    • 7
  10. eanmos
    2020-10-13T21:20:49Z2020-10-13T21:20:49Z

    C、193 191 178 175 字节

    int f(int n,int a[][n],int*b){int d=0,j=0,k=0,s=0,m=n-1,f=0;for(int i=0;i<n*n;i++,s++){if(s==m){d++,d%=4,s=0,f++;if(f%3==0)m--,f=1;}b[i]=!d?a[j][k++]:d==1?a[j++][k]:d==2?a[j][k--]:a[j--][k];}}
    

    您可以在Ideone上查看代码。

    第一次编辑

    使除m静态之外的所有变量都摆脱了零初始化,并i从以下位置删除了变量声明for:

    int f(int n,int a[][n],int *b){static int d,j,k,s,f,i;int m=n-1;for(;i<n*n;i++,s++){if(s==m){d++;d%=4;s=0;f++;if(f%3==0){m--;f=1;}}b[i]=!d?a[j][k++]:d==1?a[j++][k]:d==2?a[j][k--]:a[j--][k];}}
    

    再次链接到 Ideone。

    第二次编辑

    删除了不必要的大括号,替换if为三元运算符,删除了int静态变量声明中的显式类型:

    int f(int n,int a[][n],int*b){static d,j,k,s,f,i;int m=n-1;for(;i<n*n;i++,s++)s==m?d++,d%=4,s=0,f++,f%3==0?m--,f=1:m:m,b[i]=!d?a[j][k++]:d==1?a[j++][k]:d==2?a[j][k--]:a[j--][k];}
    

    你可以在这里查看第三个版本。

    第三次编辑

    据我了解,不更改算法的编辑不被视为“修复”,因此我将对代码进行另一项调整:我将m其设为静态并将其初始化为for:

    int f(int n,int a[][n],int*b){static d,j,k,s,f,i,m;for(m=n-1;i<n*n;i++,s++)s==m?d++,d%=4,s=0,f++,f%3==0?m--,f=1:m:m,b[i]=!d?a[j][k++]:d==1?a[j++][k]:d==2?a[j][k--]:a[j--][k];}
    

    让我们检查第四个版本。

    • 6

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5