Pattern alternato


16

In una domanda stackoverflow ora eliminata, qualcuno ha pubblicato quanto segue:

Scrivi un programma o una funzione per stampare schemi alternati *e in #base a un dato intero n. Qualche esempio:

Ingresso: n=1
Uscita:

*

Ingresso n=5
Uscita:

*####
###**
***##
###**
*####

Ingresso: n=8
Uscita:

*#######
######**
***#####
####****
****####
#####***
**######
#######*

Dal momento che sembrava una bella sfida per giocare a golf, eccolo qui.

Come vengono costruiti questi schemi?

La prima riga inizia con una singola *, seguita dalla n-1quantità di trascinamento #.
La seconda riga ne contiene quindi due *, con n-2quantità di lead #.
La terza riga inizia con tre *, seguita dalla n-3quantità di trascinamento #.
eccetera.

Una volta raggiunto il centro ( n/2), contiamo di nuovo con la quantità di *, che può essere vista negli esempi sopra.

NOTA che per i numeri di input dispari la coppia inversa di righe (quindi prima e ultima; seconda e prossima all'ultima; ecc.) Sono esattamente le stesse. Nel n=5esempio le righe prime e ultime sono *####; la seconda e la penultima riga sono ###**.
Per numeri di input pari, tuttavia, la coppia di righe inversa viene invertita. Nel n=8esempio le righe prime e ultime sono *#######e #######*; la seconda e la penultima riga sono ######**e **######; eccetera.

Regole della sfida:

  • È possibile utilizzare due caratteri stampabili distinti anziché *e #. Puoi usare Ae B; 3e 7; <e >; ecc. Indica nelle risposte cosa hai usato.
  • Puoi presumere nche sarà un numero intero positivo ( >= 1)
  • È consentito produrre un elenco / array di stringhe per ogni riga o una matrice di caratteri 2D, anziché stamparli su STDOUT.

Regole generali:

  • Questo è , quindi vince la risposta più breve in byte.
    Non lasciare che le lingue di code-golf ti scoraggino dal pubblicare risposte con lingue non codegolfing. Prova a trovare una risposta il più breve possibile per "qualsiasi" linguaggio di programmazione.
  • Per la tua risposta valgono regole standard , quindi puoi usare STDIN / STDOUT, funzioni / metodo con i parametri corretti e tipo di ritorno, programmi completi. La tua chiamata.
  • Sono vietate le scappatoie predefinite .
  • Se possibile, aggiungi un link con un test per il tuo codice.
  • Inoltre, si consiglia vivamente di aggiungere una spiegazione per la risposta.

Casi di test (dalla prima n=1alla n=10)

*

*#
#*

*##
#**
*##

*###
##**
**##
###*

*####
###**
***##
###**
*####

*#####
####**
***###
###***
**####
#####*

*######
#####**
***####
###****
***####
#####**
*######

*#######
######**
***#####
####****
****####
#####***
**######
#######*

*########
#######**
***######
#####****
*****####
#####****
***######
#######**
*########

*#########
########**
***#######
######****
*****#####
#####*****
****######
#######***
**########
#########*

" Puoi usare due caratteri distinti invece di * e #. " - Devono essere stampabili? Possiamo usare NUL e SOH (codici ASCII 0 e 1)?
ngn,

@ngn Siamo spiacenti, solo caratteri stampabili. Chiarirà nella descrizione della sfida.
Kevin Cruijssen,

Risposte:


14

Gelatina , 9 byte

>þµoṚUÐeY

Provalo online!

Spiegazione

>þ           Create a table of (x>y) over [1…n]×[1…n]:
               [0 1 1 1 1]
               [0 0 1 1 1]
               [0 0 0 1 1]
               [0 0 0 0 1]
               [0 0 0 0 0]
  µ          Take this array, and...
   oṚ        OR it with its reverse:
               [0 1 1 1 1]
               [0 0 1 1 1]
               [0 0 0 1 1]
               [0 0 1 1 1]
               [0 1 1 1 1]
    UÐe      Apply U (reverse) to even-indexed rows.
       Y     Join by newlines.

17

Python 2 , 62 byte

lambda n:["%*s"%(i%2*2*n-n,"x"*min(i+1,n-i))for i in range(n)]

Provalo online!

Usi xe spazio.

Le righe vengono calcolate in questo modo:

"%-5s" % "x"      == "x    "
"%5s"  % "xx"     == "   xx"
"%-5s" % "xxx"    == "xxx  "
"%5s"  % "xx"     == "   xx"
"%-5s" % "x"      == "x    "

Utilizzando lo %*sspecificatore per scegliere tra ne -n.



6

MATL, 34 31 18 byte

:t!>tPY|!"@X@oQ&P!

Provalo su MATL online

Usa 0 per * e 1 per #. Basato sulla risposta di Lynn Jelly .


Risposta precedente, 31 byte:

2/tk:wXk:Ph"X@ot~XHh@Gy-hHQ&PY"

Provalo su MATL online

Usa 1 per * e 0 per #.

         % implicit input, say 5
2/       % divide input number by 2 [2.5]
tk       % make a copy and floor that [2.5, 2]
:        % create range 1 to the floored value [2.5, [1, 2]]
wXk      % bring out the division result and this time ceil it
         %  [[1, 2], 3]
:        % create range 1 to that [[1, 2], [1, 2, 3]]
Ph       % flip the last array and concatenate horizontally 
         %  [[1, 2, 3, 2, 1]]
"        % loop through the array
  X@o    % Is the current loop index odd? 1 for odd, 0 for even
  t~     % duplicate and logical negate that
  XH     % copy that value to clipboard H
  h      % and concatenate the values ([1 0] on odd iterations, [0 1] on even) 
  @      % push current value from array (say 2, then stack is [[0 1], 2)
  G      % push input again
  y-     % subtract current array value from input [[0 1], 2, 3]
  h      % concatenate those two [[0 1], [2, 3]]
  H      % get the stored value from clipboard H (1 for even iterations, 0 for odd) 
  Q      % increment that
  &P     % flip the array in that dimension: in even iterations, this flips
         %   across columns and hence inverts the two values. [[0 1], [3, 2]]
         %   in odd iterations, it's a no-op
  Y"     % run-length decoding - repeat the element from first array the number of times
         %  specified in the second array
         % implicit loop end, implicit output

6

APL (Dyalog Classic) , 18 byte

a[↑⊢∘⌽\(⊂>⊢⌊⌽)⍳⎕]

Provalo online!

output ABanziché*#

input valutato n

⍳⎕ il vettore 0 1 ... n-1

⊢⌊⌽min ( ) tra loro ( ) e il loro contrario ( ) - vedi i treni

⊂>⊢⌊⌽dove è il vettore nel suo insieme ( ) inferiore a ciascuno dei suoi ⊢⌊⌽- restituisce un vettore di vettori booleani (0/1)

⊢∘⌽\ invertire ogni altro vettore

mescolare in una matrice

⎕al'alfabeto inglese maiuscolo, 'AB...Z'

⎕a[ ]sostituire 0 1con'A' 'B'


Per curiosità. Quanti byte sarebbe semplicemente generare la matrice di 0 e 1 senza spazi? Suppongo che ⎕a[...}convertirli in Ae Bsenza spazi sia più breve di tenerli come 0e 1senza spazi considerando che lo hai usato, ma sono solo curioso di sapere se c'è molta differenza nei byte se li mantieni come 0e 1.
Kevin Cruijssen,

1
@KevinCruijssen Per quanto posso golf, sarebbe della stessa lunghezza - o ⎕d[... ]o ⊃¨⍕¨... Nell'ultima espressione ⍕¨è "formatta ciascuno" - trasforma ogni numero in un vettore di caratteri nidificato , quindi abbiamo bisogno di "prima ciascuno "( ⊃¨) per ottenere solo caratteri scalari (e quindi nessuno spazio bianco durante la stampa).
ngn,

5

Carbone , 21 byte

≔⮌…⁰NθEθ⭆θ›§⟦μλ⟧κ⌊⟦κι

Provalo online! Usi 0e 1. Il collegamento è alla versione dettagliata del codice e include §*#che traduce l'output in *e #nella domanda. Spiegazione:

    N                   Input number
  …⁰                    Range from 0
 ⮌                      Reversed
≔    θ                  Assign to `q`
      Eθ                Map over reversed range
        ⭆θ              Map over reversed range and join
           §⟦μλ⟧κ       Alternate between range and reversed range column
                 ⌊⟦κι   Minimum of range and reversed range row
          ›             Greater
                        Implicitly print each row on its own line

5

Gelatina ,  12  15 byte

+3 correzione n=1del bug del caso limite :(

R«Ṛ$‘r⁸ṬUÐe0YE?

Un programma completo che accetta un numero intero che stampa l'output come definito nell'OP usando 0e 1per *e #rispettivamente.

Provalo online!

Come?

R«Ṛ$‘r⁸ṬUÐe0YE? - Main Link: integer, n
R               - range -> [1,2,3,4,...,n]
   $            - last two links as a monad:
  Ṛ             -   reverse -> [n,...,4,3,2,1]
 «              -   minimum (vectorises) -> [1,2,3,4,...,4,3,2,1]
    ‘           - increment (vectorises) -> [2,3,4,5,...,5,4,3,2]
      ⁸         - chain's left argument, n
     r          - inclusive range (vectorises) -> [[2,3,...,n],[3,4,...n],[4,5,...n],[5,...n],...,[5,...n],[4,5,...n],[3,4,...n],[2,3,...,n]]
       Ṭ        - untruth (vectorises) -> [[0,1,1,...,1],[0,0,1,1,...,1],[0,0,0,1,...,1],[0,0,0,0,1,...,1],...,[0,0,0,0,1,...,1],[0,0,0,1,...,1],[0,0,1,1,...,1],[0,1,1,...,1]]
         Ðe     - apply to entries with even indices:
        U       -   upend              -> [[0,1,1,...,1],[1,1,...,1],[0,0,0,1,...,1],[1,...,1,0,0,0,0],...]
              ? - if...
             E  - ...condition: all equal? (only true when n=1, where we have [1,1])
           0    - ...then: zero
            Y   - ...else: join with newline characters
                - implicit print

Sembra che questo sia esattamente il mio algoritmo, ma un'implementazione diversa che genera 0 invece di 1 e viceversa.
Erik the Outgolfer,

Sì, effettivamente la stessa cosa ... e non avevo aggiornato il mio post per mostrare la correzione che ho fatto.
Jonathan Allan,


4

Java 10, 145 byte

n->{var r=new char[n][n];for(int j=0,k;j<n;++j)for(k=0;k<n;)r[j][k]=k++<(j<n/2?j%2<1?j+1:n+~j:j%2>0?j:n-j)?j%2<1?'*':'#':j%2>0?'*':'#';return r;}

Tutto il ternario lo rende un po 'disordinato, ma funziona benissimo. Ho provato ad appiattire il ciclo nidificato e varie altre cose, ma hanno solo aumentato il conteggio dei byte. Provalo online qui .

Ungolfed:

n -> { // lambda taking an integer as output and returning a char[][]
    var r = new char[n][n]; // the output array; we make use of Java 10's var here (replace with char[][] for another 4 bytes to make this work in Java 8)
    for(int j = 0, k; j < n; ++j) // iterate over the lines
        for(k = 0; k < n; )       // iterate over the j'th line
            r[j][k] = // set the current character
                      k++ < // determine if we're in the first or second portion of the line:
                            (j < n/2 ? // for the first half of the output:
                                 j%2 < 1  // on even lines ...
                                 ? j + 1  // ... print the first symbol j+1 times ...
                                 : n + ~j // ... on odd lines, print it n-j-1 times.
                             : j%2 > 0 ?  // for the second half of the output, on odd lines ...
                                 j :      // ... print the first symbol j times ...
                                 n - j)   // ... on even lines, print it n-j times.
                      ? j%2 < 1 ? '*' : '#'  // for the first part of the line, use '*' on even lines, '#' otherwise
                      : j%2 > 0 ? '*' : '#'; // for the second part of the line, use '*' on odd lines, '#' otherwise
    return r; // return the completed array
}

Java 8 11, 179 127 byte

n->{String r="",a,b;for(int j=0;j<n;b="#".repeat(j<n/2?n+~j:j),r+=(j++%2<1?a+b:b+a)+"\n")a="*".repeat(j<n/2?j+1:n-j);return r;}

Provalo online qui (TIO non ha ancora Java 11, quindi utilizza un metodo personalizzato che determina lo stesso numero di byte di String#repeat()).

Grazie a Kevin Cruijssen per il golf di ben 52 byte!

Ungolfed:

n -> { // lambda taking an int argument and returning a String
    String r = "", // the output String
           a,      // temporary String containing the '*'s
           b;      // temporary String containing the '#'s
    for(int j = 0; j < n; // loop over the lines
        b = "#".repeat( // repeat the '#' character ...
            j < n/2 ? n + ~j // ... n-j-1 times in the first half of the output ...
            : j), // ... j times in the second half
        r += (j++ % 2 < 1 ? a + b : b + a) + "\n") // assemble the j'th line and append it to the output: on even lines, the '*'s go first; on odd lines, the '#'s go first
        a = "*".repeat( // repeat the '*' character ...
              j < n/2 ? j + 1 // ... j+1 times in the first half of the output ...
              : n - j); // n-j times in the second half
    return r; // return the completed output
}

3
Se si passa a Java 11, è possibile giocare a golf a 127 byte utilizzando "*".repeat(...)e "#".repeat(...)(oltre a restituire una stringa invece di stampare direttamente e giocare n-j-1a golf n+~j):n->{String r="",a,b;for(int j=0;j<n;b="#".repeat(j<n/2?n+~j:j),r+=(j++%2<1?a+b:b+a)+"\n")a="*".repeat(j<n/2?j+1:n-j);return r;}
Kevin Cruijssen,

Grazie, è un grande risparmio di byte. Sono riuscito a creare una versione a 145 byte per Java 10 usando loop nidificati - non vedo l'ora del rilascio di Java 11, questo repeat()metodo è davvero bello per giocare a golf.
OOBalance,

4

Lua ,  148  133 byte

function(n)t,a,b={},".","#"for i=1,n do r=i<n/2+1 and i or-~n-i s=a:rep(r)..b:rep(n-r)t[i]=i%2<1 and s:reverse()or s end return t end

Provalo online!

-15 byte grazie a @KevinCruijssen e @JoKing.

function(n)
   t = {}; a = "."; b = "#"          -- initialize variables, output is in table
                                     -- strings are needed in variables for
                                     --   the str:rep and str:reverse syntax

   for i = 1, n do                          -- build the rows of the table
      r = i<=(n+1)/2 and i or n-i+1         -- logic used to count up then down
      str = a:rep(r)..b:rep(n-r)            -- append correct number of '.'s, fill
                                            --   in the rest with '#'s
      t[i]=i%2==0 and str:reverse() or str  -- logic used to control reversing
   end
   return t                                 -- return table
end

2
Non conosco troppo bene Lua, ma sembra che tu possa salvare cinque byte: (n+1)/2a -~n/2; or n-i+1a or-~n-i; i%2==0a i%2<1; e reverse() ora reverse()or. Inoltre, la tua versione TIO e il conteggio dei byte contengono entrambi un punto e virgola finale che non sembra essere necessario. Bella prima risposta, comunque. +1 da me. E benvenuto in PPCG! :)
Kevin Cruijssen il

2
In realtà non hai bisogno di nessuno dei punti e virgola. 133 byte inclusi i suggerimenti di Kevin.
Jo King,

@KevinCruijssen Grazie! Potrei chiedere cosa -~nsta facendo nei tuoi suggerimenti? Funziona sicuramente, ma non capisco perché.
Azure Heights,

1
@AzureHeights Certo. ~è un operatore di negazione bit a bit unario. Ciò che è importante per il codegolfing è che ~iha lo stesso valore di -i-1. Possiamo quindi usare al -~iposto di i+1e ~-iinvece di i-1. Ciò è utile in due casi, che potrei entrambi utilizzare nella tua risposta: sbarazzarsi della parentesi, perché -e ~avere la precedenza dell'operatore su altre operazioni matematiche, quindi (n+1)/2può essere così -~n/2. E l'altra parte utile è sbarazzarsi degli spazi in alcuni casi, come ho fatto io or-~n-i.
Kevin Cruijssen,

1
Ecco i due consigli utili se vuoi leggere qualcosa in più al riguardo: Usa unario ~per x+1ex-1 e Usa unario ~per a-b-1ea+b+1 . Tutti i suggerimenti generali, così come i suggerimenti specifici per la lingua ( Suggerimenti per il golf a Lua in questo caso), potrebbero essere interessanti da leggere. :)
Kevin Cruijssen,




3

C (gcc) , 118 108 byte

Questo non vincerà, ma è un approccio diverso (o almeno lo penso!) Invece di fare manipolazioni di stringhe, faccio uso del fatto che 10X-1 al di sopra di [1 ..n]={9,99,999,...}, che quindi può essere moltiplicato per ottenere il modello appropriato; printf()quindi esegue lo zero-padding per la giustificazione a destra.

Purtroppo, intha solo un intervallo sufficiente per eseguire fino a 9 cifre (su piattaforme a 32 bit), quindi è necessario andare along per schemi più grandi; un linguaggio che fa nativamente l'aritmetica dei parlamentari potrebbe essere in grado di usarlo per qualcosa.

Grazie a ceilingcat per il suggerimento.

h,j,k;p(h){h=h?10*p(--h):1;}f(i){for(j=0,h=i++;k=++j>i/2?i-j:j,j<i;printf("%0*d\n",h,~-p(k)*p(j%2*(h-k))));}

Provalo online!


Prova del concetto che questo funziona con l'aritmetica MP:

C # (compilatore Mono C #) , 187 165 byte

(143 byte + 22 byte per using System.Numerics;l'intestazione)

q=>{var r="";for(int j=0,h=q+1,k;j<q;r+=((BigInteger.Pow(10,k)-1)*BigInteger.Pow(10,j%2*(q-k))).ToString("D"+q)+"\n")k=++j>h/2?h-j:j;return r;}

Provalo online!


1
Prova del concetto con numeri al di fuori degli intervalli di numeri interi nativi massimi (usando C # e BigIntegers): provalo online!
ErikF,

3

Vim, 99 battiture

È sempre interessante provare a fare vim con argomenti di input. È molto innaturale, quindi non sarà incredibilmente breve. Probabilmente ci sono altri buoni approcci a questo.

Si presume che l'input sia da solo in un buffer. Si presume che i registri siano vuoti. Si presume che l'editor sia abbastanza alto da contenere il risultato senza scorrere (ciò potrebbe tecnicamente essere evitato al costo di alcuni tasti).

"nD@ni<cr><esc>MmaGddM
<c-v>'aI*<esc>qwgvjokoI*<esc>@wq@w<esc>
:set ve=all<cr>@nlh<c-v>@nkr#
:%s/ /#/g<cr>o<esc>
2Gqqdt#$p2j0@qq@q

Spiegazione

 | Buffer state (odd and even case):
 | 5                    6

"nD              read input into register n
@ni<cr><esc>     add n newlines
MmaGddM<c-v>'a   visual block select center row(s)
I*<esc>          prepend a column of *
qw               record macro w
  gvjoko         expand selection up and down
  I*<esc>
  @w             recurse
q
@w<esc>          run macro w and exit visual block select

 | Buffer state:
 | *                    *
 | **                   **
 | ***                  ***
 | **                   ***
 | *                    **
 |                      *

:set ve=all<cr>  move anywhere!
@nlh<c-v>@nkr#   add last column of #s

 | Buffer state:
 | *   #                *    #
 | **  #                **   #
 | *** #                ***  #
 | **  #                ***  #
 | *   #                **   #
 |                      *    #

:%s/ /#/g<cr>      replace spaces with #

 | Buffer state:
 | *####                *#####
 | **###                **####
 | ***##                ***###
 | **###                ***###
 | *####                **####
 |                      *#####

o<esc>2G           prep and jump to line 2
qqdt#$p2j0@qq@q    (effectively) flip every other onward

 | Buffer state:
 | *####                *#####
 | ###**                ####**
 | ***##                ***###
 | ###**                ###***
 | *####                **####
 |                      #####*

E in base64, con caratteri effettivi (inserisci input inpute sequenze di tasti keysed esegui usando vim -u NONE -s keys input)

Im5EQG5pDRtNbWFHZGRNFidhSSobcXdndmpva29JKhtAd3FAdxs6c2V0IHZlPWFsbA1AbmxoFkBua3IjOiVzLyAvIy9nDW8bMkdxcWR0IyRwMmowQHFxQHE=

2

R , 75 byte

function(n)outer(1:n,1:n,function(x,y,a=x<y|x>n-y+1)+ifelse(x%%2,a,rev(a)))

Provalo online!

  • Ispirato dalla risposta @Lynn
  • ottenere la funzione ncome parametro e restituire una matrice di 0/1dove 0corrisponde '*'e 1corrisponde'#'

2

K (ngn / k) , 22 byte

{"*#"i|:/'i>/:i&|i:!x}

Provalo online!

{ } funzione con argomento x

!xl'elenco (0;1;...;x-1)

i: assegnato a i

i&|iminima ( &) di ie il suo contrario ( |)

i>/:confronta con maggiore di ( >)i rispetto a ciascun elemento dall'elenco a destra ( /:) - restituisce una matrice booleana (elenco di elenchi)

i|:/'per ogni ( ') j in i, reverse ( |:- abbiamo bisogno :di forzare |per essere unari) l'elemento corrispondente j volte ( n f/ xapplica i f ntempi sux ). Effettivamente, inverti ogni altra riga.

"*#" usa gli elementi della matrice come indici nella stringa "*#"

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.