З днем ​​народження V!


72

Дякуємо @KritixiLithos за те, що допомагає мені вирішити цю проблему!


V - мова програмування, яку я написав, щоб я міг використовувати і розширювати vim для проблем з кодовим гольфом. Найперший вчинок відбувся 3 березня 2016 року, це означає, що сьогодні V виповнюється рік! Ву-ху

За перший рік існування V було зареєстровано 176 доручень від чотирьох різних учасників, 140 відповідей від 12 різних користувачів і занадто багато зламаних дублікатів операторів для підрахунку . У ньому є перекладач в Інтернеті , який щедро розміщував @Dennis, який проводився майже 8000 разів із грудня .

Будемо мати виклик святкувати день народження V! Оскільки більшість функцій V розроблені з використанням маніпуляцій зі струнами та , то просто видається природним, що будь-який виклик святкування V повинен стосуватися мистецтва ascii. Отже, ваше завдання сьогодні полягає в тому, щоб взяти слово як вхідне і змінити це слово у формі V. Наприклад, введення "Привіт" повинно містити наступне V:

Hello         olleH
 Hello       olleH
  Hello     olleH
   Hello   olleH
    Hello olleH
     HellolleH
      HellleH
       HeleH
        HeH
         H

Ось кілька деталей про те, як повинен виглядати ваш V. Якщо вхідний рядок довжиною n символів, V має бути n*2високими рядками. Перший рядок повинен складатися з:

<input string><(n*2) - 1 spaces><input string reversed>

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

Можна припустити, що вхід завжди буде надрукованим ASCII без пробілів у ньому, і ви можете приймати введення та вихід будь-яким розумним методом. Ось ще кілька прикладних входів:

Happy:

Happy         yppaH
 Happy       yppaH
  Happy     yppaH
   Happy   yppaH
    Happy yppaH
     HappyppaH
      HapppaH
       HapaH
        HaH
         H

Birthday:

Birthday               yadhtriB
 Birthday             yadhtriB
  Birthday           yadhtriB
   Birthday         yadhtriB
    Birthday       yadhtriB
     Birthday     yadhtriB
      Birthday   yadhtriB
       Birthday yadhtriB
        BirthdayadhtriB
         BirthdadhtriB
          BirthdhtriB
           BirthtriB
            BirtriB
             BiriB
              BiB
               B

V!:

V!   !V
 V! !V
  V!V
   V

~:

~ ~
 ~

Звичайно, оскільки це , стандартні лазівки заборонені, і ваша мета - написати якомога коротшу програму для виконання цього завдання. Щасливого гольфу!


Що для цього варто, у мене є м'яке місце для відповідей на vim, тому уявні бонусні бали за використання vim або V, хоча будь-яка мова є прийнятною. :)


Чи можна надрукувати один нульовий символ (0x00) після кожного нового рядка?
Пшеничний майстер

@wheatwizard Хм. Це трохи дивно, але я гадаю, що це добре, якщо результат візуально однаковий.
DJMcMayhem

21
5-й день народження буде чимось іншим! (Романськими цифрами)
Альберт Реншо

5
Найкращі побажання V-мові від Vee :-)
The Vee

Відповіді:


44

MATL , 21 14 байт

MATL бажає V щасливого дня народження!

tnEXyY+c3MZvZ)

Спробуйте в Інтернеті!

Пояснення

Розглянемо вхід

'Hello'

довжини n=5. Код обчислює двовимірну згортку цього рядка з ідентифікаційною матрицею розміру 2*n,

[1 0 0 0 0 0 0 0 0 0;
 0 1 0 0 0 0 0 0 0 0;
 0 0 1 0 0 0 0 0 0 0;
 0 0 0 1 0 0 0 0 0 0;
 0 0 0 0 1 0 0 0 0 0;
 0 0 0 0 0 1 0 0 0 0;
 0 0 0 0 0 0 1 0 0 0;
 0 0 0 0 0 0 0 1 0 0;
 0 0 0 0 0 0 0 0 1 0;
 0 0 0 0 0 0 0 0 0 1]

Результат згортки, перетвореної в char і з char 0, показаної як пробіл, є

['Hello         ';
 ' Hello        ';
 '  Hello       ';
 '   Hello      ';
 '    Hello     ';
 '     Hello    ';
 '      Hello   ';
 '       Hello  ';
 '        Hello ';
 '         Hello']

Тоді стовпці [1, 2, ..., 2*n-1, 2*n, 2*n-1, ..., 2, 1]вибираються з цієї матриці char, даючи бажаний результат:

['Hello         olleH';
 ' Hello       olleH ';
 '  Hello     olleH  ';
 '   Hello   olleH   ';
 '    Hello olleH    ';
 '     HellolleH     ';
 '      HellleH      ';
 '       HeleH       ';
 '        HeH        ';
 '         H         ']

Коментований код

t      % Implicitly input string. Duplicate
nE     % Length, say n. Multiply by 2
Xy     % Identity matrix of that size
Y+     % 2D convolution. This converts chars to ASCII codes
c      % Convert to char
3M     % Push 2*n, again
Zv     % Push symmetric range [1, 2, ..., 2*n, 2*n-1, ..., 1]
Z)     % Apply as column indices. This reflects the first 2*n columns
       % symmetrically, and removes the rest. Implicitly display

Дуже цікавий підхід! +1
seshoumara

3
@seshoumara Дякую! Як каже недолік, згортання - запорука успіху :-)
Луїс Мендо

38

V , 24, 23 , 20 байт

3Ù2Ò Íî
Xæ$òâÙHãêxx>

Спробуйте в Інтернеті!

Набагато коротше, коли V має "зворотний" оператор .

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

00000000: 33d9 32d2 20cd ee0a 58e6 24f2 e2d9 48e3  3.2. ...X.$...H.
00000010: ea78 783e                                .xx>

Пояснення:

3Ù                  " Make three extra copies of this current line
  2Ò                " Replace each character on this line and the next line with spaces
     Íî             " Join all lines together
X                   " Delete one space
 æ$                 " Reverse the word under the cursor

У цей момент буфер виглядає приблизно так:

Happy         yppaH

Ні, ми будемо рекурсивно будувати трикутник вниз.

ò                   " Recursively:
 â                  "   Break if there is only one non-whitespace character on this line
  Ù                 "   Make a copy of this line
   H                "   Move to the first line
    ã               "   Move to the center of this line
     ê              "   Move to this column on the last line
      xx            "   Delete two characters
        >           "   Indent this line

Ось де я можу показати одну з моїх улюблених особливостей V. Багато команд вимагають аргументу. Наприклад, >команда відступить змінну кількість рядків залежно від аргументу:

>>    " Indent this line (this command is actually a synonym for '>_')
>j    " Indent this line and the line below
>k    " Indent this line and the line above
6>>   " Indent 6 lines
>}    " Indent to the end of this paragraph
>G    " Indent to the last line
...   " Many many many more

але більшість команд буде змушене закінчуватися аргументом за замовчуванням (зазвичай це поточний рядок), якщо він знаходиться в кінці програми і не вказаний. Наприклад, те, що V насправді працює для нашого рекурсивного циклу, це:

òâÙHãêxx>>ò

Другий òнеявно заповнений. Холодно, що команди, що неявно закінчуються, наносять кілька шарів глибоко, тож хоч ми лише писали >, V неявно подасть _аргумент, і він відступить поточний рядок.


Я працював над цим, але думаю, що вам більше підходить відповісти!
nmjcman101

29

Brainfuck , 152 байти

Це така важлива нагода, що я вирішив зламати інтерпретатора ol 'BF і роздумувати це.

++++++++++[->+>+++<<]>>++>>+>>>,[[<]<<+>>>[>],]<[<]<<-[->+>>[>]>++++[-<++++++++>]<[<]<<]>[->++<]>[-<+>]<[<[-<+<.>>]<[->+<]>+>->>[.>]<[-]<[.<]<<<<<.>>>>]

З коментарями

++++++++++
[->+>+++<<] Insert 0 into the first buffer (Which we don't care about) 10 into the second and 30 into the thrd
>>++    Raise the third buffer to 32 making us our space
>   This buffer is reserved for the Insertable spaces counter
>
+>>>    Raise our incrementer This will be used to fill the other half of the string with spaces
,[  Read a byte
    [<]<<   Move to the back of the string buffer which is our incrementer
    +       increment it
    >>>[>]      And move to the next space of the string
    ,       And then read a new byte
]
<[<]<<-     Decrement the incrementer and begin to add spaces
[
    -       Decrement the incrementer
    >+      Raise the incrementer in the padding
    >>[>]   Move to a new part of the string buffer
    >++++[-<++++++++>]< Write a space
    [<]<<   Move all the way back to the string counter
]
BEGIN WRITING!!
>
[->++<]>[-<+>]<Double the incrementer
[
    <[  Move to the space counter
        -<+<.>> Decrement the space counter increment the temporary one to the left of it then print the space we stored to the left of that then return
    ]<[->+<]>+> Move the temporary space counter back
    -   Decrement the incrementer
    >>[.>]  Print every character from left to right
    <[-]    Snip the end off this
    <[.<]   Print every character from right to left
    <   Move back ot the incrementer
    <<<<.>>>> Print a newline aswell
]

Спробуйте в Інтернеті!


23

> <> , 221 байт

Я витратив шлях надто багато часу на це. З днем ​​народження, V!

l:2*01           p84*/v
 !@:$-1         /!?:$<
  1.v/ ^       v\~~>a
   vv\}o<     >ao  /
    1\/84/   :}o:$-
     \\!?<: l;!?\v
      p10-1:g10r\
       >  :>?\vv
        v:$-1/~
         </r+*
          </~
           l

Ви можете спробувати в Інтернеті , але набагато веселіше отримати цього перекладача та запустити його за допомогою --playпрапора

python3 fish.py v.fish -s "ppcg" --tick 0.05 --play

що призводить до анімації нижче.

Приклад

Приклад рибного бігу

(це займає трохи менше двох хвилин)

Пояснення

Оскільки цікавою частиною цієї відповіді є загортання її у Vформу, ось пояснення, яке відповідає їй. Для довідки використовуємо наступну рядкову версію.

1. l:2*01           p84*/v
2.  !@:$-1         /!?:$<
3.   1.v/ ^       v\~~>a
4.    vv\}o<     >ao  /
5.     1\/84/   :}o:$-
6.      \\!?<: l;!?\v
7.       p10-1:g10r\
8.        >  :>?\vv
9.         v:$-1/~
10.         </r+*
11.          </~
12.           l

Іноді стрілки (→ ↓ ←) використовуються для позначення напрямку, у якому досягається фрагмент.

  1. Ініціалізація

       1.→l:2*01           p84*/v
       2.  !@:$-1   X     /!?:$<
       3.   1.            \~~>a
    

    Перший рядок буде натискати 2n до [0,1], залишити n у стеці та додавати пробіл. Далі ми піднімаємось вгору і загортаємо до другої лінії праворуч, де ми почнемо йти ліворуч. Існує цикл для додавання n + 1 пробілів. Це працює наступним чином.

                    Initial:                 "ppcg4 "
    !@:$-1 /!?:$<
               $     Swap.                   "ppcg 4"
              :      Duplicate.              "ppcg 44"
             ?       If more spaces to add:
        -1            Subtract 1.            "ppcg 3"
       $              Swap.                  "ppcg3 "
      :               Duplicate.             "ppcg3  "
     @                Rotate top 3.          "ppcg 3 "
    !                 Jump over stored value
                             and wrap around.
                    Else:
            /         Go to next part.
    

    Після цього він відхиляється до рядка 3. Там два верхніх елемента стека (0 і пробіл) видаляються ( ~~), і ми переходимо до Xмісця розташування [10,1] ( a1.), продовжуючи праворуч. Ми стикаємося на /, переходимо до рядка 7 і запускаємо основний цикл програми.

  2. Основний цикл ( 2n рази)

     6.              ;!?\
     7.       p10-1:g10r\   ←
    

    Це умова циклу. Спочатку стек перевертається для друку. Тоді отримуємо лічильник з [1,0] ( 01g) і зберігаємо зменшену версію ( :1-01p). Обертаючись навколо, стикаючись вгору і вправо, ми стикаємося з умовою припинення програми. Якщо ми не припинимо, ми перестрибуємо в перший цикл друку.

    • Перша петля друку (ліва половина)

      5.    1\   /   :}o:$-
      6.     \\!?<: l         ←
      

      Починаємо з довжини вверху стека і виконуємо наступний код до тих пір, поки верхній елемент не дорівнює 0.

      1-$:o}
      
      1-        Subtract 1.    "ppcg3"
        $       Swap.          "ppc3g"
         :      Duplicate.     "ppc3gg"
          o     Output.        "ppc3g"
           }    Rotate right.  "gppc3"
      

      Це надрукує стек, не скидаючи його. Якщо цикл закінчується, ми переходимо вправо по рядку 5, готуючись до наступного циклу друку.

    • Підготовка правої половини

      5.  →    /84/   
      6.       \     
      7.            :    
      8.            >
      9.         v:$-1/~
      10.         </r+*
      11.          </~
      12.           l
      

      Це була одна з найважчих деталей. Нижче наведена версія, яка позбавлена ​​всіх напрямків, щоб вказати, що відбувається.

                   Initial stack:   "    gcpp0"
      84*+r~
      84*          Push 32 == " ".  "    gcpp0 "
         +         Add 32 and 0.    "    gcpp "
          r        Reverse.         " gcpp    "
           ~       Remove top.      " gcpp   "
      

      Потім натискаємо на довжину того, що має бути надруковано, і починаємо другий цикл друку (з початковим дублікатом, що не є частиною циклу).

    • Друга петля друку (права половина)

      3.     / ^ 
      4.     \}o<
      5.    
      6.           ↓   
      7.           
      8.       >  :>?\vv
      9.        v:$-1/~ 
      

      Код, що виконується, повністю такий самий, як у першому циклі друку, при цьому o}він розміщується трохи далі, оскільки там були доступні місця. Закінчивши, нам залишається зробити кілька речей, перш ніж ми зможемо ще раз перевірити інваріант основного циклу. Після виконання ~лінії 9 обертаємося вертикально, закінчуючи наступним фрагментом коду.

                      ↓
      2.          X     / 
      3.  1.v/             >a
      4.              >ao  /
      

      Спочатку aoнадрукуємо новий рядок. Тоді ми підстрибуємо вгору і доходимо до того самого місця, що відбулося після ініціалізації, а саме стрибки на X.


ви, мабуть, повинні зробити версію для гольфу основною версією
лимон

1
@DestructibleWatermelon публікація детальніше про V-версію, однак, оскільки це було набагато важче сформувати все у конкретній формі з лише обмеженою кількістю доступних байтів. Пояснення, таким чином, буде застосовуватися для V-версії, а не для звичайної. Я можу зробити справді гольф пізніше.
PidgeyUsedGust

Це золото просто золото
Крістофер

Я розумію, що ця відповідь є мовою, назва якої складається виключно з обернених "V".
Селлім

19

Мозок-Флак , 486 + 1 = 489 байт

З днем ​​народження V від Brain-Flak!

Також дякую 0 ', які надали частину коду, який використовується у цій відповіді

+1 через -cпрапор, необхідний для ASCII вхід та випуск

((([]<{({}<>)<>}<>([]){({}[()]<(([][()])<{({}[()]<({}<>)<>>)}{}><>)<>({}<<>{({}[()]<({}<>)<>>)}{}><>)(({})<>)<>>)}{}([][][()]){({}[()]<((((()()()()){}){}){})>)}{}<>{({}<>)<>}<>>){}[()])<{((({})<((({}){}())){({}[()]<(({}<(({})<>)<>>)<(({}<({}<>)<>>[()])<<>({}<<>{({}[()]<({}<>)<>>)}{}>)<>>){({}[()]<({}<>)<>>)}{}<>>)>)}{}{}((()()()()()){})(<()>)<>>)<{({}[()]<({}<>)<>>)}{}{}{}{({}<>)<>}<>>[()])}{}>()())([][()]){{}(({}[()])<{({}[()]<((((()()()()){}){}){})>)}{}{({}<>)<>}{}>)([][()])}{}<>

Спробуйте в Інтернеті!

Це, без сумніву, найважче, що я коли-небудь робив у «Брейн-Флак».

Brain-Flak, як відомо, дуже жахливий у дублюванні та перевороті рядків, і це завдання полягає лише в дублюванні та перевороті рядків.

Мені вдалося дістати цей майже працюючий фрагмент лише за годину напруженої роботи, але додавання в останні кілька просторів виявилося однією з найскладніших речей, які я коли-небудь робив у Brain-Flak.

Пояснення

Основна ідея полягає в тому, що ми створимо першу вершину V і кожну ітерацію видалимо два символи з середини та додамо пробіл до початку.

На практиці це стає досить важким.

Існуючі алгоритми існують для копіювання та реверсу, тому я використовував один із них для створення зворотної копії коду на офстаці. Після того, як я зробив це, я ставлю 2n-1пробіли поверх оригінального стека і переміщую офсет на задній план, щоб створити сендвіч.

Тест 1

Тепер у нас є наш верхній ряд. Тепер ми хочемо видалити два символи з початку і додати пробіл спереду. Це виявляється найскладнішою частиною. Причиною цього є те, що нам потрібно, по суті, зберігати два значення, одне для глибини поточного фрагмента і одне для глибини до центру V, де має відбутися видалення.

Це важко.

Через все дублювання та перевернення, що відбувається на обох стеках, весь час використовується в повній мірі. Дійсно ніде на цих стеках нічого не ставити. Навіть за допомогою Magic третього стека у світі ви не можете отримати тип доступу, який вам потрібен для вирішення цієї проблеми.

То як же це виправити? Словом, насправді насправді немає; ми зараз ігноруємо пробіли і виправляємо їх пізніше. До коду додамо нулі, щоб відзначити, куди мають бути пробіли, окрім того, що ми нічого не будемо робити.

Тож на кожній ітерації робимо копію останньої ітерації і кладемо її на офсет. Ми використовуємо глибину, яку ми зберегли, щоб розділити її навпіл, тому у нас ліва половина V на правій стеці, а права половина V - у лівій. Видаляємо два елементи і склеюємо два назад разом. Додаємо новий рядок для гарної міри та починаємо наступну ітерацію. Кожен раз, коли глибина до центру V зменшується на одиницю, і коли вона досягає нуля, ми зупиняємо цикл.

Тепер у нас побудована основна частина V. Однак нам не вистачає належних просторів, і наш V наразі трохи (читайте: повністю) догори ногами.

Тест 2

Так ми перевертаємо. Щоб перевести його на інший стек, ми повинні переміщати кожен елемент по одному. По мірі переміщення елементів ми перевіряємо нулі. Якщо ми стикаємось з одним, ми повинні повернути пробіли туди, де вони належать. Збиваємо нуль і додаємо в купу пробіли. Як ми можемо знати, скільки? Ми стежимо; перегортання стека на відміну від дублювання чи повернення назад - дуже неінтенсивне завдання, тому ми насправді маємо пам'ять для зберігання та доступу до додаткового лічильника, щоб відстежувати, скільки пробілів потрібно додати. Кожен раз, коли ми додаємо пробіли, ми лічимо лічильник на один. Лічильник повинен досягти нуля на останньому новому рядку (у верхній частині V), і таким чином ми готові до друку.

Нарешті, ми очищаємо кілька речей, що звисають навколо, та припиняємо програму для неявного виведення.

Тест 3


Дуже вражаюче, що вам вдалося змусити його працювати взагалі! Як ви думаєте, ви могли б зберегти байти, залишивши його перевернутою та додавши -rпрапор?
DJMcMayhem

@DJMcMayhem Я не думаю, що так. Процес розвороту та вставлення пробілів відбувається одночасно, тому, якщо я додав -rпрапор, мені потрібно було б фактично змінити його в інший раз. Це стає пізно, де я є, але я думаю, що завтра я буду працювати над тим, щоб спробувати пограти в гольф. Якщо я зможу виправити проблему з пробілами, я обов'язково використаю -rпрапор.
Пшеничний майстер

16

Желе , 15 12 байт

⁶ṁ⁸;;\Uz⁶ŒBY

Спробуйте в Інтернеті!

Як це працює

⁶ṁ⁸;;\Uz⁶ŒBY  Main link. Argument: s (string)

⁶ṁ            Mold ' ' like s, creating a string of len(s) spaces.
  ⁸;          Prepend s to the spaces.
    ;\        Cumulative concatenation, generating all prefixes.
      U       Upend; reverse each prefix.
       z⁶     Zip/transpose, filling empty spots with spaces.
         ŒB   Bounce; map each string t to t[:-1]+t[::-1].
           Y  Join, separating by linefeeds.

Це 12 символів, але чи є кодування, де воно вийшло б лише 12 байтами?
kasperd

1
Так, Jelly використовує власну кодову сторінку .
Денніс


16

JavaScript (ES6), 108 106 98 94 байт

f=
s=>s.repeat((j=l=s.length*4)*2).replace(/./g,_=>--j?s[j+j<l?j-i:l-i-j]||` `:(j=l,++i,`
`),i=1)
<input oninput=o.textContent=f(this.value)><pre id=o>


Чи зможете ви написати пост, пояснюючи це? Мене трохи бентежить заміна і регулярні вирази.
Яків Персі

@JacobPersi Вони - червона оселедець. Все , що потрібно це вихідна область розміру n*2від n*4( в тому числі нових рядків в кінці кожного рядка). Потім я обчислюю символ, який повинен з’явитися у кожній комірці.
Ніл

Приємно! Ви можете голити байт, видаливши новий рядок між f=і s=>.
yummypasta

@yummypasta Це f=лише частина фрагмента, а не відповідь. Як такий, він не входить до складу байтів.
Ніл

11

Сітківка , 51 47 байт

З днем ​​народження від іншої мови обробці рядків!

Кількість байтів передбачає кодування ISO 8859-1.

$
$.`$* 
$
¶$`
O$^r`.\G

;{*`.¶

(\S.*).¶.
 $1¶

Спробуйте в Інтернеті!

Пояснення

$
$.`$* 

Це додає nпробіли (де nдовжина рядка), зіставляючи кінець рядка, отримуючи довжину рядка з $.`та повторюючи пробіл, який багато разів $*.

$
¶$`

Ми дублюємо всю нитку (відокремлену прямою передачею рядків), знову зіставляючи кінець рядка і вставляючи саму рядок $`.

O$^r`.\G

Це обертає другий рядок, зіставляючи справа-наліво ( r), потім порівнюючи один символ ( .), але переконуючись, що вони всі суміжні ( \G). Таким чином, сірники не можуть пройти повну лінію передачі. Потім це використовується на етапі сортування. Використовуючи режим сортування ( $), але замінюючи кожну відповідність порожнім рядком, фактичне сортування не проводиться. Але завдяки ^опції, сірники перевертаються в кінці, перевертаючи весь другий рядок.

;{*`.¶

Цей етап призначений для виведення, а також впливає на решту програми. {загортає решту етапів у цикл, який повторюється, поки ці етапи не змінять рядок (що станеться тому, що останній етап більше не збігатиметься). ;Вихід відключає в кінці програми. На *черзі цього етапу в суху перспективі це означає , що етап обробку і результат виводиться, але після попереднього рядка відновлюється.

Сама сцена просто прибирає подачу ліній та попередній символ. Що дає нам один рядок бажаного виводу (починаючи з першого рядка).

(\S.*).¶.
 $1¶

Нарешті, цей етап перетворює кожен рядок у наступний. Це робиться, вставляючи пробіл перед першим символом, який не є пробілом, видаляючи останній символ у першому рядку, а також перший символ у другому рядку. Цей процес припиняється, як тільки в першому рядку залишився один непробільний символ, який відповідає останньому рядку виводу.


Хочеться пояснити, як це працює. Я знаю, що синтаксис sed є менш компактним, але мій чернетка вдвічі довший. Повернення рядка та з'єднання першого вихідного рядка - це найбільше.
seshoumara

@seshoumara Звичайно, ви йдете.
Мартін Ендер

Дякую. Тепер я знаю, що сценарій sed подвійної довжини не поганий :)) завдяки додатковим s///символам, які складаються, більш тривалому розвороту рядків та іншим операціям, яким не вистачає смаку Retina. Добре читати. +1
seshoumara

9

05AB1E , 12 байт

Dgð×J.p€ûR.c

Спробуйте в Інтернеті!

Пояснення

D             # duplicate input
 g            # length of copy
  ð×J         # append that many spaces to input
     .p       # get a list of all prefixes
       €û     # turn each into a palindrome
         R    # reverse the list
          .c  # pad each line until centered

Або для того ж байтового рахунку з іншого напрямку.

Âsgú.sí€ûR.c

Пояснення

             # push a reversed copy of input
 s            # swap the input to the top of the stack
  g           # get its length
   ú          # prepend that many spaces
    .s        # get a list of all suffixes
      í       # reverse each
       €û     # turn each into a palindrome
         R    # reverse the list
          .c  # pad each line until centered

2
Якщо поступово відступати коментарі, то навіть джерело виглядає як V :)
1717

9

Japt, 22 20 16 14 + 2 байти

Japt бажає V ще багато успішних років у гольф!

²¬£²îU²ç iYU)ê

Потрібен -Rпрапор. Перевірте це в Інтернеті!

Пояснення

Тут використовуються функції çта îфункції, які я додав кілька днів тому:

²¬£²îU²ç iYU)ê    Implicit: U = input string
²                 Double the input string.
 ¬                Split into chars.
  £               Map each char X and index Y by this function:
     U²             Take the input doubled.
       ç            Fill this with spaces.
         iYU        Insert the input at index Y.
    î       )       Mask: repeat that string until it reaches the length of
   ²                the input doubled.
                    This grabs the first U.length * 2 chars of the string.
             ê      Bounce the result ("abc" -> "abcba").
                  Implicit: output result of last expression, joined by newlines (-R flag)

Техніка Денніса на байт довше:

U+Uç)å+ mw y mê

5

GNU sed , 110 100 + 1 (r прапор) = 101 байт

Редагувати: 9 байт коротше завдяки Райлі

В якості ще однієї мови маніпуляцій зі струнами, sed бажає V найкращого!

h;G
:;s:\n.: \n:;t
h;:r;s:(.)(\n.*):\2\1:;tr
H;x
s:\n\n ::
:V
h;s:\n::p;g
s:^: :;s:.\n.:\n:
/\n$/!tV

Спробуйте в Інтернеті!

Пояснення: припустимо, що вхід є останнім тестовим випадком ("V!"). Я буду показувати простір шаблонів на кожному кроці для наочності, замінюючи пробіли на 'S'.

h;G                       # duplicate input to 2nd line: V!\nV!
:;s:\n.: \n:;t            # shift each char from 2nd line to 1st, as space: V!SS\n
h;:r;s:(.)(\n.*):\2\1:;tr # save pattern space, then loop to reverse it: \nSS!V
H;x                       # append reversed pattern to the one saved V!SS\n\n\nSS!V
s:\n\n ::                 # convert to format, use \n as side delimiter: V!SS\nS!V
:V                        # start loop 'V', that generates the remaining output
h;s:\n::p;g               # temporarily remove the side delimiter and print pattern
s:^: :;s:.\n.:\n:         # prepend space, delete char around both sides: SV!S\n!V
/\n$/!tV                  # repeat, till no char is left on the right side
                          # implicit printing of pattern left (last output line)

@Riley Відповідь оновлено, дякую!
seshoumara


4

Джольф, 31 байт

Джольф з повагою бажає V щасливого дня народження!

RΜwzΒώlid+γ_pq_ l+*␅Hi0ΒΒ␅ L_γ1S

Спробуйте тут! має бути 0x05.

Пояснення

RΜzΒώlid+γ_pq_ l+*␅Hi0ΒΒ␅ L_γ1S  i = input
     li                                  i.length
    ώ                                2 * 
   Β                             Β =
  z                              range(1, Β + 1)
 Μ     d                         map with: (S = index, from 0)
                +                 add:
                 *␅H               S spaces
                    i              and the input
               l                  slice (^) from
                     0Β            0 to Β
           pq_         Β␅         pad (^) with spaces to the right
         γ_                       γ = reverse (^)
        +                 L_γ1    γ + behead(γ)
R                             S  join with newlines

4

Вугілля деревне , 29 байт

З днем ​​народження V, від ваших колег, розчарувально-довго-для цього виклику ASCII-мови мистецтва!

SσF…·¹Lσ«Fι§σκMι←↖»Fσ«Pσ↖»‖O→

Спробуйте в Інтернеті!

Пояснення

Наша стратегія: роздрукувати ліву половину V, починаючи з нижньої та переходячи до верхньої лівої; потім відобразити це.

Sσ                                    Input σ as string
                                       The bottom len(σ) half-rows:
   F…·¹Lσ«           »               For ι in inclusive range from 1 to length(σ):
            Fι                          For κ in range(ι):
               §σκ                         Print character of σ at index κ
                  Mι←                   Move cursor ι spaces leftward
                      ↖                  Move cursor one space up and left
                                       The top len(σ) half-rows:
                        Fσ«    »      For each character ι in σ:
                            Pσ          Print σ without moving the cursor
                               ↖         Move cursor one space up and left
                                 ‖O→  Reflect the whole thing rightward, with overlap

(Якщо тільки у вугіллі було нарізання рядків ... на жаль, схоже, це ще не було реалізовано.)


Незважаючи на те, що у вугілля не було нарізки рядків, у нього було таке CycleChop, яке можна використовувати для витягування головки рядка, економлячи таким чином 4 байти. Однак є кращий підхід, який економить 9 байт. Ще кілька заощаджень, які, на мою думку, теж працювали в той час: Reflectза замовчуванням праворуч відображається, зберігаючи подальший байт, і одна із змінних заздалегідь визначена для першого вводу, економлячи два байти.
Ніл

4

Піп , 32 25 байт

a.:sX#aL#a{OaDQaPRVaaPUs}

Приймає рядок введення як аргумент командного рядка. Спробуйте в Інтернеті!

Пояснення

                           a is 1st cmdline arg, s is space (implicit)
     #a                    Len(a)
   sX                      Space, string-multiplied by the above
a.:                        Concatenate that to the end of a
       L#a{             }  Loop len(a) times (but NB, a is now twice as long as it was):
           Oa                Output a (no trailing newline)
             DQa             Dequeue one character from the end of a
                PRVa         Print reverse(a) (with trailing newline)
                    aPUs     Push one space to the front of a

4

R з пакетом stringi, 225 байт

library(stringi)
f=function(){
s=scan(,'',1,sep="\n")
m=2*nchar(s)
l=stri_pad(sapply(1:m-1,function(x)substr(paste(paste(rep(" ",x),collapse=""),s),1,m)),m,"right")
r=substr(stri_reverse(l),2,m)
message(paste0(l,r,"\n"))}
f()

Якщо ви запускаєте R в інтерактивному коді, після вставки моєї відповіді просто введіть що-небудь. Вам буде потрібно пакет stringi R для встановлення (сподіваюся, це не проти правил).

Пояснення:

Основна ідея - додати пробіли в ліву сторону, а потім вирізати її на праву довжину. Після цього вставте його з перевернутою версією як праву сторону. Ось довша, зрозуміла для людини версія функції:

library(stringi)
make_V <- function(){                  # declaring the function
  string <- scan(, '', n=1, sep="\n")  # reading input
  max_length <- 2*nchar(string)        # number of chars in each half row

  # creating the left side of the V

  left <- stri_pad(                    
            sapply(1:max_length-1,     # for each row
                   function(x){     
                    substr(            
                      paste0(
                        paste0(rep(" ", x),
                               collapse=""), string), # add spaces to left side
                           1,
                           max_length) # cut the unneeded end
                    }),
            width=max_length,
            side="right")              # add spaces to the right side

  # creating the right side of the V

  right <- substr(stri_reverse(left), 2, max_length)

  # print it without any symbols before the strings 
  message(paste0(left, right, "\n"))
}

# run the function
make_V()

Ласкаво просимо на сайт! :)
DJMcMayhem

4

Рубі, 92 89 85 байт

s=gets.chomp
s<<" "*n=s.size*2
n.times{s=s[0..(n-1)]
puts s+s.reverse[1..-1]
s=" "+s}

Мій процес полягав у видаленні першого символу з правої половини кожного рядка після перевернення першого тайму. Подобається це:

Hello     |    olleH
 Hello    |   olleH 
  Hello   |  olleH  
   Hello  | olleH   
    Hello |olleH    
     Hello|lleH     
      Hell|leH      
       Hel|eH       
        He|H        
         H|         

Я не звик намагатися грати в гольф, тому дайте мені знати, чи є щось, що я можу зробити, щоб скоротити його.


Ласкаво просимо на сайт, це приємна відповідь! На жаль, я дійсно не знаю багато про рубін, тому не можу запропонувати жодних порад. Можливо, ви зможете знайти щось на цій сторінці .
DJMcMayhem

Дякую! На цій сторінці є багато цікавого, але, здається, я вже багато їх роблю. Я зрозумів, що можу зберегти деякі байти через побічні ефекти та порядок операцій.
користувач3334690

1
Я припускаю, що [Рубі] - це просто Рубі, більш-менш відома мова програмування?
Rɪᴋᴇʀ

Ви можете зберегти 8 байт , зробивши це лямбда .
Йорданія

4

Пакетна, 186 185 байт

@set e=@set 
%e%/ps=
%e%t=%s%
%e%r=
:l
%e%s=%s% 
%e%r= %r%%t:~-1%
%e%t=%t:~,-1%
@if not "%t%"=="" goto l
:g
%e%r=%r:~1%
@echo %s%%r%
%e%s= %s:~,-1%
@if not "%r%"=="" goto g

У рядках 1 і 6 є простір. Редагувати: Збережено 1 байт завдяки @ ConorO'Brien


1
Ось спільний спосіб зберегти байт . (створіть псевдонім для @set та видаліть @echo off, вставляючи @за необхідності.
Conor O'Brien

@ ConorO'Brien Спасибі, я ніколи не здогадувався, що 8 sets врятував би мені достатньо байтів, щоб зробити це вартим.
Ніл

3

Haskell , 76 байт

vє основною функцією, беручи Stringаргументи і даючи Stringрезультат.

v i=unlines.r$i++(' '<$i)
r""=[]
r s|t<-init s=(s++reverse t):map(' ':)(r t)

Спробуйте в Інтернеті!

Примітки:

  • i є початковим аргументом / входом.
  • sспочатку iз length iдоданими пробілами.
  • v iдзвінки r s, потім приєднується до результатів.
  • rповертає список Stringрядків.
  • tце sз останнім символом відрубали.
  • Рекурсія r tстворює рядки, крім першого, мінус початковий пробіл у кожному рядку.

2
+1 для називання основної функції v. : D
DJMcMayhem

1
@DJMcMayhem: не називаючи основною функцією є один байт більше: unlines.r.((++)<*>(' '<$)).
німі

1
@nimi Я припускаю, що йому сподобалось, яке ім’я я вибрав. Технічно лямбда-зв'язки ... Коли я писав відповідь, я не знав, що ви можете використовувати декларації верхнього рівня для деяких функцій, але не називати головну функцію. Хоча я бачив, як хтось це робить, я вважаю це дещо тривожним. У цей час він працює принаймні у GHCi.
Ørjan Johansen

3

Желе , 13 байт

⁶ṁ;@µḣJUz⁶ŒBY

Спробуйте в Інтернеті!

Як?

⁶ṁ;@µḣJUz⁶ŒBY - Main link: string s
⁶             - space character
 ṁ            - mould like s: len(s) spaces
  ;@          - concatenate s with that
    µ         - monadic chain separation (call that t)
      J       - range(length(t))
     ḣ        - head (vectorises): list of prefixes from length to all
       U      - upend: reverse each of them
        z     - transpose with filler:
         ⁶    -     space: now a list of the left parts plus centre
          ŒB  - bounce each: reflect each one with only one copy of the rightmost character
            Y - join with line feeds
              - implicit print

Подібні уми чудово думають. : P
Dennis

О, я не думав про накопичувальну конкатенацію! Деревне вугілля має напрямок V, можливо, якесь розслідування починається ...
Джонатан Аллан

3

Рубі, 85 83 байти

редагувати: видалено зайвий пробіл

s=ARGV[0];s+=' '*s.length;s.length.times{|i|puts s+s[i..-2].reverse;s=' '+s[0..-2]}

Мені насправді було важко пограти в гольф у Рубі. Після додавання пробілів він розширюється на досить читабельний фрагмент коду:

s = ARGV[0]
s+=' ' * s.length

s.length.times do |i|
  puts s + s[i..-2].reverse
  s = ' ' + s[0..-2]
end

1
Можливо, ви могли би трохи заощадити, встановивши s.length на змінну, як я? Крім того, я думаю, ви повинні розглянути можливість розміру замість довжини?
користувач3334690

Виконуючи те, що @ користувач3334690 запропонував і перемістив. Заяву про час, 79 байт:s=ARGV[0];(s+=' '*s.size).size.times{|i|puts s+s[i..-2].reverse;s=' '+s[0..-2]}
Conor O'Brien

Можна зберегти п’ять байтів, зробивши це лямбда .
Йордан

3

MATLAB (R2016b), 223 183 байт

r=input('');l=nnz(r)*2;for i=1:l;m=l+1-2*i;c={' '};s=cell(1,i-1);s(:)=c;x=cell(1,m);x(:)=c;e=r;y=flip(r);if(m<1);e=r(1:2*end-i+1);y=r(l/2+end-i:-1:1);end;disp(cell2mat([s e x y]));end

Код гольфу вперше. Поради вітаються!

Вихід програми:

MATLAB Code Golf

Редагувати:

Збережено 40 байт завдяки Луїсу Мендо.


2
Ласкаво просимо до PPCG, і приємна перша відповідь! На жаль, я нічого не знаю про MATLAB, тому я не можу допомогти тобі в гольфі, але, можливо, ти знайдеш кілька корисних порад :-)
ETHproductions

1
За замовчуванням дозволено введення рядка, включаючи його додані лапки. Тож можна видалити 's'з input. Також я не бачу, чому ви користуєтесь evalc(disp(...)), але я думаю, що ви можете просто скористатися cell2mat цим способом
Луїс Мендо

1
Крім того, flipкоротше end:-1:1, дивіться тут
Луїс Мендо

3

PHP, 95 92 85 80 78 77 байт

Примітка: використовується кодування IBM-850

for($s.=strtr($s^$s=$argn,~ ,~▀);~$s[$i++];)echo$s,strrev($s=" $s"^$s^$s),~§;
          # Note that this ^ char is decimal 255 (negating it yields "\0")

Бігайте так:

echo "Hello" | php -nR 'for($s.=strtr($s^$s=$argn,"\0",~▀);~$s[$i++];)echo$s,strrev($s=" $s"^$s^$s),~§;'
> Hello         olleH 
>  Hello       olleH  
>   Hello     olleH   
>    Hello   olleH    
>     Hello olleH     
>      HellolleH      
>       HellleH       
>        HeleH        
>         HeH         
>          H          

Пояснення

for(
  $s.=strtr(             # Set string to the input, padded with spaces.
    $s^$s=$argn,         # Input negated with itself, leads to string with
                         # only null bytes with the same length.
    ~ ,                  # Replace null bytes...
    ~▀                   # ... with spaces.
  );
  ~$s[$i++];             # Iterate over the string by chars, works because 
                         # there are just as many lines as the padded
                         # string has chars.
)
  echo                   # Output!
    $s,                  # The string.
    strrev(              # The reverse of the string.
      $s=" $s"^$s^$s     # After each iteration, prefix string with a
    ),                   # space, and trim the last character.
    ~§;                  # Newline.

Налаштування

  • Збережено 3 байти, позбавившись від символу майданчика ( str_padза замовчуванням до місця, що нам потрібно)
  • Збережено 7 байт, використовуючи двійкові операції над рядком, щоб обрізати його замість substr
  • Збережено 5 байт, обертаючи рядок при друкуванні зворотного боку. Запобігає необхідності друку зворотного простору, але призводить до появи пробілу у кожному рядку.
  • Збережено 2 байти, додавши рядок, використовуючи більш складний, але коротший метод.
  • Збережено байт через те, що справа не потрібна ~"0"(ASCII 207), оскільки всі вхідні дані можна вважати ascii для друку (Thx @Titus)

echo$s,strrev($s=" $s"^$s^$s),~§;економить 5 байт.
Тит

@Titus, thx. Зазвичай я уникаю пробілів пробілів, але ОП заявив, що це прийнятно
1717

~$s[$i++]достатньо (вхід для друку ASCII, так і є $s)
Тит

@Titus, thx, хороший улов. Я схильний
кодувати

2

JavaScript (ES6), 169 157 байт

(-10 байт завдяки Conor O'Brien)

V=(j,i=0,p="")=>i<(f=j.length)*2?V(j,-~i,p+" ".repeat(i)+j.slice(0,f-i*(i>f))+" ".repeat(i<f?(f-i)*2-1:0)+[...j.slice(0,f+~i*(i>=f))].reverse().join``+`
`):p

Рекурсивне рішення. Я новачок у JavaScript, тому будь ласка, будь ласка! Будь-які поради щодо гольфу дуже вдячні. :)

І, звичайно, дуже з днем ​​народження V!

Тест-фрагмент


1
Це досить добре! Як правило, s.split("")може бути змінено на [...s], і a.join("")може стати a.joinнаступною парою зворотних лапок. Ви можете зберегти додаткові 3 байти, замінивши [r='repeat']і [r]простим повторенням ol ', те ж саме slice.
Conor O'Brien

@ ConorO'Brien Дякую за поради! Їх дуже цінують. :)
Р. Кап

2

CJam , 26 байт

З днем ​​народження від вашого старого товариша CJam!

q_,2*:L,\f{LS*+m>L<_W%(;N}

Спробуйте в Інтернеті!

Пояснення

q                           Push the input
 _,2*:L                     Push 2 times the length of the input, store it in L
       ,                    Take the range from 0 to L-1
        \                   Swap top stack elements
         f{                 Map over the range, using the input as an extra parameter
           LS*+               Append L spaces to the input
               m>             Rotate the resulting string right i positions (where i is the
                               current number being mapped)
                 L<           Take the first L characters of the string
                   _W%        Duplicate it and reverse it
                      (;      Remove the first character from the copy
                        N     Add a newline
                         }  (end of block)
                            (implicit output)

2

PowerShell, 126 байт 124 байт

$l=($s="$args")|% Le*;$r=-join$s[-1..-$l];0..($l*2-1)|%{' '*$_+($s+' '*$l).substring(0,$l*2-$_)+(' '*$l+$r).substring($_+1)}

Викликайте його за допомогою одного параметра, наприклад .\V.ps1 Hello.

Редагувати: 2 байти збережено з підказкою від AdmBorkBork


1
Спробуйте його в Інтернеті! посилання, якщо ви зацікавлені.
Денніс

О, я не знав про цей маленький інструмент, дякую!
Тор

Привіт там! Пару маленьких гольфів спереду. Візьміть введення як рядок і використовуйте капсулювання для передачі змінної уздовж. Зберігає два байти. $l=($s="$args")|% Le*;
AdmBorkBork

Нічого, не знав про ці 2 гольфи, дякую!
Тор


2

JavaScript (ES6), 94 байти

f=(s,y=0,x=0,l=s.length*2-1)=>(s[(x>l?l*2-x:x)-y]||' ')+(x<l*2?f(s,y,x+1):y<l?`
`+f(s,y+1):'')

Тестові справи


2

J, 44 байт

(([(,}.@|.)@{."1-@i.@[|."0 1(,#&' ')~)~+:@#)

1
Хм, я не можу зрозуміти, як запустити це в Інтернеті. Спробуйте в Інтернеті! Я просто називаю це неправильно? (Я J newb)
DJMcMayhem

@DJMcMayhem Це функція, а не програма. tio.run/nexus/…
Dennis

Гольф: |."0 1до |."{(збережено 2 байти)
Conor O'Brien

Крім того, не потрібно мати зовнішні дужки.
Conor O'Brien
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.