Construire un triangle sans triangles


43

Quand j'étais petit, j'aimais beaucoup jouer avec ces jouets:

entrez la description de l'image ici

Ils avaient probablement l'intention de les utiliser pour l'art, mais je les utilisais toujours pour les mathématiques! Fractales, motifs, etc. Une fois, on m'a donné ce défi:

Construisez un triangle sans utiliser aucun des carreaux triangulaires verts.

Ce défi m'a laissé perplexe très longtemps, jusqu'à ce que je tombe par hasard sur un moyen vraiment beau et simple de le faire avec seulement 3 trapèzes:

  /\  
 /_/\ 
/__\_\

Maintenant, prenez ce triangle et faites-le pivoter:

______         
\ \__/         
 \/ /          
  \/ 

En utilisant ces deux triangles, nous pouvons en construire de plus grands. Voici un triangle de hauteur 2:

     /\           
    /_/\          
   /__\_\         
  /\ \__/\        
 /_/\/ /_/\       
/__\_\/__\_\    

Et voici des triangles de hauteur 3-7:

#3
        /\
       /_/\
      /__\_\
     /\ \__/\
    /_/\/ /_/\
   /__\_\/__\_\
  /\ \__/\ \__/\
 /_/\/ /_/\/ /_/\
/__\_\/__\_\/__\_\

#4
           /\
          /_/\
         /__\_\
        /\ \__/\
       /_/\/ /_/\
      /__\_\/__\_\
     /\ \__/\ \__/\
    /_/\/ /_/\/ /_/\
   /__\_\/__\_\/__\_\
  /\ \__/\ \__/\ \__/\
 /_/\/ /_/\/ /_/\/ /_/\
/__\_\/__\_\/__\_\/__\_\

#5
              /\
             /_/\
            /__\_\
           /\ \__/\
          /_/\/ /_/\
         /__\_\/__\_\
        /\ \__/\ \__/\
       /_/\/ /_/\/ /_/\
      /__\_\/__\_\/__\_\
     /\ \__/\ \__/\ \__/\
    /_/\/ /_/\/ /_/\/ /_/\
   /__\_\/__\_\/__\_\/__\_\
  /\ \__/\ \__/\ \__/\ \__/\
 /_/\/ /_/\/ /_/\/ /_/\/ /_/\
/__\_\/__\_\/__\_\/__\_\/__\_\

#6
                 /\
                /_/\
               /__\_\
              /\ \__/\
             /_/\/ /_/\
            /__\_\/__\_\
           /\ \__/\ \__/\
          /_/\/ /_/\/ /_/\
         /__\_\/__\_\/__\_\
        /\ \__/\ \__/\ \__/\
       /_/\/ /_/\/ /_/\/ /_/\
      /__\_\/__\_\/__\_\/__\_\
     /\ \__/\ \__/\ \__/\ \__/\
    /_/\/ /_/\/ /_/\/ /_/\/ /_/\
   /__\_\/__\_\/__\_\/__\_\/__\_\
  /\ \__/\ \__/\ \__/\ \__/\ \__/\
 /_/\/ /_/\/ /_/\/ /_/\/ /_/\/ /_/\
/__\_\/__\_\/__\_\/__\_\/__\_\/__\_\

#7
                    /\
                   /_/\
                  /__\_\
                 /\ \__/\
                /_/\/ /_/\
               /__\_\/__\_\
              /\ \__/\ \__/\
             /_/\/ /_/\/ /_/\
            /__\_\/__\_\/__\_\
           /\ \__/\ \__/\ \__/\
          /_/\/ /_/\/ /_/\/ /_/\
         /__\_\/__\_\/__\_\/__\_\
        /\ \__/\ \__/\ \__/\ \__/\
       /_/\/ /_/\/ /_/\/ /_/\/ /_/\
      /__\_\/__\_\/__\_\/__\_\/__\_\
     /\ \__/\ \__/\ \__/\ \__/\ \__/\
    /_/\/ /_/\/ /_/\/ /_/\/ /_/\/ /_/\
   /__\_\/__\_\/__\_\/__\_\/__\_\/__\_\
  /\ \__/\ \__/\ \__/\ \__/\ \__/\ \__/\
 /_/\/ /_/\/ /_/\/ /_/\/ /_/\/ /_/\/ /_/\
/__\_\/__\_\/__\_\/__\_\/__\_\/__\_\/__\_\

Le défi

Ecrivez un programme ou une fonction qui prend un nombre n et imprime un triangle de hauteur n sans triangle . Les espaces de fin sur chaque ligne sont acceptables, et il est également possible d’utiliser une nouvelle ligne. IO peut être dans n'importe quel format raisonnable. L'entrée étant garantie comme un entier positif, vous n'avez pas à vous soucier des nombres négatifs, des nombres décimaux, des non-nombres, etc.

La réponse la plus courte en octets gagne!


Essayez de fabriquer plus de trapèzes à partir de ceux-ci. Les longueurs 2 et 3 sont tout à fait possibles (et, par extension, tous les nombres de la forme 2 ^ a * 3 ^ b) (Comment le savoir? Joué avec le même type de blocs quand j'étais enfant.)
CalculatorFeline

1
@CatsAreFluffy Eh bien, puisque vous pouvez créer un trapèze à partir de triangles, vous pouvez en conclure que vous pouvez créer des trapèzes à partir de trapèzes. En fait, si vous regardez les triangles de hauteur 3 et 7, vous pouvez voir le même motif répété avec de grands trapèzes.
DJMcMayhem

Ce challenge est vraiment cool. J'ai bien aimé comprendre comment faire cela à Retina.
mbomb007

@ mbomb007 Heureux de vous entendre apprécier! = D C'est exactement pourquoi j'écris des défis.
DJMcMayhem

2
Ce défi s’intègre parfaitement à l’écran avec l’application mobile. Était-ce intentionnel? :)
Doddy

Réponses:


15

CJam, 47 ans

ri_"/__\_\/_/\/ /\ \__"6/f**eeW%{_S.*s\~,\-<N}/

Explication:

ri_       read the input, convert to integer and duplicate
"…"       push that string, containing the repeating pattern
           (3 lines in reverse order, concatenated)
6/        split into (3) lines of 6 characters
f*        multiply (repeat) each line n times
*         repeat the array of 3 lines n times
           at this point we have an array of 3*n strings with 6*n characters each
ee        enumerate the array (obtaining an array of [index string] pairs)
W%        reverse the array
           (so the lines are in correct order and indices in reverse order)
{…}/      for each [index string] pair
  _       duplicate the pair
  S.*     vectorized-multiply with " "
           this effectively replaces the index with a string of <index> spaces
  s       convert the pair to string, effectively concatenating the spaces
           with the string
  \       swap with the other copy of the [index string] pair
  ~,      dump the index and string on the stack and get the string length
  \-      subtract the index from it - this is the desired line length
  <       cut the concatenated string to that length
  N       add a newline

Essayez-le en ligne


17

Ruby, 79

->n{1.upto(n*=3){|i|puts (' '*(n-i)).ljust(n+i,'/__\_\/\ \__/_/\/ '[i%3*6,6])}}

A. (-4 octets, -1 +1) est passé de 0-indexé ( .times) à 1-indexé ( 1.upto)

B. (-5 octets) est passé d'un tableau de trois chaînes de 6 caractères à la sélection d'une sous-chaîne de 6 caractères d'une chaîne de 18 caractères.

C. (-1 octet) m=n*3->n*=3

D. (-5 octets) réduit les cinq doubles barres obliques inverses en une seule barre oblique inversée (rendue possible en partie par la réorganisation de la chaîne requise pour le point A)

Ruby, 94

->n{(m=n*3).times{|i|puts (' '*(m-i-1)).ljust(m+i+1,[ '/\\ \\__','/_/\\/ ','/__\\_\\'][i%3])}}

explication

L'unité de base est un losange 3x6 comme suit (le dernier caractère de chaque ligne est dupliqué pour plus de clarté :)

    /\ \__/
   /_/\/ / 
  /__\_\/

Tout ce que nous avons à faire est d’afficher une fenêtre appropriée de ce modèle. Ruby's ljustvous permet de jouer avec n'importe quelle ficelle, pas seulement les espaces. Normalement, ljustserait utilisé pour compléter une chaîne de caractères imprimables en ajoutant des espaces à la fin, mais ici, nous l’utilisons à l’inverse: pour compléter une chaîne d’espaces en ajoutant des caractères imprimables à la fin.

programme non testé

f=->n{
  (m=n*3).times{|i|                  #for each line of the triangle
    puts (' '*(m-i-1)).              #print m-i-1 spaces, 
      ljust(m+i+1,[ '/\\ \\__',      #left justified and padded to total length m+i+1
                   '/_/\\/ ',        #by one of these three strings
                  '/__\\_\\'][i%3])
  }
}

f[gets.to_i]

@ mbomb007 C'est la première fois que j'ai cette plainte. En tant qu'ingénieur, je suis habitué à réviser tout. C'est un défi assez simple et les améliorations sont assez triviales. Je suis donc allé de l'avant et j'ai supprimé les lettres de révision. ne fait aucun mal, car il est plus facile à suivre que la version actuelle.
Level River St

3
La taille du code identifie généralement de manière unique toute révision, mais l'historique de révision est également disponible pour toute personne consultant l'historique de modification.
mbomb007

9

Retina , 150 122 118 octets

La sortie de ce défi a l'air génial, au fait!

L'entrée est unaire. La sortie contient un retour à la ligne final. Le code utilise le codage ISO 8859-1. Notez l'espace de fin sur l'avant dernière ligne.

(?=_\\¶.*1)
_\/__\
(?=/_/\\¶.*1)
/_/\/ 
(^|__)(?=/\\¶.*1)
$1/\ \__
ms}`(.*1*)1
/\¶/_/\¶/__\_\¶$1
m`^(?=(.*¶)*.)
$#1$* 

Essayez-le en ligne

Explication

Si vous souhaitez une explication plus détaillée, commentez ou envoyez-moi un message en discussion.

(?=_\\¶.*1)                     # Matches the start of the 3rd line of every triangle
/__\_\                          #   and prepends another layer if needed
(?=/_/\\¶.*1)                   # 2nd line of each triangle
/_/\/ 
(^|__)(?=/\\¶.*1)               # 1st line of each triangle
$1/\ \__
ms}`(.*1*)1                 # This and above in a multi-single-line loop.
/\¶/_/\¶/__\_\¶$1               #   This stage adds a flattened triangle on top
m`^(?=(.*¶)*.)                  # Prepend a space for every line following -1
$#1$* 

Merci à Martin d'avoir joué 32 octets au golf.


6

Le langage d'impression ascii de Tarmo, 46 ​​octets. (non-concurrent)

1  /\| /_/\|/__\_\2 \__|/ 0n{n-a-1{~}1a{2#1}$}

En regardant des langages de programmation bizarres comme CJam, je suis un peu étonné de la complexité du langage, du naturel et du cryptique, que je voulais "aller hardiment là où aucun homme n’a été auparavant" et inventer mon propre langage. En conséquence, j'ai créé mon propre langage pour l'impression de motifs ascii.

L'idée de base est que vous pouvez définir le premier motif, puis imprimer - en utilisant le même type de caractère "1" ou "2" ou un nombre quelconque - vous pouvez définir votre propre motif d'impression.

Une fois que le motif est défini (commence à partir du numéro jusqu'à la fin du numéro) - les numéros suivants exécuteront l'impression du motif.

Par exemple

1  /\| /_/\|/__\_\01

Des sorties comme celle-ci:

  /\
 /_/\
/__\_\

Définira le motif 1, puis l’imprimera immédiatement. Le motif est défini tout ce qui est séparé avec '|' personnage. 0 à la fin - agit comme une terminaison de motif.

Des caractères spéciaux tels que '$' sont réservés comme saut de ligne et '~' pour l’espacement - à la moitié - d’un modèle spécifique.

1  /\| /_/\|/__\_\01$~11$~1~11

Le texte en sortie sera-t-il comme ceci:

  /\
 /_/\
/__\_\
     /\
    /_/\
   /__\_\
        /\
       /_/\
      /__\_\

Ensuite va pour les boucles. Celui-ci doit être facilement visible - j'ai donc conservé les {} crochets pour les boucles, mais les noms de variables sont nommés automatiquement - le premier crochet utilise donc 'une' variable, le second 'b', etc. L'itération ira toujours de 0 à un nombre spécifique - et ce nombre est défini avant les {} parenthèses.

'n' est une variable réservée pour la saisie de la fonction entière.

Donc code:

1  /\| /_/\|/__\_\0n{1$}

Sorties de volonté (avec n == 4):

  /\
 /_/\
/__\_\
  /\
 /_/\
/__\_\
  /\
 /_/\
/__\_\
  /\
 /_/\
/__\_\

Et '#' est un modificateur spécial pour les espaces blancs de découpe.

Et enfin toute la solution:

DrawPatterns.cs:

using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.CSharp;

class DrawPatterns
{
//Command line parameters - for example like this: "1  /\| /_/\|/__\_\2 \__|/ 0n{n-a-1{~}1a{2#1}$}" 3
    static Dictionary<char, String[]> patterns = new Dictionary<char,string[]>();

    static string Tabs(int n)
    {
        if( n < 0 ) n = 0;

        String r = "";

        for( int i = 0; i < n ; i++ )
            r += "    ";

        return r;
    }

    static int[] left = new int[10];
    static int top = Console.CursorTop;
    static int lastTop = Console.CursorTop;

    static public void DoPrint(char c, char modifier = ' ')
    {
        if (c == '$')
        {
            for (int i = 0; i < left.Length; i++)
                left[i] = 0;
            top = lastTop + 1;
            return;
        }

        if (!patterns.ContainsKey(c))
            return;

        if (modifier == '½' || modifier == '~')
        {
            int maxSize = patterns[c].Select(x => x.Length).Max();
            for( int i = 0; i < left.Length; i++ )
                left[i] += maxSize / 2;
            return;
        }

        int iLine = 0;
        foreach (var l in patterns[c])
        {
            Console.SetCursorPosition(left[iLine], top + iLine);
            if( top + iLine > lastTop ) 
                lastTop = top + iLine;

            String s = l;
            if (modifier == '#')
                s = s.TrimStart(' ');

            Console.WriteLine(s);
            left[iLine] += s.Length;
            iLine++;
        }
    }

    static void Main(string[] _args)
    {
        List<String> args = _args.ToList();
        String todo = "";
        String code = "";
        char nextVar = 'a';
        String lf = "\r\n";
        int align = 1;
        char lastModifier = ' ';
        int nextArg = 1;
        Dictionary<String, String> argValues = new Dictionary<string,string>();
        bool bDebug = false;

        if (args.Count != 0 && args[0].ToLower() == "-d")
        {
            bDebug = true;
            args.RemoveAt(0);
        }

        if (args.Count == 0)
        {
            Console.WriteLine("Usage: DrawPatterns.cs [options] \"script\" <arguments to script>");
            Console.WriteLine("[options] allowed:");
            Console.WriteLine("-d - debug");
            return;
        }

        String prog = args[0];

        for( int i = 0; i < prog.Length; i++ )
        {
            char c = prog[i];

            // Define pattern.
            if (c >= '0' && c <= '9' && !patterns.ContainsKey(c))
            {
                String p = Regex.Match(prog.Substring(i + 1), "[^0-9]*").Groups[0].Value;
                patterns[c] = p.Split('|');
                i += p.Length;
                if( prog[i + 1] == '0' ) i++;
                continue;
            }

            String procRemain = prog.Substring(i);
            // modifier specified, but pattern number is not provided - use first pattern.
            if( lastModifier != ' ' && ( c < '0' || c > '9' ) )
            {
                code += Tabs(align);
                code += "print('1' , '" + lastModifier + "');" + lf;
                lastModifier = ' ';
            }

            switch ( c )
            {
                case '{':
                    code += Tabs(align);
                    code += "for ( int " + nextVar + " = 0; " + nextVar + " < " + todo + " ; " + nextVar + "++ )" + lf;

                    //  Check for all variable names if they can be used in program.
                    foreach ( var m in Regex.Matches(todo, "[a-zA-Z_][a-zA-Z0-9_]*", RegexOptions.Singleline) )
                    {
                        String varName = m.ToString();

                        if( varName.Length == 1 && varName[0] <= nextVar )
                            // Already declared as a loop.
                            continue;

                        if( argValues.ContainsKey(varName ) )
                            continue;

                        if( nextArg >= args.Count )
                        {
                            Console.WriteLine("Insufficient parameters provided to script - argument '" + varName + "' value is needed");
                            return;
                        }

                        argValues[varName] = args[nextArg];
                        nextArg++;
                    }


                    code += Tabs(align);
                    code += "{" + lf;
                    nextVar++;
                    todo = "";
                    align++;
                    break;

                case '}':
                    align--;
                    code += Tabs(align);
                    code += "}" + lf;
                    break;

                default:
                    if (((c >= '0' && c <= '9') || c == '<' || c == '$') && todo == "")
                    {
                        code += Tabs(align);
                        code += "print('" + c + "' , '" + lastModifier + "');" + lf;
                        lastModifier = ' ';
                        continue;
                    }

                    if (c == '½' || c == '~' || c == '#')
                    {
                        lastModifier = c;
                        continue;
                    }

                    if( c == '\r' || c == '\n' )
                        continue;

                    todo += c;
                    break;
            }

        } //for

        String code2 = "";
        code2 += "using System;" + lf;
        code2 += "public class ExecClass { static void Exec( Action<char, char> print";

        object[] invokeArgs = new object[ argValues.Count+1];
        invokeArgs[0] = new Action<char, char>(DoPrint);
        int iValueIndex = 1;

        foreach ( var kv in argValues )
        {
            code2 += ",";
            code2 += "int " + kv.Key;
            invokeArgs[iValueIndex] = Int32.Parse(kv.Value);
            iValueIndex++;
        }

        code2 += ") {" + lf;
        code2 += code;
        code2 += "} };";

        if( bDebug )
        {
            int line = 1;
            String lineNumberedCode =Regex.Replace(code2, "^(.*)$", 
                delegate(Match m) { return (line++).ToString("d2") + ": " + m.Value; },
                RegexOptions.Multiline
            );
            Console.WriteLine(lineNumberedCode);
            Console.WriteLine();
            Console.WriteLine();
        }

        left[0] = Console.CursorLeft;
        for( int i = 1; i < left.Length; i++ )
            left[i] = left[0];
        top = Console.CursorTop;

        try
        {
            var compileResult = new CSharpCodeProvider().CompileAssemblyFromSource( new CompilerParameters() { GenerateExecutable = false, GenerateInMemory = true }, code2);
            if (compileResult.Errors.HasErrors)
            {
                foreach (CompilerError ce in compileResult.Errors)
                {
                    if (ce.IsWarning) continue;
                    Console.WriteLine("{0}({1},{2}: error {3}: {4}", ce.FileName, ce.Line, ce.Column, ce.ErrorNumber, ce.ErrorText);
                }
                return;
            }

            var method = compileResult.CompiledAssembly.GetType("ExecClass").GetMethod("Exec", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
            method.Invoke(null, invokeArgs);

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }

        Console.SetCursorPosition(1, lastTop);
        Console.WriteLine();
        Console.WriteLine();
    } //Main
}

Avec des arguments de ligne de commande comme celui-ci: -d "1 / \ | / _ / \ | / ___ \ 2 __ | / 0n {na-1 {½} 1a {2 # 1} $}" 3

Sera sortie ceci:

01: using System;
02: public class ExecClass { static void Exec( Action<char, char> print,int n) {
03:     for ( int a = 0; a < n ; a++ )
04:     {
05:         for ( int b = 0; b < n-a-1 ; b++ )
06:         {
07:             print('1' , '~');
08:         }
09:         print('1' , ' ');
10:         for ( int c = 0; c < a ; c++ )
11:         {
12:             print('2' , ' ');
13:             print('1' , '#');
14:         }
15:         print('$' , ' ');
16:     }
17: } };


        /\
       /_/\
      /__\_\
     /\ \__/\
    /_/\/ /_/\
   /__\_\/__\_\
  /\ \__/\ \__/\
 /_/\/ /_/\/ /_/\
/__\_\/__\_\/__\_\

1
C'est vraiment génial! Vous devriez mettre cela sur Github et encourager les gens à l'utiliser!
DJMcMayhem

3
Bienvenue dans Programmation Puzzles et Code Golf! C'est très bien que vous ayez inventé votre propre langage de programmation, mais la dernière version dans laquelle il peut être exécuté est-elle antérieure au défi?
Adnan

Je ne vous ai pas bien compris, que dites-vous?
TarmoPikaro

Eh bien, si le langage lui-même est plus récent que le défi, il est courant de le marquer comme non compétitif (droit assez logique;)). Cela pourrait être un poste pertinent.
Adnan

La langue dépend du domaine du problème, et je ne savais pas que ce problème existait avant de le lire ici. Je suppose que je pourrais coder la langue plus tôt si j'ai déjà rencontré le même problème. :) Quoi qu'il en soit, en exploitant ce site, j'ai compris que CJam est un langage assez "normal". :)
TarmoPikaro

5

JavaScript (ES6), 119 octets

n=>`,/\\ \\__,/_/\\/ ,/__\\_\\`[r=`repeat`](n).split`,`.map((s,i)=>` `[r](n*3-i)+s[r](n).slice(0,i*2)).slice(1).join`\n`

\nreprésente le caractère de nouvelle ligne littéral. Si une ligne principale avec des n*3espaces et une nouvelle ligne est acceptable, vous .slice(1)pouvez la supprimer pour une sauvegarde de 9 octets.



2

Python 2, 142 octets

def f(n,m):return f(n-1,m+3)+[' '*(m+x)+(y*n)[x*2:]for x,y in((2,' \\__/\\'),(1,'/ /_/\\'),(0,'/__\\_\\'))]if n else[]
print '\n'.join(f(n,0))

Le principe est très similaire à celui des autres réponses: prenez trois chaînes répétées, puis superposez-les de manière à ne couper que certaines d'entre elles pour obtenir le triangle, puis placez-les à gauche.


2

C ++, 395 octets

Première fois le code de golf avec une taille glorieuse de 395 octets en C ++. Dans mon cas, cela ressemble un peu à un concours d’obscurcissement: D

#include <iostream>
#include <cstring>
#define A for (int k=0;k<((s-(i+1))*3+(2-j));k++) cout<<" ";
using namespace std; string t[3]={"/\\","/_/\\","/__\\_\\"};string r[2]={" \\__","/ "};int tr=3;int main(int,char**argv){int s=atoi(argv[1]);for(int i=0;i<s;i++){for(int j=0;j<tr;j++){A for(int l=1;l<=2*(i+1)-1;l++){if((l%2)==0&&(j<2)){cout<<r[j];}else if ((l%2)==1)cout<<t[j];}A cout<<endl;}}}

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.