Фальсифицируйте краткие истины


28

Найдите самое длинное значение true в списке логических значений. Возвратите тот же список со всеми другими фальсификациями.

Ввод, вывод

Список; любой обычный формат (например, список с разделителями в виде строки).

Детали

Истина и ложь могут быть любым, что ваш язык обычно использует для этих значений, или целыми числами 1 и 0. Если вы используете одиночные символы, список может быть конкатенацией (например, 10001).

Если есть связь для самого длинного пробега, сохраняйте все пробежки связывания истинными и фальсифицируйте все короткие пробежки

Примеры

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

(прямо с /programming//q/37447114 )

Ответы:


19

Желе , 8 байт

ṣ0¬¬M¦j0

Попробуйте онлайн! или проверьте все контрольные примеры .

Как это работает

ṣ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
Боже ... этот язык ...
AdmBorkBork

11

Haskell, 59 , 58 , 55 , 64 байта

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

Забавное примечание, это работает для любого списка значений, где falsy < truthy. Так False/True, 0/1, 'f'/'t'и т.д.

Заметка:

Как указали несколько человек (включая @proud haskellerи @nimi), предыдущая версия не удалась в списке всех ложных значений. Добавление .([1<2]:)исправило это, как предложено @proud haskeller. Сейчас я оставляю объяснение таким же, потому что я думаю, что оно все еще имеет смысл. Если кто-то прокомментирует, попросив объяснения правки, я отредактирую.

Объяснение:

Я сначала desugar без group, а затем добавлю его обратно. Во-первых, я нахожу, что слова часто проще для глаз, чем символы, поэтому я сделаю несколько замен. (Обратите внимание, что =<<это «классный», поэтому он применяется по-разному для списков и функций. Я вызываю bindверсию =<<для функций.)

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)

Последние детали - это то, что x <$ listзаменяет каждый элемент listс xи group listразбивает listего на куски равных элементов. Так group [1, 1, 2, 3, 3, 3] == [[1, 1], [2], [3, 3, 3]].

Подводя итог, функция разбивает список значений на группы только true и группы только false. Затем для каждой группы замените каждый элемент результатом оператора this is the biggest group(самая большая группа trueбудет самой большой) и объедините группы.

Четыре байта сохранены @Zgarb


1
Я думаю, что вы можете заменить (\y->(maximum g==y)<$y)на ((<$)=<<(==maximum g)). Я не проверял это все же.
Згарб

@Zgarb Я только что решил это из объявления экземпляра, и это работает. Спасибо.
Майкл Кляйн

3
Еще лучше: заменить все определение fна функцию без точек ((=<<)=<<(=<<)(<$).(==).maximum).group. Сохраняет три байта и совершенно нечитаем!
Згарб

@Zgarb: Круто! В этот момент он b=(=<<);b b(b(<$).(==).maximum).groupеще на один байт короче. Я никогда не видел ничего подобного в гольфе на Haskell :)
Линн

1
Если я не ошибаюсь, вы можете исправить это, вставив (:[t])перед максимумом или что-то подобное
гордый haskeller

6

Сетчатка, 47 43 36

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

Попробуйте онлайн! или попробуйте все контрольные примеры

Спасибо msh210 за игру в гольф 4 байта!

Также большое спасибо Мартину за 7 байтов!

Объяснение:

0
!

Заменить все 0s на !s. Это сделано для того, чтобы сделать соответствующие группы 1s короче, как сейчас, 1!и между ними !1будет иметь слово border ( \b), которое также соответствует либо началу, либо концу строки.

T`p`0`

Это параметр конфигурации, который говорит о том, что после применения регулярного выражения после обратного кавычки ко входу в каждом совпадении переводить каждый печатный символ ascii в 0символ.

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

Это регулярное выражение соответствует группам 1s, которые окружены нулями, но не могут соответствовать ни одному из них, 1за которым следует строка в строке. Это немаксимальные группы, которые будут сфальсифицированы. Кроме того, это также соответствует !символам, которые мы добавили, чтобы преобразовать их обратно в 0s.


5

MATL, 14 байтов

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

Попробуйте онлайн!

Модифицированная версия со всеми тестами

объяснение

        % 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 байта

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

Проверьте это на Ideone .

Как это работает

s.split('0')разбивает входной строки S в пробегов нуля или более 1

Для каждого прогона t мы проверяем, t+'1'является ли подстрока s .

  • Если это так, цикл не максимален, t+'1'in sверните True , 1-(t+'1'in s)верните 1 - True = 0, и цикл будет заменен серией 0 той же длины.

  • Если это не так, прогон максимальный, t+'1'in sверните False , 1-(t+'1'in s)верните 1 - False = 1, и прогон будет заменен на прогон 1 с той же длины, т.е. сам по себе.

Наконец, '0'.joinвосстанавливает все удаленные 0 .


3

J, 25 байт

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

Это монадический глагол, который принимает и возвращает массив 0-1. Используйте это так:

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

объяснение

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

Хорошее использование вырезать ;..
мили

3

Pyth, 26 24 23 21 байт

M,G&HGJrgMrQ8 9qReSJJ

Тестирование.

  • Использует 1/0или true/falseна входе.
  • Использует true/falseв выводе.

объяснение

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-байтовый

M,G&HGJrgMrQ8 9msqdeSJJ

Тестирование.

  • Использует 1/0или true/falseна входе.
  • Использует 1/0в выводе.

Предыдущий 24-байтовый

Jrm,hd&edhdrQ8 9msqdeSJJ

Тестирование.

  • Использует 1/0или true/falseна входе.
  • Использует 1/0в выводе.

Предыдущий 26 байт

rm?nhdeS.u&YhNQ0,hd0drQ8 9

Тестирование.

  • Использует 1/0или true/falseна входе.
  • Использует 1/0в выводе.

Создание функции, которая вызывается только в одном месте, почти всегда является ошибкой. Например, вы можете заменить его на: Jr.b,N&YNrQ8)9qReSJJили Jrm,hd*FdrQ8 9qReSJJ. Обе версии сохраняют один байт. Или пойти еще безумнее с JrXR1*FdrQ8 9qReSJJи сохранить два. ;-)
Якуб

2

Oracle SQL 12.1, 137 135 байтов

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

Для ввода используйте одиночные символы. Пример: «1100111»


2

Математика , 46 41

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

Работает по спискам 0и 1. Я думал, что у меня все получилось, пока не посмотрел другие ответы!


Пояснения к 46-символьной версии; Я буду обновлять, когда я не могу улучшить его дальше.

Было запрошено объяснение этого кода.
Эквивалент, не относящийся к коду для гольфа (с использованием форм оператора версии 10)

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

Это означает, что функция состоит из пяти шагов (подфункций), применяемых по порядку сверху вниз.

  • Split: разбить на серии одинаковых элементов: {1,1,0,1,1,0,1} ↦ {{1,1}, {0}, {1,1}, {0,0}}

  • Map[# Tr@# &]: Для каждого подсписка ( Map) умножьте его ( #) на его сумму (векторная трассировка Tr): {1,1} ↦ {2, 2}

  • # - Max[1, #] &вычтите из каждого элемента максимальное значение, отображаемое в любом месте списка списков, или единицу, в зависимости от того, какое значение больше. (Один обрабатывает случай всех нулей.)

  • UnitStep: равно 0 для x <0 и 1 для x> = 0, применяется к каждому элементу.

  • Apply[Join]: объединить подсписки в один список. Можно также сделать с Flattenили Catenate, но в краткой форме Join@@является более кратким.


2

C 135 129 байт

Попробуйте онлайн

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 байт

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

Работает, проверяя все серии 1 и заменяя символы на 0, за исключением случаев, когда последовательность (одинаково) самая длинная, что измеряется поиском строки для более длинной серии 1.

Предыдущее 72-байтовое рекурсивное решение:

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

Ничего не делает, если нет прогонов 1с (т.е. не более 1). В противном случае вычитает по одному 1из каждого 1или из каждого прогона, затем рекурсивно вызывает себя при более коротких прогонах, а затем добавляет один 1обратно в прогоны (теперь такие же самые длинные). Количество рекурсивных вызовов на один меньше длины самого длинного прогона.


«Во всех прогонах 1 с заменяйте каждый 1 на 0, если существует прогон 1 с, который длиннее текущего прогона, в противном случае замените на 0». Brilliant!
Патрик Робертс

1

Юлия, 51 байт

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

Попробуйте онлайн!

Как это работает

replaceнаходит все все пробеги один или более 1 «S в строку ввода с помощью регулярного выражения r"1+"и называет лямбда , t->map(c->c-contains(s,"1"t),t)чтобы определить строку замены.

Лямбда отображает c->c-contains(s,"1"t)все символы подряд t .

  • Если "1"t(сцепление) является подстрокой s , прогон не максимален, containsвозвращает true и c-contains(s,"1"t)возвращает '1' - true = '0' , заменяя все 1 в этом прогоне на 0 .

  • Если "1"t(сцепление) не является подстрокой s , цикл является максимальным, containsвозвращает false и c-contains(s,"1"t)возвращает «1» - false = «1» , оставляя цикл без изменений.


1

APL, 22 символа

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

На английском языке (справа налево блоками):

  • добавить 0 к входу
  • поле, начинающееся с каждого 0
  • умножьте каждую коробку на ее сумму
  • расплющить
  • 1, если число равно максимальному, 0 в противном случае

1

Java 8, 205 байт

Это лямбда-выражение для 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;}

вход / выход - это Stringгде истина представлена ​​1, а ложь - 0. Нет разделительных символов, разделяющих значения.

код с объяснением:

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

см. ideone для тестовых случаев


1

Clojure, 137 байт

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

Первые делят входные данные на последовательные нули и единицы и отображают их в «кортежи» первого элемента разбиений и количества элементов. Затем он повторяет необходимое количество нулей или единиц, в зависимости от того, является ли это максимальной последовательностью единиц или нет.

Менее гольф:

(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 байт

67, плюс 1 -peвместо-e

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

Ожидает и печатает строку (конкатенацию) 0 и 1.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.