脱绳


48

现在我们已经知道如何从其空格中删除字符串。

但是,作为适当的先生/女士,我们宁愿脱衣服


脱绳与剥线相同,只是更细腻。与其一次删除所有前导和尾随空格,不如一一删除它们。我们也交替领先和落后,以免烫伤步骤之间。

" codegolf "(五个前导和尾随空格)开头的示例:

     codegolf     
    codegolf     
    codegolf    
   codegolf    
   codegolf   
  codegolf   
  codegolf  
 codegolf  
 codegolf 
codegolf 
codegolf

  1. 首先输出字符串不变。然后,输出每个步骤。首先删除前导空格(如果适用-参见规则2)。

  2. 输入可能具有不同数量的前导和尾随空格。如果一侧空间不足,请继续给另一侧脱衣服,直到弦线裸露为止。

  3. 输入可能没有前导空格或尾随空格。如果是这样,请原样输出。

  4. 使用PPCG的默认I / O方法PPCG默认漏洞是禁止的。

  5. 可以确定在空输入或仅包含空格的输入上的未定义行为。

  6. 您可以假设该字符串将仅包含ASCII可打印空间(0x200x7E)中的字符。


示例-用点替换空格.以提高可读性:

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

绅士/女士很简洁,所以最短答案以字节为单位



我们是否可以假设至少会有一个非空格字符?
Martin Ender

2
@KevinCruijssen您只需要处理可打印空间(0x200x7E)中的ASCII字符。其他是未定义行为。
Nathan.Eilisha Shiraini

1
@KevinCruijssen是的,不会有这样的测试用例。会有不一样的事情" test\r "" \v test"任。
Nathan.Eilisha Shiraini

1
这是一个有效的测试用例".....................a....."吗?如果是这样,我建议添加它,因为某些答案似乎无法通过这种测试。(圆点当然是为了提高可读性)
Cinaski

Answers:


11

视网膜,26字节

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

在线尝试!(为了清楚起见,测试套件使用句点。页脚和标头将它们与主代码之间的空格进行转换。)

说明

如果我们能在每次放置前导和尾随空格与打印中间结果之间交替选择,那就太好了。问题是当前Retina不能有条件地打印,因此,如果没有前导空格或尾随空格,它甚至会打印此中间结果,从而生成重复项。(Retina 1.0将提供一个选项,该选项仅在操作更改了字符串的情况下才打印结果,但我们还没有出现...)

因此,相反,我们正在构建一个包含所有中间结果的字符串,并在最后打印出来。

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

{程序的两个阶段都包装在一个循环中,该循环重复执行直到字符串停止更改为止(这意味着没有剩余的前导/尾随空格)。阶段本身将字符串的最后一行和该最后一行的前导空格匹配,然后回写匹配以及新行中空格之后的内容(从而在副本中删除前导空格)。

 $
 ¶$%`

删除尾随的空间要容易一些。如果我们只匹配最后一个空格,则可以访问它前面的内容(在同一行上),$%`这是前缀替换的行感知变体$`


11

Python 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
您可以通过替换a为内置函数id来进一步完善Python 2代码,从而省去了在开始时对其进行定义的麻烦。-2个字节。
LyricLy

7

Perl 6、55个字节

感谢@nwellnhof,节省了3个字节。

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

在线尝试!

说明($_,{$++%2??S/" "$//!!S/^" "//}...*)是以原始字符串($_)开头的递归无限序列,下一个元素由在前一个元素上调用的块给出。

块本身获取$_变量中的字符串。操作员S/(regex)/(string)/将搜索(regex)in 的第一个匹配项$_,将其替换为(string),然后返回结果。如果不匹配,则返回未$_更改的内容。我们将三元运算符?? !!与条件一起使用,该条件$++%2False和之间交替True$是一个自由变量,可在调用该块时保留其内容。)

在最坏的情况下(一侧上的所有空格和另外1个字符),我们每2步删除1个空格。因此,我们可以确定在2 *(字符串的长度)步骤中,所有空格都将被删除。我们使用递归序列中的许多元素[^.comb*2],最后使用丢弃重复项(只要应该删除空格但不存在空格,重复项就会出现).unique。这将返回字符串列表,并逐步删除空格。


[^.comb*2]节省2个字节。出于某种原因,此方法有效,但[^2*.comb]无效。不知道为什么。使用三元数?? !!选择正则表达式可保存另一个字节。
nwellnhof

谢谢!我尝试了一下[^2*.comb],但是没有用,所以我只用了[0..2*.comb]。感谢三元组,我只是觉得它太贵了,我没想到我用更贵的东西代替了它……
Ramillies

7

05AB1E21 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

Dang,我尝试了类似的操作,但是由于某种原因,我确定头/尾无法在字符串上工作,并且我打算在github上提出有关此问题。必须读取错误的调试日志。:-)
scottinet

1
@scottinet:我刚刚找到了解决最终检查的方法:)
Emigna

哦...为什么我们以前没有考虑过?由于我们有条件地进行打印,因此不需要精确地循环次数,因此只需要循环足够的次数即可。我借用这个想法来改善答案:-)
scottinet

1
@scottinet:是的。考虑到这一点很明显,但有时很容易错过那些事情:P
Emigna

TFW笨拙的多余答案取得了领先……
Outgolfer的Erik

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字节

@Jonathan Frech使用空格和〜,节省了2个字节

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现在可以了,因为OP声明没有预期的字符少于''。谢谢
edc65

6

Perl 5,32个字节

由于@Abigail节省了4个字节。

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固定。
primo

5

C#(.NET核心)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可能是由于OP的新添加的规则:“ 您可以假设该字符串将仅包含ASCII可打印空间中的字符(0x200x7E)。
Kevin Cruijssen

5

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

@Nevay更改(f<1&s.charAt(0)<33)为-4个字节f+s.charAt(0)<33
通过使用@someone的C#.NET答案中!s.trim().equals(s)技巧而不是-1字节。 -8字节感谢@Nevay通过改变再次到,因为将返回“ 此字符串的一个副本,开头和结尾的空格去掉,或者这个字符串,如果它没有前导或尾随空白 ”,因此参考保持不变,并可用于检查它们是否为相同的引用,而不是检查相同的值。s.matches(" .*|.* ")
!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字节)。
Nevay

1
您可以使用s!=s.trim()而不是!s.trim().equals(s);(-8字节)。
Nevay


4

果冻,16字节

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

在线尝试!

-2个字节感谢Outgolfer的Erik
-1个字节感谢Miles

说明

Ḋ=⁶Ḣ$¡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


@EriktheOutgolfer谢谢,编辑来了。
HyperNeutrino

反向/身份交替命令的好主意!
Emigna

@Emigna谢谢!:DI主要只是想找一个借口使用新快速程序... heh:P
HyperNeutrino

ƭ仅当链长于两个时才需要nilad。¹Ṛƭ在这里工作正常。
英里


3

Java(OpenJDK 8)161147146字节

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个字节,并且将其删除。;)
Kevin Cruijssen

1
我不能完全肯定,但我认为你可以打高尔夫球字节改变(u=32-x.charAt(l)>>-1)(u=32-x.charAt(l)>>k)
凯文Cruijssen

@KevinCruijssen不会工作,k0每秒迭代一次。
Nevay

1
是的,但很奇怪的是TIO可以正常工作,并为更改了所有测试用例,并给出正确的结果u。当我也-1改为kfor 时并非如此v。我很困惑为什么它会起作用,因为k确实会0在之后k=~k..:S
Kevin Cruijssen

1
@KevinCruijssen对于k=0场景:如果left左边有空格,则u其值与以前(0)相同;如果left左边没有空格,则(k=~k)&~v|u求值为-1|u~0&-1|u),因此的undefined(负)值u无关紧要(-1|x==-1)。
Nevay

3

05AB1E25 17字节

通过从Emigna借用不需要结束检查的想法,获得 -8个字节

,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

我喜欢您的循环方法:)我一直在试图找到一种无需多次if就可以一次完成所有操作的方法,但是我还没有弄清楚。另外,您的解释似乎包含空字符串而不是空格。
Emigna

谢谢!我固定了解释,我忘了在打高尔夫球时使用S#-1” 代替“ is empty”部分。循环...好吧...相比简单的方法,它节省了高达1个字节。我目前正在寻找一种检测任务结束的更短方法(为此需要5个字节),并且我也在考虑一种完全不同的方法。我确实认为,有一种更聪明的方法来解决这一挑战。
scottinet

如果您尝试一次完成所有操作(正如我目前正在研究的那样),则退出循环的最佳检查是8个字节...
Emigna

3

[R 145个 133 111字节

通过@Giuseppe,可以将-12个字节存储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

@Giuseppe是的,由于需要添加,我认为将其全部包含在单个语句中的时间略长sep=""。在大多数挑战中,多余的尾随空间并不重要,但不幸的是在这里确实如此!
user2390246

133个字节 -谈谈你的使用sub只是提出这一点,IDK为什么
朱塞佩

@Giuseppe非常优雅!
user2390246

您可以设置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个字节一样短,但是您仍然可以像这样打高尔夫球12个字节: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)));}
Kevin Cruijssen

当前,此操作不会“ ...不变地输出字符串”,并且在输入前导空格而没有尾随空格时会失败。
Nevay

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个字节)(似乎是正确的,但测试并不多)。
Nevay

3

MATL21 16字节

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

为了更清晰,这使用点而不是空格。对于空格,请替换4632

在线尝试!

说明

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.

真好!确实,我们需要更多的内置函数来周期性地应用函数...顺便说一句,我发现删除第一个空格的方法要短得多:tio.run / ## yygtzv7 / v / ...
Leo

@Leo谢谢!?在事后看来,使用似乎很明显……
Zgarb

3

C ++,196个 193 189 186 183字节

-10字节归功于Jonathan Frech
-3字节归功于Zacharý

#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)176170字节

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

在线尝试!

这是@someone的答案的替代方法,仅直接输出字符串。


您的程序在删除空格之前不会输出未修改的字符串。
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字节

感谢Stewie Griffin节省 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
Stewie Griffin

@StewieGriffin我的意思是您的回答... :-D好主意,谢谢!
Luis Mendo

我可能会删除我的……与之相比,这真是太没有灵感了……
Stewie Griffin

@StewieGriffin这是删除两个字节的想法。min由于s动态收缩而需要的怜悯
Luis Mendo

2

Linux的x86机器代码,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的功能。它以输入指针指向in中的字符串edi和in中的字符串长度ebp

毫无用处,需要测试一些基础结构(使用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,假设不是-errnoprint则为写入的字符数),如果不pop eax末尾也是如此。您可以在xor eax,eax之前cmp byte [edi], ' '保存mov al,1,也可以eax保存/还原。尽管您直到用废话才真正保存它SYS_WRITE。嗯,0您可以使用SYS_WRITEvs. 1,因为cmp al, imm8它的大小与相同test al,al
彼得·科德斯

您可以将a '\n'放入数组mov byte [ecx + edx], '\n'而不是执行2nd write()吗?(要减小打印后的长度吗?)可能为您节省一些说明。
彼得·科德斯

实际上,print()当前离开'\n'的位置eax,不同于SYS_WRITE,因此您仍然可以进行检查。我以为您正在保存/恢复eax,但这只是保存字节并复制一个常数。对于长字符串,sys_write()可以将eax的高字节保留为非零,因此很不幸地排除了使用mov al, SYS_WRITE
彼得·科德斯

@PeterCordes实际上是的,mov al, 1是无关紧要的。现在是-2个字节,谢谢。
Ruslan

注册调用约定将为您节省加载指令。在代码高尔夫球中,自定义调用约定通常对于asm是公平的游戏。OTOH,如果您更喜欢标准的stack-args调用约定,那也很有趣。
彼得·科德斯

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

C#-再说一次,125个字节

while(s.Trim()!=s){if(s[0]==' '){yield return s=s.Substring(1);}if(s.Last()==' '){yield return s=s.Substring(0,s.Length-1);}}

干杯!

在线尝试!


欢迎来到PPCG!
Laikoni

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 = ...吗?(我知道是最常见的问题)
Luis Mendo

无论如何,看看是否可以删除几个字节:-P
Luis Mendo

1

Bash,98 94字节

使用subshel​​l而不是序列节省了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% }";};}

请注意!必须以交互方式进行转义

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.