Детонировать строку


34

Для любой строки выведите ее в форме треугольника, где текст проходит вверх и вниз по каждой диагонали. Например, вход "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

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


1
Можем ли мы предположить, что строка не пуста?
Мистер Кскодер

@ Mr.Xcoder Да, вы можете
Макиавелли

1
Пробел между каждым символом в строке должен быть не менее 1 : означает ли это, что H l o W r dявляется допустимой центральной строкой? Спросите, потому что в вашем примере каждая строка имеет 3 пробела между каждым символом.
Emigna

1
@ Emigna Я неправильно понял твой вопрос, мои извинения. Да, ваш пример будет верным.
Макиавелли

1
Разрешены лидирующие или конечные пробелы?
Луис Мендо

Ответы:


19

Древесный уголь , 10 7 байт

↗ELθ✂θιUE¹

Попробуйте онлайн! Попробуйте онлайн! Ссылки на подробную версию кода. Объяснение:

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

Впервые я использовал UEкоманду.


Я знал, что Древесный уголь будет одним из первых ответов здесь .. Было почти заманчиво начать самому, но я неопытен, чтобы закончить решение вовремя, и оно все равно выйдет из игры в гольф ...;)
Кевин Круйссен

6
@ Emigna ... но это был мой большой шанс использовать UE...
Нил

6
@EriktheOutgolfer ... но это был мой большой шанс использовать UE..
Нил

1
@Neil Это -3 байта! -3 за хорошую жертву! Кто не хочет хороших -3?
Эрик Outgolfer

4
@EriktheOutgolfer То, что вы должны сказать, это: «Вы не можете позволить 05AB1E победить вас, не так ли?»
Нил

12

05AB1E , 10 8 7 байт

Спасибо Emigna за сохранение 2 байта!

ðâƶ.cðζ

Использует кодировку 05AB1E . Попробуйте онлайн!


Согласно этой строке расстояние между символами в строке должно быть не менее 1, которое вы можете удалить ¶«. (также проверил действительность с OP)
Emigna

@ Emigna Спасибо! :)
Аднан


@ Mr.Xcoder ninja'd
Аднан

1
Умное использование âв ðâвместо Sð«!
Эрик Outgolfer


8

C 86 78 73 70 символов

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

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

объяснение

Наивная реализация: два цикла, заполнение сверху вниз, слева направо (99 байт):

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

Здесь put () просто печатает \ n на выходе. Давайте объединим объявления переменных и совместим j ++ с чем-либо (94 байта):

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

Хорошо. Переменная j имеет диапазон 0 ... 2n; пусть это будет в пределах -n ... n, это упрощает математику. Обратите внимание, что логическое выражение справа от && всегда имеет значение 0 или 1. Это означает, что мы можем заменить && на &. 91 байт:

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

И теперь мы поняли, что печатаем лишнее пространство. И да, нам не нужно printf () для печати только одного символа. 86 байт:

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

Даже лучше. Обратите внимание, что условие i * i> = j * j такое же, как i> = abs (j), но короче. Давайте переместим put () в выражение для приращения цикла. И угадайте, что? На самом деле, нам не нужны скобки вокруг i + j. 78 байт:

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

Знаете ли вы, что putchar () возвращает напечатанный символ? Давайте использовать XOR для проверки чисел на эквивалентность. Давайте заменим пробел кодом ASCII, 32. Помните, что символ конца строки равен 13. И, наконец: знаете ли вы, что GCC / Clang поддерживает https://en.wikipedia.org/wiki/Elvis_operator ? 73 байта:

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

Наконец, угадайте что? Нам не нужны две петли. Мы можем заменить уродливый ~ i + j просто ij. 70 байтов:

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

Будущая работа: изменить направление петли? Это может сэкономить несколько байтов, если все сделано правильно.


5

SOGL V0.12 , 13 10 9 байтов

ēI*@∑}¹╚H

Это использует функцию, которую я только что добавил , но был задокументирован некоторое время назад.

Попробуй это здесь!
В эту ссылку ,добавляется, потому что это ожидает ввода в стек и {добавляется, потому что в противном случае ,будет выполняться каждый раз в цикле

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


3

Gaia , 16 байт

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

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

объяснение

$                 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




3

Java, 292 байта (извините)

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

1
Вы можете удалить переводы строк, в противном случае это выглядит довольно красиво!
Захари

1
Вы можете играть в гольф больше: 1 boolean a=1<0,o=L%2>0;.. 2. Если вам не нужно iиспользовать этот цикл: for(i=0;i++<n;). 3. Вы можете избавиться от o: j%2<L%2тогда j%2>L%2. 4. Использование dфункции flip занимает столько символов: просто сделайте j<(x<0?-x:x). 5. У вас больше переменных, чем нужно. 6. Вам не нужна полная программа: достаточно лямбды или метода. - Если вы хотите пример игры в гольф на Java, проверьте мой ответ .
Оливье Грегуар


3

Java (OpenJDK 8) , 116 байт

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

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

объяснение

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


3

Haskell , 140 137 байт

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

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

Сохранено 3 байта спасибо Challenger5

Я не думаю, что это оптимально ...

fпроизводит одну из строк ( m= 0 или 1 по модулю номера строки,n это номер строки)

g интеркалирует «нечетные» и «четные» строки и добавляет к результату зеркало самого себя.


Вы можете сохранить байты, определив их fкак инфиксную функцию (как в (m#n)s=...), а не как префиксную функцию.
Esolanging Fruit



2

Mathematica 105 байт

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

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


2

J 54 байта

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

Попробуйте онлайн!(обратите внимание, что вывод на TIO имеет новую строку и три пробела, но это не из вызова функции - это, вероятно, то, что интерпретатор J делает автоматически).

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

Предыдущие варианты

55 байт

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

56 байт

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

объяснение

Это будет разделено на несколько функций. Кроме того, я не был настолько внимателен с последними частями объяснения, поэтому дайте мне знать, если вы хотите более подробное объяснение определенной части, и я могу отредактировать это в.

dup   =. >:@i.@# <@#"0 ]
space =. (,' '&,)/&.>
pad   =. |.@i.@# (>@],~' '#~[)"_1 ]
trans =. |:
  • dup дублирует каждый символ столько раз, сколько его индекс (плюс один) в строке
  • space вставляет пробелы между каждым символом
  • pad дополняет символы нужным количеством пробелов
  • trans транспонирует полученную матрицу

Образец звонка:

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

дубликат

>:@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

Результаты помещены в рамку, чтобы предотвратить заполнение J пробелами (поскольку они имеют неравную длину).

Образец звонка:

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

Космос

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

Образец звонка:

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

подушечка

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

В основном, отступ первого элемента с длиной - 1 пробел, второго с длиной - 2 и т. Д. Также удаляется бокс.

Образец звонка:

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

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

Это просто встроенная функция, |:которая выполняет транспонирование матрицы.


1
Я использовал аналогичный подход, но избегал бокса. 45 байт: |:@(-@i.@-@#|."0 1((,@,.~' '#~#)@$"0~1+i.@#)). это, безусловно, может быть дальше. эта часть -@i.@-@#- какой-то низко висящий фрукт, скорее всего
Иона

@Jonah Я не могу быстро расшифровать, как работает твой ответ, поэтому я оставлю это тебе, если хочешь, чтобы опубликовать его, так как я хотел бы включить объяснение моего ответа. Я думаю, что J для меня сейчас это язык только для записи.
Коул

полезно для быстрого дешифрования:, f=. <some tacit expression>затем 5!:2 <'f'дает коробочную визуализацию и 5!:4 <'f'дает древовидную визуализацию. в моем случае попробуйте $"0~1+i.@#сначала запустить с какой-нибудь строкой, затем запустить все справа от |."0 1, затем понять, что |."0 1и все слева, кроме окончательной транспонирования, просто выполняет необходимые повороты.
Иона

1
о, я не ожидал, что вы обновите свой ответ. это было скорее "эй, вы можете найти это интересным". Я мог бы опубликовать это, но чувствовал, что подходы высокого уровня были достаточно похожи, это того не стоило.
Иона

2
Просто вспомнил сложные аргументы #|:@((-#)|."_1(1j1##)"0)~#\
миль


1

Perl 5 , 86 + 2 (-F) = 88 байт

Использовал предложения @ Dom и несколько моих собственных настроек, чтобы уменьшить количество байтов.

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

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


Извините за это, рад, что вы получили свой ответ, хотя! Немного поиграл, когда я пытался починить свое и не смог найти решение, ваш подход был лучше! Можно отбросить пару байтов, используя -aFдля ввода всех букв, @Fи несколько небольших настроек ( -Fсчитается как 3, так как после этого требуется пробел): попробуйте онлайн!
Дом Гастингс

1
Почему -F считается 3? Разве это не должно быть максимум 2? Разве это не разница между perl -e'code...'и perl -eF 'code...'? Также -aне -Fтребуется при использовании , чтобы можно было вырезать байт.
Xcali

Это точно. Так что -Fпринимает аргумент, но мы не хотим его передавать ( -Fпозволяет нам контролировать то, -aна что делится, без аргументов, разделять каждый символ самостоятельно), так что это разница между perl -ae '...'и perl -aF -e '...'. По умолчанию -aразделяется на /\s+/. Надеюсь, это поможет уточнить!
Дом Гастингс

Кроме того, хорошее использование $#F! Всегда забудь об этом!
Дом Гастингс

0

q / kdb +, 55 байт

Решение:

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

Пример:

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

Объяснение:

СДЕЛАТЬ. Развернутая версия - 66 байт:

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

Бонус:

Чтобы получить тот же вывод, что и в примере (74 байта):

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