建立一个没有任何三角形的三角形


44

小时候,我很喜欢玩这些玩具:

在此处输入图片说明

他们可能打算将它们用于艺术,但是我总是将它们用于数学!分形,图案等。有一次,我受到了挑战:

无需使用任何绿色三角形瓷砖即可构建一个三角形。

这个挑战困扰了我最长的时间,直到我偶然发现了一种仅用3个梯形来完成的真正美丽而简单的方法:

  /\  
 /_/\ 
/__\_\

现在,取下这个三角形,然后旋转它:

______         
\ \__/         
 \/ /          
  \/ 

使用这两个三角形,我们可以从中构造出更大的三角形。这是一个高度为2的三角形:

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

这是高度为3-7的三角形:

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

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

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

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

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

挑战

编写一个程序或函数,该程序或函数采用数字n并打印高度为n的无三角形三角形。每行上的尾随空格都是可以接受的,并且最多可以包含一个尾随或前导换行符。IO可以采用任何合理的格式。确保输入为正整数,因此您不必担心负数,小数,非数字等。

以字节为单位的最短答案胜出!


尝试从梯形中制作更多的梯形。长度2和3绝对是可能的(并扩展为2 ^ a * 3 ^ b形式的所有数字)(我怎么知道?我小时候玩过相同类型的积木。)
CalculatorFeline

1
@CatsAreFluffy好吧,由于可以从三角形中制作出梯形,因此可以得出结论,可以从梯形中制作出梯形。实际上,如果您查看高度3和7的三角形,您可能会发现相同的图案与大梯形重复出现。
DJMcMayhem

这个挑战真的很酷。我很喜欢弄清楚如何在Retina中做到这一点。
mbomb007 '16

@ mbomb007很高兴听到您喜欢它!= D这正是我写挑战的原因。
DJMcMayhem

2
这项挑战非常适合移动应用程序在屏幕上显示。那是故意的吗?:)
Doddy

Answers:


15

CJam,47岁

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

说明:

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

在线尝试


17

Ruby,79岁

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

A。(-4字节,-1 +1)从0索引(.times)更改为1索引(1.upto

B。(-5字节)从三个6字符字符串的数组更改为18字符字符串的6字符子字符串的选择。

C。(-1个字节)m=n*3->n*=3

D。(-5字节)将所有五个双反斜杠减少为单反斜杠(部分可以通过对A点所需的字符串进行重新排序来实现)

露比(94)

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

说明

基本单位是3x6菱形,如下所示(为清楚起见,每行上的最后一个字符重复:)

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

我们需要做的就是显示此模式的合适窗口。Ruby ljust允许您使用任何字符串填充,而不仅仅是空格。通常ljust,通过在末尾添加空格来填充一串可打印的字符,但是在这里我们相反地使用它:通过在末尾添加可打印的字符来填充一串空格。

在测试程序中取消

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这是我第一次有这种抱怨。作为一名工程师,我习惯对所有内容进行修订,这是一个相当简单的挑战,并且改进非常琐碎,因此我继续删除了修订字母,我认为保留原始代码是好事,至少无害,因为它比当前版本更容易遵循。
水平河圣

3
代码大小通常唯一地标识任何修订,但是查看修订历史的任何人也可以使用修订历史。
mbomb007 '16

9

视网膜150个 122 118字节

顺便说一下,此挑战的输出看起来很棒!

输入为一元。输出包含尾随换行符。该代码使用ISO 8859-1编码。注意倒数第二行上的尾随空格。

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

在线尝试

说明

如果您需要更深入的说明,请在聊天中发表评论或给我发消息。

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

感谢Martin打高尔夫球32个字节。


6

Tarmo的ascii打印语言,46字节。(非竞争)

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

仅仅通过寻找像CJam这样奇怪的编程语言,我就感到头晕目眩,因为我想“大胆地走到以前没有人去过的地方”,并发明自己的语言,这是多么复杂,不自然和神秘的语言。结果,我创建了自己的语言来打印ASCII模式。

基本思想是,您可以先定义图案,然后使用相同类型的字符“ 1”或“ 2”或任何数字进行打印,然后定义自己的打印图案。

定义图案后(从数字开始到数字结束)-下一个数字将执行图案打印。

例如

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

这样的输出:

  /\
 /_/\
/__\_\

将定义图案1,然后立即打印。模式已定义,所有内容均以'|'分隔 字符。最后为0-就像图案终止。

像'$'这样的特殊字符保留为换行符,而'〜'保留为特定图案的间距-一半。

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

将输出如下文本:

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

接下来是循环。该位置必须易于显示-所以我为循环保留了{}括号,但是变量名是自动命名的-因此第一个括号将使用'a'变量,第二个将使用'b',依此类推。迭代将始终从0到特定数字-该数字在{}括号之前定义。

'n'是整个函数输入的保留变量。

所以代码:

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

将输出(n == 4):

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

“#”是微调引线空白的特殊修饰符。

最后是整体解决方案:

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
}

使用这样的命令行参数:-d“ 1 / \ | / _ / \ | / ___ \ 2 __ | / 0n {na-1 {½} 1a {2#1} $}” 3

将输出以下内容:

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
真是太棒了!您应该将它放在Github上并鼓励人们使用它!
DJMcMayhem

3
欢迎来到编程难题和Code Golf!您发明了自己的编程语言非常好,但是可以运行该语言的最新版本是否早于挑战?
阿德南

没有完全理解你,你在说什么?
TarmoPikaro '16

好吧,如果语言本身比挑战性新,通常将其标记为非竞争性(相当合逻辑的权利;)。可能是相关的帖子。
阿德南

语言取决于问题领域,在从这里阅读之前,我不知道存在这样的问题。我想如果已经遇到类似的问题,我可以更早地编写语言。:)无论如何,通过收获此站点,我了解到CJam在这里是相当“正常”的语言。:)
TarmoPikaro '16

5

JavaScript(ES6),119个字节

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

其中\n代表文字换行符。如果带有n*3空格和换行符的前导行是可接受的,则.slice(1)可以将其删除以节省9个字节。



2

Python 2,142字节

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

原理与其他答案非常相似:取三个重复的字符串,然后以某种方式分层它们,只需要修剪其中的一些即可得到三角形,然后将其填充在左侧。


2

C ++,395字节

首次使用C ++编写代码,具有395字节的出色大小。就我而言,这有点像混淆竞赛: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;}}}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.