Pemotong serakah

27

iBug baru-baru ini mendapatkan batang panjang yang terbuat dari bahan komposit namun bernilai. Bilah itu sangat panjang sehingga iBug tidak bisa dengan mudah menjualnya untuk kredit, jadi dia ingin memotongnya. Bilah terbuat dari bahan yang rapuh dan ajaib sehingga, jika bagiannya pecah, semua bagian batang yang terbuat dari bahan yang sama akan pecah juga, sehingga sulit untuk memotong dengan sewenang-wenang.

iBug ingin memotong bilah menjadi potongan-potongan sebanyak mungkin. Dia juga menyukai program yang sangat singkat dan golf code, jadi dia membuat analisis abstrak dari masalahnya.

Bilah ajaib iBug direpresentasikan sebagai string (atau array atau urutan karakter jika Anda suka), seperti ini:

aaabbccccccbbbaaacccccaabbbaaaaa

Setiap huruf dalam string mewakili satu bahan ajaib. Bilah selalu cocok dengan RegEx ^\w*$, jadi mungkin ada hingga 63 materi di bilah. "Bagian" adalah urutan karakter yang berurutan yang tidak dipisahkan oleh spasi.

iBug ingin Anda menulis sebuah program yang menghitung bagian maksimum yang bisa ia dapatkan, jika nol atau lebih set karakter sepenuhnya dihapus (diganti dengan spasi), dan beri tahu iBug nomor itu.


Contoh 1:

In:  aaabbccccccbbbaaacccccaabbbaaaaa
Out: 4

Deskripsi: Jika bdihapus sepenuhnya dari bilah, iBug dapat memperoleh 4 bagian. Dia juga bisa mendapatkan 4 bagian dengan melepas bdan c, seperti yang ditunjukkan di bawah ini

aaabbccccccbbbaaacccccaabbbaaaaa  # Original string
aaa  cccccc   aaacccccaa   aaaaa  # Remove 'b'
aaa           aaa     aa   aaaaa  # Remove 'b' and 'c'

Dan itulah jumlah maksimum bagian yang bisa didapatkan iBug dari bilah ini

Contoh 2:

In:     111aa___9999____aaa99111__11_a_aa999
Result: 111aa   9999    aaa99111  11 a aa999
Out:    6

Deskripsi: Dengan hanya menghapus garis bawah, iBug bisa mendapatkan 6 bagian dari bilah dan itu maksimum.

Contoh 3:

In:  __________
Out: 1

Deskripsi: Apa? Kamu ingin memotong ini? Ini hanya mungkin untuk mendapatkan 1 bagian jika Anda tidak memotongnya sama sekali.

Contoh 4:

In:  
Out: 0

Deskripsi: Tidak ada yang dipotong, jadi nol.


Ada juga beberapa aturan yang iBug ingin program patuhi:

  1. iBug tidak suka celah standar dan mereka dilarang.

  2. Selama ini bekerja, tidak perlu program yang lengkap. Fungsi yang mengambil input dari parameter dan memberikan output melalui nilai balik juga diterima.

  3. Input dan output yang fleksibel diperbolehkan. Program atau fungsi Anda dapat mengambil string, atau array karakter, atau apa pun yang Anda anggap paling mudah untuk ditangani. Anda dapat memberikan output dengan mencetak nomor atau mengembalikannya.


Sampel uji kasus (tetapi tidak terbatas pada ini)

aaabbbaaa           = 2
123456789           = 5
AaAaAaAa            = 4
aaabcccdedaaabefda  = 6
________            = 1
(empty)             = 0

Karena ini adalah , program terpendek (dalam byte) di setiap bahasa menang!


Tambahan

iBug sangat menghargai jika Anda dapat memberikan penjelasan untuk program Anda, meskipun itu tidak mempengaruhi skor Anda (masih panjang dalam byte).

iBug
sumber
2
Bagaimana 123456789hasil 5? Dan bagaimana cara aaabcccdedaaabefdamenghasilkan 6? Saya mendapatkan 2 dan 4 masing-masing untuk dua kasus uji ini.
Tn. Xcoder
@ Mr.Xcoder untuk yang pertama, hapus 2468, untuk yang kedua, hapus bd.
Martin Ender
@MartinEnder Oh sehingga setiap subsequence dapat dihapus? jika ada karakter yang dihapus sepenuhnya disarankan sebaliknya.
Tn. Xcoder
1
@ Mr.Xcoder, jika saya memahami tantangan dengan benar, Anda hapus 2,4,6,8dari yang pertama dan b,d,fdari yang kedua.
Shaggy
2
@ Mr.Xcoder artinya menghapus semua salinan kumpulan karakter apa pun. Saya pikir contoh yang berhasil menunjukkannya dengan cukup baik.
Martin Ender

Jawaban:

8

Haskell , 73 71 70 byte

x#z|z==x=' '|1<2=z
f x=maximum$length(words x):[f$(c#)<$>x|c<-x,c>' ']

Terima kasih kepada Laikoni karena telah menghemat 1 byte!

Cobalah online!

Cristian Lupascu
sumber
1
maximum$(length$words x):dapat disingkat menjadi maximum$length(words x):.
Laikoni
6

JavaScript (ES6), 109 90 byte

f=s=>Math.max((s.match(/\s+/g)||[]).length,...[...s].map(c=>c>` `&&f(s.split(c).join` `)))
<input oninput=o.textContent=/\s/.test(this.value)?``:f(this.value)><pre id=o>0

Agak lambat pada 123456789test case. Jawaban 109 byte sebelumnya tidak terbatas pada !/\s/:

f=
s=>(g=a=>Math.max(a.filter(s=>s).length,...[...a.join``].map(c=>g([].concat(...a.map(s=>s.split(c)))))))([s])
<input oninput=o.textContent=f(this.value)><pre id=o>0

Neil
sumber
@ AsoneTuhid Oh, saya tidak melihat batasan pada set karakter; kode saya berfungsi untuk semua string.
Neil
Satu-satunya karakter yang tidak harus bekerja adalah ruang bukan?
Asone Tuhid
@AsoneTuhid Port Anda hanya berfungsi untuk karakter-karakter yang dibutuhkannya saja; dokumen asli Anda tampaknya berfungsi untuk apa pun kecuali spasi.
Neil
Karakter apa yang berhasil dijawab oleh jawaban asli Anda untuk yang baru?
Asone Tuhid
4

Python 2 , 111 93 72 byte

-21 byte, terima kasih Kirill L.

f=lambda s:max([len(s.split())]+[f(s.replace(c,' '))for c in s if'/'<c])

Cobalah online!

ovs
sumber
Sepertinya pendekatan yang saat ini digunakan oleh JS dan Ruby bekerja sangat baik untuk Python juga: 73 byte
Kirill L.
@ KirillL. terima kasih untuk rekomendasinya
Ov
3

Jelly ,  13  11 byte

Terlalu banyak instruksi 2-byte
-2 berkat Zgarb (gunakan quick produk luarþ>. <)

eþŒPŒr¬S€ṀḢ

Tautan monadik yang menerima daftar karakter dan mengembalikan bilangan bulat non-negatif.

Cobalah online!

Bagaimana?

Untuk setiap urutan input (set yang dapat kita hapus, ditambah ekuivalen redundan) mendapatkan daftar keberadaan untuk mengidentifikasi yang dihapus kemudian secara efektif menemukan berapa banyak sisa nol yang tersisa dan menghasilkan maksimum. Bagian terakhir bekerja dengan cara yang agak aneh karena saya menemukan golfier daripada alternatif yang lebih naif - ia menemukan berjalan sebagai [element, count]pasangan, meniadakan untuk mengidentifikasi nol sebagai yang, jumlah menemukan maksimum kemudian mengambil kepala (jumlah elemen daripada hitungan) ).

eþŒPŒr¬S€ṀḢ - Link: list of characters        e.g. "aabcde"
  ŒP        - power-set - gets all subsequences    ["","a","a","b",...,"bd",...,"aabcde"]
 þ          - outer-product with:
e           -   exists in?                         [[0,0,0,0,0,0],[1,1,0,0,0,0],[1,1,0,0,0,0],[0,0,1,0,0,0],..,[0,0,1,0,1,0]...,[1,1,1,1,1,1]]
    Œr      - run-length encode                    [[[0,6]],[[1,2],[0,4]],[[1,2],[0,4]],[[0,2],[1,1],[0,3]],...,[[0,2],[1,1],[0,1],[1,1],[0,1]],...,[[1,6]]]
      ¬     - NOT                                  [[[1,0]],[[0,0],[1,0]],[[0,0],[1,0]],[[1,0],[0,0],[1,0]],...,[[1,0],[0,0],[1,0],[0,0],[1,0]],...,[[0,0]]]
        €   - for €ach:
       S    -   sum                                [[1,0],[1,0],[1,0],[2,0],...,[3,0],...,[0,0]]
         Ṁ  - maximum                              [3,0]
          Ḣ - head                                 3
Jonathan Allan
sumber
Saya pikir €Đ€bisa þ.
Zgarb
3

Ruby , 98 89 75 64 61 byte

f=->s{[s.split.size,*s.scan(/\w/).map{|c|f[s.tr c,' ']}].max}

Cobalah online!

lebih kecil dan lebih lambat dari sebelumnya!

Pada dasarnya port jawaban Javascript @ Neil

Tidak disatukan dan dijelaskan

def f(input_string)
    # splits by / +/ by default
    size0 = input_string.split.size
    # an array of all non-space characters in input_string
    characters = input_string.scan(/\w/)
    size1 = characters.map {|i|
        # all letters and digits and _ are "bigger" than /, space isn't
        if i > '/'
            # tr replaces every occurrence of i in input_string with space
            next_string = input_string.tr(i, ' ')
            f(next_string) # recursive call
        else
            0
        end
    }
    # max value between size0 and any element in size1
    return [size0, *size1].max
end

Cobalah online!

Asone Tuhid
sumber
2

Sekam , 12 11 byte

▲mȯ#€0gM€¹Ṗ

Cobalah online! Ini bekerja dengan kekerasan dan cukup lambat. Tambahkan uke ujung kanan untuk membuatnya berjalan lebih cepat, tanpa mengubah semantik.

Penjelasan

▲mȯ#€0gM€¹Ṗ  Implicit input, say S = "abddccbdcaab"
          Ṗ  Powerset of S: P = ["","a","b","ab","d","ad"...,"abddccbdcaab"]
 m           Map this function over P:
              Argument is a subsequence, say R = "acc"
       M ¹    Map over S
        €     index of first occurrence in R: [1,0,0,0,2,2,0,0,2,1,1,0]
      g       Group equal elements: [[1],[0,0,0],[2,2],[0,0],[2],[1,1],[0]]
  ȯ#          Count the number of groups
    €0        that contain 0: 3
▲            Take maximum of the results: 4
Zgarb
sumber
2

Perl 5 , (versi yang lebih lama) -p -I.,, 52 49 43 byte

Penghitungan gaya lama: +3untuk -p: 46byte (karena harus dalam suatu program, itu tidak dapat dijalankan menggunakan -e)

barsplit.pl:

#!/usr/bin/perl -pI.
$G[split]+=s%\S%do$0for s/$&/ /rg%eg;$_=$#G

Jalankan dengan string di STDIN:

echo aaabcccdedaaabefda | ./barsplit.pl; echo

Cobalah online!

The -I.pilihan yang ada untuk membuat juga ini bekerja pada perls baru-baru ini di mana secara default .tidak lebih dalam @INC. Dalam versi perl yang lebih lama opsi itu tidak diperlukan. Saya menguji bahwa pada mesin yang lebih tua yang masih memiliki perl 5.20, jadi skor didasarkan pada itu (kalau tidak saya juga harus menghitung .argumen untuk -I)

Versi cepat ( 49byte):

#!/usr/bin/perl -pI.
$G[split]+=s%.%$$_++||do$0for s/$&/ /rg%eg;$_=$#G
Ton Hospel
sumber