Лимон-ограничить строку


34

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

Напечатайте или верните ASCII художественную ромбовидную форму, похожую на лимон или лайм, сделанные из префиксов строки.

Предположим, что длина входной строки составляет n букв. Затем такая форма состоит из 2n - 1 столбцов искусства ASCII, сшитых вместе, каждая из которых состоит из 2n - 1 линий. Считая от 1, k-й столбец имеет ширину f (k) = min (k, 2n - k) символов и содержит f (k) копии первых f (k) символов ввода, по центру по вертикали с одним пробелом линии, разделяющие копии.

Например, если на входе Lemon, выход должен быть:

          Lemon
      Lemo     Lemo
   Lem    Lemon    Lem
 Le   Lemo     Lemo   Le
L  Lem    Lemon    Lem  L
 Le   Lemo     Lemo   Le
   Lem    Lemon    Lem
      Lemo     Lemo
          Lemon

Если на входе limeвывод, должен быть:

      lime
   lim    lim
 li   lime   li
l  lim    lim  l
 li   lime   li
   lim    lim
      lime

И тот же шаблон применяется для других входов:

a

a

Be

 Be
B  B
 Be

/\

 /\
/  /
 /\

cat

   cat
 ca   ca
c  cat  c
 ca   ca
   cat

|||

   |||
 ||   ||
|  |||  |
 ||   ||
   |||

.__.

      .__.
   .__    .__
 ._   .__.   ._
.  .__    .__  . 
 ._   .__.   ._
   .__    .__
      .__.

$tring

               $tring
          $trin      $trin
      $tri     $tring     $tri
   $tr    $trin      $trin    $tr
 $t   $tri     $tring     $tri   $t
$  $tr    $trin      $trin    $tr  $
 $t   $tri     $tring     $tri   $t
   $tr    $trin      $trin    $tr
      $tri     $tring     $tri
          $trin      $trin
               $tring

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

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


13
Я был удивлен, что вы использовали только префиксы - я ожидал префиксы слева и суффиксы справа!
Нил

1
(На самом деле из кодировки POV я бы предпочел суффиксы повсюду, но вы не можете съесть свой пирог и съесть его.)
Нил

2
Определите « форму, похожую на лимон или лайм »
Питер Тейлор,

6
@PeterTaylor Форма, показанная в примерах. Если честно, есть входная строка, для которой вы не можете вывести вывод?
Увлечения Келвина

6
Мне не нужно ничего делать: у вопроса должна быть спецификация .
Питер Тейлор

Ответы:


11

Matlab, 140 136 128 124 байтов

В основном сначала начинается со средней секции, а затем шаг за шагом добавляет / добавляет сокращенные / измененные версии.

a=input('');v=ones(nnz(a)*2-1,1)*a;v(2:2:end,:)=0;b=v;for k=a;v=v(2:end,1:end-1);v(end+1,:)=0;b=[v,b,v,''];end;b(~flip(b))=0

Спасибо за 8 байтов @LuisMendo!

Например, MATLABмы получаем:

               MATLAB               
          MATLA      MATLA          
      MATL     MATLAB     MATL      
   MAT    MATLA      MATLA    MAT   
 MA   MATL     MATLAB     MATL   MA 
M  MAT    MATLA      MATLA    MAT  M
 MA   MATL     MATLAB     MATL   MA 
   MAT    MATLA      MATLA    MAT   
      MATL     MATLAB     MATL      
          MATLA      MATLA          
               MATLAB                    

О, классная идея! К сожалению, моя старая версия не имеет flip: /
flawr

Я протестировал ваш 124-байтовый код на R2015b, и я подтверждаю, что он работает
Луис Мендо

Tha п к у о ц!
flawr

7

Python 2, 121 110 байт

s=input()
n=len(s)
r=range(1,n)+range(n,0,-1)
for y in r:print''.join(s[:(x+y-n&(x+y>n))*x]or' '*x for x in r)

116 байт при использовании raw_input. Программа по существу делает маску на основе L1-нормы / манхэттенского расстояния от центра, а также четности этого расстояния по сравнению с четностью входной длины.

(Спасибо @Lynn за -9 байтов и еще 2)


Одна вещь, которая появляется, состоит в том, что вы могли бы сжать первые две строки до l = len (input ()), нет?
Франк

@Frank sиспользуется в конце длинной строки, поэтому, к сожалению, это невозможно
Sp3000

Python 2 может получить 112 или 116 байтов, используя немного другой выбор для R.
Линн

Ах, я этого не понял, извини.
Франк

@ Линн Ого, этот выбор или Rделает код намного аккуратнее!
Sp3000


6

JavaScript (ES6), 132 байта

s=>{x=' '.repeat(l=s.length);for(n=r='';n++<l;r=r?t+`
${r}
`+t:t)for(i=l,t='';i;t=t?w+t+w:w)w=(i<n|n+i&1?x:s).slice(0,i--);return r}

Тест

var solution =

s=>{
  x=' '.repeat(l=s.length);
  for(n=r='';n++<l;r=r?t+`\n${r}\n`+t:t)
    for(i=l,t='';i;t=t?w+t+w:w)
      w=(i<n|n+i&1?x:s).slice(0,i--);
  return r
}

result.textContent = solution('Lemon');
<input type="text" id="input" value="Lemon" oninput="result.textContent=solution(this.value)" /><pre id="result"></pre>




2

JavaScript, 187 178 байт

Побитовый подход. Функция mопределяет маску, начиная с 2 ** length, например, 00100в двоичном, и определяя m(n) = m(n-1) << 1 | m(n-1) >> 1для первой половины. Интересно, что вторая половина может быть определена как m(n) = m(n-1) << 1 & m(n-1) >> 1. (хотя программа вместо этого выбирает определение m(n) = m(2 * length - 1)для второй половины) Отсюда эти маски могут использоваться, чтобы определить, должно ли слово или пробел появляться, проверяя 2 ** column & m(row). Конечно, в JavaScript писать проще 2 ** somethingс помощью 1 << something...

примечание: написано, когда устал Может почти наверняка есть ошибки.

s=>{m=n=>n?n>l?m(2*l-n):(p=m(n-1))>>1|p<<1:1<<l
for(r=0;r/2<=(l=s.length-1);r++){for(i=1,o="";i/2-1<l;i++)o+=(1<<i-1&m(r)?s:" ".repeat(i)).slice(0,i>l?2*l+2-i:i)
console.log(o)}}

2

Haskell, 109 байт

f s|n<-length s,r<-[1..n]++[n-1,n-2..1]=unlines[do x<-r;min(" ~"!!mod((x+y+n)*min(n-x-y)0)2)<$>take x s|y<-r]

2

Брахилог , 46 байт

{a₀⟨{;Ṣ}j₎l⟩}ᶠL&l;Ṣj₍ẹa₁ᶠ;Lz{czzcᵐ}ᵐ⟨kc↔⟩zcᵐ~ṇ

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

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

              L    The variable L
{           }ᶠ     is a list containing every possible
 a₀                prefix of
                   the input
    {;Ṣ}           paired with a space
        j          and concatenated with itself
   ⟨     ₎l⟩       a number of times equal to its length.
          ᶠ    A list containing every possible
        a₁     suffix of
   Ṣ           a space
    j          concatenated with itself
  ;  ₍         a number of times equal to
 l             the length of
&              the input
      ẹ        then split back up into its elements
               is an important list which doesn't actually get a name.
                         That list
;Lz                      zipped with L
   {     }ᵐ              with each pair being
    c                    concatenated,
     z                   zipped with cycling,
      z                  zipped back,
        ᵐ                and subjected to each of its elements being
       c                 concatenated itself,
           ⟨kc↔⟩         then palindromized
                z        and zipped yet again
                 cᵐ      with every line concatenated once more
                   ~ṇ    and finally joined on newlines
                         is the output.

Почти единственной умной частью всего этого является использование a₁для генерации вертикальных пробелов с наибольшими первыми, в то время как a₀генерирует префиксы слов наименьший из первых, и zzдля расширения одиночных пробелов в блоки пространства, соответствующие ширине префиксов.


1

TSQL, 259 байт

Golfed:

DECLARE @ VARCHAR(30)='TSQL'

,@o VARCHAR(max),@i INT=0,@j INT,@t VARCHAR(max)SET @j=LEN(@)z:WHILE @i<LEN(@)SELECT @o=x+ISNULL(@o+x,''),@i+=1FROM(SELECT LEFT(IIF((@j-@i)%2=1,@,SPACE(99)),LEN(@)-@i)x)z SELECT @j-=1,@t=@o+ISNULL(CHAR(10)+@t+CHAR(10)+@o,''),@o=null,@i=0IF @j>0GOTO z PRINT @t

Ungolfed:

DECLARE @ VARCHAR(30)='TSQL'

,@o VARCHAR(max),@i INT=0,@j INT,@t VARCHAR(max)SET @j=LEN(@)
z:
WHILE @i<LEN(@)
  SELECT @o=x+ISNULL(@o+x,''),@i+=1
  FROM(SELECT LEFT(IIF((@j-@i)%2=1,@,SPACE(99)),LEN(@)-@i)x)z
SELECT @j-=1,@t=@o+ISNULL(CHAR(10)+@t+CHAR(10)+@o,''),@o=null,@i=0
IF @j>0 GOTO z

PRINT @t

скрипка


0

C 167 байт

Эта программа ожидает, что входной текст будет передан в качестве первого параметра программе (через командную строку или как-либо еще), и запишет вывод в стандартный вывод.

int i,j,k,l,v;main(h,s)char**s;{h=strlen(s[1]);l=h*2;for(;++i<l;puts(""))for(j=0;++j<l,v=j<h?j:l-j;)for(k=0;k++<v;putchar((i+j+h%2)%2&&v>h-(i<h?i:l-i)?s[1][k-1]:32));}

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

объяснение

/* Static variables
   i - "Row" number
   j - "Column" number
   k - String character counter
   l - Double length of the input string
   v - Inverted column distance from center */
int i,j,k,l,v;

/* Main parameters
   h - (argc) Input string length
   s - argv */
main(h, s)
char**s;
{
  /* Assign the input string length and double length */

  h = strlen(s[1]);
  l = h * 2;

  /* Display content */

    /* Loop over rows l - 1 times and put a newline after each */
  for (; ++i < l; puts(""))
      /* Loop over columns l - 1 times and set the inverted column
         distance each time */
    for (j = 0; ++j < l, v = ((j < h) ? j : l - j);)
        /* Loop over characters up to the inverted column distance from the
           center (this generates the pattern of output lengths needed) */
      for (k = 0; k++ < v;)
        putchar(
            /* Check for if the current row + column (with an offset based on
               the input parity) parity is even or odd, creating the needed
               checkerboard pattern */
          (i + j + h % 2) % 2 &&
            /* If the inverted column distance from the center is more than the
               row distance from the center, then the cell is inside the
               circular shape */
          v > (h - ((i < h) ? i : l - i)) ?
              /* Display the requested character (minus one for 0 based) */
            s[1][k-1] :
            32 /* Otherwise display a space (ASCII 32) */
        );
}

Достаточно важно отметить использование (n < m) ? n : (m * 2) - nв программе как минимум дважды, чтобы получить инвертированное расстояние от центральной позиции mв диапазоне m * 2с входом n. Если есть более короткий способ сделать это, его можно было бы упростить, так как этот алгоритм важен для работы этой программы.


0

C, 137 байтов

x,y,w;main(l,v)char**v;{for(y=l=strlen(v[1]);-l<--y;putchar(10))for(x=l;-l<--x;printf("%*.*s",w,w,x+y+l&1&&w>abs(y)?v[1]:""))w=l-abs(x);}

Сломать:

Это рисует каждый элемент сетки 2n-1 x 2n-1 с функцией маски, решающей, должен ли текущий элемент быть пробелом или входным словом (маска проверяет форму ромба и рисунок шахматной доски).

x,y,w;
main(l,v)char**v;{
    for(y=l=strlen(v[1]);-l<--y;/*...*/)    // row loop (count down to save bytes)
        for(x=l;-l<--x;/*...*/)             // column loop
            w=l-abs(x);                     // calculate current word's width
            printf("%*.*s",                 // print...
                w,w,                        // ...with min & max width...
                x+y+l&1&&w>abs(y)           // Check mask:
                    ?v[1]                   //  ...word
                    :"")                    //  ...or blank space
        putchar(10)                         // Newline
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.