Роздягніть рядок


48

Ми вже зараз, як зняти рядок з її пробілів.

Однак, як належні панове / пані, ми повинні скоріше це роздягнути .


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

Приклад, починаючи з " codegolf "(п'ять провідних та кінцевих пробілів):

     codegolf     
    codegolf     
    codegolf    
   codegolf    
   codegolf   
  codegolf   
  codegolf  
 codegolf  
 codegolf 
codegolf 
codegolf

  1. Спочатку виведіть рядок без змін. Потім виведіть кожен крок. Почніть з видалення провідного простору (якщо це застосовано - див. Правило №2).

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

  3. На вході може бути немає провідних чи кінцевих пробілів. Якщо це так, виведіть його як є.

  4. Використовуйте методи вводу / виводу за замовчуванням PPCG . PPCG Лазівки за замовчуванням заборонені.

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

  6. Можна припустити, що рядок буде містити лише символи з простору друку ASCII ( 0x20до 0x7E).


Приклади - пробіли замінюються крапками .для кращої читабельності:

4 leading spaces, 5 trailing: "....Yes, Sir!....."
....Yes, Sir!.....
...Yes, Sir!.....
...Yes, Sir!....
..Yes, Sir!....
..Yes, Sir!...
.Yes, Sir!...
.Yes, Sir!..
Yes, Sir!..
Yes, Sir!.
Yes, Sir!

6 leading, 3 trailing: "......Let's go golfing..."
......Let's go golfing...
.....Let's go golfing...
.....Let's go golfing..
....Let's go golfing..
....Let's go golfing.
...Let's go golfing.
...Let's go golfing
..Let's go golfing
.Let's go golfing
Let's go golfing

0 leading, 2 trailing: "Hello.."
Hello..
Hello.
Hello

0 leading, 0 trailing: "World"
World

21 leading, 5 trailing: ".....................a....."
.....................a.....
....................a.....
....................a....
...................a....
...................a...
..................a...
..................a..
.................a..
.................a.
................a.
................a
...............a
..............a
.............a
............a
...........a
..........a
.........a
........a
.......a
......a
.....a
....a
...a
..a
.a
a

Джентльмен / дама є лаконічним, тому найкоротша відповідь у байтах виграє .



Чи можна припустити, що буде хоча б один непросторовий персонаж?
Мартін Ендер

2
@KevinCruijssen Вам потрібно обробляти лише символи ASCII у просторі 0x20для друку ( до 0x7E). Інші - Невизначена поведінка.
Nathan.Eilisha Shiraini

1
@KevinCruijssen Так, не буде такого тестового випадку. Не буде таких речей, як те " test\r "чи інше " \v test".
Nathan.Eilisha Shiraini

1
Це дійсний тестовий випадок ".....................a....."? Якщо це так, я пропоную додати його, оскільки деякі відповіді, здається, не відповідають цьому тесту. (крапки для кращої читабельності звичайно)
Cinaski

Відповіді:


11

Сітківка , 26 байт

{m`^ (.+)\z
$&¶$1
 $
 ¶$%`

Спробуйте в Інтернеті! (Тестовий набір використовує періоди для ясності. Нижній колонтитул та заголовок перетворюють їх у пробіл та з пробілів для основного коду.)

Пояснення

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

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

{m`^ (.+)\z
$&¶$1

{Обертає обидва етапи програми в циклі , який повторюється до рядка перестає змінюватися (що означає , що немає ні провідні / кінцеві прогалини вліво). Сам етап узгоджує провідний пробіл у заключному рядку рядка та цей фінальний рядок, а потім записує відповідність матчу, а також речі після пробілу в новому рядку (тим самим опускаючи провідний пробіл у копії).

 $
 ¶$%`

Видалити простір дещо простіше. Якщо ми просто узгоджуємо кінцевий пробіл, ми можемо отримати доступ до матеріалів, що знаходяться перед ним (у тому ж рядку), з $%`яким є відомий рядком варіант заміни префікса $`.


11

Пітон 2 , 122 107 103 102 98 95 93 91 90 88 87 байт

s=input()+' '
a=0
while-a*s!=id:
 if a:id=s
 a=~a
 if'!'>s[a]:s=s[1+a:len(s)+a];print s

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


Python 3 , 97 95 93 90 байт

s=input()
a=p=print
p(s)
while s!=a:
 a=s
 if'!'>s:s=s[1:];p(s)
 if'!'>s[-1]:s=s[:-1];p(s)

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


Використання s=input()замість функції займе менше байтів.
Джонатан Фрех

Посилаючись на 5. Undefined behaviour on empty input, or input that only contains spaces, is OK., 98 байт .
Джонатан Фрех


@JonathanFrech я цього не бачив; дякую :)
TFeld

2
Ви можете додатково пограти в код Python 2, замінивши aвбудовану функцію, idщоб зберегти необхідність його визначення на початку. -2 байти.
LyricLy

7

Perl 6 , 55 байт

Збережено 3 байти завдяки @nwellnhof.

{($_,{$++%2??S/" "$//!!S/^" "//}...*)[^.comb*2].unique}

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

Пояснення : ($_,{$++%2??S/" "$//!!S/^" "//}...*)це рекурсивна нескінченна послідовність, яка починається з початкового рядка ( $_), а наступний елемент задається блоком, викликаним попереднім елементом.

Сам блок отримує рядок у $_змінній. Оператор S/(regex)/(string)/буде шукати перше виникнення (regex)в $_, замінює його (string)і повертає результат. Якщо збігу немає, він повертає вміст $_без змін. Ми використовуємо потрійний оператор ?? !!з умовою $++%2, яка чергується між Falseі True( $є вільною змінною, яка зберігає її вміст на викликах до блоку.)

У гіршому випадку (усі пробіли на одній стороні та 1 інший символ) ми видаляємо 1 пробіл кожні 2 кроки. Тож ми можемо бути впевнені, що за кроками 2 * (довжина рядка) всі пробіли будуть видалені. Ми беремо, що багато елементів з рекурсивної послідовності з [^.comb*2]і, нарешті, відкидають дублікати (які виникають, коли пробіл повинен був бути видалений, але його немає) .unique. Це повертає список рядків, прогресивно позбавлених пробілів.


[^.comb*2]економить 2 байти. Чомусь це працює, але [^2*.comb]ні. Не знаю чому. Використання терміналу ?? !!для вибору регулярного вираження зберігає ще один байт.
nwellnhof

Дякую! Я спробував, [^2*.comb]і це не вийшло, тому я просто використовував [0..2*.comb]. І дякую за тернар, я просто подумав, що це занадто дорого, і мені не прийшло в голову, що я замінив його чимось ще дорожчим ...
Раміллі

7

05AB1E , 21 15 байт

=v¬ðQi¦=}¤ðQi¨=

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

Пояснення ^

=                 # print input
 v                # for each character in input
  ¬ðQi  }         # if the first char in the current string is a space
      ¦=          # remove it and print without popping
         ¤ðQi     # if the last char in the current string is a space
             ¨=   # remove it and print without popping

Данг, я спробував щось подібне, але чомусь я був впевнений, що голова / хвіст не працюють на струнах, і я збирався порушити питання про це на Github. Повинні неправильно прочитати журнали налагодження. :-)
scottinet

1
@scottinet: Я просто знайшов спосіб обійти кінцевий чек :)
Emigna

о ... чому ми не думали про це раніше? Оскільки ми друкуємо умовно, немає необхідності циклічно визначати потрібну кількість разів, нам потрібно лише циклічно провести цикл. Я позичаю цю ідею, щоб покращити свою відповідь :-)
scottinet

1
@scottinet: Так. Це зрозуміло, коли ти думаєш про це, але іноді легко пропустити ці речі: P
Emigna

TFW незграбна відповідна відповідь отримує лідерство ...
Erik the Outgolfer

7

C (gcc) , 89 84 байт

Рекурсивна версія коротша ;-)

j;f(char*s){puts(s);*s^32||puts(++s);s[j=strlen(s)-1]<33?s[j]=0,f(s):*s^32||f(s+1);}

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

C (gcc) , 107 102 101 100 99 байт

Збережено 2 байти завдяки @Jonathan Frech за допомогою пробілів та ~

i,j,k;f(char*s){for(i=~++k,puts(s);i^k;k=s[j=strlen(s)-1]<33?s[j]=0,puts(s):0)*s^32?i=0:puts(++s);}

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


2
Я думаю, що питання справді хоче, щоб ви видаляли пробіли, а не крапки. Є навіть перевага у використанні пробілів; ви можете замінити ==46з <33як простір є найменшим для друку характер і у вас є тільки для обробки тих.
Джонатан Фрех

Що робить ++k+?
Джонатан Фрех

@JonathanFrech Він попередньо збільшує kі додає один, що еквівалентно k = k + 1; i = k + 1;або i = k + 2; k = k + 1.
HyperNeutrino

Технічно i=k+++2працює і те, що я використовував би, тому що +++виглядає дивно: P
HyperNeutrino

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

6

JavaScript (ES6) 92

@Upvoters: подивіться на іншу відповідь JS нижче, що має 76 байт

(s,q,l=2,p=0)=>{for(alert(s);l--;p=!p)s[+p&&s.length-p]<'!'&&alert(s=s.slice(!p,-p||q,l=2))}

Петля, яка шукає простір спереду або в кінці. Якщо знайдено, видаліть пробіл та вихідний рядок. Якщо місця не знайдено 2 рази, зупиніться.

F=
(s,q,l=2,p=0)=>{for(alert(s);l--;p=!p)s[+p&&s.length-p]<'!'&&alert(s=s.slice(!p,-p||q,l=2))}

// some trick to show dots instead of spaces, for test
alert=x=>console.log(x
  .replace(/^ +/g,z=>'.'.repeat(z.length))
  .replace(/ +$/g,z=>'.'.repeat(z.length))
)

function go() {F(I.value.replace(/\./g,' '))}

go()
<input ID=I value='....yes Sir!....'> (use dot instead of space)
<button onclick='go()'>Go</button>


Ви можете зберегти байт, перевіривши пробіл на <'!'. Щоб ваш фрагмент все ще працював, ви можете replaceперіодично пропускати пробіли, перш ніж переходити до функції.
Джастін Марінер

@JustinMariner нормально, тому що ОП заявила, що очікуваний показник не менший за ''. Спасибі
edc65

6

Perl 5, 32 байти

Збережено 4 байти завдяки @Abigail .

1while s/^ /!say/e+s/ $/!say/e

Потрібні -plрахуються як 2, на які посилаються -E.

Використання зразка

$ echo '   test   ' | perl -plE'1while s/^ /!say/e+s/ $/!say/e'
   test   
  test   
  test  
 test  
 test 
test 
test

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


Не працює правильно для рядків без пробілів.
nwellnhof

print;s/^ //&&print,s/ $//&&print while/^ | $/працює з -nпрапором, теж -lне потрібен
Nahuel Fouilleul

@nwellnhof виправлено.
прима

5

C # (.NET Core) , 192 183 182 181 179 178 байт

-3 байти завдяки Kevin Cruijssen

n=>{var o=n+"\n";for(var e=1;n.Trim()!=n;){if(1>(e^=1))if(n[0]<33)n=n.Remove(0,1);else continue;else if(n.TrimEnd()!=n)n=n.Remove(n.Length-1);else continue;o+=n+"\n";};return o;}

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


Деякі речі для гольфу: var e=1;while(n.Trim()!=n)-> for(var e=1;n.Trim()!=n;); if(n[0]==' ')->if(n[0]<33)
Кевін Круїссен

Я подумав над другим, але що робити, якщо тестова рядок містить нові рядки?
хтось

Гаразд, <33це можливо завдяки нещодавно доданому правилу ОП: " Ви можете припустити, що рядок буде містити лише символи з місця для друку ASCII ( 0x20до 0x7E). "
Кевін Круїйсен

5

Java 8, 150 146 145 137 байт

s->{String r=s;for(int f=0;s!=s.trim();f^=1)r+="\n"+(s=f+s.charAt(0)<33|!s.endsWith(" ")?s.substring(1):s.replaceAll(" $",""));return r;}

-4 байти завдяки зміні @Nevay(f<1&s.charAt(0)<33) на f+s.charAt(0)<33.
-1 байт, використовуючи !s.trim().equals(s)фокус із відповіді @someone на C # .NET замість s.matches(" .*|.* ").
-8 байт завдяки @Nevay знову змінивши !s.trim().equals(s)на s!=s.trim(), тому що String#trimповернеться " Копія цього рядка з вилученим провідним і заднім пробілом, або цей рядок, якщо у нього немає провідної або кінцевої пробілів ", таким чином посилання залишається такою ж і !=може використовуватися для перевірки того, чи є вони однаковими, а не .equalsдля того самого значення.

Пояснення:

Спробуйте тут (або спробувати більш візуальну версію тут з #замість пробілів).

s->{                               // Method with String as both parameter and return-type
  String r=s;                      //  Result-String (starting at the input)
  for(int f=0;                     //  Flag-integer (starting at 0)
      s!=s.trim();                 //  Loop as long as `s` contains leading/trailing spaces
      f^=1)                        //    And XOR(1) `f` after every iteration (0->1; 1->0)
    r+="\n"                        //   Append the result with a new-line
       +(                          //    Followed by:
         s=f+                      //     If `f` is 0,
             s.charAt(0)<33        //     and `s` starts with a space
           |!s.endsWith(" ")?      //     Or doesn't end with a space
            s.substring(1)         //      Remove the first leading space
           :                       //     Else:
            s.replaceAll(" $",""));//      Remove the last trailing space
                                   //  End of loop (implicit / single-line body)
  return r;                        //  Return the result-String
}                                  // End of method

1
Ви можете використовувати s=f+s.charAt(0)<33замість (f<1&s.charAt(0)<33)(-4 байти).
Невай

1
Ви можете використовувати s!=s.trim()замість !s.trim().equals(s);(-8 байт).
Невай


4

Желе , 16 байт

Ḋ=⁶Ḣ$¡UµÐĿ¹Ṛƭ€QY

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

-2 байта завдяки Еріку Аутгольферу
-1 байт завдяки милі

Пояснення

Ḋ=⁶Ḣ$¡UµÐĿ¹Ṛƭ€QY  Main link
       µÐĿ        While the results are unique (collecting intermediate results), apply the last link (`µ` creates a new monadic link):
Ḋ=⁶Ḣ$¡            Remove a space from the beginning if there is one
 =⁶Ḣ$             If the first character is a space, then 1, else 0
 =                Compare each character to
  ⁶               ' '
   Ḣ              Get the first comparison
Ḋ                 Then Dequeue the string (s -> s[1:])
    ¡             That many times
     U            And reverse the string (the next time this is called, it will remove spaces from the end instead)
             €    For each string
            ƭ     Alternate between two commands:
          ¹       Identity (do nothing), and
           Ṛ      Reverse
          ¹Ṛƭ€    Correct all strings that are reversed to remove the trailing space
              Q   Remove duplicates (where there was no space to remove)
               Y  Join on newlines

ḣ1Ḣ=⁶->=⁶Ḣ
Ерік Аутгольфер

@EriktheOutgolfer Дякую, редагуємо, що надходить.
HyperNeutrino

Класна ідея з чергуванням команд зворотного / ідентичного!
Емінья

@Emigna Дякую! : DI в основному просто хотів виправдати, щоб скористатися новим швидким ... heh: P
HyperNeutrino

ƭпотрібен нілад, лише якщо ланцюг довший двох. ¹Ṛƭдобре працює тут.
миль


3

Java (OpenJDK 8) , 161 147 146 байт

x->{for(int l=0,r=x.length(),k=-1,u,v;((u=32-x.charAt(l)>>k)*(v=32-x.charAt(r-1)>>-1))<1;x+="\n"+x.substring(l-=k&~u|v,r+=(k=~k)&~v|u));return x;}

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

-1 байт завдяки @Kevin Cruijssen !

x -> {
    /*
     * l: left index (inclusive)
     * r: right index (exclusive)
     * k: side to remove from, -1:=left, 0:=right
     * u: left character   0:=space, <0:=no space (-1 if k is left side)
     * v: right character  0:=space, -1:=no space
     */
    for (int l = 0, r = x.length(), k = -1, u, v;
            ((u = 32 - x.charAt(l) >> k)
           * (v = 32 - x.charAt(r - 1) >> -1)) < 1; // loop while left or right has space(s)
            x += "\n" + x.substring(                // append newline and substring
                    l -= k & ~u | v,                // inc. left  if k is left side
                                                    //               and left has space
                                                    //            or right has no space
                    r += (k = ~k) & ~v | u));       // dec. right if k is right side
                                                    //               and right has space
                                                    //            or left has no space
    return x;
}

1
Хе-хе, я побачив вашу видалену відповідь і мені було цікаво, коли ви опинитесь нижче моїх 150 байтів, і ви скасуєте її. ;)
Кевін Круїссен

1
Я не зовсім впевнений, але я думаю, що ви можете (u=32-x.charAt(l)>>-1)(u=32-x.charAt(l)>>k)
пограти

@KevinCruijssen Не працюватиме, kце 0кожна друга секунда.
Невай

1
Так, але дивно, що TIO працює і дає правильний результат для всіх тестових випадків із цією зміною для u. Це не коли я змінити -1в kпротягом v. Мене бентежить, чому це працює, хоча kце справді стане 0після k=~k..: S
Кевін Круїйсен

1
@KevinCruijssen Для k=0сценарію: Якщо ліворуч залишилося пробіли, то uмає те саме значення, що і раніше ( 0); якщо ліворуч не залишилося пробілів, то (k=~k)&~v|uобчислюється до -1|u( ~0&-1|u), таким чином невизначене (негативне) значення значення uне має значення ( -1|x==-1).
Невай

3

05AB1E , 25 17 байт

-8 байт, запозичивши ідею відсутності необхідності для перевірки в Emigna

,v2F¬ðQi¦DNiR},}R

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

Я впевнений, що менш простий підхід може легко перемогти це рішення. Зараз...

Пояснення:

,v2F¬ðQi¦DNiR},}R           Full Programm
,                           Print the input string
 v                          For each char of the string
                               (we don't really care, we only need to loop
                                enough times to accomplish our task, since
                                we print conditionally we can loop more
                                times than necessary)
  2F...........}            Two times...
    ¬õQi                       Is 1st item a space?
        ¦D                        Remove 1st item + duplicate
          NiR}                    If on the second pass: reverse the list
              ,                   Pop & print with newline
               }               End If
                 R          Reverse the list

Мені подобається ваш підхід з циклом :) Я намагався знайти спосіб зробити все за один прохід без декількох ifs, але я ще не зрозумів цього. Крім того, у вашому поясненні, здається, порожній рядок замість пробілу.
Емінья

Дякую! Я виправив пояснення, я забув відредагувати "порожню" частину, коли гольфував свій код, використовуючи Sзамість #(-1 байт). Цикл ... ну ... це економить колосальні 1 байт порівняно з прямим підходом. Зараз я шукаю коротший спосіб виявити кінець завдання (5 байтів для цього багато), і я взагалі розглядаю інший підхід. Я думаю, що є більш розумний спосіб вирішити цю проблему.
scottinet

Якщо ви спробуєте зробити все за один прохід (як я зараз розглядаю), найкраща перевірка, яку я маю на вихід із циклу, - 8 байт ...
Emigna

3

R , 145 133 111 байт

-12 байт завдяки @Giuseppe, зберігаючи результат subу новій змінній та перевіряючи, чи змінився він

-22 байти, повертаючи вектор рядків, а не рядок з новими рядками

function(s){L=s
while(grepl("^ | $",s)){if((x=sub("^ ","",s))!=s)L=c(L,x)
if((s=sub(" $","",x))!=x)L=c(L,s)}
L}

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

Пояснення щодо частково неперевершеної версії:

function(s){
  L=s                          # Initialise a vector with the original string
  while(grepl("^ | $",s)){     # While there are leading or trailing spaces...
    if((x=sub("^ ","",s))!=s){ # Check whether we can remove a leading space
      L=c(L,x)                 # If so, add the shortened string to the vector
    }
    if((s=sub(" $","",x))!=x){ # Check whether we can remove a trailing space
      L=c(L,x)                 # If so, add the shortened string to the vector
    }
  }
  L                            # Return the vector
}                              

не можете використовувати C(s<-sub(),\n)замість окремої заяви друку? Ага, ні, черезsep=" "
Джузеппе

@Giuseppe Так, я думаю, що це працює трохи довше, щоб включити все це в одне твердження через необхідність додавання sep="". У більшості викликів додатковий простір не має значення, але тут, на жаль, це є!
користувач2390246

133 байти - щось про те, що ви використовуєте, subщойно запропонувало це, IDK чому
Джузеппе

@Giuseppe Дуже елегантно!
користувач2390246

Чи можете ви просто встановити L=sі повернути вектор рядків?
Джузеппе

3

Java (OpenJDK 8) , 137 125 121 120 124 байт

s->{int i=1;do System.out.println(s);while(s!=(s=s.substring(s.charAt(0)<33?i:(i=0),s.length()-(s.endsWith(" ")?i^=1:0))));}

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


Гарна відповідь! Настільки ж коротка, як моя відповідь на 137 байт, але ви все одно можете s->{for(int i=0;s!=s.trim();)System.out.println(s=s.substring(s.charAt(0)<33?1-i%2:0,s.length()-(s.endsWith(" ")?i++%2:0)));}
грати в

Наразі це не "... виводить рядок незмінним" і не вдається для введення з провідними пробілами і без пробілів.
Невай

1
Можливо, ви можете використовувати s->{int i=1;do System.out.println(s);while(s!=(s=s.substring(s.charAt(0)<33?i:(i=0),s.length()-(s.endsWith(" ")?i^=1:0))));}(124 байти) (здається, це правильно, але не тестували багато).
Невай

3

MATL , 21 16 байт

tnE:"t@o&)w46-?x

Для більшої чіткості використовуються крапки замість пробілів. Для пробілів замінити 46на 32.

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

Пояснення

tn      % Input (implicit). Duplicate and push length, say L
E       % Multiply by 2
:       % Push range [1 2 ... 2*L]
"       % For each k in that array
  t     %   Duplicate the string at the top of the stack
  @     %   Push k
  o     %   Parity: gives 1 or 0
  &)    %   Two-ouput indexing. Pushes the k-th entry of the string and then
        %   the rest of the string. The 1-st output is the first, the 0-th
        %   is the last (indexing is 1-based dand modular)
  w     %   Swap
  46-   %   Subtract 46, which ias ACII for '.'
  ?     %   If non-zero
    x   %     Delete sub-string that was obained by removing that entry
        %   End (implicit)
        % End (implicit)
        % Display stack (implicit)

3

Лушпиння , 23 22 байт

u§↑L`G`I¢e₁ȯ↔₁↔
?tI<"!

Дякую Леву за -1 байт.

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

Пояснення

Ця функція `G`Iсправді повинна бути вбудованою ...

?tI<"!  Helper function: remove initial space.
?  <"!  If less than the string "!",
 t      remove first character,
  I     else return as is.
u§↑L`G`I¢e₁ȯ↔₁↔  Main function.
         e       List containing
          ₁      the helper function
           ȯ↔₁↔  and the composition reverse-helper-reverse.
        ¢        Repeat it cyclically.
    `G`I         Cumulative reduce from left by function application
                 using input string as initial value.
 §↑L             Take first length(input) values.
u                Remove duplicates.

Приємно! Дійсно, нам знадобиться більше вбудованих програм для циклічного застосування функцій ... btw Я знайшов трохи коротший спосіб видалити перший пробіл: tio.run/##yygtzv7/v/…
Лев

@Leo Дякую! Використання ?здається очевидним заднім числом ...
Zgarb

3

C ++, 196 193 189 186 183 байт

-10 байт завдяки Джонатану Фреху
-3 байти завдяки Захарі

#include<iostream>
#include<string>
#define D std::cout<<s<<'\n'
#define R ~-s.size()
auto u=[](auto s){D;while(s[0]<33||s[R]<33){if(s[0]<33)s.erase(0,1),D;if(s[R]<33)s.erase(R),D;}};

Для компіляції з MSVC потрібна неактивація перевірок SDL


Можливо, ви зможете замінити ==32на <33.
Джонатан Фрех

Я не майстер C ++, хоча це #include<string> справді потрібно ?
Джонатан Фрех

if(...){...;D;}-> if(...)...,D;.
Джонатан Фрех

@JonathanFrech Те, що ви там зробили, було специфічним для компілятора, не гарантованим стандартом. VC ++ не може знайти визначення << операторів без явного включення рядка.
HatsuPointerKun

#define R ...<33, ||R){і if(R){-> #define R ...<33), ||R{і if(R{.
Джонатан Фрех

2

C # (.NET Core) , 176 170 байт

using System;s=>{Action o=()=>Console.WriteLine(s);o();Func<int>l=()=>s.Length-1;while(s!=s.Trim()){if(s[0]<33){s=s.Remove(0,1);o();}if(s[l()]<33){s=s.Remove(l());o();}}}

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

Це альтернатива @ чиїйсь відповіді і просто виводить рядки безпосередньо.


Ваша програма не виводить рядок без змін перед видаленням пробілів.
Nathan.Eilisha Shiraini

@ Nathan.EilishaShiraini Я виправив цю помилку і набрав кілька байтів, щоб зменшити кількість байтів.
BgrWorker

2

JavaScript (ES6), 76 байт

f=(s,r,n,l=s.length)=>s[r?--l:0]<"!"?s+`
`+f(s.slice(!r,l),!r):n?s:f(s,!r,1)

Виводиться як багаторядковий рядок.

Випробування

Використовуючи крапки замість пробілів, як це робить більшість відповідей.



2

Октава , 88 83 байти

5 байт, завдяки Стюі Гріффін!

x=[input('') 0];for p=mod(1:sum(x),2)if x(~p+end*p)<33,disp(x=x(2-p:end-p)),end,end

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


Дуже хороша. "У будь-якому випадку, подивіться, чи можете ви видалити пару байтів " :-P
Стюі Гріффін

@StewieGriffin Я мав на увазі у вашій відповіді ... :-D Гарна ідея, дякую!
Луїс Мендо

Я можу видалити мою ... Це настільки не натхненно порівняно з цим ...
Стюі Гріффін

@StewieGriffin Ось ідея видалити два байти . Шкода, що minпотрібна через sте, що динамічно скорочується
Луїс Мендо

2

машинний код x86 для Linux, 60 байт

e8 1f 00 00 00 31 c0 80 3f 20 75 09 47 4d 74 10
e8 0f 00 00 00 80 7c 2f ff 20 74 05 84 c0 75 e5
c3 4d eb dc 6a 04 58 50 31 db 43 89 f9 89 ea cd
80 58 6a 0a 89 e1 89 da cd 80 58 c3

Це функція для Linux x86. Він бере як вхідний вказівник на рядок в ediі довжину рядка в ebp.

Ungolfed, з певною інфраструктурою для тестування (компілюйте з FASM, запустіть з рядком як програмний аргумент; шукайте undress:мітку для фактичного коду функції):

format ELF executable
segment executable
SYS_WRITE = 4
    jmp     callUndress
; -------------------- the function itself --------------------------------
; Input:
;   edi=string
;   ebp=length
undress:
undressLoopPrint:
    call    print
undressLoop:
    xor     eax, eax    ; flag of having printed anything on this iteration
    cmp     byte [edi], ' '
    jne     startsWithoutSpace
    inc     edi
    dec     ebp
    jz      quit
    call    print
startsWithoutSpace:
    cmp     byte [edi+ebp-1], ' '
    je      endsWithSpace
    test    al, al      ; if print has been called, then we have 0x0a in eax
    jnz     undressLoop
quit:
    ret
endsWithSpace:
    dec     ebp
    jmp     undressLoopPrint
print:
    push    SYS_WRITE
    pop     eax
    push    eax
    xor     ebx, ebx
    inc     ebx ; STDOUT
    mov     ecx, edi
    mov     edx, ebp
    int     0x80
    pop     eax
    push    0x0a    ; will print newline
    mov     ecx, esp
    mov     edx, ebx ; STDOUT=1, which coincides with the length of newline
    int     0x80
    pop     eax
    ret
; --------------------- end undress ---------------------------------------
SYS_EXIT = 1
STDERR = 2
callUndress:
    pop     eax     ; argc
    cmp     eax, 2
    jne     badArgc
    pop     eax     ; argv[0]
    pop     edi
    mov     al, 0
    cld
    mov     ecx, -1
    repne   scasb
    lea     edi, [edi+ecx+1] ; argv[1]
    neg     ecx
    sub     ecx, 2
    mov     ebp, ecx     ; strlen(argv[1])
    call    undress
    xor     ebx, ebx
exit:
    mov     eax, SYS_EXIT
    int     0x80
    ud2
badArgc:
    mov     esi, eax
    mov     eax, SYS_WRITE
    mov     ebx, STDERR
    mov     ecx, badArgcMsg
    mov     edx, badArgcMsgLen
    int     0x80
    mov     ebx, esi
    neg     ebx
    jmp     exit
badArgcMsg:
    db      "Usage: undress YourString",0x0a,0
badArgcMsgLen = $-badArgcMsg
segment readable writable
string:
    db      100 dup(0)
    stringLen = $-string

sys_write()робить eaxне нульовим (конкретно 1, кількість написаних символів, якщо припустити, що це не так -errno). Так буде, printякщо ви цього не зробите pop eaxв кінці. Ви можете безпосередньо xor eax,eaxперед cmp byte [edi], ' 'і зберегти mov al,1, а може бути, eaxзберегти / відновити. Хоча ви насправді не зберігаєте її до того часу, як після того, як пограбуєте SYS_WRITE. Хм, замість цього 0ви можете використовувати SYS_WRITEпорівняно 1, оскільки cmp al, imm8має той самий розмір, що і test al,al.
Пітер Кордес

Чи можете ви помістити '\n'в масив, mov byte [ecx + edx], '\n'а не робити другий write()? (І зменшення довжини після друку?) Можливо, ви заощадите кілька інструкцій.
Пітер Кордес

Насправді в print()даний час виїжджає '\n'в eax, що відрізняється від SYS_WRITE, так що ви все ще можете перевірити це. Я думав, що ви економите / відновлюєте eax, але це просто збереження байтів, копіювання константи навколо. Для довгих рядків sys_write()можна залишити високі байти eax не нульовими, так що, на жаль, виключається просто використання mov al, SYS_WRITE.
Пітер Кордес

@PeterCordes насправді так, mov al, 1був стороннім. -2 байт зараз, дякую.
Руслан

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

2

PHP , 117 байт

Я додаю додатковий пробіл на початку, тому він займе пробіл і покаже оригінал без зайвого коду.

Щось нове в цьому ... додасть <? Php та пробіл на початку файлу PHP 6 додаткових байтів чи я можу це отримати безкоштовно?

$s=" $argn";while($r!=$s){$r=$s;if($s[0]==" ")echo($s=substr($s,1))."
";if($s[-1]==" ")echo($s=substr($s,0,-1))."
";}

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


1
Використовуючи свій метод, 6 байт можна зменшити: Спробуйте в Інтернеті!
Ніч2

1
Ви можете опустити тег відкриття PHP, оскільки ви можете запустити його за допомогою такої команди: php -r "echo 1;"Але якщо ви хочете використовувати щось подібне, <?=1;вам слід включити тег у кількість байтів.
Ніч2

1

Pyth , 28 байт

QW<lrKQ6lQ=hZ?&%Z2qdhQ=tQ=PQ

Спробуйте тут! або Перевірте всі тестові випадки!

Пояснення

QW<lrKQ6lQ=hZ?&%Z2qdhQ=tQ=PQ   ~ Full program. Q is autoinitialized to input.

Q                              ~ Output the input.
 W<lrKQ6lQ                     ~ Loop while the condition is met.
  <                            ~ Is smaller?
   lrKQ6                       ~ The length of the original input, stripped on both sides.
        lQ                     ~ The length of the current Q.
          =hZ                  ~ Increment a variable Z, initially 0
             ?&%Z2qdhQ         ~ If Z % 2 == 1 and Q[0] == " ", then:
                      =tQ      ~ Make Q equal to Q[1:] and output, else:
                         =PQ   ~ Make Q equal to Q[:-1] and output.

1

Python 2 , 79 байт

-1 байт завдяки @JonathanFrech

f=lambda s,i=1:[s]+(s>i*'!'and'!'>s[-1]and f(s[:-1])or'!'>s and f(s[1:],0)or[])

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

Тестовий костюм замінює "."з " "перед викликом функції і замінює " "назад на "."перед друком результатів для ясності.


'!'*i and-> i*'!'and.
Джонатан Фрех


1

Октава , 89 байт

s=input('');while any(s([1,end])<33)if s(1)<33,s(1)=[],end,if s(end)<33,s(end)=[],end,end

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

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

Останні букви тут написані: "sendsendendend". Я хотів би, щоб був спосіб зберігати endяк змінну і використовувати це, але вгадайте, що ...


Чи правильно виводити за допомогою s = ...? (Звичайне запитання, я знаю)
Луїс Мендо

У будь-якому разі, подивіться, чи можете ви видалити пару байтів :-P
Луїс Мендо

1

Баш, 98 94 байти

Збережено 4 байти, використовуючи допоміжну оболонку замість послідовностей (погані показники)

r()(s=$1;[[ $s = $b ]]||([[ $s = $a ]]||echo "$s"
b=$a a=$s;((i=!i))&&r "${s# }"||r "${s% }"))

Перша відповідь

r(){ s=$1;[[ $s = $b ]]||{ [[ $s = $a ]]||echo "$s"
b=$a a=$s;((i=!i))&&r "${s# }"||r "${s% }";};}

Зверніть увагу, що !потрібно уникати в інтерактивному режимі

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