Giảm chuỗi thành một đoạn của bảng chữ cái


25

Đưa ra một chuỗi không trống chỉ bao gồm các ký tự chữ cái in hoa và chữ thường và dấu cách ( [a-zA-Z ]), giảm nó thành một đoạn của bảng chữ cái, bắt đầu bằng ký tự đầu tiên.

Để giảm một chuỗi, bắt đầu với ký tự chữ cái đầu tiên, sau đó xóa mọi ký tự sau nó không phải là chữ cái tiếp theo của bảng chữ cái. Tiếp tục làm điều này cho đến khi bạn đạt đến cuối chuỗi.

Ví dụ codegolf:

Bắt đầu với c, loại bỏ ovì nó không phải là chữ cái tiếp theo của bảng chữ cái.
Giữ dvì nó chữ cái tiếp theo của bảng chữ cái, và giữ evì nó cũng là chữ cái tiếp theo.
Loại bỏ g, ol, và giữ f.

Đoạn trích cuối cùng của bạn sẽ là cdef

Quy tắc

  • Viết hoa nên được duy trì, do đó CodEgolFsẽ dẫn đếnCdEF
  • Không gian không phải là một chữ cái của bảng chữ cái và do đó phải luôn được loại bỏ, ngay cả khi đó là bắt đầu của chuỗi
  • Do tính chất của việc giảm, ký tự chữ cái đầu tiên của đầu vào sẽ luôn là ký tự đầu tiên của đầu ra.
  • zZlà chữ cái cuối cùng của bảng chữ cái. Không có chữ cái nào sau nó, bảng chữ cái không lặp.

Các trường hợp thử nghiệm

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

Chấm điểm

Đây là , vì vậy ít byte nhất trong mỗi ngôn ngữ sẽ thắng!


Từ trường hợp thử nghiệm cuối cùng thứ hai, tôi thấy rằng nếu chúng ta đạt được zChúng ta chỉ dừng lại, phải không?
Ông Xcoder

@ Mr.Xcoder Đúng, xem điểm cuối cùng trong "Quy tắc"
Skidsdev

2
Vui lòng thêm một trường hợp thử nghiệm với một không gian ở đầu. Giống như:<space>codegolf
Ông Xcoder

Tôi có thể trả về một mảng các chữ cái đầu ra không?
TheLethalCoder

1
@ Mr.Xcoder có bạn có thể
Skidsdev

Câu trả lời:


12

JavaScript (ES6), 66 79 68 67 byte

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

Làm sao?

Kiểm tra các chữ cái liên tiếp

Vì việc chuyển đổi hai ký tự thành mã ASCII của chúng sẽ là một hoạt động khá dài trong JS, nên chúng tôi sử dụng công thức sau:

~parseInt(b + a, 36) % 37

Với điều kiện cả ab đều ở trong [a-zA-Z ], biểu thức trên bằng với 0khi và chỉ khi ab là các chữ cái liên tiếp (tức là các chữ số liên tiếp trong cơ sở 36), bất kể trường hợp của các ký tự.

Ví dụ:

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

Định dạng và nhận xét

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

Các trường hợp thử nghiệm


7

Python 2 , 69 byte

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

Hãy thử trực tuyến!

Một giảm đơn giản của chuỗi. Chúng tôi chỉ đơn giản là ghép các ký tự tiếp theo nếu và chỉ khi (ord(y)-ord(x[~0]))%32==1. Kiểm tra rất xấu - tôi chắc chắn nó có thể được cải thiện, nhưng tôi không biết làm thế nào!


Giải pháp thông minh! Quá tệ, đó chỉ là Python 2: P
Ông Xcoder

Bạn có thể làm cho nó tương thích với Python 3 với from functools import*.
hoàn toàn là

1
@ThomasWard hoàn toàn chỉ nói cho người khác biết làm thế nào để nó tương thích với Python 3. Btw, import functools as ff.lâu hơn nhiều so from functools import*với chắc chắn, thậm chí được sử dụng một lần. Xem chủ đề này để biết thêm thông tin.
Ông Xcoder

7

Python 3 , 75 85 84 91 81 77 75 byte

Tôi nghĩ rằng nó ngắn như nó có thể có trong Python 3 . Nó có thể được rút ngắn bằng một vài byte trong Python 2, như thể hiện trong bài nộp của Sisyphus .

  • EDIT: +10 để sửa lỗi
  • EDIT: -1 bằng cách sửa một lỗi khác
  • EDIT: +7 để sửa lỗi khác
  • EDIT: -10 byte với sự trợ giúp từ @Ruud
  • EDIT: -4 byte kể từ khi OP cho phép chúng tôi xuất các chữ cái được phân tách bằng một dòng mới
  • EDIT: -2 byte nhờ @Ruud , trở lại số byte ban đầu!
s=input().strip();k=0
for i in s:
 if(ord(i)-ord(s[0]))%32==k:k+=1;print(i)

Hãy thử trực tuyến!


Tôi có ý tưởng để cải thiện, chơi golf trên điện thoại di động sớm.
Ông Xcoder

2
81 byte . Chữ in hoa và chữ thường phù hợp thuận tiện khi được điều chế bởi 32
Arfie

@Ruud Đó chính xác là những điều tôi đã nói trong phần bình luận, chỉnh sửa.
Ông Xcoder


8
Tôi đang chờ đợi downvoter giải thích lý do của họ.
Ông Xcoder


4

Brachylog , 15 byte

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

Hãy thử trực tuyến!

Đây sẽ là 10 byte : ⊇.ḷ~sẠ&h~h, nếu không có ràng buộc "các chuỗi có thể bắt đầu bằng khoảng trắng" không thú vị.

Giải trình

;Ṣ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

Vì điều này là khá khai báo, điều này cũng thực sự chậm.


Chà, ít nhất thì nó cũng đánh bại Jelly! Và, về mặt tích cực, tôi không nghĩ rằng bạn thực sự có thể vượt qua điều này ...
Erik the Outgolfer

3

MATL , 18 16 15 byte

Cảm ơn Mr.Xcoder đã chỉ ra một lỗi, giờ đã sửa

Xz1&)"t@hkd1=?@

Các chữ cái trong đầu ra được phân tách bằng dòng mới.

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp kiểm tra (mã chân trang hiển thị tất cả các chữ cái đầu ra trên cùng một dòng cho rõ ràng).

Giải trình

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)

Bạn đã quên xóa các khoảng trắng khi chúng ở đầu chuỗi: Dấu cách không phải là chữ cái của bảng chữ cái và do đó phải luôn được xóa, ngay cả khi đó là phần đầu của chuỗi .
Ông Xcoder

@ Mr.Xcoder Cảm ơn! Đã sửa
Luis Mendo


2

C # (Mono) , 129 107 93 91 87 byte

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

Đã lưu 2 byte nhờ @Mr. Xcoder.
Đã lưu 4 byte nhờ @jkelm.

Hãy thử trực tuyến!



@Mayube Woops không thấy điều đó, đã sửa.
TheLethalCoder

2
91 byte . Trong các ngôn ngữ giống như C và Python, (c-1)%32~-c%32
Ông Xcoder

1
87 byte Bạn không cần gán lại chuỗi đã cắt vì các kiểm tra trong vòng lặp for
jkelm

2

PHP, 64 + 1 byte

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

Chạy như ống với -nRhoặc thử trực tuyến .


Ngoài các thủ thuật thông thường: Khi $cđạt Z, ++$ckết quả trong AA,
&__giữ chiều dài mà không bị ảnh hưởng; vì vậy $nsẽ không phù hợp nữa $c.




2

Pyth, 21 20 18 byte

ef&qhThQhxGrT0tyr6

Hãy thử nó ở đây.

Phiên bản 20 byte hiệu quả hơn:

.U+b?t-CrZ1Creb1kZr6

Hãy thử nó ở đây.

-1 nhờ ông Xcoder (gián tiếp).


Tương đương: .U+b?tlrreb1rZ1kZrz6(Tôi nghĩ). Thủ thuật đó đã giúp tôi mặc dù.
Ông Xcoder

@ Mr.Xcoder Nếu đó là một tương đương, tôi có thể đã lưu một byte với .U+b?tlrreb1rZ1kZr6nhưng không may r <str> 6có nghĩa là A.strip(), không xóa khoảng trắng không dẫn đầu hoặc theo dõi.
Erik the Outgolfer 17/8/17

Ồ vâng, tôi không thấy giải pháp của bạn phụ thuộc vào tất cả các không gian bị xóa (của tôi không)
Ông Xcoder

@ Mr.Xcoder Umm, bạn nên xóa tất cả các khoảng trắng.
Erik the Outgolfer

Không, tôi không nên, vì không gian có giá trị ASCII 32, trong khi tất cả các chữ cái đều có > 64, và do đó không ảnh hưởng đến chức năng. Tôi nghĩ rằng điều này áp dụng cho câu trả lời của bạn quá.
Ông Xcoder

1

Perl 6 , 51 byte

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

Kiểm tra nó

Mở rộng:

{  # 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
}

Lưu ý rằng đó <!before …>là một xác nhận độ rộng bằng không



1

Japt , 18 17 16 byte

Đã lưu 1 byte nhờ @Shaggy

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

Kiểm tra nó trực tuyến!

Đã nghĩ rằng điều này sẽ ngắn hơn một chút, nhưng ... Đó là cuộc sống ...

Giải trình

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.

Ngắn hơn chuyến đi 28 byte của tôi, ít nhất! : D Có vẻ như bạn có thể thay thế rSbằng x.
Xù xì

1

C # (.NET Core) , 70 60 + 18 byte

-10 byte nhờ TheLethalCoder

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

Số lượng byte cũng bao gồm:

using System.Linq;

Hãy thử trực tuyến!

Dài hơn 1 byte (hiện tại) (không còn nữa) so với TheLethalCoder's vì vậy hãy đăng bài để giải trí. Cách tiếp cận khác nhau, với LINQ.

Điều này tận dụng hai tính năng giống như C trong C # - một charbiến ký tự được mặc nhiên hoạt động giống như một số nguyên intvà toán tử boolean AND &&không thực hiện thao tác đúng nếu trái trả về a false. Mã giải thích:

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

Loại bỏ .ToArray()bằng cách trở lại như một IEnumerable<char>để lưu byte.
TheLethalCoder

@TheLethalCoder đúng, tôi vừa thấy bình luận dưới thử thách. Cảm ơn bạn!
Grzegorz Puławski

1

q / kdb +, 47 45 byte

Dung dịch:

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

Ví dụ:

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"

Giải trình:

Tận dụng mod 32mánh khóe từ các giải pháp hiện có cùng với chức năng hội tụ . Lặp lại chuỗi, nếu sự khác biệt giữa phần tử cuối cùng của kết quả (ví dụ: bắt đầu bằng T"Con cáo đỏ nhanh ...") và ký tự hiện tại là 1 (sau khi là mod'd với 32), thì chúng ta thêm nó vào kết quả (do đó lấy lý do tại sao chúng ta lấy last x), sau đó chuyển mọi thứ trở lại chuỗi.

{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

1

Perl 5 , 30 + 1 (-n) = 31 byte

/$b/i&&(print,$b=++$_)for/\S/g

Hãy thử trực tuyến!

Làm sao?

/$b/i        # check if this letter equals the one in $b, ignore case
&&(print,    # output it if so
$b=++$_)     # store the next character to find
for/\S/g     # Looping over all non-whitespace characters

0

Võng mạc , 76 byte

 

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

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. Giải trình:

 

Xóa dấu cách.

^.
$&$&$&¶

Nhân ba ký tự đầu tiên và chèn dấu phân cách.

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

Chuyển đổi ký tự thứ hai và thứ ba thành chữ thường và tăng chúng. Chuyển đổi cái sau sang chữ hoa Đây là những nhân vật tìm kiếm.

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

Cố gắng khớp một trong hai ký tự tìm kiếm. Nếu tìm thấy, sau đó nhân ba trận đấu, khởi động lại vòng lặp cho lần tìm kiếm tiếp theo. Nếu không, chỉ cần xóa các ký tự tìm kiếm và phần còn lại của đầu vào.


0

8 , 114 byte

: 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 ;

Giải trình

: 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
;

Thí dụ

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



0

Bình thường, 15 byte

eo,}r0NG_xQhNty

Bộ kiểm tra

Không giống như tất cả các câu trả lời khác, điều này không kết hợp đầu ra, nó tạo ra tất cả các phần tiếp theo của đầu vào, sau đó ra lệnh cho chúng đặt chuỗi mong muốn ở cuối và xuất ra nó.


Tôi nghĩ bạn phải kiểm tra xem chữ cái đầu tiên của đầu ra có phải là chữ cái đầu tiên của đầu vào không. Và tôi nghĩ rằng vấn đề đặt hàng ban đầu.
Erik the Outgolfer

@EriktheOutgolfer Xin lỗi, bạn có nói câu trả lời là sai không? Tôi chắc chắn rằng chuỗi có ký tự đầu tiên xuất hiện sớm nhất trong số tất cả các chuỗi có trong bảng chữ cái là chuỗi được sắp xếp đến cuối. Xem trường hợp thử nghiệm bắt đầu với một không gian.
isaacg

Bạn có thể thêm một lời giải thích xin vui lòng? Tôi có thể đã hiểu lầm hoặc một cái gì đó ...
Erik the Outgolfer

0

J, giải pháp một phần

Tôi đang đăng bài này để phản hồi và ý tưởng để cải thiện hơn bất cứ điều gì khác. Nó hoạt động, nhưng không xử lý các trường hợp viết hoa và cạnh không gian, và đã dài cho J.

Đầu tiên, một động từ trợ giúp dyadic cho bạn biết nếu các đối số bên trái và bên phải được sắp xếp theo thứ tự abc:

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

Tiếp theo một động từ loại bỏ phần tử đầu tiên không phải là một phần của một chuỗi chữ cái bắt đầu từ phần tử đầu tiên:

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

Lưu ý chúng tôi sử dụng bất lợi :: để trả về toàn bộ đối số không thay đổi nếu không tìm thấy phần tử không có vệt nào (nghĩa là, nếu toàn bộ đối số là một vệt chữ cái hợp lệ).

Cuối cùng, giải pháp được đưa ra bằng cách áp dụng fcho đến khi hội tụ:

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

Hãy thử trực tuyến!


Và đây là phiên bản được phân tích cú pháp fđể dễ đọc hơn:

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

Câu hỏi bên lề : tại sao các ký tự hộp không căn chỉnh hoàn hảo khi hiển thị trên SO (chúng hoạt động trong bảng điều khiển của tôi):

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.