文字列をアルファベットのスニペットに減らします


25

大文字と小文字のアルファベット文字とスペースのみで構成される空でない文字列([a-zA-Z ])がある場合、最初の文字から始まるアルファベットのスニペットに減らします。

文字列を減らすには、最初のアルファベット文字から始め、その後のアルファベットの次の文字ではないすべての文字を削除します。文字列の最後に到達するまでこれを繰り返します。

codegolf

で始まり、アルファベットの次の文字ではないcため削除oします。
キープdそれはようであるアルファベットの次の文字、そして保つeそれはあまりにも次の文字であるとして。
削除goおよびl、と続けますf

最終的なスニペットは cdef

ルール

  • 大文字を維持する必要があるため、CodEgolF結果としてCdEF
  • スペースはアルファベットの文字ではないため、文字列の先頭であっても常に削除する必要があります
  • 縮小の性質により、入力の最初のアルファベット文字は常に出力の最初の文字になります。
  • zZはアルファベットの最後の文字です。その後に文字はなく、アルファベットはループしません。

テストケース

codegolf -> cdef
CodEgolf -> CdEf
 codeolfg -> cdefg
ProgrammingPuzzles -> P
Stack Exchange -> St
The quick red fox jumped over the lazy brown dog -> Tuvw
Zebra -> Z
Abcdegfhijkl -> Abcdef

得点

これはなので、各言語で最少のバイト勝ちます!


最後から2番目のテストケースから、私たちが到達したらz停止するだけですよね?
ミスターXcoder

正しいMr.Xcoder @、「ルール」の下で最後のポイントを参照してください
Skidsdev

2
先頭にスペースを含むテストケースを追加してください。いいね:<space>codegolf
Mr Xcoder

出力文字の配列を返すことはできますか?
TheLethalCoder

1
@ Mr.Xcoderはい、できます
Skidsdev

回答:


12

JavaScript(ES6)、66 79 68 67バイト

f=([c,...s],p)=>c?(p?~parseInt(c+p,36)%37:c<'!')?f(s,p):c+f(s,c):''

どうやって?

連続した文字をテストする

2文字をASCIIコードに変換するのはJSではかなり長い操作になるため、代わりに次の式を使用します。

~parseInt(b + a, 36) % 37

両方のことを条件とするA及びBは、であり[a-zA-Z ]、上記式に等しい0場合にのみとbは連続文字(ベース36、すなわち連続した数字)であり、無文字の場合を問わ。

例えば:

~parseInt("Y" + "x", 36) = ~(36 * parseInt("Y", 36) + parseInt("x", 36))
                         = ~(36 * 34 + 33)
                         = -(36 * 34 + 33 + 1)
                         = -(37 * 34)

書式設定およびコメント化

f = ([c,                              // c = current character
         ...s],                       // s = array of remaining characters
                p) =>                 // p = previous matching letter
  c ? (                               // if there's still at least 1 character to process:
      p ?                             //   if p was already defined:
        ~parseInt(c + p, 36) % 37     //     test if p and c are NON-consecutive letters
      :                               //   else:
        c < '!'                       //     test if c is a space character
    ) ?                               //   if the above test passes:
      f(s, p)                         //     ignore c and keep the current value of p
    :                                 //   else:
      c + f(s, c)                     //     append c to the final result and update p to c
  :                                   // else:
    ''                                //   stop recursion

テストケース


7

Python 2、69バイト

lambda s:reduce(lambda x,y:x+y*((ord(y)-ord(x[~0]))%32==1),s.strip())

オンラインでお試しください!

文字列の単純な縮小。の場合にのみ、次の文字を連結し(ord(y)-ord(x[~0]))%32==1ます。非常にいチェック-改善できると確信していますが、どうすればいいかわかりません!


賢い解決策!P:あまりにも悪いことは、Python 2-だけだ
氏Xcoder

を使用してPython 3と互換性を持たせることができfrom functools import*ます。
完全に人間

1
@ThomasWard totallyhumanは、Python 3互換にする方法を他の人に伝えていました。ところで、import functools as fそしてf.はるかに長いよりもfrom functools import*、確かに一度も使用していました。詳細については、このスレッドを参照してください。
ミスターXcoder

7

Pythonの375の85 84 91 81 77 75バイト

これはPython 3でできる限り短いと思います。Sisyphusの申請に示されているように、Python 2では数バイト短縮できます。

  • 編集:バグを修正するために+10
  • 編集: -1別のバグを修正して
  • 編集:別のバグを修正するための+7
  • 編集:@Ruudの助けを借りて-10バイト
  • 編集: OPにより改行で区切られた文字を出力できるため、-4バイト
  • 編集:@Ruudのおかげで-2バイト、元のバイト数に戻りました!
s=input().strip();k=0
for i in s:
 if(ord(i)-ord(s[0]))%32==k:k+=1;print(i)

オンラインでお試しください!


改善のアイデアがあります。モバイルでゴルフを楽しみます。
ミスターXcoder

2
81バイト。大文字と小文字は、32
Arfie

@Ruudこれらはまさに、私のコメント、編集で話していたものです。
ミスターXcoder


8
ダウンボッターがその理由を説明するのを待っています。
ミスターXcoder


4

Brachylog、15バイト

;ṢxS⊇.ḷ~sẠ∧Sh~h

オンラインでお試しください!

これは10バイトになります:⊇.ḷ~sẠ&h~hかなり面白くない「文字列はスペースで始めることができます」という制約がない場合。

説明

;ṢxS               S is the Input with all spaces removed
   S⊇.             The Output is an ordered subset of the Input
     .ḷ            The Output lowercased…
        ~sẠ          …is a substring of "abcdefghijklmnopqrstuvwxyz"
           ∧
            Sh     The first char of S…
              ~h   …is the first char of the Output

これはかなり宣言的であるため、これも非常に遅いです。


まあ、少なくともそれはゼリーを打ち負かす!そして、プラス側に、私はこのoutgolf本当にあなたができるとは思わない...
エリックOutgolfer

3

MATL18 16 15バイト

間違いを指摘してくれたMr.Xcoderに感謝します。

Xz1&)"t@hkd1=?@

出力の文字は改行で区切られます。

オンラインでお試しください!または、すべてのテストケースを確認します(わかりやすくするために、フッターコードにはすべての出力文字が同じ行に表示されます)。

説明

Xz       % Implicitly input a string. Remove spaces
1&)      % Push first character and then the remaining substring
"        % For each
  t      %   Duplicate previous character
  @      %   Push current character
  h      %   Concatenate both characters
  k      %   Convert to lowercase
  d      %   Consecutive difference. Gives a number
  1=     %   Is it 1?
  ?      %   If so
    @    %     Push current char
         %   End (implicit)
         % End (implicit)
         % Display stack (implicit)

文字列の先頭にあるスペースを削除するのを忘れました:スペースはアルファベットの文字ではないため、文字列の先頭であっても常に削除する必要があります
氏Xcoder

@ Mr.Xcoderありがとう!修正済み
ルイスメンドー


2

C#(モノラル)129 107 93 91 87バイト

s=>{var r=s.Trim()[0]+"";foreach(var c in s)if(r[r.Length-1]%32==~-c%32)r+=c;return r;}

@Mrのおかげで2バイト節約されました。Xcoder。
@jkelmのおかげで4バイト節約されました。

オンラインでお試しください!


主要なスペースで失敗
Skidsdev

@Mayube Woopsはそれを見なかった、修正。
TheLethalCoder

2
91バイト。C-ような言語とPythonでは、(c-1)%32ある~-c%32
氏Xcoder

1
87のバイトは、あなたはので、forループでチェックのトリミングされた文字列を再割り当てする必要はありません
jkelm

2

PHP、64 + 1バイト

while($c=$argn[$i++])$c<A||$n&&($c&_)!=$n||(print$c)&$n=++$c&__;

でパイプとして実行する-nR、オンラインで試してください


別に普通のトリックから:$cに達するZ++$cをもたらしAA
そして&__そのままその長さを保持します。これ$n以上一致しません$c



2

Haskell、106105 97バイト

import Data.Char
import Data.List
z=ord.toUpper
a%b|z a+1==z b=b|0<3=a
nub.scanl1(%).filter(>' ')

fromEnumはインポートの代わりに+文字演算を使用しようとしましたData.Charが、それは長くなりました...

H.PWizのおかげで8バイト節約されました!

オンラインでお試しください。



または、100バイトData.List
H.PWiz

@ H.PWiz素晴らしい!ありがとう!
クリスティアンルパスク

2

Pyth、21 20 18バイト

ef&qhThQhxGrT0tyr6

ここで試してみてください。

より効率的な20バイトバージョン:

.U+b?t-CrZ1Creb1kZr6

ここで試してみてください。

-1 Xcoder氏に(間接的に)感謝します。


同等:(.U+b?tlrreb1rZ1kZrz6私は思う)。そのトリックは私を助けました。
ミスターXcoder

私はバイトを保存した可能性が同等であったMr.Xcoderもし@ .U+b?tlrreb1rZ1kZr6残念ながらr <str> 6手段A.strip()、非リーディングや、末尾の空白を削除しません。
エリックアウトゴルファー

そうそう、私はあなたのソリューションが削除されているすべてのスペースに依存しています表示されませんでした(私はありません)
ミスターXcoder

@ Mr.Xcoderうーん、すべてのスペースを削除する必要があります。
エリックアウトゴルファー

いいえ、できません。スペースのASCII値はですが32、すべての文字は> 64であり、したがって機能には影響しません。これはあなたの答えにも当てはまると思います。
ミスターXcoder

1

Perl 6、51バイト

{S:i:g/\s|(\w){}<([<!before "{chr $0.ord+1}">.]+//}

試して

拡張:

{  # bare block lambda with implicit parameter $_

  S                          # substitute implicitly on $_, not in-place
  :ignorecase
  :global
  /

    |  \s                    # match any space

    |  (\w)                  # match a word character
       {}                    # make sure $/ is updated (which $0 uses)

       <(                    # ignore everything before this

       [

           <!before "{       # make sure this won't match after this point
             chr $0.ord + 1  # the next ASCII character
           }">

           .                 # any character

       ]+                    # match it at least once

  //                         # remove what matched
}

それ<!before …>はゼロ幅のアサーションであることに注意してください



1

Japt18 17 16バイト

@Shaggyのおかげで1バイト節約

x
c
Çc %H¥V%H©V°

オンラインでテストしてください!

これは少し短くなると思っていましたが、...これが人生です...

説明

x    First line: set U to the result.
x    Trim all spaces off of the input. Only necessary to remove leading spaces.

c    Second line: set V to the result.
c    Take the charcode of the first character in U.

 Ç   c %H¥ V%H© V°
UoZ{Zc %H==V%H&&V++}   Final line: output the result.
UoZ{               }   Filter to only the chars in Z where
    Zc                   the charcode of Z
       %H                mod 32
         ==V%H           equals V mod 32.
              &&V++      If true, increment V for the next letter.

少なくとも私の28バイトの悲劇よりも短い!:あなたは置き換えることができますようにDに見えrSx
シャギー

1

C#(.NET Core)70 60 + 18バイト

TheLethalCoderのおかげで-10バイト

a=>{var c=a.Trim()[0];return a.Where(x=>x%32==c%32&&++c>0);}

バイト数には以下も含まれます。

using System.Linq;

オンラインでお試しください!

TheLethalCoderの投稿の楽しみよりも1バイト長い(現在は)(もうない)。LINQを使用した異なるアプローチ。

これは、C#の2つのCのような機能を利用します。文字char変数は暗黙的に整数と同じ動作をし、intブール値AND演算子&&は、左がを返す場合、右操作を実行しませんfalse。コードの説明:

a =>                                  // Take string as input
{
    var c = a.Trim()[0];              // Delete leading spaces and take first letter
    return a.Where(                   // Filter out characters from the string, leaving those that:
               x => x % 32 == c % 32  // it's the next character in alphabet case-insensitive (thanks to modulo 32 - credits to previous answers)
               && ++c > 0             // If it is, go to the subsequent character in alphabet (and this always has to return true)
           );
}

バイトを節約するためにaを.ToArray()返すことで削除しIEnumerable<char>ます。
TheLethalCoder

@TheLethalCoder右、私はちょうど挑戦の下でコメントを見ました。ありがとうございました!
グルゼゴルツプワフスキ

1

q / kdb +、47 45バイト

溶液:

{10h$({(x;x,y)1=mod[y-last x;32]}/)7h$trim x}

例:

q){"c"$({(x;x,y)1=mod[y-last x;32]}/)7h$trim x}"CodEgolf"
"CdEf"
q){"c"$({(x;x,y)1=mod[y-last x;32]}/)7h$trim x}" codeolfg"
"cdefg"
q){"c"$({(x;x,y)1=mod[y-last x;32]}/)7h$trim x}"ProgrammingPuzzles"
"P"
q){"c"$({(x;x,y)1=mod[y-last x;32]}/)7h$trim x}"The quick red fox jumped over the lazy brown dog"
"Tuvw"

説明:

収束機能mod 32とともに既存のソリューションのトリックを活用します。結果の最後の要素(たとえば、 "The quick red fox ..."で始まる)と現在の文字(32 で'd された後)の差が1である場合、文字列を反復処理し、これを結果(したがって、なぜ私たちがとるのかを考えます)、すべてを文字列にキャストします。Tmodlast x

{10h$({(x;x,y)1=mod[y-last x;32]}/)7h$trim x} / the solution
{                                           } / lambda function
                                      trim x  / trim whitespace (leading/trailing)
                                   7h$        / cast string to ASCII (a -> 97)
     ({                         }/)           / converge
                    y-last x                  / y is the next item in the list, x contains results so far
              1=mod[        ;32]              / is the result mod 32 equal to 1
       (x;x,y)                                / if false, return x, if true return x concatenated with y
 10h$                                         / cast back to characters


0

網膜、76バイト

 

^.
$&$&$&¶
{T`@@L@l`@l@l@`..¶
T`l`L`.¶
(.)(.)((¶).*?(\1|\2)|¶.*)
$5$5$5$4

オンラインでお試しください!リンクにはテストケースが含まれます。説明:

 

スペースを削除します。

^.
$&$&$&¶

最初の文字を複製し、区切り記号を挿入します。

{T`@@L@l`@l@l@`..¶
T`l`L`.¶

2番目と3番目の文字を小文字に変換し、増分します。後者を大文字に変換します。これらは現在、検索文字です。

(.)(.)((¶).*?(\1|\2)|¶.*)
$5$5$5$4

検索文字のいずれかと一致するようにしてください。見つかった場合は、一致を3回複製し、次の検索のためにループを再開します。それ以外の場合は、検索文字と残りの入力を削除するだけです。


0

8番目、114バイト

コード

: z dup n:1+ 32 bor >r "" swap s:+ . ; 
: f s:trim 0 s:@ z ( nip dup 32 bor r@ n:= if rdrop z then ) s:each rdrop ;

説明

: z             \ n -- (r: x)
                \ print letter and save on r-stack OR-bitwised ASCII code of following letter
  dup           \ duplicate item on TOS
  n:1+          \ get ASCII code of the following letter
  32 bor        \ bitwise OR of ASCII code and 32 
  >r            \ save result on r-stack
  "" swap s:+ . \ print letter
;

: f        \ s -- 
  s:trim   \ remove trailing whitespace
  0 s:@    \ get 1st letter
  z        \ print 1st letter and save on r-stack OR-bitwised ASCII code of following letter
  ( nip    \ get rid of index
    dup    \ duplicate item on TOS
    32 bor \ bitwise OR of current ASCII code and 32 
    r@     \ get value stored on r-stack
    n:=    \ compare values to see if letter is printable or not
    if 
      rdrop \ clean r-stack
      z     \ print letter and save on r-stack OR-bitwised ASCII code of following letter
    then 
  ) 
  s:each    \ handle each character in string
  rdrop     \ clean r-stack
;

ok> " The quick red fox jumped over the lazy brown dog" f
Tuvw



0

Pyth、15バイト

eo,}r0NG_xQhNty

テストスイート

他のすべての回答とは異なり、これは出力を結び付けず、入力のすべてのサブシーケンスを生成してから、目的の文字列を最後に配置するように命令し、出力します。


出力の最初の文字も入力の最初の文字であるかどうかを確認する必要があると思います。そして、最初の注文が重要だと思います。
エリックアウトゴルファー

@EriktheOutgolfer申し訳ありませんが、答えが間違っていると言っていますか?アルファベット順のすべてのサブシーケンスの中で、最初の文字が入力で最も早いシーケンスが最後にソートされていることを確認します。スペースで始まるテストケースを参照してください。
isaacg

説明を追加してください。私は誤解か何か...持っていること
エリックOutgolfer

0

J、部分解

フィードバックや改善のためのアイデアのためにこれを投稿しています。動作しますが、大文字と小文字の区別のケースを処理せず、Jにはすでに長いです。

最初に、左右の引数がアルファベット順に隣接しているかどうかを示す2項ヘルパー動詞:

g=.(= <:)&(a.&i.)  NB. could save one char with u:

次に、最初の要素から始まるアルファベットストリークの一部ではない最初の要素を削除する動詞:

f=.({~<^:3@>:@i.&0@(0,~2&(g/\))) ::]

::非ストリーク要素が見つからない場合(つまり、引数全体が有効なアルファベットストリークである場合)、Adverseを使用して引数全体を変更せずに返すことに注意してください。

最後に、解答はf収束まで適用することにより与えられます:

f^:_ 'codegolf'  NB. => 'cdef'

オンラインでお試しください!


そして、これはf読みやすいように解析されたバージョンです:

           ┌─ ~ ─── {                         
           │                              ┌─ <
           │                       ┌─ ^: ─┴─ 3
           │                 ┌─ @ ─┴─ >:      
       ┌───┤           ┌─ @ ─┴─ i.            
       │   │     ┌─ & ─┴─ 0                   
       │   │     │                            
       │   └─ @ ─┤     ┌─ 0                   
── :: ─┤         │     ├─ ~ ─── ,             
       │         └─────┤                      
       │               │     ┌─ 2             
       │               └─ & ─┴─ \ ─── / ──── g
       └─ ]         

サイドの質問:SOで表示するときにボックスの文字が完全に揃わないのはなぜですか(コンソールで動作します):

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.