Motif alterné

16

Dans une question de stackoverflow maintenant supprimée, quelqu'un a publié ce qui suit:

Écrivez un programme ou une fonction pour imprimer des motifs alternatifs dans *et #sur la base d'un entier donné n. Quelques exemples:

Entrée: n=1
Sortie:

*

n=5
Sortie d' entrée :

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

Entrée: n=8
Sortie:

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

Comme cela ressemblait à un défi de golf de code assez cool, le voici.

Comment ces modèles sont-ils construits?

La première ligne commence par un simple *, suivi par la n-1quantité de fin #.
La deuxième ligne en contient alors deux *, avec une n-2quantité de interligne #.
La troisième ligne commence par trois *, suivie par la n-3quantité de fuite #.
etc.

Une fois que nous avons atteint le milieu ( n/2), nous comptons à nouveau avec la quantité de *, qui peut être vue dans les exemples ci-dessus.

REMARQUE: pour les nombres d'entrée impairs, la paire de lignes inversée (donc première et dernière; deuxième et avant-dernière; etc.) sont exactement les mêmes. Dans l' n=5exemple, les première et dernière lignes sont *####; l'avant-dernière ligne et l'avant-dernière sont ###**.
Cependant, pour les nombres en entrée pairs, la paire de lignes inversée est inversée. Dans l' n=8exemple, les première et dernière lignes sont *#######et #######*; l'avant-dernière ligne et l'avant-dernière ligne sont ######**et **######; etc.

Règles du défi:

  • Vous pouvez utiliser deux caractères imprimables distincts au lieu de *et #. Vous pouvez utiliser Aet B; 3et 7; <et >; etc. Veuillez indiquer dans vos réponses ce que vous avez utilisé.
  • Vous pouvez supposer que ce nsera un entier positif ( >= 1)
  • Vous êtes autorisé à générer une liste / un tableau de chaînes pour chaque ligne ou une matrice 2D de caractères, au lieu de les imprimer sur STDOUT.

Règles générales:

  • C'est le , donc la réponse la plus courte en octets l'emporte.
    Ne laissez pas les langues de golf de code vous décourager de publier des réponses avec des langues autres que le golf de code. Essayez de trouver une réponse aussi courte que possible pour «n'importe quel» langage de programmation.
  • Des règles standard s'appliquent à votre réponse, vous êtes donc autorisé à utiliser STDIN / STDOUT, fonctions / méthode avec les paramètres appropriés et des programmes complets de type retour. Ton appel.
  • Les failles par défaut sont interdites.
  • Si possible, veuillez ajouter un lien avec un test pour votre code.
  • De plus, l'ajout d'une explication à votre réponse est fortement recommandé.

Cas de test (du premier n=1au dernier n=10)

*

*#
#*

*##
#**
*##

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

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

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

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

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

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

*#########
########**
***#######
######****
*****#####
#####*****
****######
#######***
**########
#########*
Kevin Cruijssen
la source
" Vous pouvez utiliser deux caractères distincts au lieu de * et #. " - Doivent-ils être imprimables? Peut-on utiliser NUL et SOH (codes ASCII 0 et 1)?
ngn
@ngn Désolé, caractères imprimables uniquement. Clarifiera dans la description du défi.
Kevin Cruijssen

Réponses:

14

Gelée , 9 octets

>þµoṚUÐeY

Essayez-le en ligne!

Explication

>þ           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.
Lynn
la source
17

Python 2 , 62 octets

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

Essayez-le en ligne!

Usages xet espace.

Les lignes sont calculées comme ceci:

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

Utilisation du %*sspécificateur pour choisir entre net -n.

Lynn
la source
6

MATL, 34 31 18 octets

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

Essayez-le sur MATL en ligne

Utilise 0 pour * et 1 pour #. Basé sur la réponse Jelly de Lynn .


Ancienne réponse, 31 octets:

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

Essayez-le sur MATL en ligne

Utilise 1 pour * et 0 pour #.

         % 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
Sundar - Rétablir Monica
la source
6

APL (Dyalog Classic) , 18 octets

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

Essayez-le en ligne!

sorties ABau lieu de*#

entrée évaluée n

⍳⎕ le vecteur 0 1 ... n-1

⊢⌊⌽min ( ) entre eux ( ) et leur marche arrière ( ) - voir trains

⊂>⊢⌊⌽où est le vecteur dans son ensemble ( ) inférieur à chacun de ses ⊢⌊⌽- retourne un vecteur de vecteurs booléens (0/1)

⊢∘⌽\ inverser tous les autres vecteurs

mélanger dans une matrice

⎕al'alphabet anglais majuscule, 'AB...Z'

⎕a[ ]remplacer 0 1par'A' 'B'

ngn
la source
Par curiosité. Combien d'octets serait-il de simplement afficher la matrice de 0 et de 1 sans espaces? Je suppose que les ⎕a[...}convertir en Aet Bsans espaces est plus court que de les conserver comme 0et 1sans espaces, étant donné que vous l'avez utilisé, mais curieux de savoir s'il y a beaucoup de différence d'octets si vous les gardez comme 0et 1.
Kevin Cruijssen
1
@KevinCruijssen Pour autant que je puisse jouer au golf, ce serait la même longueur - soit ⎕d[... ]soit ⊃¨⍕¨... Dans cette dernière expression ⍕¨est "formater chaque" - il transforme chaque nombre en un vecteur de caractères imbriqué , nous avons donc besoin de "d'abord chacun" "( ⊃¨) pour n'obtenir que les scalaires de caractères (et donc aucun espace lors de l'impression).
ngn le
5

Fusain , 21 octets

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

Essayez-le en ligne! Utilise 0et 1. Le lien est vers une version détaillée du code et inclut §*#ce qui traduit la sortie en *et #dans la question. Explication:

    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
Neil
la source
5

Gelée ,  12  15 octets

+3 correction n=1du bug de bord de cas :(

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

Un programme complet acceptant un entier qui imprime la sortie telle que définie dans l'OP en utilisant 0et 1pour *et #respectivement.

Essayez-le en ligne!

Comment?

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
Jonathan Allan
la source
Il semble que ce soit exactement mon algorithme, mais une implémentation différente qui génère des 0 au lieu de 1 et vice versa.
Erik the Outgolfer le
Oui effectivement la même chose ... et je n'avais pas mis à jour mon post pour montrer le correctif que j'avais fait.
Jonathan Allan
4

Gelée , 15 octets

r1«RR;ṬṖɗ€‘UÐeY

Essayez-le en ligne!

Programme complet.

*= 1
#=0

Erik le Outgolfer
la source
4

Java 10, 145 octets

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

Tout le ternaire le rend un peu désordonné, mais cela fonctionne bien. J'ai essayé d'aplatir la boucle imbriquée et diverses autres choses, mais elles n'ont fait qu'augmenter le nombre d'octets. Essayez-le en ligne ici .

Non golfé:

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 octets

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

Essayez-le en ligne ici (TIO n'a pas encore Java 11, donc cela utilise une méthode personnalisée qui se traduit par le même nombre d'octets que String#repeat()).

Merci à Kevin Cruijssen d' avoir joué au golf 52 octets!

Non golfé:

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
}
OOBalance
la source
3
Si vous passez à Java 11, vous pouvez le jouer à 127 octets en utilisant "*".repeat(...)et "#".repeat(...)(ainsi qu'en renvoyant une chaîne au lieu d'imprimer directement et de jouer n-j-1au 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
Merci, c'est une grande économie d'octets. J'ai réussi à créer une version de 145 octets pour Java 10 en utilisant des boucles imbriquées - j'ai hâte de voir la sortie de Java 11, cette repeat()méthode est vraiment agréable pour le golf.
OOBalance
4

Lua ,  148133  octets

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

Essayez-le en ligne!

-15 octets grâce à @KevinCruijssen et @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
Azure Heights
la source
2
Je ne connais pas trop Lua, mais il semble que vous puissiez économiser cinq octets: (n+1)/2to -~n/2; or n-i+1à or-~n-i; i%2==0à i%2<1; et reverse() orà reverse()or. En outre, votre version TIO et le nombre d'octets contiennent tous deux un point-virgule de fin qui ne semble pas nécessaire. Belle première réponse, cependant. +1 de moi. Et bienvenue chez PPCG! :)
Kevin Cruijssen
2
En fait, vous n'avez besoin d' aucun des points-virgules. 133 octets, y compris les suggestions de Kevin.
Jo King
@KevinCruijssen Merci! Puis-je demander ce que -~nfait votre suggestion? Ça marche vraiment, mais je ne comprends pas pourquoi.
Azure Heights
1
@AzureHeights Bien sûr. ~est un opérateur de négation unaire au niveau du bit. Cependant, ce qui ~iest important pour le codegolfing, c'est qu'il a la même valeur que -i-1. On peut donc utiliser à la -~iplace de i+1et ~-iau lieu de i-1. Ceci est utile dans deux cas, que je pourrais tous deux utiliser dans votre réponse: se débarrasser des parenthèses, car -et ~avoir la priorité de l'opérateur sur les autres opérations mathématiques, il (n+1)/2peut donc en être ainsi -~n/2. Et l'autre partie utile est de se débarrasser des espaces dans certains cas, comme je l'ai fait avec or-~n-i.
Kevin Cruijssen
1
Voici les deux conseils pertinents si vous souhaitez en savoir un peu plus à ce sujet: Utilisez unaire ~pour x+1etx-1 et Utilisez unaire ~pour a-b-1eta+b+1 . Tous les conseils généraux, ainsi que les conseils spécifiques à la langue ( Conseils pour le golf à Lua dans ce cas), peuvent être intéressants à lire. :)
Kevin Cruijssen
3

Perl 5 + -pa -MPOSIX -M5.010, 58 octets

say+sort{$|--}1x abs,2x("@F"-abs)for(1..ceil$_/=2),-$_..-1

Essayez-le en ligne!

Dom Hastings
la source
3

C (gcc) , 118108 octets

Celui-ci ne va pas gagner, mais c'est une approche différente (ou du moins, je pense que oui!) Au lieu de faire des manipulations de cordes, j'utilise le fait que dixX-1 plus de [1..n]={9,99,999,...}, qui peut ensuite être multiplié pour obtenir le motif approprié; printf()effectue ensuite le remplissage nul pour la justification à droite.

Malheureusement, intil n'a qu'une plage suffisante pour faire jusqu'à 9 chiffres (sur les plates-formes 32 bits), vous devez donc aller àlong pour des modèles plus grands; un langage qui fait nativement l'arithmétique MP pourrait être capable de l'utiliser pour quelque chose.

Merci à plafondcat pour la suggestion.

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

Essayez-le en ligne!


Preuve de concept que cela fonctionne avec l'arithmétique MP:

C # (compilateur mono C #) , 187 165 octets

(143 octets + 22 octets pour l' using System.Numerics;en-tête)

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

Essayez-le en ligne!

ErikF
la source
1
Preuve de concept avec des nombres en dehors des plages entières natives maximales (en utilisant C # et BigIntegers): Essayez-le en ligne!
ErikF
3

Vim, 99 frappes

Il est toujours intéressant d'essayer de faire vim avec des arguments d'entrée. C'est très contre nature, donc ça ne va pas être incroyablement court. Il existe probablement d'autres bonnes approches à ce sujet.

L'entrée est supposée être par elle-même dans un tampon. Les registres sont supposés être vides. L'éditeur est supposé être assez grand pour contenir le résultat sans défilement (cela pourrait techniquement être évité au prix de certaines frappes).

"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

Explication

 | 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:
 | *####                *#####
 | ###**                ####**
 | ***##                ***###
 | ###**                ###***
 | *####                **####
 |                      #####*

Et en base64, avec des caractères réels (mettez les entrées inputet les touches keyset exécutez en utilisant vim -u NONE -s keys input)

Im5EQG5pDRtNbWFHZGRNFidhSSobcXdndmpva29JKhtAd3FAdxs6c2V0IHZlPWFsbA1AbmxoFkBua3IjOiVzLyAvIy9nDW8bMkdxcWR0IyRwMmowQHFxQHE=
algmyr
la source
2

R , 75 octets

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

Essayez-le en ligne!

  • Inspiré par la réponse @Lynn
  • fonction obtenant ncomme paramètre et renvoyant une matrice d' 0/10correspond '*'et 1correspond à'#'
digEmAll
la source
2

K (ngn / k) , 22 octets

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

Essayez-le en ligne!

{ } fonction avec argument x

!x la liste (0;1; ...;x-1)

i: affecter à i

i&|iminima ( &) de iet son inverse (| )

i>/:comparer avec supérieur à ( >) par irapport à chaque élément de la liste de droite (/: ) - retourner une matrice booléenne (liste de listes)

i|:/'pour chaque ( ') j dans i, inverse ( |:- nous avons besoin :de forcer |pour être unaire) l'élément correspondant j fois ( n f/ xapplique les f ntemps sur x). Effectivement, inversez toutes les deux rangées.

"*#" utiliser des éléments de matrice comme indices dans la chaîne "*#"

ngn
la source