Memalsukan kebenaran singkat

28

Temukan run terpanjang dari true dalam daftar boolean. Kembalikan daftar yang sama, dengan semua trues lainnya dipalsukan.

Input output

Sebuah daftar; format biasa (mis., daftar terbatas sebagai string).

Detail

Benar dan salah dapat berupa apa saja yang bahasa Anda biasanya gunakan untuk nilai-nilai itu, atau bilangan bulat 1 dan 0. Jika Anda menggunakan karakter tunggal, daftar dapat berupa gabungan (misalnya, 10001).

Jika ada dasi untuk jangka waktu terpanjang, jaga agar semua ikatan berjalan benar, dan palsukan semua lari lebih pendek.

Contohnya

input ↦ output
1,0,1,0,1 ↦ 1,0,1,0,1
1,1,0,1,1,0,1 ↦ 1,1,0,1,1,0,0
1,1,0,1,1,1,0,1,1 ↦ 0,0,0,1,1,1,0,0,0
1,1,1 ↦ 1,1,1
0,0,1 ↦ 0,0,1
0,0 ↦ 0,0
1,1,1,0,0,0,1,1,1,1,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0 ↦ 0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0

(langsung dari https://stackoverflow.com/q/37447114 )

msh210
sumber

Jawaban:

19

Jelly , 8 byte

ṣ0¬¬M¦j0

Cobalah online! atau verifikasi semua kasus uji .

Bagaimana itu bekerja

ṣ0¬¬M¦j0  Main link. Argument: A (list of Booleans)

ṣ0        Split at zeroes. This leaves a 2D list of ones.
  ¬       Negate each 1, replacing it with 0.
     ¦    Conditional application:
    M       Yield all maximal indices.
            In lexicographical list comparison, a shorter list of zeroes is less
            than a longer one, so this identifies the longest runs.
   ¬        Negate the items in those lists, changing zeroes back to ones.
      j0  Join, separating by single zeroes.
Dennis
sumber
23
Astaga ... bahasa ini ...
AdmBorkBork
11

Haskell, 59 , 58 , 55 , 64 byte

import Data.List
((=<<)=<<(=<<)(<$).(==).maximum.([1<2]:)).group

Catatan menyenangkan, ini berfungsi pada daftar nilai mana pun di mana falsy < truthy. Jadi False/True, 0/1, 'f'/'t', dll

catatan:

Seperti yang ditunjukkan oleh beberapa orang (termasuk @proud haskellerdan @nimi), versi sebelumnya gagal pada daftar semua nilai falsy. Penambahan .([1<2]:)telah memperbaiki ini, seperti yang disarankan oleh @proud haskeller. Saya meninggalkan penjelasan yang sama untuk saat ini, karena saya pikir itu masih masuk akal. Jika ada yang berkomentar, meminta penjelasan tentang hasil edit, saya akan mengedit.

Penjelasan:

Saya akan desugar pertama tanpa group, dan kemudian menambahkannya kembali. Pertama, saya menemukan bahwa kata-kata seringkali lebih mudah di mata daripada simbol, jadi saya akan membuat beberapa pergantian. (Perhatikan bahwa =<<'berkelas' sehingga berlaku berbeda untuk daftar dan fungsi. Saya memanggil bindversi =<<untuk fungsi.)

bind :: (a -> b -> c) -> (b -> a) -> b -> c
bind k f = k =<< f
bind k f = \ r -> k (f r) r

f = ((=<<)=<<(=<<)(<$).(==).maximum)
f = ((bind) concatMap (bind)(<$).equals.maximum)
f = (bind concatMap (bind (<$) . equals . maximum))
f = bind concatMap ((bind (<$)) . equals . maximum))
f = bind concatMap ((\f r -> (<$) (f r) r) . equals . maximum))
f = bind concatMap ((\f r -> (f r) <$ r) . equals . maximum)
f = bind concatMap ((\g r -> (g r) <$ r) . equals . maximum)
f = (\h r -> concatMap (h r) r) ((\g r -> (g r) <$ r) . equals . maximum)
f = \r -> concatMap (((\g r -> (g r) <$ r) . equals . maximum) r) r
f = \r -> concatMap (((\g r -> (g r) <$ r) . equals) (maximum r)) r
f = \r -> concatMap (((\g s -> (g s) <$ s)) (equals (maximum r))) r
f = \r -> concatMap (((\s -> ((equals (maximum r)) s) <$ s))) r
f = \r -> concatMap (\s -> (s == (maximum r)) <$ s) r

f . group = ((=<<)=<<(=<<)(<$).(==).maximum).group
f . group = \r -> concatMap (\s -> (s == (maximum (group r))) <$ s) (group r)

Rincian terakhir adalah yang x <$ listmengganti setiap elemen listdengan xdan group listmembagi bagian list-bagiannya menjadi potongan-potongan elemen yang sama. Jadi group [1, 1, 2, 3, 3, 3] == [[1, 1], [2], [3, 3, 3]].

Singkatnya, fungsi membagi daftar nilai menjadi kelompok hanya benar dan kelompok hanya salah. Kemudian untuk setiap grup, ganti setiap elemen dengan hasil pernyataan this is the biggest group(grup terbesar trueakan menjadi yang terbesar) dan gabungkan grup.

Empat byte disimpan oleh @Zgarb

Michael Klein
sumber
1
Saya pikir Anda bisa menggantinya (\y->(maximum g==y)<$y)dengan ((<$)=<<(==maximum g)). Saya belum mengujinya.
Zgarb
@ Zgarb Saya baru saja menyelesaikannya dari deklarasi instance dan berfungsi. Terima kasih.
Michael Klein
3
Bahkan lebih baik: ganti seluruh definisi fdengan fungsi point-free ((=<<)=<<(=<<)(<$).(==).maximum).group. Menghemat tiga byte dan benar-benar tidak dapat dibaca!
Zgarb
@Zgarb: Keren! Pada saat itu, b=(=<<);b b(b(<$).(==).maximum).groupmasih satu byte lebih pendek. Saya belum pernah melihat yang seperti ini sebelumnya di Haskell golf :)
Lynn
1
Jika saya tidak salah, Anda dapat memperbaikinya dengan memasukkan (:[t])sebelum maksimum atau sesuatu yang serupa
bangga haskeller
6

Retina, 47 43 36

0
!
T`p`0`\b(1+)\b(?<=(?=.*1\1).*)|!

Cobalah online! atau coba semua test case

Berkat msh210 untuk bermain golf 4 byte!

Juga terima kasih sebesar-besarnya kepada Martin untuk 7 byte!

Penjelasan:

0
!

Ganti semua 0dengan !s. Hal ini dilakukan untuk membuat grup yang cocok 1lebih pendek, seperti sekarang 1!dan !1akan memiliki batas kata ( \b) di antara mereka, yang juga cocok dengan awal atau akhir string.

T`p`0`

Ini adalah opsi konfigurasi yang mengatakan bahwa setelah menerapkan regex setelah backtick ke input, dalam setiap pertandingan, terjemahkan setiap karakter ascii yang dapat dicetak menjadi sebuah 0karakter.

\b(1+)\b(?<=(?=.*1\1).*)|!

Regex ini cocok dengan grup dari 1 s yang dikelilingi oleh nol, tetapi tidak dapat mencocokkan 1diikuti oleh dirinya sendiri di mana saja di string. Ini adalah kelompok non-maksimal yang akan dipalsukan. Selain itu, ini juga cocok dengan !karakter yang kami tambahkan untuk mengubahnya kembali menjadi 0.

FryAmTheEggman
sumber
5

MATL, 14 byte

Y'yy*X>y=b*wY"

Cobalah secara Online!

Versi modifikasi dengan semua kasus uji

Penjelasan

        % Implicitly grab the input as an array
Y'      % Perform run-length encoding of the input. Yields an array of values and an array
        % of run-lengths
yy      % Copy these outputs
*       % Multiply the values (booleans) by the run-lengths. This will zero-out all
        % zero-valued runs so we don't consider them when computing the longest run.
X>      % Compute the longest run of 1's
y       % Copy the run lengths vector
=       % Determine which runs are the same length as the longest run of ones
b*      % Bubble-up the values from the run-length encoding and multiply element-wise
        % With this boolean. This substitutes all 1's that are not in the longest run
        % of ones with 0's
w       % Flip the run-lengths and values on the stack
Y"      % Perform run-length decoding using these substituted values
        % Implicitly display the resulting boolean
Suever
sumber
4

Python 2, 62 byte

lambda s:'0'.join(`1-(t+'1'in s)`*len(t)for t in s.split('0'))

Cobalah Ideone .

Bagaimana itu bekerja

s.split('0')memisahkan string input s menjadi nol atau lebih 1 's

Untuk setiap t yang dijalankan , kami memeriksa apakah t+'1'substring dari s .

  • Jika ya, prosesnya tidak maksimal, t+'1'in skembalikan True , 1-(t+'1'in s)kembalikan 1 - True = 0 dan jalankan diganti dengan proses 0 dengan panjang yang sama.

  • Jika tidak, jalankan maksimal, t+'1'in skembalikan False , 1-(t+'1'in s)kembalikan 1 - False = 1 dan jalankan digantikan dengan proses 1 dengan panjang yang sama, yaitu dengan sendirinya.

Akhirnya, '0'.joinpulihkan semua 0 yang dihapus .

Dennis
sumber
3

J, 25 byte

[:(}.=>./)@;0<@(*#);.1@,]

Ini adalah kata kerja monadik yang mengambil dan mengembalikan array 0-1. Gunakan seperti ini:

   f =: [:(}.=>./)@;0<@(*#);.1@,]
   f 1 1 0 1 1 1 0 1 1
0 0 0 1 1 1 0 0 0

Penjelasan

[:(}.=>./)@;0<@(*#);.1@,]  Input is y.
            0          ,]  Prepend 0 to y, and
                   ;.1@    cut the result along occurrences of 0,
                           so that each piece begins with a 0.
               (*#)        Multiply each piece element-wise by its length,
             <@            and put it in a box.
                           Without the boxing, the pieces would go in a 0-padded array.
           ;               Join the pieces back together.
                           Now all runs of 1 have been replaced by runs of (1+length of run).
[:(      )@                Apply verb in parentheses:
   }.                        remove the prepended 0,
     =                       form the 0-1 array of equality with
      >./                    the maximum value.
Zgarb
sumber
Penggunaan potongan yang bagus ;..
mil
3

Pyth, 26 24 23 21 byte

M,G&HGJrgMrQ8 9qReSJJ

Suite uji.

  • Penggunaan 1/0atau true/falseinput.
  • Penggunaan true/falsedalam output.

Penjelasan

M,G&HGJrgMrQ8 9qReSJJ

           Q      input
          r 8     run-length encode
        gM        convert each run of 1 to their length
                  for example: [1,1,1,0,1,1] will be
                  converted to [3,3,3,0,2,2]
                  in the run-length encoded version
                  [1,1,1,0,1,1] will be [[3,1],[1,0],[2,1]]
                  [3,3,3,0,2,2] will be [[3,3],[1,0],[2,2]]
                  therefore basically [G,H] becomes [G,H and G]
                  which is what the code below does:
M,G&HG            def g(G,H): return [G,H and G]
       r      9   run-length decode
      J           store to J

               qReSJJ

                R   J   in each element of J
               q eSJ    check if equal to maximum of J

23 byte sebelumnya

M,G&HGJrgMrQ8 9msqdeSJJ

Suite uji.

  • Penggunaan 1/0atau true/falseinput.
  • Penggunaan 1/0dalam output.

24 byte sebelumnya

Jrm,hd&edhdrQ8 9msqdeSJJ

Suite uji.

  • Penggunaan 1/0atau true/falseinput.
  • Penggunaan 1/0dalam output.

26 byte sebelumnya

rm?nhdeS.u&YhNQ0,hd0drQ8 9

Suite uji.

  • Penggunaan 1/0atau true/falseinput.
  • Penggunaan 1/0dalam output.
Biarawati Bocor
sumber
Membuat fungsi yang hanya dipanggil di satu lokasi hampir selalu merupakan kesalahan. Misalnya Anda bisa menggantinya dengan: Jr.b,N&YNrQ8)9qReSJJatau Jrm,hd*FdrQ8 9qReSJJ. Kedua versi menghemat satu byte. Atau menjadi lebih gila dengan JrXR1*FdrQ8 9qReSJJdan menyimpan dua. ;-)
Jakube
2

Oracle SQL 12.1, 137 135 byte

SELECT REPLACE(REPLACE(REPLACE(:1,m,2),1,0),2,m)FROM(SELECT MAX(TRIM(COLUMN_VALUE))m FROM XMLTABLE(('"'||REPLACE(:1,0,'",0,"')||'"')));

Tidak bermain golf

-- Replace the max value with 2
-- Then replace every 1 with 0
-- Then replace 2 with the max value
SELECT REPLACE(REPLACE(REPLACE(:1,m,2),1,0),2,m)
FROM   ( -- Split on 0 and keep the max value
         SELECT MAX(TRIM(COLUMN_VALUE))m 
         FROM XMLTABLE(('"'||REPLACE(:1,'0','",0,"')||'"'))
       );

Input menggunakan karakter tunggal. Mis: '1100111'

Jeto
sumber
2

Mathematica , 46 41

1-Join@@Sign[1~Max~#-#]&[#*Tr/@#]&@*Split

Bekerja pada daftar 0dan 1. Saya pikir saya telah melakukan cukup baik sampai saya melihat jawaban yang lain!


Penjelasan untuk versi 46 karakter; Saya akan memperbarui ketika saya tidak bisa memperbaikinya lebih lanjut.

Penjelasan tentang kode ini diminta.
Setara non-kode-golf (menggunakan formulir operator versi 10) adalah:

RightComposition[
  Split,
  Map[# Tr@# &],
  # - Max[1, #] &,
  UnitStep,
  Apply[Join]
]

Ini berarti suatu fungsi yang terdiri dari lima langkah (sub-fungsi) yang diterapkan secara berurutan dari atas ke bawah.

  • Split: pecah menjadi elemen-elemen identik yang identik: {1,1,0,1,1,0,1} ↦ {{1,1}, {0}, {1,1}, {0,0}}

  • Map[# Tr@# &]: Untuk setiap sub-daftar ( Map) kalikan ( #) dengan jumlahnya (jejak vektor, Tr): {1,1} ↦ {2, 2}

  • # - Max[1, #] &kurangi dari setiap elemen nilai maksimum yang muncul di mana saja dalam daftar daftar, atau satu, yang mana yang lebih tinggi. (Yang menangani kasus semua nol.)

  • UnitStep: sama dengan 0 untuk x <0 dan 1 untuk x> = 0, diterapkan ke setiap elemen.

  • Apply[Join]: gabungkan sub-daftar menjadi satu daftar. Bisa juga dilakukan dengan Flattenatau Catenate, tetapi dalam bentuk Join@@singkat lebih singkat.

Tuan Wisaya
sumber
2

C, 135 129 byte

Coba Online

m,c,i,d,j;f(int*l,int s){while(i<s)c=l[i++]?c+1:0,m=c>m?c:m;while(j<s)if(l[j++])d=d+1;else if(d<m)while(d)l[j-1-d--]=0;else d=0;}

Tidak disatukan

m,c,i;
f(int*l,int s)
{
    // obtain max
    while(i<s)
        c = l[i++] ? c+1 : 0,
        m = c>m ? c : m;

    c=0,i=0;

    // remove smaller segments
    while(i<s)
        if(l[i++]) c=c+1;
        else if(c<m) while(c) l[(i-1)-c--]=0;
        else c=0;
}
Khaled.K
sumber
1

JavaScript (ES6), 56 byte

s=>s.replace(/1+/g,t=>t.replace(/1/g,+!~s.indexOf(t+1)))

Bekerja dengan memeriksa semua run 1s dan mengganti karakter dengan 0s kecuali jika run (sama) terpanjang, yang diukur dengan mencari string untuk run yang lebih lama dari 1s.

Solusi rekursif 72 byte sebelumnya:

f=s=>/11/.test(s)?f(s.replace(/1(1*)/g,"0$1")).replace(/0(1+)/g,"1$1"):s

Tidak melakukan apa-apa jika tidak ada run 1s (yaitu paling banyak single 1s). Jika tidak, kurangi satu 1dari masing 1- masing atau jalankan, kemudian panggilan itu sendiri secara rekursif pada berjalan yang lebih pendek, kemudian tambahkan satu 1kembali pada berjalan (sekarang sama-sama terpanjang). Jumlah panggilan rekursif adalah kurang dari satu jangka waktu terpanjang.

Neil
sumber
"Dalam semua proses 1s, ganti masing-masing 1 dengan 0 jika ada proses 1s yang lebih lama dari saat ini, ganti dengan 0." Cemerlang!
Patrick Roberts
1

Julia, 51 byte

s->replace(s,r"1+",t->map(c->c-contains(s,"1"t),t))

Cobalah online!

Bagaimana itu bekerja

replacemenemukan semua semua berjalan dari satu atau lebih 1 's di input string s melalui regex r"1+"dan memanggil lambda t->map(c->c-contains(s,"1"t),t)untuk menentukan string pengganti.

Lambda memetakan c->c-contains(s,"1"t)semua karakter dalam t yang dijalankan .

  • Jika "1"t(gabungan) adalah substring dari s , proses tidak maksimal, containsmengembalikan true dan c-contains(s,"1"t)mengembalikan '1' - true = '0' , mengganti semua 1 dalam jalankan itu dengan 0 's.

  • Jika "1"t(gabungan) bukan substring dari s , prosesnya adalah maksimal, containsmengembalikan false dan c-contains(s,"1"t)mengembalikan '1' - false = '1' , meninggalkan proses yang tidak dimodifikasi.

Dennis
sumber
1

APL, 22 karakter

(⊣=⌈/)∊(⊣×+/¨)(~⊂⊣)0,⎕

Dalam bahasa Inggris (dari kanan ke kiri dalam blok):

  • tambahkan 0 ke input
  • kotak dimulai dengan masing-masing 0
  • kalikan setiap kotak dengan jumlahnya
  • meratakan
  • 1 jika angka sama dengan maks, 0 sebaliknya
lstefano
sumber
1

Java 8, 205 byte

Ini adalah ungkapan lambda untuk Function<String,String>:

s->{int x=s.length();for(String t="1",f="0";s.indexOf(t+1)>=0;t+=1){s=s.replaceAll(0+t+0,0+f+0);if(s.indexOf(t+0)==0)s=s.replaceFirst(t,f);if(s.lastIndexOf(0+t)==--x-1)s=s.substring(0,x)+f;f+=0;}return s;}

input / output adalah a String mana true diwakili oleh 1 dan false diwakili oleh 0. Tidak ada karakter pembatas yang memisahkan nilai.

kode dengan penjelasan:

inputString -> {
  int x = inputString.length();
  //starting with the truth combination "1",
  //loop until the input string does not contain the combination appended with another "1"
  //with each consecutive loop appending a "1" to the combination
  for( String truthCombo = "1", falseCombo = "0"; inputString.indexOf( truthCombo + 1 ) >= 0; truthCombo += 1 ) {
    //all instances in the input string 
    //where the combination has a "0" on either side of it
    //are replaced by "0"'s
    inputString = inputString.replaceAll( 0 + truthCombo + 0, 0 + falseCombo + 0 );
    //if the combination followed by a "0"
    //is found at the beginning of the input string
    //replace it with "0"'s
    if( inputString.indexOf( truthCombo + 0 ) == 0 )
      inputString = inputString.replaceFirst( truthCombo , falseCombo );
    //if the combination preceeded by a "0"
    //is found at the end of the input string
    //replace it with "0"'s
    if( inputString.lastIndexOf( 0 + truthCombo ) == --x - 1 )
      inputString = inputString.substring( 0, x ) + falseCombo;
    falseCombo += 0;
  }
  return inputString;
}

lihat ideone untuk test case

Jack Ammo
sumber
1

Clojure, 137 byte

#(let[v(map(juxt first count)(partition-by #{1}%))](mapcat(fn[t](repeat(t 1)(if(=[1(apply max(map(fn[[f c]](if(= 1 f)c 0))v))]t)1 0)))v))

Pertama, partisi input menjadi nol berturut-turut dan yang satu dan memetakan ini menjadi "tuple" elemen pertama partisi dan jumlah elemen. Itu kemudian mengulangi jumlah nol yang diperlukan atau yang, tergantung apakah ini adalah urutan maksimum panjang atau tidak.

Kurang bermain golf:

(def f #(let [v(map(juxt first count)(partition-by #{1}%))
              m(apply max(map(fn[[f c]](if(= 1 f)c 0))v))]
           (mapcat (fn[[f c]](repeat c(if(=[1 m][f c])1 0))) v)))
NikoNyrh
sumber
0

Perl 5, 68 byte

67, ditambah 1 untuk -pebukan-e

y/0/ /;$_<${[sort@a]}[-1]&&y/1/0/for@a=split/\b/;$_=join"",@a;y; ;0

Mengharapkan dan mencetak string (gabungan) dari 0s dan 1s.

msh210
sumber