Kurangi string menjadi potongan alfabet


25

Diberikan string yang tidak kosong yang hanya terdiri dari karakter dan spasi alfabet huruf kecil dan huruf besar ( [a-zA-Z ]), kurangi menjadi potongan alfabet, dimulai dengan karakter pertama.

Untuk mengurangi string, mulailah dengan karakter alfabet pertama, lalu hapus setiap karakter setelah itu yang bukan huruf berikutnya dari alfabet. Lanjutkan melakukan ini sampai Anda mencapai akhir string.

Sebagai contoh codegolf:

Mulailah dengan c, hapus okarena ini bukan huruf alfabet berikutnya.
Tetap dseperti itu adalah huruf berikutnya alfabet, dan tetap eseperti itu huruf berikutnya juga.
Hapus g,, odan l, dan simpan f.

Cuplikan terakhir Anda akan menjadi cdef

Aturan

  • Kapitalisasi harus dipertahankan, sehingga CodEgolFakan menghasilkanCdEF
  • Spasi bukan huruf alfabet, dan karenanya harus selalu dihapus, bahkan jika itu adalah awal dari string
  • Karena sifat reduksi, karakter alfabet pertama dari input akan selalu menjadi karakter pertama dari output.
  • zZadalah huruf terakhir dari alfabet. Tidak ada huruf setelahnya, alfabet tidak berulang.

Uji Kasus

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

Mencetak gol

Ini adalah , sehingga byte paling sedikit di setiap bahasa menang!


Dari test case terakhir kedua, saya melihat bahwa jika kita mencapai zKita hanya berhenti, kan?
Tn. Xcoder

@ Mr.Xcoder Benar, lihat poin terakhir di bawah "Aturan"
Skidsdev

2
Silakan tambahkan tempat uji dengan spasi di awal. Seperti:<space>codegolf
Tn. Xcoder

Bisakah saya mengembalikan array surat keluaran?
TheLethalCoder

1
@ Mr.Xcoder ya Anda bisa
Skidsdev

Jawaban:


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):''

Bagaimana?

Menguji huruf berturut-turut

Karena mengonversi dua karakter ke kode ASCII mereka akan menjadi operasi yang agak panjang di JS, kami menggunakan rumus berikut sebagai gantinya:

~parseInt(b + a, 36) % 37

Asalkan kedua a dan b berada di [a-zA-Z ], ekspresi di atas sama dengan 0jika dan hanya jika a dan b adalah huruf berurutan (yaitu digit berurutan dalam basis 36), tidak peduli kasus karakternya.

Contohnya:

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

Diformat dan dikomentari

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

Uji kasus


7

Python 2 , 69 byte

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

Cobalah online!

Pengurangan sederhana dari string. Kami hanya menggabungkan karakter berikutnya jika dan hanya jika (ord(y)-ord(x[~0]))%32==1. Pemeriksaan sangat jelek - Saya yakin ini bisa diperbaiki, tapi saya tidak yakin bagaimana caranya!


Solusi pintar! Sayang sekali itu hanya Python 2: P
Mr. Xcoder

Anda dapat membuatnya kompatibel dengan Python 3 dengan from functools import*.
totallyhuman

1
@ThomasWard benar-benar manusiawi hanya memberitahu orang lain bagaimana membuatnya kompatibel dengan Python 3. Btw, import functools as fdan f.jauh lebih lama dari yang from functools import*pasti, bahkan digunakan sekali. Lihat utas ini untuk informasi lebih lanjut.
Tn. Xcoder

7

Python 3 , 75 85 84 91 81 77 75 byte

Saya pikir ini sesingkat itu bisa di Python 3 . Itu dapat dipersingkat oleh beberapa byte dalam Python 2, seperti yang ditunjukkan dalam pengajuan Sisyphus .

  • EDIT: +10 untuk memperbaiki bug
  • Sunting: -1 dengan memperbaiki bug lain
  • EDIT: +7 untuk memperbaiki bug lain
  • EDIT: -10 byte dengan bantuan dari @Ruud
  • EDIT: -4 byte karena OP memungkinkan kita untuk mengeluarkan huruf yang dipisahkan oleh baris baru
  • EDIT: -2 byte terima kasih kepada @Ruud , kembali ke jumlah byte asli!
s=input().strip();k=0
for i in s:
 if(ord(i)-ord(s[0]))%32==k:k+=1;print(i)

Cobalah online!


Saya punya ide untuk perbaikan, golf segera di ponsel.
Tn. Xcoder

2
81 byte . Huruf besar dan kecil cocok dengan mudah ketika dimodulasi oleh 32
Arfie

@Ruud Itulah hal-hal yang saya bicarakan dalam komentar saya, mengedit.
Tn. Xcoder


8
Saya menunggu downvoter untuk menjelaskan alasan mereka.
Tn. Xcoder


4

Brachylog , 15 byte

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

Cobalah online!

Ini akan menjadi 10 byte:, ⊇.ḷ~sẠ&h~hjika bukan karena kendala "string dapat mulai dengan spasi" yang tidak menarik.

Penjelasan

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

Karena ini cukup deklaratif, ini juga sangat lambat.


Yah, setidaknya itu mengalahkan Jelly! Dan, di sisi positifnya, saya tidak berpikir Anda bisa benar-benar mengalahkan ini ...
Erik the Outgolfer

3

MATL , 18 16 15 byte

Terima kasih kepada Mr.Xcoder karena menunjukkan kesalahan, sekarang diperbaiki

Xz1&)"t@hkd1=?@

Huruf dalam output dipisahkan oleh baris baru.

Cobalah online! Atau verifikasi semua kasus uji (kode footer menampilkan semua huruf keluaran pada baris yang sama untuk kejelasan).

Penjelasan

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)

Anda lupa menghapus spasi ketika mereka berada di awal string: Spasi bukan huruf alfabet, dan karenanya harus selalu dihapus, bahkan jika itu adalah awal dari string .
Tn. Xcoder

@ Mr.Xcoder Terima kasih! Diperbaiki
Luis Mendo

3

Java (OpenJDK 8) , 102 101 74 byte

s->{char c=0;for(char x:s)if(c<1&x>32|~-x%32==c%32)System.out.print(c=x);}

Cobalah online!

-27 byte terima kasih kepada @Olivier Grégoire


1
75 byte: s->{char c=0;for(char x:s)if(c<33&x>33|~-x%32==c%32)System.out.print(c=x);}(dengan char[]input)
Olivier Grégoire

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

Disimpan 2 byte berkat @Mr. Xcoder.
Disimpan 4 byte berkat @jkelm.

Cobalah online!


Gagal memimpin ruang
Skidsdev

@Mayube Woops tidak melihat itu, diperbaiki.
TheLethalCoder

2
91 byte . Dalam bahasa C-like dan Python, (c-1)%32adalah~-c%32
Tn. Xcoder

1
87 byte Anda tidak perlu menetapkan kembali string yang dipangkas karena cek di dalam untuk loop
jkelm

2

PHP, 64 +1 byte

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

Jalankan sebagai pipa dengan -nRatau coba online .


Terlepas dari trik yang biasa: Ketika $cmencapai Z, ++$cmenghasilkan AA,
dan &__menjaga panjang itu tidak tersentuh; jadi tidak $nakan cocok lagi $c.




2

Pyth, 21 20 18 byte

ef&qhThQhxGrT0tyr6

Coba di sini.

Versi 20-byte yang lebih efisien:

.U+b?t-CrZ1Creb1kZr6

Coba di sini.

-1 terima kasih kepada Tn. Xcoder (secara tidak langsung).


Setara: .U+b?tlrreb1rZ1kZrz6(saya pikir). Trik itu membantu saya.
Tn. Xcoder

@ Mr.Xcoder Jika itu setara, saya bisa saja menyimpan byte dengan .U+b?tlrreb1rZ1kZr6tetapi sayangnya r <str> 6berarti A.strip(), tidak menghapus spasi kosong yang tidak terkemuka atau tertinggal.
Erik the Outgolfer

Oh ya, saya tidak melihat solusi Anda bergantung pada semua ruang yang dihapus (milik saya tidak)
Tn. Xcoder

@ Mr.Xcoder Umm, Anda harus menghapus semua spasi.
Erik the Outgolfer

Tidak, saya tidak boleh, karena ruang memiliki nilai ASCII 32, sementara semua surat memiliki > 64, dan dengan demikian tidak mempengaruhi fungsi. Saya pikir ini berlaku untuk jawaban Anda juga.
Tn. Xcoder

1

Perl 6 , 51 byte

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

Menguji

Diperluas:

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

Perhatikan bahwa <!before …>pernyataan lebar nol



1

Japt , 18 17 16 byte

Disimpan 1 byte berkat @Shaggy

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

Uji secara online!

Berpikir ini akan menjadi sedikit lebih baik, tapi ... Seperti itulah kehidupan ...

Penjelasan

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.

Lebih pendek dari parodi 28 byte saya, setidaknya! : D Sepertinya Anda dapat menggantinya rSdengan x.
Shaggy

1

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

-10 byte terima kasih kepada TheLethalCoder

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

Hitungan byte juga mencakup:

using System.Linq;

Cobalah online!

1 byte lebih lama (saat ini) (tidak lagi) daripada posting TheLethalCoder untuk kesenangan. Pendekatan berbeda, dengan LINQ.

Ini mengambil keuntungan dari dua fitur mirip-C dalam C # - charvariabel karakter secara implisit berperilaku sama dengan integer int, dan operator boolean DAN &&tidak menjalankan operasi yang benar jika kiri mengembalikan a false. Penjelasan kode:

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

Hapus .ToArray()dengan mengembalikan sebagai IEnumerable<char>untuk menyimpan byte.
TheLethalCoder

@TheLethalCoder benar, saya baru saja melihat komentar di bawah tantangan. Terima kasih!
Grzegorz Puławski

1

q / kdb +, 47 45 byte

Larutan:

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

Contoh:

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"

Penjelasan:

Memanfaatkan mod 32trik dari solusi yang ada bersama dengan fungsi konvergen . Iterate atas string, jika perbedaan antara elemen terakhir dari hasil (misalnya dimulai dengan Tuntuk "rubah merah cepat ...") dan karakter saat ini adalah 1 (setelah mod'd dengan 32), maka kita tambahkan ini ke hasilnya (oleh karena itu mengambil mengapa kita mengambil last x), lalu melemparkan semuanya kembali ke string.

{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

Cobalah online!

Bagaimana?

/$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

Retina , 76 byte

 

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

Cobalah online! Tautan termasuk kasus uji. Penjelasan:

 

Hapus spasi.

^.
$&$&$&¶

Rangkap tiga karakter pertama dan masukkan pemisah.

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

Konversikan karakter kedua dan ketiga menjadi huruf kecil dan tambahkan mereka. Ubah yang terakhir menjadi huruf besar. Sekarang ini adalah karakter pencarian.

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

Cobalah untuk mencocokkan salah satu karakter pencarian. Jika ditemukan, rangkap tiga pertandingan, yang memulai ulang loop untuk pencarian berikutnya. Jika tidak, hapus saja karakter pencarian dan sisa input.


0

8 , 114 byte

Kode

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

Penjelasan

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

Contoh

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



0

Pyth, 15 byte

eo,}r0NG_xQhNty

Suite uji

Tidak seperti semua jawaban lain, ini tidak menyatukan output, itu menghasilkan semua urutan input, dan kemudian memerintahkan mereka untuk meletakkan string yang diinginkan di akhir, dan output itu.


Saya pikir Anda harus memeriksa apakah huruf pertama dari output adalah huruf pertama dari input juga. Dan saya pikir urutan awal penting.
Erik the Outgolfer

@EriktheOutgolfer Maaf, apakah Anda mengatakan jawabannya salah? Saya memastikan urutan karakter pertama yang paling awal dalam input di antara semua urutan yang dalam abjad adalah yang diurutkan sampai akhir. Lihat test case dimulai dengan spasi.
isaacg

Bisakah Anda menambahkan penjelasan? Saya mungkin salah paham atau sesuatu ...
Erik the Outgolfer

0

J, solusi parsial

Saya memposting ini untuk umpan balik dan ide untuk perbaikan lebih dari apa pun. Ini bekerja, tetapi tidak menangani huruf kapital dan spasi, dan sudah lama untuk J.

Pertama kata kerja pembantu diad yang memberi tahu Anda jika args kiri dan kanan berbatasan dengan abjad:

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

Berikutnya kata kerja yang menghilangkan elemen pertama yang bukan bagian dari garis alfabet mulai dari elemen pertama:

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

Catatan kami menggunakan Adverse ::untuk mengembalikan seluruh argumen tidak berubah jika tidak ada elemen non-streak ditemukan (yaitu, jika seluruh argumen adalah beruntun alfabet yang valid).

Akhirnya, solusi diberikan dengan menerapkan fhingga konvergensi:

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

Cobalah online!


Dan ini adalah versi yang diuraikan funtuk memudahkan membaca:

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

Pertanyaan Samping : mengapa karakter kotak tidak selaras sempurna saat ditampilkan pada SO (mereka bekerja di konsol saya):

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.