Costruisci un triangolo senza triangoli


43

Da bambino mi piaceva molto giocare con questi giocattoli:

inserisci qui la descrizione dell'immagine

Probabilmente hanno inteso che questi fossero usati per l'arte, ma li ho sempre usati per la matematica! Frattali, motivi, ecc. Una volta mi è stata data questa sfida:

Costruisci un triangolo senza usare nessuna delle tessere triangolo verde.

Questa sfida mi ha sorpreso per il tempo più lungo, fino a quando mi sono imbattuto in un modo davvero bello e semplice per farlo con soli 3 trapezi:

  /\  
 /_/\ 
/__\_\

Ora prendi questo triangolo e ruotalo:

______         
\ \__/         
 \/ /          
  \/ 

Usando questi due triangoli, possiamo costruire triangoli più grandi da essi. Ecco un triangolo di altezza 2:

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

E qui ci sono triangoli di altezza 3-7:

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

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

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

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

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

La sfida

Scrivi un programma o una funzione che accetta un numero n e stampa un triangolo senza triangolo di altezza n . Gli spazi finali su ogni riga sono accettabili, e sono accettabili anche fino a una riga finale o iniziale nuova. IO può essere in qualsiasi formato ragionevole. L'input è garantito per essere un numero intero positivo, quindi non devi preoccuparti di numeri negativi, decimali, non numeri ecc.

Vince la risposta più breve in byte!


Prova a creare più trapezoidi dai trapezi. Le lunghezze 2 e 3 sono sicuramente possibili (e per estensione, tutti i numeri del modulo 2 ^ a * 3 ^ b) (Come faccio a sapere? Giocato con lo stesso tipo di blocchi quando ero un bambino.)
CalculatorFeline

1
@CatsAreFluffy Bene, dato che puoi creare un trapezio da triangoli, puoi concludere che puoi creare trapezoidi da trapezi. In effetti, se si osservano i triangoli di altezza 3 e 7, è possibile vedere lo stesso motivo ripetuto con grandi trapezi.
DJMcMayhem

Questa sfida è davvero fantastica. Mi è piaciuto capire come farlo a Retina.
mbomb007,

@ mbomb007 Sono contento di sentire che ti è piaciuto! = D Questo è esattamente il motivo per cui scrivo sfide.
DJMcMayhem

2
Questa sfida si adatta perfettamente allo schermo con l'app per dispositivi mobili. Era intenzionale? :)
Doddy,

Risposte:


15

CJam, 47

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

Spiegazione:

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

Provalo online


17

Ruby, 79

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

A. (-4 byte, -1 +1) modificato da 0-indicizzato ( .times) a 1-indicizzato ( 1.upto)

B. (-5 byte) modificato dall'array di tre stringhe da 6 caratteri alla selezione della sottostringa da 6 caratteri della stringa da 18 caratteri.

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

D. (-5 byte) ha ridotto tutte e cinque le barre rovesciate doppie in barre rovesciate singole (in parte rese possibili dal riordino della stringa richiesta per il punto A)

Ruby, 94

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

spiegazione

L'unità base è un diamante 3x6 come segue (ultimo carattere su ogni riga duplicato per chiarezza :)

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

Tutto quello che dobbiamo fare è visualizzare una finestra adatta di questo modello. Ruby ti ljustpermette di pad con qualsiasi stringa, non solo spazi. Normalmente ljustverrebbe utilizzato per riempire una stringa di caratteri stampabili aggiungendo spazi alla fine, ma qui lo usiamo al contrario: per riempire una stringa di spazi aggiungendo caratteri stampabili alla fine.

non golfato nel programma di 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 È la prima volta che mi lamento. Come ingegnere, sono abituato a fare revisioni su tutto Questa è una sfida abbastanza semplice e i miglioramenti sono abbastanza banali, quindi sono andato avanti e ho eliminato le lettere di revisione. Penso che lasciare il codice originale in alto sia buono o almeno non fa male, in quanto è più facile da seguire rispetto alla versione corrente.
Level River St

3
La dimensione del codice di solito identifica in modo univoco qualsiasi revisione, ma la cronologia delle revisioni è disponibile anche per chiunque visualizzi la cronologia delle modifiche.
mbomb007,

9

Retina , 150 122 118 byte

Il risultato di questa sfida sembra fantastico, a proposito!

L'input è in unario. L'output contiene un avanzamento riga finale. Il codice utilizza la codifica ISO 8859-1. Nota lo spazio finale sulla penultima riga.

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

Provalo online

Spiegazione

Se vuoi una spiegazione più approfondita, commenta o inviami un messaggio in chat.

(?=_\\¶.*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$* 

Grazie a Martin per il golf a 32 byte di sconto.


6

Linguaggio di stampa ASCII di Tarmo, 46 ​​byte. (Fuori concorso)

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

Solo guardando a linguaggi di programmazione così strani come CJam, mi fa venire le vertigini su quanto possa essere complesso, innaturale e criptico il linguaggio, che volevo "andare coraggiosamente dove nessun uomo è mai stato prima" e inventare il mio linguaggio. Di conseguenza ho creato il mio linguaggio per la stampa di modelli ASCII.

L'idea di base è che puoi definire prima lo zoccolo e poi la stampa - usando lo stesso tipo di carattere '1' o '2' o qualunque numero - puoi definire il tuo modello di stampa.

Una volta definito il motivo (inizia dal numero fino alla fine del numero) - i numeri successivi eseguiranno la stampa del motivo.

Per esempio

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

Output come questo:

  /\
 /_/\
/__\_\

Definirà il motivo 1 e quindi lo stamperà immediatamente. Il modello è definito tutto separato da '|' personaggio. 0 alla fine - si comporta come la terminazione del pattern.

I caratteri speciali come '$' sono riservati come avanzamento riga e '~' è riservato alla spaziatura - metà - di un motivo specifico.

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

Emetterà un testo come questo:

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

Il prossimo passa per i loop. Quello deve essere facilmente visibile - quindi ho conservato le parentesi {} per i for-loop, ma i nomi delle variabili sono auto-nominati - quindi la prima parentesi utilizzerà 'una' variabile, la seconda 'b' e così via. L'iterazione passerà sempre da 0 a un numero specifico e quel numero è definito tra parentesi {}.

'n' è una variabile riservata per l'input dell'intera funzione.

Quindi codice:

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

Volontà (con n == 4):

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

E '#' è un modificatore speciale per lo spazio bianco del piombo.

E infine l'intera soluzione:

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
}

Con argomenti della riga di comando come questo: -d "1 / \ | / _ / \ | / ___ \ 2 __ | / 0n {na-1 {½} 1a {2 # 1} $}" 3

Uscirà questo:

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
È davvero fantastico! Dovresti metterlo su Github e incoraggiare le persone a usarlo!
DJMcMayhem

3
Benvenuti in Puzzle di programmazione e Code Golf! È molto bello che tu abbia inventato il tuo linguaggio di programmazione, ma l'ultima versione in cui può essere eseguito anticipa la sfida?
Adnan,

Non ti ho capito del tutto, cosa stai dicendo?
TarmoPikaro,

Bene, se il linguaggio stesso è più recente della sfida, è comune contrassegnarlo come non competitivo (diritto piuttosto logico;)). Questo potrebbe essere un post rilevante.
Adnan,

La lingua dipende dal dominio del problema e non sapevo che esistesse un problema del genere prima di averlo letto da qui. Immagino che potrei programmare il linguaggio prima se ho già riscontrato un problema simile. :) Comunque, raccogliendo questo sito ho capito che CJam è un linguaggio abbastanza "normale" qui. :)
TarmoPikaro,

5

JavaScript (ES6), 119 byte

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

Dove \nrappresenta il carattere letterale di newline. Se una linea iniziale con n*3spazi e una nuova riga è accettabile, è .slice(1)possibile rimuoverla per un risparmio di 9 byte.



2

Python 2, 142 byte

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

Il principio è molto simile alle altre risposte: prendi tre stringhe ripetute e poi stratificale in modo tale che devi solo tagliare alcune di esse per ottenere il triangolo, quindi riempirle a sinistra.


2

C ++, 395 byte

Codice golf per la prima volta con una dimensione gloriosa di 395 byte in C ++. Nel mio caso, sembra un po 'una gara per l'offuscamento: 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;}}}

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.