Як надрукувати наведений нижче формат у найменших байтах?


20

Цей виклик натхненний цим , тепер видаленим запитанням.


Візьміть додаткове ціле число N як вхідне та виведіть матрицю з числами 1 .. N 2, яка відповідає наведеному нижче шаблону:

Заповніть перший рядок 1 .. N, а потім заповніть останній рядок (номер рядка N ) цифрою (N + 1) .. 2N , потім заповніть другий ряд (2N + 1) .. 3N і продовжуйте, поки ви не заповнили всі ряди.

Формат виводу є гнучким, тому приймаються списки списків тощо.

N = 1
1

N = 2
1  2
3  4

N = 3
1  2  3
7  8  9
4  5  6

N = 4
 1  2  3  4
 9 10 11 12
13 14 15 16
 5  6  7  8

N = 5
 1  2  3  4  5
11 12 13 14 15
21 22 23 24 25
16 17 18 19 20
 6  7  8  9 10

Діють стандартні правила. Найкоротша відповідь у байтах на кожній мові виграє. Пояснення заохочуються, як завжди.


Чи дозволяється записам закінчуватися помилкою, якщо ця помилка не надрукується в STDOUT?
Сок

@ Так, це дозволено за замовчуванням.
Мартін Ендер

1
Я думаю, що назва взята із видаленого запитання, але оскільки це не дуже зручно для пошуку (щоб знайти дуп тощо), чи можете ви змінити на кращий?
користувач202729

1
Оскільки "формат виводу є гнучким", чи можу я вивести одновимірний масив із числами, упорядкованими з рядка в рядок? (наприклад:) 1 2 3 7 8 9 4 5 6Чи є формат виводу таким гнучким?
Олів'є Грегоар

4
Рішення APL, мабуть, є одним символом старої перської клинопису.
Марк

Відповіді:


7

05AB1E , 13 8 байт

Збережено 5 байт завдяки Роду

nLô«āÉÏ

Спробуйте в Інтернеті!

Пояснення

n           # push input^2
 L          # push range [1 ... input^2]
  ô         # split into pieces each the size of the input
   «       # append the reverse of this 2D-list
     ā      # push range [1 ... len(list)]
      É     # check each element for oddness
       Ï    # keep only the elements in the 2D list which are true in this list

5

Рубін , 53 байти

->n{r=*1..n*n;n.times{|x|p r.slice!(r[x*=n]?x:-n,n)}}

Пояснення:

Покладіть спочатку всі числа в один масив, а потім наріжте масив, пропускаючи рядок для кожної ітерації. Після перших (n / 2 + n% 2) ітерацій не залишається нічого іншого, а потім повернути всі решта рядків назад.

Спробуйте в Інтернеті!



4

JavaScript, 68 байт

Відредагуйте 3 байти, збережені під назвою @ user71546

Спершу спробуйте, дотримуючись очевидного маршруту: порахуйте від 1 і заповніть масив з обох сторін - від зовнішньої до внутрішньої

n=>(v=0,q=[...Array(n)]).map((_,i)=>q[i&1?--n:i/2]=q.map(_=>++v))&&q

Тест

var F=
n=>(v=0,q=[...Array(n)]).map((_,i)=>q[i&1?--n:i/2]=q.map(_=>++v))&&q

function test() {
  var n=+N.value;
  O.innerHTML = '<tr><td>'
  +F(n).map(r=>r.join('</td><td>')).join('</td></tr><tr><td>')
  +'</td></tr>'
}

test()
#O { margin: 1em }
td { text-align: right }
<input id=N type=number min=1 value=5 oninput='test()'>
<table id=O>



1
@ user71546 зараз 68
edc65


3

> <> , 51 + 3 = 54 47 байт

:&v
?!\1-:&:&*}}r:
 ~\
!~>1+::n&:&%:a84*@@?$~o?

Спробуйте в Інтернеті!

Введення очікується вверху стеку при запуску програми з використанням -vпрапора. Вихід складається з нерівневих чисел, розділених окремими пробілами, і кожен рядок відокремлений одним новим рядком. Приклад виводу для N=5:

1 2 3 4 5
11 12 13 14 15
21 22 23 24 25
16 17 18 19 20
6 7 8 9 10

... слідом за єдиним новим рядком. Програма закінчується помилкою ( something smells fishy...), але це на STDERR, а не на STDOUT.

Пояснення:

Перший рядок просто зберігає копію Nреєстру.

Другий рядок створює зміщення для кожного вихідного рядка, віднімаючи 1 з N, множимо це на N, обертаючи його в нижній частині стека і потім повертаючи всю стек. Коли число вгорі стека досягає 0, стек повинен виглядати приблизно так (приклад використовує N=5):

5 15 20 10 0 0

Третій рядок відкидає дублікат 0у верхній частині стека.

Четвертий рядок збільшує верхню частину стека і виводить його копію. Потім використовується мод N, і він використовується для вирішення питання про те, чи слід друкувати пробіл чи новий рядок, і чи слід відкинути верхню частину стека - якщо надруковано останнє число x, то x mod N == 0вказує, що кінець цього рядка виводу досягнуто . Виконання завершується, коли 1+він виконується в порожній стек, видаючи помилку завершення.

Попередня версія

Це явно перевірило наявність порожнього стека для завершення виконання, і я також включав 3 байти для використання -vпрапора.

:&v
?!\1-:&:&*}}r:
 ~\
!;>1+::n&:&%:a84*@@?$~o?!~l?

Спробуйте в Інтернеті!


Відповідно до цього мета , ми більше не додаємо прапори до підрахунку байтів, тому достатньо вказати, що прапор використовується.
Емінья

@Emigna O_O дякую за добро! Дякую за голову вгору
Sok


2

Java (OpenJDK 9) , 101 байт

n->{int x[][]=new int[n][n],i=0,j;for(;i<n;i++)for(j=0;j<n;)x[i%2<1?i/2:n+~i/2][j]=++j+i*n;return x;}

Спробуйте в Інтернеті!

Кредити


1
Ви можете зберегти три байти, змінивши позицію j++: 102 байти
Кевін Круїйсен

1
І ще один байт, що змінюється n-i/2-1на n+~i/2 101 байт
Кевін Круїссен

@KevinCruijssen Дякую! Я якось розмістив сиру версію, а не повністю гольф-версію. Моя помилка, перше питання було вирішено, але не друге. Але ви їх написали, тому вам кредити ;-)
Олів'є Грегоар

Зауважте: якщо якимось чином приймаються одновимірні масиви,n->{int i=n*n,x[]=new int[i],r;for(;i-->0;x[(r%2<1?r/2:n+~r/2)*n+i%n]=i+1)r=i/n;return x;}
Олів'є Грегоар

2

JavaScript (ES6), 69 68 байт

n=>[...Array(n)].map((_,i,a,j=((i*=2)<n?i:n+n+~i)*n)=>a.map(_=>++j))

Ну, це перевершило ще до того, як я міг його опублікувати, але ось це все одно. Редагувати: Збережено 1 байт завдяки @KevinCruijssen.


n+n-i-1може становити n+n+~i-1 байт, тож тоді ви знову з другою відповіддю JavaScript. :)
Кевін Круїссен

@KevinCruijssen Блискуче дякую!
Ніл

2

Желе , 10 байт

²ss2Ṛj@/Fs

Спробуйте в Інтернеті!

Як це працює

²ss2Ṛj@/Fs  Main link. Argument: n

²           Square; yield n².
 s          Split; promote n² to [1, ..., n²] and split it into chuks of length n.
  s2        Split 2; generate all non-overlapping pairs of chunks.
            If n is odd, this leaves a singleton array at the end.
    Ṛ       Reverse the order.
     j@/    Reduce by join with reversed arguments.
            In each step, this places the first and second element of the next pair
            at the top and bottom of the accumulator.
        Fs  Flatten and split to restore the matrix shape.

2

Стакс , 10 байт

│æ╘▐⌡r▌═∟Y

Запустити та налагодити його в Інтернеті

Відповідне представлення ascii тієї ж програми - 12 символів.

JRx/r{]+rFmJ

Ось як це працює.

JR              range [1 .. x^2] where x=input
  x/            split into subarrays of size x
    r           reverse
     {   F      for each subarray, execute block
      ]+r       concat array, and reverse result
          m     for each row, output ...
           J        each subarray joined by spaces


2

R , 70 59 47 байт

function(n)matrix(1:n^2,n,,T)[c(1:n,n:1)*!0:1,]

Спробуйте в Інтернеті!

Дякую Робіну Райдеру за 4-байтний гольф, який я потім гольфував далі.

Повертає матрицю; будує matrixпослідовність, наприклад [[1 2 3] [4 5 6] [7 8 9]], потім переставляє рядки.


66 байт , уникаючи rbind.
Робін Райдер

@RobinRyder 59 байт - на мобільному пристрої, тому я відредагую це пізніше
Джузеппе


1

Октава , 102 байти

n=input('');A=B=vec2mat(1:n*n,n);i=j=0;do
B(++i,:)=A(++j,:);if++j<n
B(n-i+1,:)=A(j,:);end;until j>=n
B

Спробуйте в Інтернеті!


Приємно! Я не знав, що Октав мав untilкоманду. І я не знав про vec2mat:( На жаль, однакова довжина: A=B=vec2mat(1:(n=input(''))*n,n):(
Стюі Гріффін

while j++<nтеж точно однакової довжини ... Ви випробували різні варіанти чи це просто збіги?
Стюі Гріффін

@StewieGriffin У цьому випадку whileцикл однакової довжини, я спробував це обома способами. Часто do ... untilце один байт коротше while ... end, хоча.
Steadybox

1

C (gcc) , 110 байт

i,c,t,b;f(a,n)int*a;{for(b=n-1;i<n*n;t++,b--){for(c=0;c<n;)a[t*n+c++]=++i;for(c=0;c<n&i<n*n;)a[b*n+c++]=++i;}}

Спробуйте в Інтернеті!

Заповнює масив, чергуючи 2 індекси для рядків: один індекс, що починається вгорі, і один починається внизу. Індекс верхнього ряду починається з 0 і збільшується кожні 2 ряди; індекс нижнього ряду починається з n-1 і зменшується кожні 2 ряди.

Безголівки:

void f(int* a, int n)
{
    //i = value to be written [1,n]; c = column index; t = top row index; b = bottom row index
    for(int i=1, c=0, t=0, b=n-1;
        i <= n*n; //when i = n*n, we have written all the values and we're done
        t++, b--) //t increments every 2 rows, b decrements every 2 rows
    {
        //write out 2 rows per loop

        //first row: fill out row at t
        for(c=0; c<n; c++, i++)
            a[t*n+c]=i;

        //second row: fill out row at b
        //this step will be skipped on the final loop for odd values of n, hence the (i<=n*n) test
        for(c=0; c<n && i<=n*n; c++, i++) 
            a[b*n+c]=i;
    }
}

1

C ++ + Діапазон V3 , 159 байт

#include<range/v3/all.hpp>
using namespace ranges::view;

[](int n){auto r=iota(1,n*n+1)|chunk(n);return concat(r|stride(2),r|reverse|drop(n%2)|stride(2));}

Наживо на Wandbox

Не рахуючи двох нових рядків після using namespace range::view; вони просто там, щоб відокремити імпорт від лямбда.

Помітно цікавий факт: це рішення не дає виділень купу. Це вирішує проблему в O(1)просторі.


Пояснення:

  1. iota(1, n*n+1) -> [1 ... n*n]
  2. chunk(n): всі nелементи разом, так[1 ... n] [n+1 ... 2*n] ...
  3. Назвіть це r
  4. r | stride(2): взяти кожен інший елемент: [1 ... n] [2*n+1...] ...
  5. поєднайте це з:
  6. r | reverse | drop(n % 2): reverse, тоді викиньте [1 ... n]термін if nнепарний (рядок буде непарна кількість, і ми хочемо надрукувати перший термін лише один раз). Здається, я мав би вміти просто робити r | reverse | take, але це чомусь не працює.
  7. stride(2)знову візьміть кожен інший елемент. Цього разу це навпаки.

Більш зрозумілі та перевірені:

#include <range/v3/all.hpp>
using namespace ranges::view;

auto f(int n)
{
    auto rows = iota(1, n * n + 1)
        | chunk(n);
    return concat(
        rows | stride(2),
        rows
            | reverse
            | drop(n % 2)
            | stride(2));
}

#include <iostream>
int main(int argc, char** argv)
{
    std::cout << "N = " << argc << '\n';
    auto res = f(argc);

    for (auto const& row : res | bounded) {
        for (auto const& elem : row | bounded) {
            std::cout << elem << ' ';
        }
        std::cout << '\n';
    }
}

O (log (n)) для зберігання вхідних даних, якщо вимірювати в бітовій складності.
користувач202729

@ user202729 Не впевнений, що ти маєш на увазі. Ви хочете сказати, що для запиту int nмені потрібні log(n)біти для зберігання вхідних даних? Але це все-таки вхід, і ми маємо справу з тим, intде sizeof(int) == 4(більшість систем), тому це постійна кількість байтів, що використовуються незалежно від введення.
Джастін




Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.