Задача соревнования:
Имеется двумерный массив N x N. Нужно написать функцию обхода двумерного массив
змейкой от правого ребра. Пример на картинке.
Пример двумерного массива:
На входе имеется следующий массив:
input = [[4, 3, 2, 1], [5, 6, 7, 8], [12, 11, 10, 9], [13, 14, 15, 16]]
На выходе одномерный массив после обхода:
output = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
Может использоваться любой язык.
Основное условие: функция должна работать корректно для любого равностороннего двумерного массива.
Указывать название языка в заголовке ответа и количество символов минифицированной версии функции через запятую.
Победителем станет тот, кто напишет ее за меньшее количество символов. За это о
получает 300 репутации. Победитель определится через 2 недели (12 января).
Ответ автора не учитывается при выборе победителя. Желаю удачи :)
Таблица лидеров:
execute("ru.stackoverflow.com", 926927);
Победители:
1 место: Haskell - 39 (@АндрейNOP)
2 место: JavaScript - 40 (@Groxan)
3 место: Groovy - 42 (@Nick)
Всем огромное спасибо за участие и интересные решения ;)
Ответы
Ответ 1
Haskell, 39 40 42
r=reverse;s[]=[];s(h:t)=r h++s(map r t)
https://ideone.com/JYttmr
Ответ 2
Octave, 47
@(l,b=l(1:2:end,:)=fliplr(l(1:2:end,:)))l'(:)';
Try it online!
Если разрешить возвращать не вектор-строку, а вектор-столбец, сокращается на 1 символ:
Octave, 46
@(l,b=l(1:2:end,:)=fliplr(l(1:2:end,:)))l'(:);
Try it online!
Прошлый вариант без анонимной функции:
Octave, 40
l(1:2:end,:)=fliplr(l(1:2:end,:));l'(:)'
Try it online!
Ответ 3
Python, 56
f=lambda l:sum([x[::i%2*2-1]for i,x in enumerate(l)],[])
Спасибо @АндрейNOP за подсказку!
Python, 60
f=lambda l:sum([[x[::-1],x][i&1]for i,x in enumerate(l)],[])
https://ideone.com/JPyzUQ (эта версия с лямбда функцией была любезно предоставлена @Let's say Pie)
Попытка 2: инвалидирована по причине неправильного оформления - решение должно быть реализовано как функция
Python, 49
sum([[x[::-1],x][i&1]for i,x in enumerate(l)],[])
https://ideone.com/WdHq4n
PS @КириллМалышев подсказал как можно сократить код еще на 6 символов - спасибо!!
Попытка 1:
Python, 55
sum([x if i&1 else x[::-1] for i,x in enumerate(l)],[])
https://ideone.com/2hoF3P
Ответ 4
JavaScript, 38
Данный код работает в Firefox, но не работает на V8 (из-за специфичного алгоритма сортировки). Если это неприемлемо, скажите =)
f=a=>a.flatMap((x,i)=>x.sort(_=>~i&1))
console.log(f([[4,3,2,1],[5,6,7,8],[12,11,10,9],[13,14,15,16]]));
JavaScript, 40
f=a=>a.flatMap((x,i)=>i%2?x:x.reverse())
console.log(f([[4,3,2,1],[5,6,7,8],[12,11,10,9],[13,14,15,16]]));
Ответ 5
JavaScript, 54
f=a=>a.reduce((c,n,i)=>c.concat(i%2?n:n.reverse()),[])
console.log(f([[4, 3, 2, 1], [5, 6, 7, 8], [12, 11, 10, 9], [13, 14, 15, 16]]));
Ответ 6
Python, 62 61
Пока ничего лучше варианта с рекурсией не придумал :)
f=lambda m,x:m and(x&1and m.pop(0)or m.pop(0)[::-1])+f(m,x+1)
https://ideone.com/i2d0f6
Ответ 7
Python, 43
f=lambda m,a=-1:m and m.pop(0)[::a]+f(m,-a)
https://ideone.com/fQVgtD
Ответ 8
F#, 68
let rec f=function|[]->[]|h::t->List.rev h@(t|>List.map List.rev|>f)
https://ideone.com/S6PhEZ
Ответ 9
PowerShell, 51
$f={$args[0]|%{if(++$i%2){[Array]::Reverse($_)}$_}}
Try it online!
Ответ 10
C#, 62
dynamic s(int[][]a)=>a.SelectMany((x,i)=>i%2>0?x:x.Reverse());
https://repl.it/repls/EmbarrassedHalfCommand
Ответ 11
PHP, 93 91
function f($a){foreach($a as$v)$r[]=$_++&1?$v:array_reverse($v);return array_merge(...$r);}
https://ideone.com/XsiPap
Ответ 12
PHP, 138 105
function f($a){foreach($a as$i=>$y){foreach($y as$x=>$w){$r[]=$i&1?$w:array_reverse($y)[$x];}}return $r;}
https://3v4l.org/DgDi8
Ответ 13
C#, 188 184
List S(T[,]a){var l=new List();int m=a.GetLength(1);for(int i=0;i=0;j--)l.Add(a[i,j]);else for(int j=0;j
Ответ 14
C#,171 168 163 153
Так как решения через LINQ уже были, то предлагаю вашему вниманию традиционных подход.
Минифицированная версия:
T[]F(T[,]a){var d=a.GetUpperBound(1);var r=new List();for(int i=0;i<=d;i++){var b=i%2>0;int j=b?0:d;while(j<=d&j>=0){r.Add(a[i,j]);j=b?++j:--j;}}return r.ToArray();}
Удобночитаемая:
static T[] F(T[,] a)
{
var d = a.GetUpperBound(1);
var r = new List();
for (int i = 0; i <= d; i++)
{
var b = i % 2 > 0;
int j = b ? 0 : d;
while (j <= d & j >= 0)
{
r.Add(a[i, j]);
j = b ? ++j : --j;//Трюк, что бы сэкономить символы на if/else
}
}
return r.ToArray();
}
Чуть чуть подправил:
T[]F(T[,]a){var d=a.GetUpperBound(1);var r=new List();for(int i=0;i<=d;i++){var b=i%2>0;int j=b?0:d;while(j<=d&j>=0){r.Add(a[i,b?j++:j--]);}}return r.ToArray();}
Удобночитаемая:
T[] F(T[,] a)
{
var d = a.GetUpperBound(1);
var r = new List();
for (int i = 0; i <= d; i++)
{
var b = i % 2 > 0;
int j = b ? 0 : d;
while (j <= d & j >= 0)
{
r.Add(a[i, b ? j++ : j--]);
}
}
return r.ToArray();
}
Опять чуть подправил:
T[]F(T[,]a){var d=a.GetLength(1)-1;var r=new List();for(int i=0;i<=d;i++){var b=i%2>0;int j=b?0:d;while(j<=d&j>=0)r.Add(a[i,b?j++:j--]);}return r.ToArray();}
Удобночитаемая:
T[] F(T[,] a)
{
var d = a.GetLength(1) - 1;
var r = new List();
for (int i = 0; i <= d; i++)
{
var b = i % 2 > 0;
int j = b ? 0 : d;
while (j <= d & j >= 0)
r.Add(a[i, b ? j++ : j--]);
}
return r.ToArray();
}
И еще чуть-чуть убрал все лишнее:
T[]F(T[,]a){int d=a.GetLength(1),g=0;var r=new T[d*d];for(int i=0;i0;int j=b?0:d-1;while(j=0)r[g++]=a[i,b?j++:j--];}return r;}
Удобночитаемый:
T[] F(T[,] a)
{
int d = a.GetLength(1), g = 0;
var r = new T[d * d];
for (int i = 0; i < d; i++)
{
var b = i % 2 > 0;
int j = b ? 0 : d - 1;
while (j < d & j >= 0)
r[g++] = a[i, b ? j++ : j--];
}
return r;
}
Ответ 15
Perl 5, 81
sub f{foreach$row(@_){foreach$val(@$row){push@$s,$i++%2?@$val:reverse@$val;}}$s;}
Try it online!
Ответ 16
Groovy, 42
f={i=0;it.each{it.reverse i=!i}.flatten()}
https://ideone.com/XirvAC
Ответ 17
C, 97
int f(int n,int a[n][n],int*b){for(int i=0;i
Ответ 18
Ruby, 63
def f(a,x)a[0]?(x%2==0?a.shift.reverse: a.shift)+f(a,x+1):[]end
https://ideone.com/T0MECG