Будь первым 1 (оставь только первую правду)

47

вступление

Ежегодно ООО «Дьялог» проводит студенческий конкурс. Задача состоит в том, чтобы написать хороший код APL. Это не зависящий от языка издание восьмой проблемы этого года.

У меня есть явное разрешение опубликовать этот вызов здесь от первоначального автора конкурса. Не стесняйтесь проверить, перейдя по предоставленной ссылке и связавшись с автором.

проблема

Учитывая булевский список *, "выключите" все Истины после первой Истины.

Нет правды? Нет проблем! Просто верните список без изменений.

Примеры

[falsy,truthy,falsy,truthy,falsy,falsy,truthy][falsy,truthy,falsy,falsy,falsy,falsy,falsy]

[][]

[falsy,falsy,falsy,falsy][falsy,falsy,falsy,falsy]


* Все ваши правды должны быть идентичны, и все ваши ложные сообщения должны быть идентичны. Это включает в себя вывод.

Адам
источник
2
Можем ли мы использовать списки битов или другие представления списков правдивых / ложных, которые более естественны для нашего языка?
Мартин Эндер
1
Ну да, если вы говорите о «правдивости» и «ложных» в вызове вместо «булевых», «истинных» и «ложных». ;)
Мартин Эндер
1
Я не ясно, на булевы. Можем ли мы использовать 0/1, даже если наш язык имеет True / False?
xnor
1
@xnor Ах, хорошо. Я думаю, что было бы справедливо разрешить выбор входных данных, но выходные данные должны совпадать, не так ли?
Адам
1
@xnor Я слышу вас, но если Haskell не может рассматривать числа как булевы, или не может выполнять арифметику с булевыми значениями, то это является реальным ограничением способности Haskell играть в гольф, и это должно отражаться в количестве байтов, требуя преобразований или другой работы. -arounds. Что вы думаете о формулировке сноски?
Адам

Ответы:

36

Python 2 , 35 байт

while 1:b=input();print b;True&=b<1

Попробуйте онлайн! Вход и выход - это линии True / False.

По решению Дениса . Переопределяет переменную, Trueкоторая будет Falseпосле Trueввода. Таким образом, любые последующие материалы Trueбудут оцениваться Falseи печататься как таковые.

Переопределение True&=b<1, то есть True = True & (b<1). Когда входной сигнал bявляется True, то (b<1)это значение False (с True==1), так что Trueстановится False.

XNOR
источник
19
Вы можете переопределить True ??? Это заслуживает +1 только потому, что hax> _>
HyperNeutrino
1
@HyperNeutrino Да, но не в Python 3. (Это нормально, потому что здесь используется язык Python 2.)
Брайан МакКатчон,
@BrianMcCutchon Хорошо, спасибо. Это просто странно, хотя ...
HyperNeutrino
@HyperNeutrino Вероятно, стоит упомянуть, что вы можете сделать True, False = False, True.
Брайан МакКатчон
1
@HyperNeutrino - нет. Встроенные функции по-прежнему возвращают «реальное» значение, просто «True», который вы вводите, изменяется. (Или модули, в некоторых случаях ...). Поэтому bool (1) возвращает True, но bool (1) == True возвращает False.
TLW
30

APL , 2 байта

<\

Оценивает функцию "сканирование с использованием менее чем". Попробуйте онлайн!

объяснение

В APL оператор \(сканирование) уменьшает каждый непустой префикс массива справа, используя предоставленную функцию. Например, для данного массива 0 1 0он вычисляет 0(префикс длины 1), 0<1(префикс длины 2) и 0<(1<0)(префикс длины 2) и помещает результаты в новый массив; круглые скобки связаны справа. Снижение <справа 1показывает, когда последний элемент массива равен 1остальному 0, а остальные равны , поэтому префикс, соответствующий крайнему левому краю 1, уменьшается до 1остальных 0.

Zgarb
источник
В заключение! Мне было интересно.
Адам
Теперь, я полагаю, вы тоже можете ответить на J, нет?
Адам
@ Adám Да, в J это 3 байта: </ \ Jelly, вероятно, также имеет аналогичное 2-байтовое решение.
Згарб
Нет, я так не думаю, потому что Джелли слева направо.
Адам
Вы должны размещать отдельные языковые ответы как отдельные сообщения.
Адам
22

Aceto , 19 17 байт не конкурирует

Новая версия (17 байт):

Эта новая версия принимает символы по одному и лучше всего выполняется с -Fопцией. Он работает аналогично, но не идентично предыдущему решению:

 >,
Op0
p|1u
,ip^

Старый ответ (19 байт):

(Не конкурирует, потому что мне пришлось исправить две ошибки в интерпретаторе)

|p1u
iOp<
|!`X
rd!r

Это первый ответ Aceto, который подчеркивает, на что он способен относительно хорошо, я бы сказал. «Списки» - это входные потоки, с одним вводом на строку, «1» для истины и «0» для «ложь», с пустой строкой, обозначающей конец списка.

иллюстрация потока кода

Программы Aceto работают по кривой Гильберта, начиная слева внизу и заканчивая справа внизу. Во-первых, мы читаем rстроку, dуточняем и отрицаем ее ( !), превращая пустые строки в True, а все остальное в False. Затем есть условное горизонтальное зеркало ( |): если верхний элемент в стеке верен, зеркально отразите по горизонтали. Это происходит, когда строка была пустой. Если мы делаем зеркалирование, мы приземляемся на того X, который убивает переводчика.

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

В противном случае, когда мы увидели 1, мы отражаемся и приземляемся на u, что меняет направление, в котором мы движемся по кривой Гильберта. 1pпечатает 1, и теперь мы продолжаем то же самое, Oчто и если бы мы видели 0, но, поскольку мы находимся в «обратном режиме», наш источник находится внизу справа , поэтому мы прыгаем туда.

Теперь мы читаем rеще одну строку и отрицаем ее. Если строка была пустой, и, следовательно, верхний элемент стека является правдивым, не` произойдет следующая команда ( ), что заставит нас выйти.X

В противном случае (если строка не была пустой), мы действительно спасаясь от Xи игнорировать его. В этом случае мы идем влево ( <), print 0 (потому что стек пуст) и возвращаемся к Origin.

L3viathan
источник
2
Поздравляю вас с первой проблемой, решенной в Aceto.
Адам
2
Смотрит на диаграмму. Верно ...
Адам
1
@ Adám Это, вероятно, не поможет (если вы не знаете Aceto) само по себе, но я подумал, что было бы неплохо увидеть рядом с текстом, чтобы иметь возможность следовать ему лучше.
L3viathan
15

Java8, 24 19 байт

Long::highestOneBit

Надеюсь, это законно; У меня сложилось впечатление, что ввод / вывод не должен оцениваться как истинный / ложный в языке. Принимает long в качестве входного значения и дает один в качестве выходного, причем единицы имеют значение true, а нули - false в двоичном представлении. Например, двоичный код 00101 равен 5 и возвращает двоичный код 00100, который равен 4.

Пять байтов благодаря @puhlen

JollyJoker
источник
4
Хороший подход. Конкурентоспособность
Java‽
3
Вау, JAVA как конкурентный ответ‽
Захари
Не совсем уверен, действительно ли это для правил codegolf, но это можно улучшить до 19 символов, используя ссылку на метод: он Long::highestOneBitдает идентичный результат с более коротким синтаксисом
puhlen
Разрешены выражения @puhlen для анонимных функций.
Cyoce
2
@NathanMerrill java.langпакет импортируется по умолчанию. Из спецификации языка «Модуль компиляции автоматически имеет доступ ко всем типам, объявленным в его пакете, а также автоматически импортирует все открытые типы, объявленные в предопределенном пакете java.lang.»
JollyJoker
12

Сетчатка , 6 байт

1>`1
0

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

Ввод - это список 0s (для False) и 1s (для True).

Соответствует всем 1и заменяет все, кроме первого ( 1>), на 0.

Мартин Эндер
источник
Я вижу это сейчас. Вы работаете в офисе на какой-то ОС. Приходит менеджер и кричит на вас за то, что вы пишете целую ОС с регулярным выражением.
Кристофер
10

V , 7 байт

f1òf1r0

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

Моя первая подача V! \ О /

Как это устроено

f1òf1r0
f1       "go to the next occurence of 1
  ò      "repeat the following until end:
   f1    "    go to the next occurence of 1
     r0  "    replace with 0
Дрянная Монахиня
источник
Как это работает?
Брайан МакКатчон
@BrianMcCutchon Объяснение добавлено.
Лаки Монахиня
Это терпит неудачу для 1 в первой позиции :(
nmjcman101
@ nmjcman101 исправлено.
Лаки Монахиня
Так как вы изменили формат ввода, вы можете поменять местами r0с <C-x>декрементировать те и сохранить байт.
nmjcman101
9

Haskell , 25 байт

Анонимная функция, принимающая и возвращающая список Bools.

Используйте как (foldr(\x l->x:map(x<)l)[])[False,True,False,False].

foldr(\x l->x:map(x<)l)[]

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

Как это устроено

  • Сворачивает список справа, добавляя новые элементы и, возможно, изменяя следующие.
  • xэто элемент, который будет добавлен к подсписку l.
  • Пользы , что Falseсопостовительные меньше True, так map(x<)lбудут превратить любого Trueс в lв , Falseесли xесть True.
Орджан Йохансен
источник
9

Желе , 4 байта

+\=a

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

Вот алгоритм, довольно отличающийся от большинства других языковых решений для игры в гольф (хотя после того, как я его опубликовал, я заметил, что решение R также использует этот алгоритм), и привязка к текущему держателю записи Jelly.

объяснение

+\=a
+\    Cumulative sum of the input list
  =   Compare corresponding elements with the input
   a  Logical AND corresponding elements with the input

Пока все элементы слева от элемента равны 0, совокупная сумма до элемента будет равна самому элементу. Справа от первого 1 они различаются (потому что теперь мы добавляем ненулевое общее количество элементов слева). Таким образом, +\=дает нам список, содержащий 1 (т. Е. Истина) до и включая первый истинный элемент. Наконец, логическое И с исходным списком даст нам 1 только для первого истинного элемента.


источник
8

JavaScript (ES6), 33 26 байт

a=>a.map(e=>e&!(i-=e),i=1)

Ввод / вывод находится в массивах 0 и 1.

Нил
источник
8

05AB1E , 6 байтов

Код:

ā<s1kQ

Объяснение:

ā         # External enumeration, get a and push [1 .. len(a)]
 <        # Decrement each
  s       # Swap to get the input
   1k     # Get the first index of 1
     Q    # Check for equality with the enumeration array

Использует кодировку 05AB1E . Попробуйте онлайн!

Аднан
источник
1k>sƶ-_это еще хуже, хотя. liftИдея может иметь потенциал , хотя.
Волшебная Урна Осьминога
4

R , 24 байта

cumsum(T<-scan(,F))==T&T

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

Пример:

Для ввода FALSE TRUE TRUE FALSE
cumsum(T<-scan(,F))==Tвозвращается TRUE TRUE FALSE FALSE. F в скане обеспечивает логический ввод.
FALSE TRUE TRUE FALSEи TRUE TRUE FALSE FALSEесть FALSE TRUE FALSE FALSE. Сингл &делает поэлементное сравнение.

MickyT
источник
@rturnbull, к сожалению, формат ввода должен совпадать с форматом вывода.
MickyT
3

Python, 58 байт

lambda x:[x[i]and x.index(x[i])==i for i in range(len(x))]

Если x[i]ложь, вывод ложен; в противном случае он определяет, является ли элемент первым вхождением в сам массив.

HyperNeutrino
источник
3

PHP, 37 байт

foreach($_GET as$v)echo$v*!$$v++,' ';
user63956
источник
3

Perl 5, 20 байт

sub{map$_&&!$x++,@_}

Истина 1и ложь'' (пустая строка).

Объяснение:

mapперебирает элементы списка it @_, аргументы передаются в подпрограмму, устанавливает для каждого элемента значение $ _ локально и возвращает массив возвращаемых значений, которые он вычисляет из каждого элемента. $_&&!$x++выводит, $_если $_это фальсификация и !$x++если это правда. (Обратите внимание, что && имеет короткое замыкание, поэтому !$x++не выполняется, пока не будет достигнуто первое истинное значение). $x++Возвращает 0(что неверно) при первом запуске, а затем увеличивается каждый раз (и поэтому остается правдивым). В !отменяет $x++, и поэтому она возвращает truthy первый раз , когда он встречается и falsey после этого.

Крис
источник
Ваши сомнения были оправданы: вам необходимо предоставить полную функцию (или полную программу); и это только фрагмент (поэтому недействительный без sub{...}).
Дада
2

Pyth - 9 байт

.e&b!s<Qk

Попробуй здесь

.e&b!s<Qk
.e          # Python's 'enumerate' (i.e., for each index k and each element b at that index)
      <Qk   # The first k elements of the input
     s      # 'Sum' these first k elements (with booleans, this is a logical 'or')
  &b!       # The value of the output at index k is [value of input @ index k]&&[the negation of the 'sum']
Мария
источник
1
Это , как представляется, более эффективно использовать переменную и только карту над ним нормально: m&!~|Z.
FryAmTheEggman
2

C #, 77 байт

a=>{var b=1<0;for(int i=0;i<a.Length;){a[i]=b?1<0:a[i];b|=a[i++];}return a;};

Компилирует в Func<bool[], bool[]>. Ничего умного на самом деле, просто прямое решение.

TheLethalCoder
источник
2

sed , 16 19 байтов

15 Исходный код 18 байтов + 1 байт для флага -r (или -E для BSD sed).

:
s/1(0*)1/1\10/
t

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

Редактировать: Спасибо Райли за указание на ошибку.

Максим Михайлов
источник
@Riley Спасибо за указание на это! Похоже, у TIO есть версия sed, которая отличается от моей (BSD). Я не могу оставить этикетки пустыми. Приятно это знать.
Максим Михайлов
Да жаль. TIO использует GNU sed. Это исправленная ошибка.
Райли
2

Желе , 4 байта

TḊṬ^

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

Как?

Это делает то, что было задано в буквальном смысле:

TḊṬ^ - Main link: list a   e.g. [0,1,0,1,0,0,1]  or  [0,1,0,1,0,1,0]
T    - get the truthy indexes   [  2,  4,    7]      [  2,  4,  6  ]
 Ḋ   - dequeue                  [      4,    7]      [      4,  6  ]
  T  - make a boolean array     [0,0,0,1,0,0,1]      [0,0,0,1,0,1  ]
   ^ - XOR that with a          [0,1,0,0,0,0,0]      [0,1,0,0,0,0,0]
Джонатан Аллан
источник
2

с (со встроенными gcc), 40

Немного другой подход:

f(n){return!n?0:1<<31-__builtin_clz(n);}

Это может быть признано недействительным - в этом случае я с радостью отмечу это как не конкурирующее.

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

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

Цифровая травма
источник
2

Пакетная, 85 73 байта

:a
@(if %1.==. exit)&set/ar=(1-f)*%1
@echo %r%&set/af^|=%1&shift&goto a

Принимает ввод в качестве аргументов командной строки. Для примера:1.bat 0 1 0 1 0 0 1

Предыдущая версия

@set f=1
:a
@(if %1.==. exit)&set/ar=f*%1
@echo %r%&(if %1==1 set f=)&shift&goto a
Андрей Одегов
источник
2

Brain-Flak , 230 байт

([]){{}({}[()]<>)<>([])}{}<>([]){{}({}<>)<>([])}{}<>({<({}<>)<>>()}<(())>){({}[()]<<>({}<>)>)}{}(([])<{{}(({})())({<{}>{}((<()>))}<{}{}>)({}<>)<>([])}<>>){({}[()]<({}<>)<>>)}{}<>([]){{}({}<>)<>([])}{}<>{}{}([]){{}({}<>)<>([])}{}<>

Я скоро объясню, но моя мама приготовила мне немного жареной картошки

([]){{}({}[()]<>)<>([])}{}<>([]){{}({}<>)<>([])}{}<> Subtracts one from every item

({<({}<>)<>>()}<(())>){({}[()]<<>({}<>)>)}{} Loops down stack until current item is zero and adds one

(([])<{{} (({})())({<{}>{}((<()>))}<{}{}>) ({}<>)<>([])}<>>){({}[()]<({}<>)<>>)}{}<> On every item of stack if it is 0 do nothing and if it is -1 add one

([]){{}({}<>)<>([])}{}<> Flip stack

{}{} Remove the two zeros at top of stack

([]){{}({}<>)<>([])}{}<> Flip stack back

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

Особая благодарность

Отдельное спасибо Wheat Wizard и Riley за помощь в написании кода!

Кристофер
источник
2

Python 3, 69 66 64 60 54 53 байта

lambda i:[k==i.index(j)and j for k,j in enumerate(i)]

Принимает массив falses и trues. Это список из falses, за исключением случаев, когда значение текущей итерации равно trueпервому trueво входных данных.

Это кажется немного длинным (и это моя первая лямбда), так что, если вы найдете способ поиграть в гольф, это будет с благодарностью!

OldBunny2800
источник
Вы можете объяснить?
Адам
Ой, ой, неправильно истолковал вопрос.
OldBunny2800
Undeleted и исправил ответ
OldBunny2800
Вы можете сохранить один байт, сделав 0 for 0for.
Захари
Это работает для 1if и 1else, верно? Спасибо!
OldBunny2800
2

Brain-Flak , 146 144 байта

([]){{}({}<>)(())<>([])}{}<>((())){{}({}<>)<>}{}<>(()){{}((){[()](<{}>)}{})(<>)<>}<>(())<>([]){{}(<{}<>>)<>([])}{}<>{}{}([]){{}({}<>)<>([])}<>{}

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

# Reverse the stack and add a 1 between each to help with reversing later
([]){{}({}<>)(())<>([])}{}<>

# Add a 1 in case there aren't any truthy values (and another 1 like before)
((()))

# Reverse the stack back to it's original order using the 1s from earlier to know when to stop
{{}({}<>)<>}{}<>

# Push 1 to start the loop
(())

# Until we find the first 1
{

 # Pop the last value
 {}

 # Logical not
 ((){[()](<{}>)}{})

  # Put a 0 on the other stack
  (<>)<>

# end loop
}

# Put a 1 on the other stack
<>(())<>

# Push the stack height
([])

# While there are values on this stack
{

 # Move them to the other stack as a 0
 {}(<{}<>>)<>([])

# End while
}{}

# Pop an extra 0
{}

# Switch stacks
<>

# Copy everything back (to reverse it back to it's original)
([])
{
 {}({}<>)<>([])
}<>{}
Райли
источник