Falsificare brevi verità


28

Trova la versione più lunga di true in un elenco di valori booleani. Restituisce la stessa lista, con tutte le altre verità falsificate.

Input Output

Una lista; qualsiasi formato normale (ad esempio, un elenco delimitato come stringa).

Dettagli

Vero e falso possono essere qualsiasi cosa la tua lingua usi tipicamente per quei valori, o gli interi 1 e 0. Se usi caratteri singoli, l'elenco può essere una concatenazione (ad es 10001.).

Se esiste un pareggio per la corsa più lunga, mantenere vere tutte le corse di legatura e falsificare tutte le corse più brevi.

Esempi

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

(direttamente da /programming//q/37447114 )

Risposte:


19

Gelatina , 8 byte

ṣ0¬¬M¦j0

Provalo online! o verifica tutti i casi di test .

Come funziona

ṣ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.

23
Accidenti ... questa lingua ...
AdmBorkBork,

11

Haskell, 59 , 58 , 55 , 64 byte

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

Nota divertente, funziona su qualsiasi elenco di valori dove falsy < truthy. Così False/True, 0/1, 'f'/'t', etc.

Nota:

Come diverse persone hanno sottolineato (incluso @proud haskellere @nimi), la versione precedente non è riuscita su un elenco di tutti i valori falsi. L'aggiunta di .([1<2]:)ha risolto questo problema, come suggerito da @proud haskeller. Lascio la spiegazione la stessa per ora, perché penso che abbia ancora senso. Se qualcuno commenta, chiedendo una spiegazione della modifica, la modifica.

Spiegazione:

Desugar prima senza il group, e poi lo aggiungo di nuovo. In primo luogo, trovo che le parole siano spesso più facili per gli occhi rispetto ai simboli, quindi farò alcune sostituzioni. (Si noti che =<<è "di classe", quindi si applica in modo diverso per elenchi e funzioni. Sto chiamando bindla versione di =<<per funzioni.)

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)

Gli ultimi dettagli sono che x <$ listsostituiscono tutti gli elementi listcon xe li group listdividono listin blocchi di elementi uguali. Così group [1, 1, 2, 3, 3, 3] == [[1, 1], [2], [3, 3, 3]].

Per riassumere tutto, la funzione divide l'elenco di valori in gruppi di solo true e gruppi di solo false. Quindi, per ogni gruppo, sostituisci ogni elemento con il risultato dell'istruzione this is the biggest group(il gruppo più grande truesarà il più grande) e concatena i gruppi.

Quattro byte salvati da @Zgarb


1
Penso che puoi sostituirlo (\y->(maximum g==y)<$y)con ((<$)=<<(==maximum g)). Non l'ho provato però.
Zgarb,

@Zgarb L'ho appena elaborato dalla dichiarazione dell'istanza e funziona. Grazie.
Michael Klein,

3
Ancora meglio: sostituisci l'intera definizione di fcon la funzione senza punti ((=<<)=<<(=<<)(<$).(==).maximum).group. Salva tre byte ed è assolutamente illeggibile!
Zgarb,

@Zgarb: Cool! A quel punto, b=(=<<);b b(b(<$).(==).maximum).groupè ancora più breve di un byte. Non ho mai visto nulla di simile prima nel golf di Haskell :)
Lynn,

1
Se non sbaglio, puoi risolverlo inserendo (:[t])prima del massimo o qualcosa di simile
orgoglioso haskeller

6

Retina, 47 43 36

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

Provalo online! oppure prova tutti i casi di test

Grazie a msh210 per giocare a golf a 4 byte!

Anche grazie a Martin per 7 byte!

Spiegazione:

0
!

Sostituisci tutte le 0s con !s. Questo viene fatto per 1abbreviare i gruppi di s più brevi, come ora 1!e !1avrà un limite di parole ( \b) tra loro, che corrisponde anche all'inizio o alla fine della stringa.

T`p`0`

Questa è un'opzione di configurazione che dice che dopo aver applicato la regex dopo il backtick all'input, in ogni corrispondenza tradurre ogni carattere ASCII stampabile in un 0carattere.

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

Questa regex corrisponde a gruppi di 1s che sono circondati da zero, ma non può corrispondere a 1seguito da solo in qualsiasi punto della stringa. Questi sono i gruppi non massimi che saranno falsificati. Inoltre, questo corrisponde anche ai !caratteri che abbiamo aggiunto per riconvertirli in 0s.


5

MATL, 14 byte

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

Provalo online!

Versione modificata con tutti i casi di test

Spiegazione

        % 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

4

Python 2, 62 byte

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

Provalo su Ideone .

Come funziona

s.split('0')divide la stringa di input s in sequenze di zero o più 1 's

Per ogni corsa t , controlliamo se t+'1'è una sottostringa di s .

  • In tal caso, la corsa non è massima, t+'1'in srestituisce True , 1-(t+'1'in s)restituisce 1 - True = 0 e la corsa viene sostituita con una corsa di 0 della stessa lunghezza.

  • In caso contrario, la corsa è massima, t+'1'in srestituisce False , 1-(t+'1'in s)restituisce 1 - False = 1 e la corsa viene sostituita con una corsa di 1 's della stessa lunghezza, ovvero da sola.

Infine, '0'.joinripristina tutti gli 0 rimossi .


3

J, 25 byte

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

Questo è un verbo monadico che accetta e restituisce un array 0-1. Usalo in questo modo:

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

Spiegazione

[:(}.=>./)@;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.

Bell'uso del taglio ;..
miglia

3

Pyth, 26 24 23 21 byte

M,G&HGJrgMrQ8 9qReSJJ

Suite di test.

  • Utilizza 1/0o true/falsein input.
  • Utilizza true/falsein uscita.

Spiegazione

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 precedenti

M,G&HGJrgMrQ8 9msqdeSJJ

Suite di test.

  • Utilizza 1/0o true/falsein input.
  • Utilizza 1/0in uscita.

24 byte precedenti

Jrm,hd&edhdrQ8 9msqdeSJJ

Suite di test.

  • Utilizza 1/0o true/falsein input.
  • Utilizza 1/0in uscita.

26 byte precedenti

rm?nhdeS.u&YhNQ0,hd0drQ8 9

Suite di test.

  • Utilizza 1/0o true/falsein input.
  • Utilizza 1/0in uscita.

La creazione di una funzione chiamata solo in una singola posizione è quasi sempre un errore. Ad esempio, è possibile sostituirlo con: Jr.b,N&YNrQ8)9qReSJJo Jrm,hd*FdrQ8 9qReSJJ. Entrambe le versioni salvano un byte. O diventa ancora più folle JrXR1*FdrQ8 9qReSJJe ne salva due. ;-)
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,"')||'"')));

Un-golfed

-- 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 utilizza caratteri singoli. Es .: "1100111"


2

Mathematica , 46 41

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

Funziona su elenchi di 0e 1. Pensavo di aver fatto abbastanza bene fino a quando non ho guardato le altre risposte!


Spiegazione per la versione di 46 caratteri; Aggiornerò quando non posso migliorarlo ulteriormente.

È stata richiesta una spiegazione di questo codice.
Un equivalente senza codice golf (utilizzando i moduli operatore versione 10) è:

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

Ciò significa una funzione composta da cinque passaggi (sotto-funzioni) applicati in ordine dall'alto verso il basso.

  • Split: suddiviso in serie di elementi identici: {1,1,0,1,1,0,1} ↦ {{1,1}, {0}, {1,1}, {0,0}}

  • Map[# Tr@# &]: Per ogni sotto-elenco ( Map) moltiplicalo ( #) per la sua somma (traccia vettoriale, Tr): {1,1} ↦ {2, 2}

  • # - Max[1, #] &sottrarre da ogni elemento il valore massimo che appare ovunque nell'elenco di elenchi, o uno, a seconda di quale sia maggiore. (Quello gestisce il caso di tutti gli zeri.)

  • UnitStep: uguale a 0 per x <0 e 1 per x> = 0, applicato a ogni elemento.

  • Apply[Join]: unisce gli elenchi secondari in un unico elenco. Potrebbe anche essere fatto con Flatteno Catenate, ma in forma abbreviata Join@@è più conciso.


2

C, 135 129 byte

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

Ungolfed

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

1

JavaScript (ES6), 56 byte

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

Funziona controllando tutte le corse di 1 e sostituendo i caratteri con 0 a meno che la corsa sia (ugualmente) più lunga, misurata cercando la stringa per una corsa più lunga di 1.

Precedente soluzione ricorsiva a 72 byte:

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

Non fa nulla se non ci sono esecuzioni di 1 (cioè al massimo 1). Altrimenti, ne sottrae uno 1da ciascuno 1o una sua corsa, quindi si chiama ricorsivamente sulle corse più brevi, quindi ne aggiunge una 1indietro sulle corse (ora ugualmente più lunghe). Il numero di chiamate ricorsive è uno in meno della lunghezza della corsa più lunga.


"In tutte le esecuzioni di 1s, sostituisci ogni 1 con 0 se esiste una esecuzioni di 1s una più lunga di quella corrente, altrimenti sostituisci con 0." Brillante!
Patrick Roberts,

1

Julia, 51 byte

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

Provalo online!

Come funziona

replacetrova tutti tutte le analisi di uno o più 1 's nell'input stringa s tramite la regex r"1+"e invita il lambda t->map(c->c-contains(s,"1"t),t)per determinare la stringa di sostituzione.

La lambda esegue c->c-contains(s,"1"t)la mappatura di tutti i personaggi nel corso di quelli t .

  • Se "1"t(concatenazione) è una sottostringa di s , la corsa non è massima, containsrestituisce true e c-contains(s,"1"t)restituisce '1' - true = '0' , sostituendo tutti gli 1 in quella corsa con 0 '.

  • Se "1"t(concatenazione) non è una sottostringa di s , la corsa è massima, containsrestituisce false e c-contains(s,"1"t)restituisce '1' - false = '1' , lasciando la corsa non modificata.


1

APL, 22 caratteri

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

In inglese (da destra a sinistra in blocchi):

  • anteporre 0 all'ingresso
  • casella che inizia con ogni 0
  • moltiplica ogni casella per la sua somma
  • appiattire
  • 1 se il numero è uguale al massimo, 0 altrimenti

1

Java 8, 205 byte

Questa è un'espressione lambda per un 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 è un Stringdove true è rappresentato da 1 e false è rappresentato da 0. Non ci sono caratteri delimitatori che separano i valori.

codice con spiegazione:

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

vedi ideone per i casi di test


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

Prime partizioni l'input in zeri e quelli consecutivi e li mappa in "tuple" del primo elemento delle partizioni e il conteggio degli elementi. Quindi ripete il numero necessario di zeri o di uno, a seconda che si tratti della sequenza di lunghezza massima di uno o meno.

Meno 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)))

0

Perl 5, 68 byte

67, più 1 per -peinvece di-e

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

Si aspetta e stampa una stringa (concatenazione) di 0s e 1s.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.