Stampa un opuscolo


39

Leggere un libro è facile, ma stampare un libro può essere un po 'complicato. Quando si stampa un opuscolo, la stampante deve disporre le pagine in un certo modo per poter essere letta da sinistra a destra. Il modo in cui ciò viene fatto è utilizzare uno schema come di seguito

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…

Casi test

Opuscolo di 4 pagine: 4, 1, 2, 3

Opuscolo di 8 pagine: 8,1,2,7,6,3,4,5

Opuscolo di 12 pagine: 12,1,2,11,10,3,4,9,8,5,6,7

Opuscolo di 16 pagine: 16,1,2,15,14,3,4,13,12,5,6,11,10,7,8,9

Opuscolo di 20 pagine: 20,1,2,19,18,3,4,17,16,5,6,15,14,7,8,13,12,9,10,11

Compito

Il tuo compito è, dato un numero intero nche è un multiplo di 4, visualizzare una matrice di numeri che potrebbero essere utilizzati per stampare un libro din pagine.

Nota: finché l'output genera i numeri corretti, delimitati da spazi, virgole, trattini o parentesi, è possibile utilizzare qualsiasi metodo per arrivare a una soluzione

Questa è una domanda di quindi le risposte verranno classificate in byte, con il minor numero di byte vincenti.


Abbiamo la garanzia che l'input sarà sempre divisibile per 4 o anche per un numero pari? Ad ogni modo, potresti aggiungere qualche altro test case, per favore? E benvenuto in PPCG :)
Shaggy,

8
Benvenuti in PPCG e bella prima sfida! Ti consigliamo di proporre nuove sfide nella sandbox prima di pubblicarle.
Oliver Ni,

1
Il tuo input deve essere un multiplo di 4
tisaconundrum,

1
Sarebbe bello (ma forse banale) supportare qualsiasi valore, riempiendo di pagine vuote se necessario (un'altra sfida, forse?)
Barranka

1
È possibile delimitare l'array con uno spazio, un trattino o un altro delimitatore anziché una virgola?
TehPers,

Risposte:


8

05AB1E , 9 8 7 byte

L`[Žˆrˆ

Provalo online!

Spiegazione

L           # push range [1 ... input]
 `          # split as separate to stack
  [Ž        # loop until stack is empty
    ˆ       # add top of stack to global list
     r      # reverse stack
      ˆ     # add top of stack to global list
            # implicitly display global list

13

JavaScript (ES6), 49 45 byte

Salvato 4 byte con l'aiuto di @RickHitchcock

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

dimostrazione


Non ricorsivo, 51 byte

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

dimostrazione


47 byte: f=(n,a=1)=>n<a+3?[]:[n,a,a+1,n-1,...f(n-2,a+2)]
Rick Hitchcock,

1
@RickHitchcock n<aè effettivamente abbastanza, quindi sono 4 byte salvati. Grazie!
Arnauld,

6

Python 2, 99 93 88 58 56 55 byte

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

Provalo online!

-6 byte rimuovendo il rientro non necessario, grazie Oliver Ni

-5 byte modificando il condizionale, grazie Luis Mendo

-30 byte ottimizzando le dichiarazioni di stampa, grazie Arnold Palmer

-2 byte mettendo il loop su una riga, grazie nedla2004

-1 byte facendo un po 'di magia, grazie Mr. Xcoder


Salva byte utilizzando 1 spazio anziché 4.
Oliver Ni

Oh sì, me ne dimentico sempre. Grazie.
Lirico

1
-29 byte usando a lambda(anche se questo potrebbe essere abbastanza diverso da giustificare una risposta separata).
Notjagan,

@notjagan Vai avanti e pubblicalo tu stesso, se lo desideri.
Lirico

58 byte modificando leggermente la stampa. Ora stampa f-i+1,i,i+1,f-iin ogni ciclo invece di stampare condizionalmente l'ultimo valore. Ciò ha anche permesso di rimuovere l'iniziale print f,.
Arnold Palmer,

6

Python 2 , 46 byte

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

Provalo online!

Genera la gamma [1..n]e si apre dalla parte anteriore e posteriore nel motivo ripetutoback, front, front, back, ...


Python 2 , 49 byte

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

Provalo online!

Genera i primi 4 elementi, quindi continua in modo ricorsivo con il valore superiore ndiminuito di 2 e il valore inferiore kaumentato di 2.


Python 2 , 49 byte

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

Provalo online!

Genera direttamente il i'valore dell'elenco, usando -i%4/2come un valore booleano per prendere il valore più basso o più alto.



5

MATL , 19 17 10 byte

:t"0&)@o?P

Provalo online!

Spiegazione

:          % 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

Gelatina ,  12  11 byte

Migliorato a 11 byte, "Metodi combinatori":

9Bṁ×ḶṚÆ¡‘Œ?

Provalo online!

Come?

Questo utilizza calcoli di permutazione e il sistema numerico fattoriale:

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 byte non migliorato, "Knitting Patterns":

RṚ‘żRs2Z€FḊṁ

Provalo online!

Come?

Questo è l'approccio semplice, crea due fili, li interfoglia e quindi taglia le estremità libere:

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]

Questo è intelligente. +1
Erik the Outgolfer

4

Ottava , 43 36 byte

Una porta di questa risposta in C (gcc) può essere trovata qui .

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

Spiegazione

  1. k=1:2:n/2: Genera una sequenza lineare da 1 a n/2 in passaggi di 2. Notare che questo viene immediatamente utilizzato nel passaggio successivo.
  2. [n-k+1;k;k+1;n-k]: Crea una matrice di 4 righe in modo tale che la prima riga crei la sequenza n, n-2, n-4...fino a n-(n/2)+2, la seconda riga sia 1, 3, 5...fino a n/2 - 1, la terza riga sia la seconda riga aggiunta da 1 e la quarta riga sia la prima riga aggiunta da 1.
  3. [n-k+1;k;k+1;n-k](:)': Questo impila tutte le colonne di questa matrice insieme da sinistra a destra per creare un vettore di singola colonna e lo trasponiamo in un vettore di riga per una facile visualizzazione. Impilando le colonne in questo modo si crea esattamente la sequenza desiderata.

Nota che questa è una funzione anonima, quindi puoi assegnarla a una variabile prima di usarla, oppure puoi usare il built-in ans variabile che viene creata dopo aver creato la funzione.

Provalo online!


1
Ciao, penso che puoi anche accorciarlo rendendolo una funzione anonima, quindi non devi chiamare l'input. Vedi questo link: gnu.org/software/octave/doc/v4.0.3/…
Michthan

1
@Michthan True. Inizialmente l'ho fatto in quel modo perché il codice era più di un'istruzione. Ho fatto un altro crack, quindi rimuovi la chiamata inpute ho abusato un po 'di più la sintassi memorizzando il vettore incrementale di base mentre stavo creando la prima riga e prendendo l'inputn dall'effettivo input della funzione anonima in modo che ora possa adattarlo una dichiarazione. Grazie!
rayryeng - Ripristina Monica il

3

R , 48 byte (migliorato)

Grazie a @Giuseppe per -7 byte!

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

Il trucco x=1:n;x[order(x%%2)]è equivalente a order(1:n%%2).

Provalo online!

R , 55 byte (originale)

golfed

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

Non rigato di commenti

Leggi nda stdin.

n=scan()

Definire xcome sequenza di pagine da 1 a n.

x=1:n

Ordina le pagine in modo che anche le pagine siano prima delle pagine irregolari.

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

Ordinare le pagine in ordine decrescente rispetto al centro del libro calcolato da n/2+.5 .

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

Esempio con 8 pagine:

  • il centro è 4.5;
  • le pagine 1 e 8 sono le più distanti dal centro, ma 8 viene prima perché 8 è pari;
  • le pagine 2 e 7 sono le più distanti dal centro, ma 2 viene prima come 2 è pari;
  • e così via.

Provalo online!


1
bello, molto meglio della mia soluzione (rubata)
Giuseppe


1
Il trucco stava notando che (1:n)[order(1:n%%2)]è lo stesso diorder(1:n%%2)
Giuseppe,

2

Mathematica, 54 53 45 byte

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

Spiegazione

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 byte

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

o

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

-12 byte grazie al commento di @TheLethalCoder sulla risposta C #.

Vecchia risposta (84 byte):

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;}

Spiegazione:

Provalo qui.

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

Swift 3 , 74 byte

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

Provalo online!

Swift 3 , 60 byte

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

Per qualche motivo, questo non funziona in nessun ambiente online che ho provato finora. Se vuoi provarlo, mettilo var g=di fronte e chiamalo con print(g(12))in Xcode (Playgrounds) .

Ecco un'immagine dopo averla eseguita in un parco giochi Xcode, versione 8.3.1 (Running Swift 3.1):

enter image description here


1

QBIC , 25 byte

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

Sebbene l'ingresso sia% 4, il ritmo effettivo è basato su 2.

Spiegazione

[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

cQuents , 21 byte

=n::n-z+1,z+1,x-1,z-1

Provalo online!

Spiegazione

                            Implicit input n
=n                          First item in the sequence is n
  ::                        Mode :: (Sequence 2): print sequence from 1 to n
                            Comma delimited items are rotated through
    n-z+1,                    n - previous + 1
          z+1,                previous + 1
              x-1,            third-previous - 1
                  z-1         previous - 1

1

R , 64 60 byte

Devastamente superato da djhurio ! La sua risposta è piuttosto elegante, va votata.

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

Una risposta Octave di un porto di rayryeng .

Provalo online!

soluzione originale (64 byte):

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

Funzione ricorsiva.

Provalo online!


La prima volta che qualcuno ha mai usato una mia risposta come ispirazione. Grazie :)
rayryeng - Ripristina Monica il

1
È stato difficile batterti , ma ci sono riuscito con una risposta di 55 byte ( codegolf.stackexchange.com/a/138045/13849 ).
djhurio,

1

Bash + Perl + Groff + Psutils, 48 ​​byte

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

Mostra l'output attivato stderr . L'output contiene alcuni rifiuti finali.

Esempio di utilizzo:

$ 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 byte

sm[hK-QddhdK):1/Q2 2

Test Suite.

Se l'output come elenco nidificato è consentito:

Pyth , 20 19 byte

m[hK-QddhdK):1/Q2 2

Test Suite.


Spiegazione

sm [hK-QddhdK): 1 / Q2 2 - Programma completo.

 m: 1 / Q2 2 - Mappa su intervallo (1, input () / 2,2) con una variabile d.
  [) - Costruisci un elenco con:
   hK-Qd - Ingresso - d + 1,
        d - d,
         hd - d + 1 e
           K - Ingresso - d.
s - Appiattisce l'elenco e stampa in modo implicito.


0

C #, 107 byte

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;}

Mantieni due segnalini, uno a partire da 1, uno a pag. In ogni iterazione del ciclo, scrivi quattro elementi e incrementa o decrementa i contatori dopo ogni voce. Quando i segnalini si incontrano nel mezzo, fermati.

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;
}

È possibile salvare alcuni byte inserendo il metodo in un delegato. Il tuo codice sarebbe quindi simile al seguente:, 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;};con il System.Func<int, int[]> f =non avere incluso nel bytecount. Inoltre puoi aggiungere un link a TIO, che è molto utile quando cerchi di consentire alle persone di provare il tuo codice da soli!
Ian H.

@IanH. Quando si utilizza un lambda, i semi-punti finali possono essere omessi.
TheLethalCoder

Inizializza qper 0e pre incremento a q<p-> ++q<pe poi togliere il secondo incremento postale per salvare un byte. Spostare le due istruzioni del ciclo finale nell'ultima fase del ciclo for in modo da poter rimuovere le parentesi graffe.
TheLethalCoder

2
Se è consentita una virgola finale, il seguente funziona per 71 byte p=>{for(int q=0;++q<p;)System.Console.Write(p--+$",{q++},{q},{p--},");}. TIO.
TheLethalCoder


0

Pyth, 27 24 23 bytes

-3 byte stampando in tutto anziché alla fine.

-1 Grazie a Mr. Xcoder

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

Provalo online!

O sul compilatore / esecutore online

Questo è il mio primo vero programma in Pyth, quindi probabilmente ci sono metodi migliori che non conosco.

Spiegazione

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)

Ho trovato alcuni miglioramenti e ho deciso che meritavano la propria risposta.
Mr. Xcoder,

A proposito, sostituisci FNcon Vper -1 byte
Mr. Xcoder

0

C ++ (gcc) , 89 84 68 byte

Come lambda generico senza nome. nè #pages (% 4 == 0) ed Cè un parametro di riferimento per il risultato, un contenitore vuoto come vector<int>( push_backè necessario solo ).

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

soluzione precedente:

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

Provalo online!

Leggermente non golfato:

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

soluzione precedente leggermente non golfata :

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

È stato sviluppato in modo piuttosto semplice e ci sono alcune ottimizzazioni minori nell'aritmetica.

  • Edit1: unificazione dell'aritmetica salvata 5 byte
  • Edit2: dopo l'unificazione i 4 passaggi sono stati combinati

Uso:

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

Variante di stampa, 77 byte non aggiornati

Se si insiste sulla stampa dei valori, esiste questa soluzione:

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

Dove osi desidera std::ostream, comestd::cout

Utilizzo (se è stato assegnato il 2 ° lambda g):

g(n, std::cout);

0

Lisp comune, 79 byte

(defun f(n &optional(k 1))(and(> n k)`(,n,k,(1+ k),(1- n),@(f(- n 2)(+ k 2)))))

Provalo online!


0

Lua, 94 byte

Per questa sfida in realtà ho escogitato 2 metodi diversi che sono entrambi 94 byte.

Metodo 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

Codice commentato:

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

Metodo 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

Questo metodo è simile al primo, tuttavia restituisco invece una stringa concatenata anziché string.format ()

In entrambi i metodi ho usato il concetto di n e mi sto avvicinando di più


0

PHP, 51 + 1 byte

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

stampa i numeri di pagina separati da un trattino basso con un delimitatore finale.
Esegui come pipe -nRo provalo online .


0

J , 22 byte

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

Provalo online!

Spiegazione

($,)_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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.