Роздрукуйте буклет


39

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

n, 1, 2, n-1, n-2, 3, 4, n-3, n-4, 5, 6, n-5, n-6, 7, 8, n-7, n-8, 9, 10, n-9, n-10, 11, 12, n-11…

Випробування

4 сторінки буклет: 4, 1, 2, 3

8 сторінок буклета: 8,1,2,7,6,3,4,5

12 сторінок буклета: 12,1,2,11,10,3,4,9,8,5,6,7

16 сторінок буклета: 16,1,2,15,14,3,4,13,12,5,6,11,10,7,8,9

20 сторінок буклета: 20,1,2,19,18,3,4,17,16,5,6,15,14,7,8,13,12,9,10,11

Завдання

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

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

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


Ми гарантуємо, що вхід завжди буде розділений на 4 або навіть парне число? У будь-якому випадку, чи можете ви додати ще кілька тестових випадків? І ласкаво просимо до PPCG :)
Shaggy

8
Ласкаво просимо до PPCG та приємного першого виклику! Зауважте, що ми рекомендуємо запропонувати нові завдання в пісочниці перед публікацією.
Олівер Ні

1
Ваше введення повинно бути кратним 4
tisaconundrum

1
Було б приємно (але, можливо, тривіально) підтримати будь-яке значення, заповнивши порожні сторінки, якщо потрібно (інший виклик, можливо?)
Barranka

1
Чи можемо ми розмежувати масив пробілом, дефісом чи іншим роздільником, а не комою?
TehPers

Відповіді:



13

JavaScript (ES6), 49 45 байт

Збережено 4 байти за допомогою @RickHitchcock

f=(n,k=1)=>n<k?[]:[n,k,k+1,n-1,...f(n-2,k+2)]

Демо


Нерекурсивний, 51 байт

n=>[...Array(n)].map((_,i)=>[2*n-i,,++i][i&2]+1>>1)

Демо


47 байт: f=(n,a=1)=>n<a+3?[]:[n,a,a+1,n-1,...f(n-2,a+2)]
Рік Хічкок

1
@RickHitchcock n<aнасправді достатньо, тому це збережено 4 байти. Спасибі!
Арнольд

6

Python 2, 99 93 88 58 56 55 байт

f=input()
for i in range(1,f/2,2):print-~f-i,i,i+1,f-i,

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

-6 байт, видаливши непотрібні відступи, завдяки Оліверу Ні

-5 байт, змінивши умовне, завдяки Луїсу Мендо

-30 байт шляхом оптимізації друкованих висловлювань, завдяки Арнольду Палмеру

-2 байти, поставивши цикл на одну лінію, спасибі nedla2004

-1 байт, зробивши трохи чарівництва, дякую містеру Xcoder


Збережіть байти, використовуючи 1 пробіл замість 4.
Олівер Ні

О так, я завжди про це забуваю. Спасибі.
LyricLy

1
-29 байтів із використанням lambda(хоча це може бути досить різним, щоб вимагати окремої відповіді).
notjagan

@notjagan Попередньо і опублікуй це, якщо хочеш.
LyricLy

58 байт , трохи змінивши друк. Тепер він друкує f-i+1,i,i+1,f-iу кожному циклі замість умовного друку останнього значення. Це також дозволило видалити початкове print f,.
Арнольд Палмер

6

Python 2 , 46 байт

lambda n:map(range(1,n+1).pop,n/4*[-1,0,0,-1])

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

Створює діапазон [1..n]і спливає спереду і ззаду у повторюваному малюнкуback, front, front, back, ...


Python 2 , 49 байт

f=lambda n,k=1:n/k*[0]and[n,k,k+1,n-1]+f(n-2,k+2)

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

Створює перші 4 елементи, потім рекурсивно продовжує верхнє значення, nзменшене на 2, а нижнє значення kзбільшується на 2.


Python 2 , 49 байт

lambda n:[[n-i/2,i/2+1][-i%4/2]for i in range(n)]

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

Безпосередньо генерує i'-те значення списку, використовуючи -i%4/2булеве значення для того, приймати нижнє або вище значення.



5

MATL , 19 17 10 байт

:t"0&)@o?P

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

Пояснення

:          % Implicitly input n. Push range [1 2 ... n]
t          % Duplicate
"          % For each (that is, do n times)
  0&)      %   Push last element, and then subarray with remaining elements
  @        %   Push 1-based iteration index
  o?       %   Is it odd? If so
    P      %     Reverse subarray of remaining elements
           %   Implicit end
           % Implicit end
           % Implicitly display stack

5

Желе ,  12  11 байт

Удосконалено до 11 байт, "Комбінаторні методи":

9Bṁ×ḶṚÆ¡‘Œ?

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

Як?

Для цього використовуються розрахунки перестановки та система числення фактичних даних:

9Bṁ×ḶṚÆ¡‘Œ? - Link n                        e.g. 16
9B          - nine in binary                     [1,0,0,1]
  ṁ         - mould like n                       [1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1]
    Ḷ       - lowered range(n)                   [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
   ×        - multiply                           [0,0,0,3,4,0,0,7,8,0,0,11,12,0,0,15]
     Ṛ      - reverse                            [15,0,0,12,11,0,0,8,7,0,0,4,3,0,0,0]
      Æ¡    - convert from factorial base        19621302981954 (=15*15!+12*12!+...+3*3!)
        ‘   - increment                          19621302981955 (we actually wanted 1*0! too)
         Œ? - shortest permutation of natural numbers [1,2,...] that would reside at that
            -   index in a sorted list of all permutations of those same numbers
            -                                    [16,1,2,15,14,3,4,13,12,5,6,11,10,7,8,9]

Неперевершений 12 байт, "В'язання шаблонів":

RṚ‘żRs2Z€FḊṁ

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

Як?

Це простий підхід, він створює дві нитки, переплітає їх і потім обрізає вільні кінці:

RṚ‘żRs2Z€FḊṁ - Link: n                      e.g. 8
R            - range(n)                          [1,2,3,4,5,6,7,8]
 Ṛ           - reverse                           [8,7,6,5,4,3,2,1]
  ‘          - increment                         [9,8,7,6,5,4,3,2]
    R        - range(n)                          [1,2,3,4,5,6,7,8]
   ż         - zip (interleave)                  [[9,1],[8,2],[7,3],[6,4],[5,5],[4,6],[3,7],[2,8]]
     s2      - split into chunks of length 2     [[[9,1],[8,2]],[[7,3],[6,4]],[[5,5],[4,6]],[[3,7],[2,8]]]
       Z€    - transpose €ach (cross-stitch?!)   [[[9,8],[1,2]],[[7,6],[3,4]],[[5,4],[5,6]],[[3,2],[7,8]]]
         F   - flatten                           [9,8,1,2,7,6,3,4,5,4,5,6,3,2,7,8]
          Ḋ  - dequeue (removes excess start)    [8,1,2,7,6,3,4,5,4,5,6,3,2,7,8]
           ṁ - mould like n (removes excess end) [8,1,2,7,6,3,4,5]

Це є розумним. +1
Ерік Аутгольфер

4

Октава , 43 36 байт

Порт цієї відповіді в C (gcc) можна знайти тут .

@(n)[n-(k=1:2:n/2)+1;k;k+1;n-k](:)';

Пояснення

  1. k=1:2:n/2: Створює лінійну послідовність від 1 до n/2кроків 2. Зауважте, що це негайно використовується на наступному кроці.
  2. [n-k+1;k;k+1;n-k]: Створює 4-ма рядкову матрицю таким чином, що перший рядок створює послідовність n, n-2, n-4...вниз n-(n/2)+2, другий рядок - 1, 3, 5...до n/2 - 1, третій ряд - другий рядок, доданий 1, а четвертий - перший рядок, доданий 1.
  3. [n-k+1;k;k+1;n-k](:)': Це укладає всі стовпці цієї матриці разом зліва направо, щоб зробити один векторний стовпець, і ми переносимо його у векторний рядок для зручного відображення. Складання стовпців разом таким чином точно створює бажану послідовність.

Зауважте, що це анонімна функція, тому ви можете призначити її змінній перед її використанням, або ви можете використовувати вбудовану ansзмінну, яка створюється після створення функції.

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


1
Привіт, я думаю, що ви навіть можете скоротити його, зробивши це анонімною функцією, тому вам не потрібно дзвонити на введення. Дивіться це посилання: gnu.org/software/octave/doc/v4.0.3/…
Міхтан

1
@Michthan True. Я спочатку робив це так, бо код був не одним твердженням. Я взяв ще одну тріщину на ньому, тому видаліть виклик, inputі я трохи більше зловживав синтаксисом, зберігаючи базовий інкрементальний вектор, коли я створював перший рядок і приймав вхід nз власне вводу анонімної функції, щоб тепер я міг його вписати одне твердження. Спасибі!
rayryeng

3

R , 48 байт (покращено)

Дякуємо @Giuseppe за -7 байт!

n=scan();(x=order(1:n%%2))[order(-(n/2+.5-x)^2)]

Хитрість у тому, що x=1:n;x[order(x%%2)]еквівалентно order(1:n%%2).

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

R , 55 байт (оригінал)

Гольф

n=scan();x=1:n;x=x[order(x%%2)];x[order(-(n/2+.5-x)^2)]

Безголовка з коментарями

Читайте nз stdin.

n=scan()

Визначте xяк послідовність сторінок від 1 до n.

x=1:n

Замовляйте сторінки так, що рівні сторінки є перед нерівними.

x=x[order(x%%2)]

Порядок впорядковуйте у порядку зменшення по відношенню до центру книги, обчисленої n/2+.5.

x[order(-(n/2+.5-x)^2)]

Приклад з 8 сторінок:

  • центр - 4,5;
  • сторінки 1 і 8 є найбільш віддаленими від центру, але 8 приходить першим, оскільки 8 є рівним;
  • сторінки 2 і 7 - наступні найбільш віддалені від центру, але 2 виходять першими, оскільки 2 є рівними;
  • і так далі.

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


1
приємно, набагато краще, ніж моє (вкрадене) рішення
Джузеппе


1
Трюк помітив, що (1:n)[order(1:n%%2)]це те саме, щоorder(1:n%%2)
Джузеппе

2

Математика, 54 53 45 байт

Join@@Range[#][[(-1)^k{k,-k}]]~Table~{k,#/2}&

Пояснення

Join@@Range[#][[(-1)^k{k,-k}]]~Table~{k,#/2}&  (* Input: # *)
                              ~Table~{k,#/2}   (* Iterate from k=1 to #/2 *)
      Range[#][[            ]]                 (* From {1..#}, take... *)
                      {k,-k}                   (* k-th and negative k-th element *)
                                               (* negative k-th = k-th from the end *)
                (-1)^k                         (* Reversed for odd k *)
Join@@                                         (* Join the result *)



2

Java 8, 84 72 байти

n->{for(int j=0;++j<n;System.out.printf("%d,%d,%d,%d,",n--,j++,j,n--));}

або

n->{for(int j=0;++j<n;System.out.print(n--+","+j+++","+j+","+n--+","));}

-12 байт завдяки @TheLethalCoder коментарю щодо відповіді C #.

Стара відповідь (84 байти):

n->{int r[]=new int[n],i=1,N=n,J=1;for(r[0]=n;i<n;r[i]=-~i++%4<2?J++:--N);return r;}

Пояснення:

Спробуйте тут.

n->{                  // Method with integer parameter and no return-type
  for(int j=0;++j<n;  //  Loop from 1 to `n` (exclusive)
    System.out.printf("%d,%d,%d,%d,",n--,j++,j,n--)
                      //   Print four numbers simultaneously
  );                  //  End of loop
}                     // End of method


1

Швидкий 3 , 74 байти

func g(f:Int){for i in stride(from:1,to:f/2,by:2){print(f-i+1,i,i+1,f-i)}}

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

Швидкий 3 , 60 байт

{f in stride(from:1,to:f/2,by:2).map{(f-$0+1,$0,$0+1,f-$0)}}

Чомусь це не працює в жодному інтернет-середовищі, яке я намагався поки що. Якщо ви хочете перевірити його, поставте його var g=перед собою та зателефонуйте print(g(12))в Xcode (Playgrounds) .

Ось малюнок після того, як я запустив його на ігровий майданчик Xcode, версія 8.3.1 (Running Swift 3.1):

введіть тут опис зображення


1

QBIC , 25 байт

[1,:/2,2|?b-a+1,a,1+a,b-a

Хоча вхід становить% 4, фактичний ритм базується на 2.

Пояснення

[1,:/2,2|   FOR ( b=1; b <= <input>/2; b=b+2)               
?           PRINT
 b-a+1,     n
 a,         1
 1+a,       2
 b-a        n-1



1

R , 64 60 байт

Джуріо згубно перевершив ! Його відповідь досить елегантна, підкресліть її.

n=scan();matrix(c(n-(k=seq(1,n/2,2))+1,k,k+1,n-k),4,,T)[1:n]

Відповідь Октави на порт Рейріенга .

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

оригінальне рішення (64 байти):

f=function(n,l=1:n)`if`(n,c(l[i<-c(n,1,2,n-1)],f(n-4,l[-i])),{})

Рекурсивна функція.

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


Перший раз хтось коли-небудь використовував мою відповідь як натхнення. Дякую :)
rayryeng

1
Тебе важко було перемогти, але мені вдалося це відповісти 55 байтами ( codegolf.stackexchange.com/a/138045/13849 ).
djhurio

1

Bash + Perl + Groff + Psutils, 48 ​​байт

perl -nE'say".bp
"x--$_'|groff|psbook>/dev/null

Показує вихід увімкнено stderr. Вихідні дані містять трохи сміття.

Приклад використання:

$ echo 20 | perl -nE'say".bp
> "x--$_'|groff|psbook>/dev/null
[20] [1] [2] [19] [18] [3] [4] [17] [16] [5] [6] [15] [14] [7] [8] [13] [12] 
[9] [10] [11] Wrote 20 pages, 4787 bytes

0

Pyth , 21 20 байт

sm[hK-QddhdK):1/Q2 2

Тестовий сюїт.

Якщо дозволено виведення у вигляді вкладеного списку:

Pyth , 20 19 байт

m[hK-QddhdK):1/Q2 2

Тестовий сюїт.


Пояснення

sm [hK-QddhdK): 1 / Q2 2 - Повна програма.

 m: 1 / Q2 2 - Мапа за діапазоном (1, вхід () / 2,2) зі змінною d.
  [) - Створіть список за допомогою:
   hK-Qd - Введення - d + 1,
        d - d,
         hd - d + 1 і
           К - Вхід - d.
s - розгладжує список і друкується неявно.


0

C #, 107 байт

int[]F(int p){var a=new int[p];for(int i=0,q=1;q<p;a[i++]=p--){a[i++]=p--;a[i++]=q++;a[i++]=q++;}return a;}

Тримайте два лічильника, один починаючи з 1, один - на p. У кожну ітерацію циклу після кожного запису впишіть чотири елементи та лічильники збільшення або зменшення. Коли лічильники зустрічаються посередині, зупиніться.

int[] F(int p)
{
    var a = new int[p];
    for(int i = 0, q = 1; q < p; a[i++] = p--)
    {
        a[i++] = p--;
        a[i++] = q++;
        a[i++] = q++;
    }
    return a;
}

Ви можете зберегти кілька байтів, помістивши метод в делегат. Ваш код буде виглядати наступним чином : p=>{var a=new int[p];for(int i=0,q=1;q<p;a[i++]=p--){a[i++]=p--;a[i++]=q++;a[i++]=q++;}return a;};, з System.Func<int, int[]> f =не маючи включений в ByteCount. Також ви можете додати посилання на TIO, що дуже корисно, намагаючись дозволити людям самостійно перевіряти ваш код!
Ян Х.

@IanH. При використанні лямбда може бути опущена крапка з двокрапкою.
TheLethalCoder

Ініціалізуйте qдо 0та попереднє збільшення на q<p->, ++q<pа потім видаліть приріст другого повідомлення, щоб зберегти байт. Перемістіть два заяви контуру в останню стадію циклу for, щоб ви могли зняти фігурні дужки.
TheLethalCoder

2
Якщо дозволена кома, слід виконати наступні дії на 71 байт p=>{for(int q=0;++q<p;)System.Console.Write(p--+$",{q++},{q},{p--},");}. ТІО.
TheLethalCoder


0

Піта , 27 24 23 байт

-3 байти, друкуючи по всьому, а не в кінці.

-1 Дякую містеру Xcoder

V:1/Q2 2pjd[-QtNNhN-QNk

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

Або на онлайн-компіляторі / виконавцю

Це моя перша реальна програма в Pyth, тому, мабуть, є кращі методи, про які я не знаю.

Пояснення

V:1/Q2 2pjd[-QtNNhN-QNk
V:1/Q2 2                   # For N in range(1, Q/2, 2):
        pjd                # print " ".join(...),
           [-QtNNhN-QNk    # The list [n - (N-1), N, N + 1, n - N, ""] (n is input)

Я знайшов деякі вдосконалення і вирішив, що вони заслужили власну відповідь.
Містер Xcoder

До речі, замінити FNз Vна -1 байт
г -

0

C ++ (gcc) , 89 84 68 байт

Як безіменна родова лямбда. nє #сторінок (% 4 == 0) і Cє еталонним параметром для результату, порожнім контейнером на зразок vector<int>( push_backпотрібен лише ).

[](int n,auto&C){for(int i=0,j=0;i<n;C.push_back(++j%4<2?n--:++i));}

попереднє рішення:

#define P C.push_back(
[](int n,auto&C){for(int i=0;i<n;P n--),P++i),P++i),P n--));}

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

Трохи незворушений:

auto f=
[](int n,auto&C){
 for(int i=0,j=0;
     i<n;
     C.push_back(++j%4<2 ? n-- : ++i));
}

попереднє рішення злегка не злетіло :

auto f=
[](int n, auto&C){
 for(
  int i=0;
  i<n;
   P n--),
   P++i),
   P++i),
   P n--)
 );
}
;

Це було досить просто розроблено і є певні незначні оптимізації в арифметиці.

  • Edit1: уніфікація арифметики зберегла 5 байт
  • Edit2: після об'єднання 4 етапи об'єднали

Використання:

std::vector<int> result;
f(n, result);

Версія для друку, застаріла 77 байт

Якщо ви наполягаєте на друкуванні значень, є таке рішення:

[](int n,auto&o){for(int i=0;i<n;o<<n--<<' '<<++i<<' '<<++i<<' '<<n--<<' ');}

Де oтвоє бажане std::ostream, якstd::cout

Використання (якщо було призначено 2-е лямбда g):

g(n, std::cout);


0

Луа, 94 байти

Для цього завдання я насправді придумав 2 різні методи, які є обома 94 байтами.

Спосіб 1:

function f(n,i)i=i or 1 return n>i and('%s,%s,%s,%s,%s'):format(n,i,i+1,n-1,f(n-2,i+2))or''end

Коментований код:

function f(n,i)
  i=i or 1
  -- On the first iteration i will be nil so I'm setting it's value to 1 if it is.

  return n>i and ('%s,%s,%s,%s,%s'):format(n,i,i+1,n-1,f(n-2,i+2)) or ''
  -- Here i return a ternary statement
  -- If n>i is true, it will return a string using string.format() and part of this is recursion
  -- If it's false, it will just return an empty string
end

Спосіб 2:

function f(n,i)i=i or 1 return n>i and n..','..i..','..i+1 ..','..n-1 ..','..f(n-2,i+2)or''end

Цей спосіб схожий на перший метод, однак я замість цього повертаю об'єднаний рядок замість string.format ()

В обох методах я використав поняття n і я зближуючись


0

PHP, 51 + 1 байт

while($i<$k=&$argn)echo$k--,_,++$i,_,++$i,_,$k--,_;

друкує номери сторінок, розділених підкресленням із знаком розмежування.
Запустіть як трубу -nRабо спробуйте в Інтернеті .


0

J , 22 байти

($,)_2|.`]\1+],@,.&i.-

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

Пояснення

($,)_2|.`]\1+],@,.&i.-  Input: integer n
             ]          Identity
                     -  Negate
                  &i.   Form the ranges [0, 1, ..., n-1] and [n-1, ..., 1, 0]
                ,.      Interleave
              ,@        Flatten
           1+           Add 1
    _2    \             For each non-overlapping sublist of size 2
        `                 Cycle between these two operations
      |.                    Reverse for the first, third, ...
         ]                  Identity for the second, fourth, ...
  ,                     Flatten
 $                      Reshape to length n
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.