Триангуляция текста


39

Напишите программу или функцию, которая принимает строку, гарантированно содержащую только печатаемые символы ASCII, за исключением пробела, и длину положительного треугольного числа (1, 3, 6, 10, 15, ...).

Выведите или верните ту же строку, но в форме треугольника, используя пробелы. Некоторые примеры лучше всего покажут, что я имею в виду:

Если входной, Rто выходной будет

R

Если входной, catто выходной будет

 c
a t

Если входной, monk3yто выходной будет

  m
 o n
k 3 y

Если входной, meanIngfu1то выходной будет

   m
  e a
 n I n
g f u 1

Если входной, ^/\/|\/[]\то выходной будет

   ^
  / \
 / | \
/ [ ] \

Если вход

Thisrunofcharactersismeanttohavealengththatcanbeexpressedasatriangularnumber.Diditwork?Youtellme,Ican'tcountverywell,ok?

тогда вывод будет

              T
             h i
            s r u
           n o f c
          h a r a c
         t e r s i s
        m e a n t t o
       h a v e a l e n
      g t h t h a t c a
     n b e e x p r e s s
    e d a s a t r i a n g
   u l a r n u m b e r . D
  i d i t w o r k ? Y o u t
 e l l m e , I c a n ' t c o
u n t v e r y w e l l , o k ?

В основном, новые строки вставляются между подстроками треугольной длины, пробелы добавляются между всеми символами, а каждая строка имеет отступы, чтобы соответствовать форме треугольника.

Допускается одиночная завершающая новая строка и строки с завершающими пробелами, но в противном случае ваш вывод должен точно соответствовать этим примерам. Последняя линия треугольника не должна иметь начальных пробелов.

Самый короткий код в байтах побеждает.


Существует ли абсолютная максимальная длина строки?
геокавель

@geokavel Это должно работать для любой длины строки, которую ваш язык может нормально обрабатывать.
Увлечения Кэлвина

11
Вот новогодняя елка для тех, кто еще не поставил свои. * / \ / | \ / | о \ / | о | \ / о | о | \ / || о | о \ / о ||| о | \ / о || О ||| \ / || о | || o | \ / | o ||| o || o \
Тимми

Ответы:


9

Pyth, 22 байта

jua+L\ GjdHfTczsM._UzY

Попробуйте онлайн: демонстрация или тестовый набор

Объяснение:

jua+L\ GjdHfTczsM._UzY   implicit: z = input string
                   Uz    create the list [0, 1, ..., len(z)-1]
                 ._      all prefixes of this list: [[0], [0,1], [0,1,2], ...]
               sM        sum up each sublist: [0, 1, 3, 6, 10, ...]
             cz          split z at these indices
           fT            remove all the unnecessary empty strings
                         this gives us the list of strings of the triangle
 u                   Y   reduce this list, with the initial value G = []
   +L\ G                    prepend a space to each string in G
        jdH                 join the current string with spaces
  a                         and append it to G
j                        print each string on a separate line

12

Python, 81 байт

def f(s,p=''):
 i=-int(len(2*s)**.5)
 if s:f(s[:i],p+' ');print p+' '.join(s[i:])

Рекурсивная функция. Идет с конца s, отрубает и печатает символы. Количество символов, которое нужно взять, рассчитывается по длине s. Функция настроена на печать в обратном порядке рекурсивных вызовов, которые завершаются, когда sпусто, а затем разрешаются обратно на линию. К каждому слою префикса pдобавляется дополнительное пространство.

В Python 3 это ifможно сделать с помощью короткого замыкания, хотя это, похоже, не спасает символы:

def f(s,p=''):i=-int(len(2*s)**.5);s and[f(s[:i],p+' '),print(p+' '.join(s[i:]))]

Не менее длинная альтернатива с цепочкой неравенства:

def f(s,p=''):i=-int(len(2*s)**.5);''<s!=f(s[:i],p+' ')!=print(p+' '.join(s[i:]))

Оба printи fвозвращаются None, что сложно использовать.


1
Это довольно умно. Отрезая строку по одной строке за раз, вы все равно получите строку треугольной длины, чтобы вычислить число начальных пробелов с помощью.
xsot

6

Retina , 108 102 94 87 82 64 63 байта

Спасибо Sp3000 за то, что он заставил меня следовать моему первоначальному подходу, благодаря которому количество байтов уменьшилось со 108 до 82.

Огромное спасибо Коби, который нашел гораздо более элегантное решение, которое позволило мне сэкономить еще 19 байтов.

S_`(?<=^(?<-1>.)*(?:(?<=\G(.)*).)+)
.
$0 
m+`^(?=( *)\S.*\n\1)
<space>

Где <space>представляет один пробел (который в противном случае был бы удален SE). Для целей подсчета каждая строка помещается в отдельный файл и \nдолжна быть заменена реальным символом перевода строки. Для удобства вы можете запустить код как есть из одного файла с -sфлагом.

Попробуйте онлайн.

объяснение

Ну ... как обычно, я не могу дать полное представление о балансирующих группах здесь. Для начинающих см. Мой ответ переполнения стека .

S_`(?<=^(?<-1>.)*(?:(?<=\G(.)*).)+)

Первая ступень представляет собой Sплоскую стадию, которая разбивает входные данные на линии увеличивающейся длины. _Указывает на то, что пустые куски должны быть исключены из расщепления (которое влияет только на конец, потому что там будет матч в последней позиции). Само регулярное выражение полностью содержится в осмотре, поэтому оно не будет совпадать ни с какими символами, а только с позициями.

Эта часть основана на решении Коби с некоторой дополнительной игрой в гольф, которую я нашел сам. Обратите внимание на то, что lookbehinds совпадают справа налево в .NET, поэтому следующее объяснение лучше всего читать снизу вверх. Я также вставил другой \Gв объяснение для ясности, хотя это не обязательно для работы шаблона.

(?<=
  ^         # And we ensure that we can reach the beginning of the stack by doing so.
            # The first time this is possible will be exactly when tri(m-1) == tri(n-1),
            # i.e. when m == n. Exactly what we want!
  (?<-1>.)* # Now we keep matching individual characters while popping from group <1>.
  \G        # We've now matched m characters, while pushing i-1 captures for each i
            # between 1 and m, inclusive. That is, group <1> contains tri(m-1) captures.
  (?:       
    (?<=
      \G    # The \G anchor matches at the position of the last match.
      (.)*  # ...push one capture onto group <1> for each character between here
            # here and the last match.
    )       # Then we use a lookahead to...
    .       # In each iteration we match a single character.
  )+        # This group matches all the characters up to the last match (or the beginning
            # of the string). Call that number m.
)           # If the previous match was at position tri(n-1) then we want this match
            # to happen exactly n characters later.

Я все еще восхищаюсь работой Коби здесь. Это даже более элегантно, чем регулярное регулярное выражение. :)

Давайте перейдем к следующему этапу:

.
$0 

Просто: вставьте пробел после каждого символа перевода строки.

m+`^(?=( *)\S.*\n\1)
<space>

На последнем этапе правильно выравнивают все линии, образуя треугольник. Это mпросто обычный многострочный режим для ^сопоставления начала строки. +Говорит Retina повторить этот этап , пока строка не перестает меняться (что, в данном случае означает , что регулярное выражение больше не соответствует).

^      # Match the beginning of a line.
(?=    # A lookahead which checks if the matched line needs another space.
  ( *) # Capture the indent on the current line.
  \S   # Match a non-space character to ensure we've got the entire indent.
  .*\n # Match the remainder of the line, as well as the linefeed.
  \1   # Check that the next line has at least the same indent as this one.
)

Так что это соответствует началу любой строки, которая не имеет большего отступа, чем следующая. В любой такой позиции мы вставляем пробел. Этот процесс завершается, когда линии располагаются в аккуратном треугольнике, потому что это минимальный макет, где каждая строка имеет больший отступ, чем следующая.


@ _ @ Какого черта это делает?
n15h ata̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Теперь на 100% больше удивительности, любезно предоставлено Коби.
Мартин Эндер

6

Конфеты , 67 59 57 байт

&iZ1-=yZ1+Z*2/>{0g}0=z@1i&{|.}bYR(" ";=)ZR(=a&{;}" ";)"\n";Y1-=ya1j

&1-8*1+r1-2/=y@1i&{|.}bYR(" ";=)ZR(=a&{;}" ";)"\n";Y1-=ya1j

&8*7-r1-2/=y@1i&{|.}bYR(" ";=)ZR(=a&{;}" ";)"\n";Y1-=ya1j

или:

          &
         8 *
        7 - r
       1 - 2 /
      = y @ 1 i
     & { | . } b
    Y R ( "   " ;
   = ) Z R ( = a &
  { ; } "   " ; ) "
 \ n " ; Y 1 - = y a
1 j

длинная форма:

stackSz
digit8    # Y = (sqrt((numCh - 1) * 8 + 1) - 1) / 2   using pythagorean
mult      # Y = (sqrt(numCh * 8 - 7) - 1) / 2  equivalent but shorter
digit7
sub
root
digit1
sub
digit2
div
popA
YGetsA
label digit1
incrZ
stackSz   # bail if we're out of letters
if
  else
  retSub
endif
stack2
pushY     # print the leading spaces (" " x Y)
range1
while
  " " printChr
  popA
endwhile
pushZ
range1      # output this row of characters (Z of them)
while
  popA
  stack1
  stackSz
  if
    printChr    # bail on unbalanced tree
  endif
  " " printChr
endwhile
"\n" printChr
pushY
digit1
sub
popA
YGetsA
stack1
digit1 jumpSub   # loop using recursion

Да, я чувствовал Рождество.
Дейл Джонсон

5

CJam, 27 26 байтов

Спасибо Sp3000 за сохранение 1 байта.

Lq{' @f+_,)@/(S*N+a@\+\s}h

Удивительно близко к Пифу, давайте посмотрим, может ли это быть в гольф ...

Проверьте это здесь.

объяснение

L        e# Push an empty array to build up the lines in.
q        e# Read input.
{        e# While the top of the stack is truthy (non-empty)...
  ' @f+  e#   Prepend a space to each line we already have.
  _,)    e#   Get the number of lines we already have and increment.
  @/     e#   Split the input into chunks of that size.
  (S*    e#   Pull off the first chunk (the next line) and join with spaces.
  N+     e#   Append a linefeed.
  a@\+   e#   Append it to our list of lines.
  \s     e#   Pull up the other chunks of the input and join them back into one string.
}h

Почему это не работает, если я перехожу ' на S???
геокавель

@geokavel Потому Sчто это строка, а не символ, поэтому fбудет отображаться поверх этой строки вместо списка строк.
Мартин Эндер

Это было мое предположение. Есть ли у вас какие-либо идеи относительно обоснования для того, чтобы сделать S строкой?
геокавель

@geokavel Нет, не знаю.
Мартин Эндер

5

Рубин, 84 77 73 байта

->v{1.upto(n=v.size**0.5*1.4){|i|puts" "*(n-i)+v[i*(i-1)/2,i].chars*" "}}

77 байт

->v{0.upto(n=(v.size*2)**0.5-1){|i|puts" "*(n-i)+v[i*(i+1)/2,i+1].chars*" "}}

Уменьшил еще несколько байтов, удалив переменную, rкак предложено steveverrill.

84 байта

->v{n=(v.size*2)**0.5-1;0.upto(n){|i|puts" "*(n-i)+v[(r=i*(i+1)/2)..r+i].chars*" "}}

Ungolfed:

->v {
  1.upto(n=v.size**0.5*1.4) { |i|
    puts" "*(n-i)+v[i*(i-1)/2,i].chars*" "
  }
}

Первый расчет треугольного числа из входной строки

n=v.size**0.5*1.4

например, размер входной строки равен 120, а наше треугольное число n будет равно 15.

puts" "*(n-i)+v[i*(i-1)/2,i].chars*" "

В приведенной выше строке он печатает пробелы, за которыми следуют серии строк, которые извлекаются из входной строки с использованием следующего шаблона

[[0,0],[1,2],[3,5],[6,9]]

Использование:

f=->v{1.upto(n=v.size**0.5*1.4){|i|puts" "*(n-i)+v[i*(i-1)/2,i].chars*" "}}
f["Thisrunofcharactersismeanttohavealengththatcanbeexpressesasatriangularnumber.Diditwork?Youtellme,Ican'tcountverywell,ok?"]
              T
             h i
            s r u
           n o f c
          h a r a c
         t e r s i s
        m e a n t t o
       h a v e a l e n
      g t h t h a t c a
     n b e e x p r e s s
    e s a s a t r i a n g
   u l a r n u m b e r . D
  i d i t w o r k ? Y o u t
 e l l m e , I c a n ' t c o
u n t v e r y w e l l , o k ?

Вау, наши подходы очень похожи, но мы, кажется, обладаем дополнительными знаниями в гольф. Я не знаю upto, не требует целочисленного аргумента, ( timesскорее всего, делает.) Я включил некоторые из вашего синтаксиса в пересмотр моего ответа. Самый большой совет, который у меня есть для вас - вам не нужна эта переменная r. Просто используйте ,вместо, ..а число после запятой - это общее количество возвращаемых элементов, а не конец диапазона.
Уровень Река St

Правда. Спасибо за подсказку, я обновляю свой ответ прямо сейчас :)
Васу Адари

4

Pyth, 27 байт

Js.IsSGlzWz+*-J=hZdjd<~>zZZ

                               z = input()
                               Z = 0
                               d = ' '
    sSG                        G -> tri(G)
  .I   lz                      Find the (float) input whose output is len(z).
 s                             Convert to int.
J                              Save as J.
         Wz                    while z:
               =hZ             Z += 1
            *-J  Zd            Generate J-Z spaces.
                      ~>zZ     Remove the first Z characters from z.
                     <    Z    Generate those first Z characters.
                   jd          Join on spaces.
           +                   Add the two together and print.

Тестирование

Интересный подход - императив, и использует .I. Вероятно, гольф.


4

C 138 136 134 байта

Принимает строку в качестве ввода:

j,r,k,a;f(char*s){j=strlen(s);r=k=sqrt(1+8*j)/2;for(;r--;printf("\n")){for(j=r;j--;)printf(" ");for(j=k-r;j--;)printf("%c ",s[a++]);}}

Вы, кажется, до сих пор победили JavaScript с C на 1 байт: D
Марк К Коуэн

@MarkKCowan да, очевидно. Я надеюсь, что я сделаю это еще меньше! :)
Сахиль Арора

@SahilArora - можно заменить printf(" ")и printf("\n")на puts(" ")и puts("\n"). Каждая замена сэкономит вам 2 байта. :)
Improzflep

@enhzflep Я уже пробовал, это дало неоднозначный вывод!
Сахиль Арора

Ой. :( Здесь отлично работает на win7 с gcc 4.7.1 - Я полагаю, это связано с тем, как вывод printf сбрасывается на стандартный вывод. +1 для победы над Javascript.
Enzzlek

4

Рубиновый подход 2 рев 1, 76 байт

->s{s=s.chars*' '
0.upto(w=s.size**0.5-1){|i|puts' '*(w-i)+s[i*i+i,i*2+2]}}

Оптимизирован с использованием идей синтаксиса из ответа Васу Адари, плюс несколько моих собственных поворотов.

Рубиновый подход 2 rev 0, 93 байта

->s{s=s.chars.to_a.join(' ')
w=(s.size**0.5).to_i
w.times{|i|puts' '*(w-i-1)+s[i*i+i,i*2+2]}}

Совершенно другой подход. Сначала мы добавляем пробелы между символами ввода. Затем мы печатаем строки построчно.

Рубиновый подход 1, 94 байта

->s{n=-1;w=((s.size*2)**0.5).to_i
(w*w).times{|i|print i/w+i%w<w-1?'':s[n+=1],-i%w==1?$/:' '}}

это закончилось намного дольше, чем ожидалось.

w содержит количество печатаемых символов в нижней строке или, что эквивалентно, количество строк.

Каждая строка содержит w пробельные символы (последний из которых - символ новой строки), поэтому идея состоит в том, чтобы напечатать эти пробельные символы и вставить печатные символы, где это необходимо.


3

Минколанг 0,14 , 42 байта

(xid2;$I2*`,)1-[i1+[" "o]lrx" "$ii-1-D$O].

Попробуй это здесь.

объяснение

(                Open while loop
 x               Dump top of stack
  i              Loop counter (i)
   d2;           Duplicate and square
      $I2*       Length of input times two
          `,     Push (i^2) <= (length of input)
            )    Close for loop; pop top of stack and exit when it's 0

1-[                              Open for loop that repeats sqrt(len(input))-1 times
   i1+[                          Open for loop that repeats (loop counter + 1) times
       " "o                      Push a space then read in character from input
           ]                     Close for loop
            l                    Push 10 (newline)
             r                   Reverse stack
              x                  Dump top of stack
               " "               Push a space
                  $i             Push the max iterations of for loop
                    i-           Subtract loop counter
                      1-         Subtract 1
                        D        Pop n and duplicate top of stack n times
                         $O      Output whole stack as characters
                           ].    Close for loop and stop.

2
Такое идеальное количество байтов! отличная работа!
TanMath

1
@TanMath, но 42 - это не треугольное число!
Пауло Эберманн

3

Python 2, 88 85 байт

s=t=raw_input()
i=1
while s:print' '*int(len(t*2)**.5-i)+' '.join(s[:i]);s=s[i:];i+=1

Спасибо xnor за сохранение 3 байта.


Разве укорочение не портит sвычисление количества пробелов?
xnor

О верно. Я удалил временную переменную перед отправкой, но не понял, что это делает код недействительным.
xsot

Что делать, если вам нравится раньше, но сохранить резервную копию S=s=raw_input()?
Норн

Хорошее предложение. Я думаю, что есть, вероятно, более короткая общая стратегия.
xsot

Вычеркнуто 88 выглядит смешно
pinkfloydx33

3

CJam, 50 байтов

q:QQ,1>{,{),:+}%:RQ,#:IR2ew<{~Q<>:LS*L,I+(Se[N}%}&

Попробуй это здесь.

объяснение

q:QQ,1>{  e# Only proceed if string length > 1, otherwise just print.
,{),:}%:R e# Generates a list of sums from 0 to k, where k goes from 0 to the length of the string [0,1,3,6,10,15,21,...]
Q,#:I     e# Find the index of the length of the string in the list
R2ew<     e# Make a list that looks like [[0,1],[1,3],[3,6],...,[?,n] ]where n is the length of the string 
{~Q<>:L   e# Use that list to get substrings of the string using the pairs as start and end indices
S*        e# Put spaces between the substrings
L,I+(Se[N e# (Length of the substring + Index of string length in sum array -1) is the length the line should be padded with spaces to. Add a new line at the end.
%}& 

2

JavaScript (ES6), 135 байт

w=>{r='';for(s=j=0;j<w.length;j+=s++);for(i=j=0;w[j+i];j+=++i)r+=Array(s-i-1).join` `+w.slice(j,i+j+1).split``.join` `+'<br>';return r}

Де-гольф + демо:

function t(w) {
    r = '';
    for (s = j = 0; j < w.length; j += s++);
    for (i = j = 0; w[j + i]; j += ++i) r += Array(s - i - 1).join` ` + w.slice(j, i + j + 1).split``.join` ` + '<br>';
    return r;
}

document.write('<pre>' + t(prompt()));


Какова цель for (s = j = 0; j < w.length; j += s++);? Кроме того, внутри <pre>, вы можете использовать \nвместо <br>. Также вы забыли упомянуть, что это ES6.
Исмаэль Мигель

Цель первого цикла - подсчитать длину последней строки, чтобы правильно сделать отступ для каждой строки.
Никаэль

2

Ява, 258 194

Golfed:

String f(String a){String r="";int t=(((int)Math.sqrt(8*a.length()+1))-1)/2-1;int i=0,n=0;while(n++<=t){for(int s=-1;s<t-n;++s)r+=" ";for(int j=0;j<n;++j)r+=a.charAt(i++)+" ";r+="\n";}return r;}

Ungolfed:

public class TriangulatingText {

  public static void main(String[] a) {
    // @formatter:off
    String[] testData = new String[] {
      "R",
      "cat",
      "monk3y",
      "meanIngfu1",
      "^/\\/|\\/[]\\",
      "Thisrunofcharactersismeanttohavealengththatcanbeexpressedasatriangularnumber.Diditwork?Youtellme,Ican'tcountverywell,ok?",
    };
    // @formatter:on

    for (String data : testData) {
      System.out.println("f(\"" + data + "\")");
      System.out.println(new TriangulatingText().f(data));
    }
  }

  // Begin golf
  String f(String a) {
    String r = "";
    int t = (((int) Math.sqrt(8 * a.length() + 1)) - 1) / 2 - 1;
    int i = 0, n = 0;
    while (n++ <= t) {
      for (int s = -1; s < t - n; ++s)
        r += " ";
      for (int j = 0; j < n; ++j)
        r += a.charAt(i++) + " ";
      r += "\n";
    }
    return r;
  }
  // End golf
}

Выход программы:

f("R")
R 

f("cat")
 c 
a t 

f("monk3y")
  m 
 o n 
k 3 y 

f("meanIngfu1")
   m 
  e a 
 n I n 
g f u 1 

f("^/\/|\/[]\")
   ^ 
  / \ 
 / | \ 
/ [ ] \ 

f("Thisrunofcharactersismeanttohavealengththatcanbeexpressedasatriangularnumber.Diditwork?Youtellme,Ican'tcountverywell,ok?")
              T 
             h i 
            s r u 
           n o f c 
          h a r a c 
         t e r s i s 
        m e a n t t o 
       h a v e a l e n 
      g t h t h a t c a 
     n b e e x p r e s s 
    e d a s a t r i a n g 
   u l a r n u m b e r . D 
  i d i t w o r k ? Y o u t 
 e l l m e , I c a n ' t c o 
u n t v e r y w e l l , o k ? 

Возможно, вы могли бы статически импортировать System.out, чтобы сохранить несколько байтов.
RAnders00

import static System.out;25 байтов и System.7 байтов. Он используется три раза, и 21 <25, так что он фактически увеличит размер на 4 байта. Хорошее лидерство, тем не менее, статический импорт может сэкономить место, и не все знают о них.

1
Я просматривал старые ответы, когда нашел этот: «написать программу или функцию », которые сначала не осознал. Изъятие материала класса сэкономило место. Я превратил это в правильную функцию и нашел еще несколько байтов для сброса.

1

JavaScript (ES6), 106 байт

a=>(y=z=0,(f=p=>p?" ".repeat(--p)+a.split``.slice(y,y+=++z).join` `+`
`+f(p):"")(Math.sqrt(2*a.length)|0))

Использует рекурсию вместо цикла for для построения строки.

Чтобы найти длину самого длинного ряда, используйте формулу для n-го треугольного числа T_nis T_n = (n^2 + n)/2. Учитывая nи решая с T_nпомощью квадратичной формулы, имеем:

1/2 * n^2 + 1/2 * n - T_n = 0

a = 1/2, b = 1/2, c = -T_n

-1/2 + sqrt(1/2^2 - 4*1/2*-T_n)   
------------------------------- = sqrt(1/4 + 2*T_n) - 1/2
             2*1/2

Оказывается, что после добавления пола 1/4 внутри квадратного корня результат не изменится, поэтому формула для самой длинной строки будет Math.sqrt(2*a.length)|0.



1

Powershell, 69 байт

($args|% t*y|?{$r+="$_ ";++$p-gt$l}|%{$r;rv r,p;$l++})|%{' '*--$l+$_}

Менее гольф тестовый скрипт:

$f = {

(
    $args|% t*y|?{  # test predicate for each char in a argument string 
        $r+="$_ "   # add current char to the result string
        ++$p-gt$l   # return predicate value: current char posision is greater then line num
    }|%{            # if predicate is True
        $r          # push the result string to a pipe
        rv r,p      # Remove-Variable r,p. This variables will be undefined after it.
        $l++        # increment line number
    }

)|%{                # new loop after processing all characters and calculating $l
    ' '*--$l+$_     # add spaces to the start of lines
}                   # and push a result to a pipe

}

@(
    ,("R",
    "R ")

    ,("cat",
    " c ",
    "a t ")

    ,("monk3y",
    "  m ",
    " o n ",
    "k 3 y ")

    ,("meanIngfu1",
    "   m ",
    "  e a ",
    " n I n ",
    "g f u 1 ")

    ,("^/\/|\/[]\",
    "   ^ ",
    "  / \ ",
    " / | \ ",
    "/ [ ] \ ")

    ,("Thisrunofcharactersismeanttohavealengththatcanbeexpressedasatriangularnumber.Diditwork?Youtellme,Ican'tcountverywell,ok?",
    "              T ",
    "             h i ",
    "            s r u ",
    "           n o f c ",
    "          h a r a c ",
    "         t e r s i s ",
    "        m e a n t t o ",
    "       h a v e a l e n ",
    "      g t h t h a t c a ",
    "     n b e e x p r e s s ",
    "    e d a s a t r i a n g ",
    "   u l a r n u m b e r . D ",
    "  i d i t w o r k ? Y o u t ",
    " e l l m e , I c a n ' t c o ",
    "u n t v e r y w e l l , o k ? ")

    ,("*/\/|\/|o\/|o|\/o|o|\/||o|o\/o|||o|\/o||o|||\/||o|||o|\/|o|||o||o\",
    "          * ",
    "         / \ ",
    "        / | \ ",
    "       / | o \ ",
    "      / | o | \ ",
    "     / o | o | \ ",
    "    / | | o | o \ ",
    "   / o | | | o | \ ",
    "  / o | | o | | | \ ",
    " / | | o | | | o | \ ",
    "/ | o | | | o | | o \ ")

) | % {
    $s,$expected = $_
    $result = &$f $s
    "$result"-eq"$expected"
    $result
}

Выход:

True
R
True
 c
a t
True
  m
 o n
k 3 y
True
   m
  e a
 n I n
g f u 1
True
   ^
  / \
 / | \
/ [ ] \
True
              T
             h i
            s r u
           n o f c
          h a r a c
         t e r s i s
        m e a n t t o
       h a v e a l e n
      g t h t h a t c a
     n b e e x p r e s s
    e d a s a t r i a n g
   u l a r n u m b e r . D
  i d i t w o r k ? Y o u t
 e l l m e , I c a n ' t c o
u n t v e r y w e l l , o k ?
True
          *
         / \
        / | \
       / | o \
      / | o | \
     / o | o | \
    / | | o | o \
   / o | | | o | \
  / o | | o | | | \
 / | | o | | | o | \
/ | o | | | o | | o \

0

C #, 202

string r(string s,List<string> o,int i=1){o=o.Select(p=>" "+p).ToList();o.Add(String.Join(" ",s.Substring(0,i).ToCharArray()));return s.Length==i?String.Join("\n",o):r(s.Substring(i,s.Length-i),o,i+1);}

Я не знаю, допустимо ли это в code-golf, но стоит ли передавать список в функции? Я не могу найти способ повторить это без List <string>, объявленного вне функции, поэтому я поместил его в качестве параметра.

Использование:

 r("1",new List<string>());
 r("123", new List<string>());
 r("123456", new List<string>());
 r("Thisrunofcharactersismeanttohavealengththatcanbeexpressedasatriangularnumber.Diditwork?Youtellme,Icanstcountverywell,ok?",new List<string>());

0

C, 102 байта

i,j;main(n,s){for(n=sqrt(strlen(gets(s))*2);j<n;printf("%*.1s",i>1?2:i*(n-j),i++>j?i=!++j,"\n":s++));}


0

R, 142 байта

Уверен, я смогу это исправить. Все еще работаю над этим, хотя. Я чувствую, что пропускаю легкую рекурсию - но я не смог сократить ее правильно.

f=function(a){n=nchar(a);l=which(cumsum(1:n)==n);w=strsplit(a,c())[[1]];for(i in 1:l){cat(rep(" ",l-i),sep="");cat(w[1:i],"\n");w=w[-(1:i)]}}

ungolfed

f=function(a){
    n = nchar(a)                 #number of characters
    l= which(cumsum(1:n)==n)     #which triangle number
    w= strsplit(a,c())[[1]]      #Splits string into vector of characters
    for (i in 1:l) {
        cat(rep(" ",l-i),sep="") #preceeding spaces
        cat(w[1:i],"\n")         #Letters
        w=w[-(1:i)]              #Shifts removes letters (simplifies indexing)
    }
}

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.