Detonuj ciąg

34

Dając dowolny ciąg, wydrukuj go w postaci trójkąta, w którym tekst biegnie w górę i w dół wzdłuż każdej przekątnej. Na przykład wejście "Hello World"powinno wypisać:

                    d
                  l  
                r   d
              o   l  
            W   r   d
              o   l  
        o   W   r   d
      l       o   l  
    l   o   W   r   d
  e   l       o   l  
H   l   o   W   r   d
  e   l       o   l  
    l   o   W   r   d
      l       o   l  
        o   W   r   d
              o   l  
            W   r   d
              o   l  
                r   d
                  l  
                    d

Odstęp między każdym znakiem w rzędzie musi wynosić co najmniej 1, aby zachować odpowiedni format.

machiavelli
źródło
1
Czy możemy założyć, że łańcuch nie jest pusty?
Pan Xcoder
@ Mr.Xcoder Tak, możesz
machiavelli
1
Odstęp między każdym znakiem w rzędzie musi wynosić co najmniej 1 : Czy to oznacza, że H l o W r djest to prawidłowy środkowy wiersz? Pytanie, ponieważ w twoim przykładzie każdy wiersz ma 3 spacje między każdą postacią.
Emigna
1
@Emigna Źle zrozumiałem twoje pytanie, przepraszam. Tak, twój przykład byłby ważny.
machiavelli
1
Dopuszczalne spacje wiodące lub końcowe?
Luis Mendo,

Odpowiedzi:

19

Węgiel drzewny , 10 7 bajtów

↗ELθ✂θιUE¹

Wypróbuj online! Wypróbuj online! Linki są do pełnej wersji kodu. Wyjaśnienie:

    ↗       Print up and to the right
     ELθ✂θι All suffixes of the input, as a list down and to the right
    UE¹     Insert blank columns

Pierwszy raz muszę użyć UEpolecenia.

Neil
źródło
Wiedziałem, że Węgiel będzie jedną z pierwszych odpowiedzi tutaj. Byłem prawie kuszący, aby zacząć, ale jestem zbyt niedoświadczony, aby dokończyć rozwiązanie na czas, a i tak zostałby wyrzucony z gry…;)
Kevin Cruijssen,
6
@Emigna ... ale to była moja wielka szansa na wykorzystanie UE...
Neil
6
@EriktheOutgolfer ... ale to była moja wielka szansa na wykorzystanie UE..
Neil
1
@Neil To -3 bajty! -3 za miłą ofiarę! Kto nie chce miłej -3?
Erik the Outgolfer
4
@EriktheOutgolfer To, co powinieneś powiedzieć, to: „Nie możesz pozwolić, żeby 05AB1E cię pokonało, prawda?”
Neil
12

05AB1E , 10 8 7 bajtów

Dzięki Emigna za uratowanie 2 bajtów!

ðâƶ.cðζ

Wykorzystuje kodowanie 05AB1E . Wypróbuj online!

Adnan
źródło
Zgodnie z tym wierszem Odstęp między każdym znakiem w rzędzie musi wynosić co najmniej 1, który można usunąć ¶«. (również zweryfikował ważność przy pomocy OP)
Emigna
@Emigna Thanks! :)
Adnan
Może chcę zaktualizować link Tio :)
Mr. Xcoder
@ Mr.Xcoder ninja'd
Adnan
1
Mądre wykorzystanie âw ðâzamiast Sð«!
Erik the Outgolfer
9

Python 2 , 75 bajtów

s=input()
k=l=len(s)
while k>1-l:k-=1;m=abs(k);print' '*m+' '.join(s[m::2])

Wypróbuj online!

Ruud zapisał 3 bajty.

Lynn
źródło
3
Jest to dozwolone przez OP: 78 bajtów . Spacja w każdym rzędzie musi wynosić co najmniej 1 .
Pan Xcoder
1
75 bajtów
Arfie
8

C, 86 78 73 70 znaków

for(int i=1,j=1-n;i=putchar(j*j<i*i&i-j?s[i-1]?:13:32)^13?i+1:++j<n;);

Wypróbuj online!

Wyjaśnienie

Naiwna implementacja: dwa cykle, wypełnianie od góry do dołu, od lewej do prawej (99 bajtów):

for(int j=1;j<n*2;j++){for(int i=0;i<n;i++)printf("%c ",(i+j)%2&&i+1>=abs(j-n)?s[i]:' ');puts("");}

Tutaj puts () po prostu drukuje \ n na wyjściu. Połączmy deklaracje zmiennych i połączmy j ++ z czymś (94 bajty):

for(int i,j=0;++j<n*2;){for(i=0;i<n;i++)printf("%c ",(i+j)%2&&i>=abs(j-n)?s[i]:' ');puts("");}

Dobry. Zmienna j ma zakres 0 ... 2n; niech będzie w zakresie -n ... n, dzięki temu matematyka jest prostsza. Zauważ, że wyrażenie logiczne po prawej stronie && ma zawsze wartość 0 lub 1. Oznacza to, że możemy zastąpić && przez &. 91 bajtów:

for(int i,j=-n;++j<n;){for(i=0;i<n;i++)printf("%c ",~(i+j)%2&i>=abs(j)?s[i]:' ');puts("");}

A teraz zdaliśmy sobie sprawę, że drukujemy dodatkową przestrzeń. I tak, nie potrzebujemy printf (), aby wydrukować tylko jeden symbol. 86 bajtów:

for(int i,j=-n;++j<n;){for(i=0;i<n;i++)putchar(~(i+j)%2&i>=abs(j)?s[i]:' ');puts("");}

Nawet lepiej. Zauważ, że warunek i * i> = j * j jest taki sam jak i> = abs (j), ale krótszy. Przejdźmy puts () do wyrażenia zwiększającego pętlę. I zgadnij co? W rzeczywistości nie potrzebujemy nawiasów klamrowych wokół i + j. 78 bajtów:

for(int i,j=-n;++j<n;puts(""))for(i=0;i<n;i++)putchar(i*i>=j*j&~i+j?s[i]:' '); 

Czy wiesz, że putchar () zwraca wydrukowany znak? Użyjmy XOR do przetestowania liczb pod kątem równoważności. Zastąpmy spację jego kodem ASCII, 32. Pamiętaj, że kod znaku końca linii to 13. I wreszcie: czy wiesz, że GCC / Clang obsługują https://en.wikipedia.org/wiki/Elvis_operator ? 73 bajty:

for(int i,j=-n;++j<n;)for(i=0;putchar(i*i>=j*j&~i+j?s[i]?:13:32)^13;i++);

Wreszcie, zgadnij co? Nie potrzebujemy dwóch na pętle. Możemy zastąpić brzydkie ~ i + j tylko ij. 70 bajtów:

for(int i=1,j=1-n;i=putchar(j*j<i*i&i-j?s[i-1]?:13:32)^13?i+1:++j<n;);

Przyszłe prace: zmienić kierunek pętli? Może to zaoszczędzić niektóre bajty, jeśli zostanie to wykonane poprawnie.

MrShoor
źródło
5

SOGL V0.12 , 13 10 9 bajtów

ēI*@∑}¹╚H

Korzysta z funkcji, którą właśnie dodałem , ale została ona wcześniej udokumentowana .

Wypróbuj tutaj!
Link ten ,jest dodawany, ponieważ oczekuje danych wejściowych na stosie i {dodawany, ponieważ w przeciwnym razie ,byłby wykonywany za każdym razem w pętli

implicitly start loop over POP
ē            increase the variable E, on first push which will be 0
 I           increase by 1
  *          multiply the current character that many times
   @∑        join with spaces
     }     end loop
      ¹    wrap everything on stack in an array
       ╚   center vertically
        H  rotate counter-clockwise
dzaima
źródło
4

Haskell , 73 bajty

f s|l<-length s-1=[zipWith min s$(' '<$[1..abs x])++cycle"~ "|x<-[-l..l]]

Wypróbuj online!

Lynn
źródło
3

Gaia , 16 bajtów

$:ċ⟪×$§×⟫†€|$¦tụ

Wypróbuj online!

Wyjaśnienie

$                 Split into list of chars
 :ċ               Push [1 .. len(input)]
   ⟪×$§×⟫†        Apply this block to corresponding elements of the two lists:
    ×              Repetition
     $             Split into chars
      §×           Join with spaces
          €|      Centre align the rows
            $¦    Split each line into chars
              t   Transpose
               ụ  Join each row with spaces, then join the rows together with newlines
Business Cat
źródło
3

Python 2 , 86 83 bajtów

-3 dzięki oficjalnemu

lambda s,j=' '.join:map(j,zip(*(j(c*-~i).center(len(s)*2)for i,c in enumerate(s))))

Wypróbuj online!

Arfie
źródło
1
83 bajty
officialaimm
3

Oktawa, 59 63 58 57 bajtów

@(s,a=@strjust)a([kron(+a(hankel(s)),[1 0;0 0]) '']',99)'

Wypróbuj online!

rahnema1
źródło
1
99: dobry pomysł :-)
Luis Mendo
3

Java, 292 bajtów (przepraszam)

public class D{
public static void main(String[]r){
String s=r[0];int L=s.length(),n=L*2-1,x=L-1,d=-1,i,j;boolean a=false,o=L%2==1;
for(i=0;i<n;i++){
for(j=0;j<L;j++)System.out.print(j<x||a&&j%2==(o?0:1)||!a&&j%2==(o?1:0)?' ':s.charAt(j));
System.out.println();
x+=d;if(x<0){x=0;d=1;}a=!a;}}}
ubzack
źródło
1
Możesz usunąć nowe linie, w przeciwnym razie wygląda to dość golfowo!
Zacharý
1
Możesz grać w golfa więcej: 1 boolean a=1<0,o=L%2>0;.. 2. W przypadku nie trzeba iużywać tej pętli: for(i=0;i++<n;). 3. Możesz pozbyć się o: j%2<L%2wtedy j%2>L%2. 4. Używanie djako klapki zajmuje tak wiele znaków: po prostu zrób j<(x<0?-x:x). 5. Masz o wiele więcej zmiennych niż potrzeba. 6. Nie potrzebujesz pełnego programu: wystarczy lambda lub metoda. - Jeśli chcesz przykład Java z golfem, sprawdź moją odpowiedź .
Olivier Grégoire,
3

Haskell , 81 bajtów

f s|l<-length s=[[last$' ':[s!!i|i>=n,mod(n+i)2<1]|i<-[0..l-1]]|n<-abs<$>[-l..l]]

Wypróbuj online!

Laikoni
źródło
3

Java (OpenJDK 8) , 116 bajtów

s->{for(int l=s.length(),i=-l;++i<l;)System.out.printf("%"+l+"s%n",s.substring(i<0?-i:i).replaceAll("(.).","$1 "));}

Wypróbuj online!

Wyjaśnienie

s->{                                // Consumer<String> lambda
 for(int l=s.length(),i=-l;++i<l;)  // For each length between l and 1 and back to l, 
  System.out.printf("%"+l+"s%n",    // Print with align to right
    s.substring(i<0?-i:i)           // skip the first |i| characters
     .replaceAll("(.).","$1 ")      // replace every even-positioned character with a space.
   );
}
Olivier Grégoire
źródło
3

C ++, 135 bajtów

Okej, oto mój strzał z C ++:

auto f=[&](auto f,int y)->void{
  for(int i{};i<n;i++) putchar(y<0?f(f,y+1?i+1:n-1-i),'\n':i<y||i+y&1?' ':s[i]);
}; f(f,-1); f(f,-2);

Wypróbuj online (ideone)!

Aleksandr Połtawski
źródło
3

Haskell , 140 137 bajtów

(m#n)s=(\(i,x)->' ':(last$"  ":[x:" "|rem i 2==m&&i>n]))=<<zip[0..]s
g s=((++)=<<reverse.tail)$id=<<[[(0#n)s,(1#n)s]|n<-[-1,1..length s]]

Wypróbuj online!

Zapisano 3 bajty thanls w Challenger5

Nie sądzę, żeby to było optymalne ...

f tworzy jedną z linii (m = 0 lub 1 to modulo numeru linii, njest numerem linii)

g interkaluje linie „nieparzyste” i „parzyste” i dodaje do wyniku zwierciadło siebie.

Jferard
źródło
Możesz zapisać bajty, definiując je fjako funkcję (m#n)s=...przedrostka (jak w ) zamiast funkcji przedrostka.
Esolanging Fruit
2

Mathematica 105 bajtów

(c=Characters@#;l=Length@c;StringRiffle@Table[If[Abs[j-l]<i&&EvenQ[j+i],c[[i]]," "],{j,1,2l+1},{i,1,l}])&

Może mógłbym wygolić kolejny bajt lub dwa, ale liczba znaków związana z obsługą ciągów znaków w Mathematica sprawia, że ​​takie proste wyzwania są niekonkurencyjne.

Kelly Lowder
źródło
2

J, 54 bajty

[:|:|.@i.@#(>@],~' '#~[)"_1[:(,' '&,)/&.>>:@i.@#<@#"0]

Wypróbuj online!(zwróć uwagę, że wyjście w TIO ma nowy wiersz i trzy spacje, ale to nie pochodzi z wywołania funkcji - prawdopodobnie jest to dokładnie to, co interpreter J robi automatycznie).

Myślę, że ogólny pomysł na rozwiązanie tego problemu jest słuszny, ale są pewne rzeczy, które prawdopodobnie robię nieoptymalnie, które zwiększają liczbę bajtów.

Poprzednie warianty

55 bajtów

<:@+:@#{.[:|:|.@i.@#(],~' '#~[)"_1>:@i.@#(,' '&,)/@#"0]

56 bajtów

<:@+:@#{.[:|:|.@i.@#(],~' '#~[)"_1#{.[:(,' '&,)//.[:]\.]

Wyjaśnienie

Zostanie to podzielone na kilka funkcji. Ponadto nie byłem tak dokładny w ostatnich częściach wyjaśnienia, więc daj mi znać, jeśli chcesz lepszego wyjaśnienia dla określonej części, a ja mogę to edytować.

dup   =. >:@i.@# <@#"0 ]
space =. (,' '&,)/&.>
pad   =. |.@i.@# (>@],~' '#~[)"_1 ]
trans =. |:
  • dup duplikuje każdy znak tyle razy, ile jego indeks (plus jeden) w ciągu
  • space wstawia spacje między każdym znakiem
  • pad wypełnia znaki odpowiednią ilością spacji
  • trans transponuje uzyskaną macierz

Przykładowe połączenie:

   trans pad space dup 'abc'
  c
 b 
a c
 b 
  c

Dup

>:@i.@# <@#"0 ]
>:@i.@#         Indices of each character plus one
      #          Length of the string
   i.            Range [0,length)
>:               Add one
        <@#"0 ] Duplicate each character as many times as it index (plus one)
           "0   For each
          #   ]  Copy the character
>:@i.@#           as many times as it index
        <        Box the result

Wyniki są umieszczane w ramkach, aby zapobiec dopełnianiu przez J spacji na końcach (ponieważ mają one nierówną długość).

Przykładowe połączenie:

   dup 'abc'
┌─┬──┬───┐
│a│bb│ccc│
└─┴──┴───┘

Przestrzeń

(,' '&,)/&.>
         &.>  For each boxed element
(,' '&,)/      Insert spaces between each

Przykładowe połączenie:

   space dup 'abc'
┌─┬───┬─────┐
│a│b b│c c c│
└─┴───┴─────┘

Podkładka

|.@i.@# (>@],~' '#~[)"_1 ]
        (>@],~' '#~[)      Pad the right arg with spaces given by the left arg
|.@i.@#                    Indices in reverse order
   i. #                     Range [0,length)
|.                          Reverse

Zasadniczo wypełnij pierwszy element długością - 1 spacje, drugi długością - 2 itd. Usuwa również boks.

Przykładowe połączenie:

   pad space dup 'abc'
  a  
 b b 
c c c

Transponować

To tylko wbudowana funkcja, |:która przejmuje transpozycję macierzy.

kapusta
źródło
1
Zastosowałem podobne podejście, ale unikałem boksowania. 45 bajtów: |:@(-@i.@-@#|."0 1((,@,.~' '#~#)@$"0~1+i.@#)). z pewnością można by dalej grać w golfa. ta część -@i.@-@#to pewnie nisko wiszący owoc, najprawdopodobniej
Jonasz
@Jonah Nie mogę szybko rozszyfrować, w jaki sposób działa twoja odpowiedź, więc zostawię to tobie, aby opublikować, jeśli chcesz, ponieważ chcę dołączyć wyjaśnienie mojej odpowiedzi. Wydaje mi się, że J jest dla mnie językiem tylko do zapisu.
cole
pomocne w szybkim rozszyfrowaniu:, f=. <some tacit expression>a następnie 5!:2 <'f'daje wizualizację w pudełku i 5!:4 <'f'wizualizację drzewa. w moim przypadku spróbuj $"0~1+i.@#najpierw uruchomić jakiś ciąg znaków, a następnie uruchom wszystko po prawej stronie |."0 1, a następnie zrozum, że |."0 1wszystko po lewej stronie, z wyjątkiem ostatniej transpozycji, wykonuje tylko niezbędne obroty.
Jonasz
1
och, nie spodziewałem się, że zaktualizujesz swoją odpowiedź. to było bardziej „hej, może ci się to wydawać interesujące”. mogłem to opublikować, ale czułem, że podejście na wysokim poziomie było wystarczająco podobne, że nie było tego warte.
Jonasz
2
Właśnie zapamiętałem złożone argumenty #pomocy tutaj, 26 bajtów z|:@((-#)|."_1(1j1##)"0)~#\
milami
1

JavaScript (ECMAScript 6), 161 bajtów

(s,n=console.log)=>s.split("").map((q,i,a,p)=>n(p=" ".repeat(q=a.length-++i)+a.map((v,j)=>j>=q&&j%2==q%2?a[j]+' ':'').join(''))||p).reverse().map((v,i)=>i&&n(v))

Wypróbuj online!

sgtdck
źródło
1

Perl 5 , 86 + 2 (-F) = 88 bajtów

Wykorzystałem sugestie @ Dom i kilka moich własnych poprawek, aby obniżyć liczbę bajtów.

for$k(0..$#F){$i=1;$a[$#F+$k]=$a[$#F-$k]=[map$i++<$k|($i+$k)%2?$":$_,@F]}say"@$_"for@a

Wypróbuj online!

Xcali
źródło
Przykro mi z tego powodu, ale cieszę się, że dostałeś swoją odpowiedź! Miałem trochę zabawy, kiedy próbowałem naprawić mój i nie mogę znaleźć rozwiązania, twoje było lepsze podejście! Możliwe jest upuszczenie kilku bajtów za pomocą, -aFaby wstawić wszystkie litery @Fi kilka drobnych poprawek ( -Fliczy się jako 3, ponieważ wymaga spacji po): Wypróbuj online!
Dom Hastings,
1
Dlaczego -F liczy się jako 3? Czy nie powinno to być co najwyżej 2? Czy to nie różnica między perl -e'code...'i perl -eF 'code...'. -aJest również niepotrzebny podczas używania -F, aby można było wyciąć bajt.
Xcali,
To jest dokładnie to. -FPrzyjmuje więc argument, ale nie chcemy go przekazywać ( -Fpozwala nam kontrolować, co -adzieli, bez argumentów, dzielenie każdego znaku osobno), więc jest to różnica między perl -ae '...'i perl -aF -e '...'. Domyślnie -adzieli się na /\s+/. Mam nadzieję, że to pomoże wyjaśnić!
Dom Hastings,
Również miłe wykorzystanie $#F! Zawsze o tym zapomnij!
Dom Hastings,
0

q / kdb +, 55 bajtów

Rozwiązanie:

-1(+){{1_a,((2*y)#" ",z),a:x#" "}'[(|)c;1+c:(!)(#)x]x};

Przykład:

q)-1(+){{1_a,((2*y)#" ",z),a:x#" "}'[(|)c;1+c:(!)(#)x]x}"Hello World";
          d
         l
        r d
       o l
      W r d
       o l
    o W r d
   l   o l
  l o W r d
 e l   o l
H l o W r d
 e l   o l
  l o W r d
   l   o l
    o W r d
       o l
      W r d
       o l
        r d
         l
          d

Wyjaśnienie:

DO ZROBIENIA. wersja bez golfa ma 66 bajtów:

-1 flip{{1_a,((2*y)#" ",z),a:x#" "}'[reverse c;1+c:til count x]x};

Premia:

Aby uzyskać takie same dane wyjściowe jak w przykładzie (74 bajty):

q)-1(+){1_'raze{(a,((2*y)#" ",z),a:x#" ";(2*y+x)#" ")}'[(|)c;1+c:(!)(#)x]x}"Hello World";
                    d
                  l
                r   d
              o   l
            W   r   d
              o   l
        o   W   r   d
      l       o   l
    l   o   W   r   d
  e   l       o   l
H   l   o   W   r   d
  e   l       o   l
    l   o   W   r   d
      l       o   l
        o   W   r   d
              o   l
            W   r   d
              o   l
                r   d
                  l
                    d
streetster
źródło