Falsificar breves verdades


28

Encontre a execução mais longa de true em uma lista de booleanos. Retorne a mesma lista, com todas as outras verdades falsificadas.

Entrada, saída

Uma lista; qualquer formato usual (por exemplo, uma lista delimitada como uma string).

Detalhes

Verdadeiro e falso podem ser qualquer coisa que seu idioma normalmente use para esses valores ou os números inteiros 1 e 0. Se você usar caracteres únicos, a lista poderá ser uma concatenação (por exemplo, 10001).

Se houver um empate na corrida mais longa, mantenha todas as corridas vinculadas verdadeiras e falsifique todas as corridas mais curtas.

Exemplos

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

(diretamente de https://stackoverflow.com/q/37447114 )

Respostas:


19

Gelatina , 8 bytes

ṣ0¬¬M¦j0

Try it online! or verify all test cases.

Como funciona

ṣ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
Eita ... essa linguagem ...
AdmBorkBork

11

Haskell, 59 , 58 , 55 , 64 bytes

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

Nota divertida, isso funciona em qualquer lista de valores em que falsy < truthy. Assim False/True, 0/1, 'f'/'t', etc.

Nota:

Como várias pessoas apontaram (incluindo @proud haskellere @nimi), a versão anterior falhou em uma lista de todos os valores falsos. A adição de .([1<2]:)corrigiu isso, conforme sugerido por @proud haskeller. Estou deixando a explicação da mesma forma por enquanto, porque acho que ainda faz sentido. Se alguém comentar, pedindo uma explicação sobre a edição, eu editarei.

Explicação:

Primeiro vou desugar sem o groupe depois adicioná-lo novamente. Primeiro, acho que as palavras costumam ser mais fáceis para os olhos do que os símbolos, então farei algumas substituições. (Observe que =<<é 'elegante', portanto se aplica de maneira diferente a listas e funções. Estou chamando binda versão de =<<for functions.)

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)

Os últimos detalhes são que x <$ listsubstitui todos os elementos de listcom xe os group listdividem listem partes de elementos iguais. Então group [1, 1, 2, 3, 3, 3] == [[1, 1], [2], [3, 3, 3]].

Para resumir tudo, a função divide a lista de valores em grupos somente de verdade e grupos somente de falso. Em seguida, para cada grupo, substitua cada elemento pelo resultado da declaração this is the biggest group(o maior grupo de true's será o maior) e concatene os grupos.

Quatro bytes salvos por @Zgarb


1
Eu acho que você pode substituir (\y->(maximum g==y)<$y)por ((<$)=<<(==maximum g)). Eu não testei embora.
Zgarb 28/05

@ Zgarb Acabei de descobrir isso a partir da declaração da instância e funciona. Obrigado.
Michael Klein

3
Ainda melhor: substitua toda a definição de fpela função sem ponto ((=<<)=<<(=<<)(<$).(==).maximum).group. Salva três bytes e é totalmente ilegível!
Zgarb

@Zgarb: Legal! Nesse ponto, b=(=<<);b b(b(<$).(==).maximum).groupé um byte mais curto ainda. Eu nunca vi nada como isso antes em Haskell golfe :)
Lynn

1
Se não me engano, você pode corrigi-lo, inserindo (:[t])antes do máximo ou algo semelhante
haskeller orgulhoso

6

Retina, 47 43 36.

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

Experimente online! ou tente todos os casos de teste

Graças ao msh210 por jogar 4 bytes!

Também muito obrigado a Martin por 7 bytes!

Explicação:

0
!

Substitua todos os 0s por !s. Isso é feito para tornar os grupos correspondentes de 1s mais curtos, como agora 1!e !1terá um limite de palavras ( \b) entre eles, que também corresponde ao início ou ao final da string.

T`p`0`

Esta é uma opção de configuração que diz que, após aplicar o regex após o backtick à entrada, em cada correspondência, traduza todos os caracteres ascii imprimíveis em um 0caractere.

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

Essa regex corresponde a grupos de 1s que são cercados por zeros, mas não podem corresponder a um 1seguido por si mesmo em qualquer lugar da sequência. Estes são os grupos não máximos que serão falsificados. Além disso, isso também corresponde aos !caracteres que adicionamos para convertê-los novamente em 0s.


5

MATL, 14 bytes

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

Experimente Online!

Versão modificada com todos os casos de teste

Explicação

        % 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 bytes

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

Teste em Ideone .

Como funciona

s.split('0')divide a sequência de entrada s em execuções de zero ou mais 1 's

Para cada execução t , verificamos se t+'1'é uma substring de s .

  • Se for, a execução não é máxima, t+'1'in sretorne True , 1-(t+'1'in s)retorne 1 - True = 0 e a execução será substituída por uma execução de 0 do mesmo comprimento.

  • Caso contrário, a execução é máxima, t+'1'in sretorne False , 1-(t+'1'in s)retorne 1 - False = 1 e a execução será substituída por uma execução de 1 do mesmo comprimento, ou seja, por si só.

Finalmente, '0'.joinrestaura todas as removidos 0 's.


3

J, 25 bytes

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

Este é um verbo monádico que recebe e retorna uma matriz 0-1. Use-o assim:

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

Explicação

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

Bom uso de corte ;..
milhas

3

Pitão, 26 24 23 21 bytes

M,G&HGJrgMrQ8 9qReSJJ

Suíte de teste.

  • Usa 1/0ou true/falsena entrada.
  • Usa true/falsena saída.

Explicação

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 bytes anteriores

M,G&HGJrgMrQ8 9msqdeSJJ

Suíte de teste.

  • Usa 1/0ou true/falsena entrada.
  • Usa 1/0na saída.

24 bytes anteriores

Jrm,hd&edhdrQ8 9msqdeSJJ

Suíte de teste.

  • Usa 1/0ou true/falsena entrada.
  • Usa 1/0na saída.

26 bytes anteriores

rm?nhdeS.u&YhNQ0,hd0drQ8 9

Suíte de teste.

  • Usa 1/0ou true/falsena entrada.
  • Usa 1/0na saída.

Criar uma função que é chamada apenas em um único local é quase sempre um erro. Você pode, por exemplo, substituí-lo por: Jr.b,N&YNrQ8)9qReSJJou Jrm,hd*FdrQ8 9qReSJJ. Ambas as versões economizam um byte. Ou fique ainda mais louco JrXR1*FdrQ8 9qReSJJe economize dois. ;-)
Jakube

2

Oracle SQL 12.1, 137 135 bytes

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

Sem golfe

-- 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,"')||'"'))
       );

A entrada usa caracteres únicos. Ex: '1100111'


2

Mathematica , 46 41

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

Trabalhos em listas de 0e 1. Eu pensei que tinha me saído muito bem até que eu olhei para as outras respostas!


Explicação para a versão de 46 caracteres; Vou atualizar quando não puder melhorá-lo ainda mais.

Uma explicação desse código foi solicitada.
Um equivalente sem código de golfe (usando os formulários de operador da versão 10) é:

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

Isso significa uma função composta de cinco etapas (subfunções) aplicadas em ordem de cima para baixo.

  • Split: divida em execuções de elementos idênticos: {1,1,0,1,1,0,1} ↦ {{1,1}, {0}, {1,1}, {0,0}}

  • Map[# Tr@# &]: Para cada sub-lista ( Map) multiplique ( #) pela sua soma (rastreamento de vetor,Tr ): {1,1} ↦ {2, 2}

  • # - Max[1, #] &subtraia de cada elemento o valor máximo que aparece em qualquer lugar da lista de listas, ou um, o que for maior. (Esse lida com o caso de todos os zeros.)

  • UnitStep: igual a 0 para x <0 e 1 para x> = 0, aplicado a todos os elementos.

  • Apply[Join]: junte as sub-listas em uma única lista. Também pode ser feito com Flattenou Catenate, mas em forma abreviada Join@@é mais conciso.


2

C, 135 129 bytes

Experimente on-line

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 bytes

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

Funciona verificando todas as execuções de 1s e substituindo os caracteres por 0s, a menos que a execução seja (igualmente) mais longa, conforme medido pesquisando na sequência por uma execução mais longa de 1s.

Solução recursiva anterior de 72 bytes:

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

Não faz nada se não houver execuções de 1s (ou seja, 1s no máximo). Caso contrário, subtrai um 1de cada um 1ou executa-os, depois se chama recursivamente nas execuções mais curtas e depois adiciona-as 1novamente nas execuções (agora igualmente mais longas). O número de chamadas recursivas é um menor que o comprimento da execução mais longa.


"Em todas as execuções de 1s, substitua cada 1 por 0 se existir uma execução de 1s mais do que a execução atual; caso contrário, substitua por 0." Brilhante!
Patrick Roberts

1

Julia, 51 bytes

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

Experimente online!

Como funciona

replaceencontra todas as todas as corridas de um ou mais 1 's na entrada de string s via regex r"1+"e chama o lambda t->map(c->c-contains(s,"1"t),t)para determinar a seqüência de substituição.

O lambda mapeia c->c-contains(s,"1"t)todos os caracteres na sequência dos t .

  • Se "1"t(concatenação) é uma substring de s , a corrida não é maximal, containsretorna verdadeiro e c-contains(s,"1"t)retorna '1' - verdadeiros = '0' , substituindo todas 1 é nesse prazo com 0 's.

  • Se "1"t(concatenação) não for uma substring de s , a execução será máxima, containsretornará false e c-contains(s,"1"t)retornará '1' - false = '1' , deixando a execução sem modificação.


1

APL, 22 caracteres

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

Em inglês (da direita para a esquerda em blocos):

  • precede 0 à entrada
  • caixa começando com cada 0
  • multiplique cada caixa pela sua soma
  • aplainar
  • 1 se o número for igual ao máximo, 0 caso contrário

1

Java 8, 205 bytes

Esta é uma expressão lambda para um 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;}

entrada / saída é um Stringonde true é representado por 1 e false é representado por 0. Não há caracteres delimitadores que separam os valores.

código com explicação:

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

veja ideona para os casos de teste


1

Clojure, 137 bytes

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

Primeiro, particiona a entrada em zeros e uns consecutivos e os mapeia em "tuplas" do primeiro elemento das partições e na contagem de elementos. Em seguida, repete o número necessário de zeros ou uns, dependendo se essa é a sequência de comprimento máximo de um ou não.

Menos golfe:

(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 bytes

67, mais 1 para em -pevez de-e

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

Espera e imprime uma sequência (concatenação) de 0s e 1s.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.