Triangulowanie tekstu


39

Napisz program lub funkcję, która przyjmuje ciąg znaków, który ma gwarantować, że zawiera tylko drukowalne znaki ASCII z wyjątkiem spacji i ma być dodatnią liczbą trójkątną (1, 3, 6, 10, 15, ...).

Wydrukuj lub zwróć ten sam ciąg, ale w kształcie trójkąta, używając spacji. Niektóre przykłady najlepiej pokażą, co mam na myśli:

Jeśli wejście jest, Rwtedy wyjście będzie

R

Jeśli wejście jest, catwtedy wyjście będzie

 c
a t

Jeśli wejście jest, monk3ywtedy wyjście będzie

  m
 o n
k 3 y

Jeśli wejście jest, meanIngfu1wtedy wyjście będzie

   m
  e a
 n I n
g f u 1

Jeśli wejście jest, ^/\/|\/[]\wtedy wyjście będzie

   ^
  / \
 / | \
/ [ ] \

Jeśli dane wejściowe to

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

wtedy wyjście będzie

              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 ?

Zasadniczo nowe linie są wstawiane między podłańcuchy o długości trójkąta, spacje są dodawane między wszystkimi znakami, a każda linia jest wcięta spacjami, aby pasowały do ​​kształtu trójkąta.

Pojedynczy znak nowej linii i linie ze znakami spacji są opcjonalnie dozwolone, ale w przeciwnym razie dane wyjściowe powinny dokładnie pasować do tych przykładów. Ostatnia linia trójkąta nie powinna mieć spacji wiodących.

Najkrótszy kod w bajtach wygrywa.


Czy istnieje absolutna maksymalna długość łańcucha?
geokavel

@geokavel Powinno działać na dowolną długość łańcucha, który Twój język normalnie obsługuje.
Calvin's Hobbies

11
Oto choinka dla każdego, kto jeszcze jej nie wystawił. * / \ / | \ / | o \ / | o | \ / o | o | \ / || o | o \ / o ||| o | \ / o || o ||| \ / || o | || o | \ / | o ||| o || o \
Timmy

Odpowiedzi:


9

Pyth, 22 bajty

jua+L\ GjdHfTczsM._UzY

Wypróbuj online: pakiet demonstracyjny lub testowy

Wyjaśnienie:

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 bajtów

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

Funkcja rekurencyjna. Idzie od końca s, odcinając i drukując postacie. Liczba znaków do pobrania jest obliczana na podstawie długości s. Funkcja jest skonfigurowana do drukowania w odwrotnej kolejności wywołań rekurencyjnych, które kończą się, gdy sjest pusta, a następnie rozwiązują z powrotem linię. Każda warstwa, prefiks pma dodatkową przestrzeń.

W Pythonie 3 ifmożna to zrobić przez zwarcie, choć nie wydaje się, aby zapisywało znaki:

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

Równie długa alternatywa z łańcuchem nierówności:

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

Zarówno printi fpowrót None, co jest trudne w użyciu.


1
To całkiem sprytne. Odcinając ciąg po jednym rzędzie, nadal otrzymujesz trójkątny ciąg, aby obliczyć liczbę wiodących spacji.
xsot

6

Retina , 108 102 94 87 82 64 63 bajty

Dzięki Sp3000 za zmuszenie mnie do kontynuowania mojego oryginalnego podejścia, co spowodowało zmniejszenie liczby bajtów ze 108 do 82.

Ogromne podziękowania dla Kobi, który znalazł znacznie bardziej eleganckie rozwiązanie, które pozwoliło mi zaoszczędzić kolejne 19 bajtów.

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

Gdzie <space>reprezentuje pojedynczy znak spacji (który w innym przypadku zostałby usunięty przez SE). Do celów zliczania każda linia przechodzi do osobnego pliku i \npowinna zostać zastąpiona rzeczywistym znakiem linii. Dla wygody możesz uruchomić kod z jednego pliku z -sflagą.

Wypróbuj online.

Wyjaśnienie

Cóż ... jak zwykle nie mogę tutaj podać pełnego opisu grup równoważących. Aby uzyskać podkład, zobacz moją odpowiedź Przepełnienie stosu .

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

Pierwszy etap to etap Splitowania, który dzieli wkład na linie o coraz większej długości. _Wskazuje, że puste kawałki powinny być pominięte z podziału (który tylko wpływa na koniec, bo nie będzie to mecz w ostatniej pozycji). Sam regex jest całkowicie zawarty w rozejrzeniu, więc nie będzie pasował do żadnych znaków, a jedynie do pozycji.

Ta część oparta jest na rozwiązaniu Kobi z pewną dodatkową golfistą, którą znalazłem. Zauważ, że lookbehinds są dopasowane od prawej do lewej w .NET, więc poniższe wyjaśnienie najlepiej jest przeczytać od dołu do góry. Do \Gwyjaśnienia dodałem także inne, chociaż nie jest to konieczne, aby wzorzec zadziałał.

(?<=
  ^         # 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.

Nadal podziwiam tu pracę Kobiego. Jest to nawet bardziej eleganckie niż regex pierwszego testu. :)

Przejdźmy do następnego etapu:

.
$0 

Proste: wstaw spację po każdym znaku nieliniowym.

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

Ten ostatni etap prawidłowo wcina wszystkie linie, tworząc trójkąt. Jest mto zwykły tryb multilinii, który ^dopasowuje początek linii. +Mówi Retina powtórzyć ten etap aż łańcuch zatrzyma się zmienia (co w tym przypadku oznacza, że regex nie pasuje już).

^      # 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.
)

To pasuje do początku dowolnej linii, która nie ma większego wcięcia niż następna. W każdej takiej pozycji wstawiamy spację. Proces ten kończy się, gdy linie zostaną ułożone w czysty trójkąt, ponieważ jest to minimalny układ, w którym każda linia ma większe wcięcie niż następna.



@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨d̷̰̀ĥ̷̳ Teraz o 100% więcej niesamowitości, dzięki uprzejmości Kobi.
Martin Ender,

6

Cukierki , 67 59 57 bajtów

&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

lub:

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

długa forma:

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

Tak, czułem Boże Narodzenie.
Dale Johnson,

5

CJam, 27 26 bajtów

Dzięki Sp3000 za oszczędność 1 bajtu.

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

Zaskakująco blisko Pyth, zobaczmy, czy można grać w golfa ...

Sprawdź to tutaj.

Wyjaśnienie

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

Dlaczego to nie działa, jeśli zmienię ' na S???
geokavel

@geokavel Ponieważ Sjest łańcuchem, a nie znakiem, więc zamapuje ften łańcuch zamiast listy linii.
Martin Ender

Tak sądziłem. Czy masz jakiś pomysł na uzasadnienie, aby S był ciągiem?
geokavel

@geokavel Nie, nie wiem.
Martin Ender

5

Ruby, 84 77 73 bajtów

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

77 bajtów

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

Zmniejszono kilka dodatkowych bajtów, usuwając zmienną, rjak sugeruje steveverrill.

84 bajtów

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

Nie golfowany:

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

Najpierw obliczamy liczbę trójkątną z ciągu wejściowego

n=v.size**0.5*1.4

tzn. na przykład rozmiar łańcucha wejściowego wynosi 120, a nasza liczba trójkątna n będzie wynosić 15.

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

W powyższym wierszu wypisuje spacje, a następnie serię ciągów, które są pobierane z ciągu wejściowego przy użyciu następującego wzorca

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

Stosowanie:

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 ?

Wow, nasze podejście jest bardzo podobne, ale wydaje się, że mamy uzupełniającą wiedzę golfową. Nie wiedziałem, uptoże nie wymaga liczb całkowitych (z timespewnością tak.) Włączyłem część twojej składni do wersji mojej odpowiedzi. Największą wskazówką, jaką mam dla ciebie, jest to, że nie potrzebujesz tej zmiennej r. Wystarczy użyć ,zamiast, ..a liczba po przecinku to całkowita liczba elementów do zwrócenia, a nie koniec zakresu.
Level River St

Prawdziwe. Dzięki za wskazówkę, od razu aktualizuję swoją odpowiedź :)
Vasu Adari,

4

Pyth, 27 bajtów

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.

Pakiet testowy

Ciekawe podejście - konieczne i użyteczne .I. Prawdopodobnie gra w golfa.


4

C, 138 136 134 bajtów

Pobiera ciąg jako dane wejściowe:

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

Wygląda na to, że jak dotąd pokonałeś JavaScript C o 1 bajt: D
Mark K Cowan

@MarkKCowan tak, najwyraźniej. Mam nadzieję, że jeszcze go zmniejszę! :)
Sahil Arora,

@SahilArora - Możesz zastąpić printf(" ")oraz za printf("\n")pomocą puts(" ")i puts("\n"). Każda zamiana pozwoli Ci zaoszczędzić 2 bajty. :)
enhzflep

@enhzflep Próbowałem już, dał niejednoznaczny wynik!
Sahil Arora,

O. :( Działa dobrze tutaj na Win7 z gcc 4.7.1 - Myślę, że ma to związek ze sposobem, w jaki wydruk
wypisuje się

4

Podejście Ruby 2 rev 1, 76 bajtów

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

Zoptymalizowany przy użyciu pomysłów na składnię z odpowiedzi Vasu Adari oraz kilku własnych zwrotów akcji.

Podejście Ruby 2 rev 0, 93 bajty

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

Zupełnie inne podejście. Najpierw dodajemy spacje między znakami wejścia. Następnie drukujemy rzędy linia po linii.

Podejście Ruby 1, 94 bajty

->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?$/:' '}}

skończyło się to znacznie dłużej niż oczekiwano.

w zawiera liczbę znaków do wydrukowania w dolnym rzędzie lub równoważnie liczbę wierszy.

Każdy wiersz zawiera wznaki białych znaków (ostatnim z nich jest nowy wiersz), więc pomysł polega na wydrukowaniu tych białych znaków i wstawieniu znaków do wydruku w razie potrzeby.


3

Minkolang 0,14 , 42 bajty

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

Wypróbuj tutaj.

Wyjaśnienie

(                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
Taka idealna liczba bajtów! dobra robota!
TanMath

1
@TanMath, ale 42 nie jest liczbą trójkątną!
Paŭlo Ebermann

3

Python 2, 88 85 bajtów

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

Dzięki xnor za zapisanie 3 bajtów.


Czy skracanie nie zakłóca sobliczeń liczby miejsc?
xnor

No tak. Przed przesłaniem usunąłem zmienną tymczasową, ale nie zdawałem sobie sprawy, że unieważniłem kod.
xsot

Co jeśli lubisz wcześniej, ale oszczędzasz kopię zapasową S=s=raw_input()?
xnor

Dobry pomysł. Myślę, że prawdopodobnie istnieje krótsza ogólna strategia.
xsot

Przekreślone 88 wygląda zabawnie
pinkfloydx33

3

CJam, 50 bajtów

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

Wypróbuj tutaj.

Wyjaśnienie

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 bajtów

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}

De-golf + wersja demo:

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


Jaki jest cel for (s = j = 0; j < w.length; j += s++);? Ponadto w środku <pre>możesz użyć \nzamiast <br>. Zapomniałeś też wspomnieć, że to ES6.
Ismael Miguel,

Celem pierwszej pętli jest policzenie długości ostatniej linii, aby prawidłowo wciąć każdą linię.
nicael,

2

Java, 258 194

Gra w golfa:

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

Nie golfowany:

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
}

Wyjście programu:

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 ? 

Prawdopodobnie możesz statycznie zaimportować plik System.out, aby zapisać niektóre bajty.
RAnders00,

import static System.out;ma 25 bajtów i System.7 bajtów. Używa się go trzy razy, a 21 <25, więc zwiększyłby rozmiar o 4 bajty. Dobry ołów, jednak import statyczny może zaoszczędzić miejsce i nie wszyscy o nim wiedzą.

1
Kiedy znalazłem tę odpowiedź, przeglądałem stare odpowiedzi: „napisz program lub funkcję ”, której na początku nie zdawałem sobie sprawy. Pozbycie się rzeczy klasowych pozwoliło zaoszczędzić miejsce. Uczyniłem z niego odpowiednią funkcję i znalazłem jeszcze kilka bajtów do ogolenia.

1

JavaScript (ES6), 106 bajtów

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

Używa rekurencji zamiast pętli for do budowania łańcucha.

Aby znaleźć długość najdłuższego rzędu, użyj wzoru na n-ty trójkątny numer T_nto T_n = (n^2 + n)/2. Biorąc pod uwagę ni rozwiązując T_nzastosowanie formuły kwadratowej, mamy:

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

Okazuje się, że po posadzce dodanie 1/4 do pierwiastka kwadratowego nie zmienia wyniku, stąd wzór na najdłuższy rząd Math.sqrt(2*a.length)|0.



1

PowerShell, 69 bajtów

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

Skrypt testu mniej golfowego:

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

Wynik:

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

Nie wiem, czy jest to legalne w code-golfie, ale czy przekazanie listy w funkcji ma znaczenie? Nie mogę znaleźć sposobu, aby to powtórzyć bez zadeklarowania List <string> poza funkcją, więc umieściłem to jako parametr.

Stosowanie:

 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 bajty

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

Bash + sed, 87

for((;i<${#1};i+=j));{
a+=(${1:i:++j})
}
printf %${j}s\\n ${a[@]}|sed 's/\S/ &/g;s/.//'

0

R, 142 bajty

Jestem całkiem pewien, że mogę to jeszcze bardziej obniżyć. Nadal nad tym pracuję. Czuję, że brakuje mi łatwej rekurencji - ale nie byłem w stanie jej odpowiednio skrócić.

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

bez golfa

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.