Будьте першим 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 не може сприймати числа як булеві або не може виконувати арифметику на булевих, то це справжнє обмеження в силі Хаскелл для гольфу, і це повинно бути відображено в кількості байтів, вимагаючи перетворень або іншої роботи -округи. Що ви думаєте про формулювання виноски?
Адам

Відповіді:


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.


19
Ви можете переглядати правду ??? Це заслуговує +1 лише тому, що hax> _>
HyperNeutrino

1
@HyperNeutrino Так, але не в Python 3. (Це добре, оскільки мова тут є Python 2.)
Брайан МакКутчон

@BrianMcCutchon Добре дякую. Це просто дивно, хоча ...
HyperNeutrino

@HyperNeutrino Напевно, варто згадати, що ти можеш зробити True, False = False, True.
Брайан Маккутчон

1
@HyperNeutrino - ні. Вбудовані як і раніше повертають "реальне" значення, ви вводите ці зміни лише "Правда". (Або модулі, в деяких випадках ...). Отже, 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.


Нарешті! Мені було цікаво.
Адама

Тепер я думаю, ви можете відповісти і в J, ні?
Адам

@ Adám Так, у J це 3 байти: </ \ Jelly, мабуть, також має аналогічне 2-байтове рішення.
Згарб

Ні, я не думаю так, тому що Джеллі зліва направо.
Адам

Ви повинні публікувати окремі мовні відповіді як окремі повідомлення.
Адам

22

Ацето , 19 17 байт, що не змагаються

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

Ця нова версія містить символів один за одним і найкраще виконувати за допомогою -Fпараметра. Це працює аналогічно, але не ідентично попередньому рішенню:

 >,
Op0
p|1u
,ip^

Стара відповідь (19 байт):

(Неконкурент, тому що мені довелося виправити дві помилки в перекладачі)

|p1u
iOp<
|!`X
rd!r

Це перша відповідь Ацето, яка підкреслює, що це може зробити порівняно добре. "Списки" - це вхідні потоки з одним входом на рядок, "1" для істинного та "0" для помилкових, з порожнім рядком, що означає кінець списку.

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

Програми Aceto запускаються на кривій Гільберта, починаючи зліва внизу і закінчуючи внизу праворуч. Спочатку ми нав'язуємо rрядок, dускладнюємо та заперечуємо ( !), перетворюючи порожні рядки в True, а все інше - у False. Тоді є умовне горизонтальне дзеркало ( |): Якщо верхній елемент на стеці є простий, дзеркально горизонтально. Це відбувається, коли рядок був порожнім. Якщо ми робимо дзеркальне відображення, ми приземляємось на той X, що вбиває перекладача.

В іншому випадку ми перетворюємо решту копій на стеку в integer і робимо ще одне умовне горизонтальне дзеркало. Цього разу, оскільки 1 є простім, а 0 - хибним, ми відображаємо, якщо бачимо (перше) справжнє значення. Якщо ми не віддзеркалюємось (тому ми побачили 0), ми показуємо pте, що є на стеку (оскільки стек порожній, нуль) і переходимо до Oригея кривої, з якої ми почали, починаючи весь процес заново.

В іншому випадку, побачивши 1, ми дзеркально і приземляємось на той u, який повертає напрямок, який рухаємо по кривій Гільберта. 1pдрукує 1, і тепер ми продовжуємо те саме, що Oми пішли б, якби бачили 0, але оскільки ми перебуваємо в "зворотному режимі", наше походження знаходиться внизу праворуч , тому ми туди стрибаємо.

Тепер ми rнав'язуємо ще один рядок і заперечуємо його. Якщо рядок був порожнім, а отже, верхній елемент стека є truthy, не` вийде з наступної команди ( ), змусивши нас вийти.X

В іншому випадку (якщо рядок не була порожньою), ми дійсно рятуючись від Xі ігнорувати його. У такому випадку ми переходимо ліворуч ( <), print 0 (тому що стек порожній) та відскакуємо назад до Oріга.


2
Вітаємо вас з першим правильним завданням, вирішеним в Асето.
Адам

2
Дивиться на схему. Правильно…
Адам

1
@ Adám Це, мабуть, не допоможе (якщо ти не знаєш Ацето) самостійно, але я подумав, що поряд із текстом може бути добре побачити, щоб можна було краще слідувати за ним.
L3viathan

15

Java8, 24 19 байт

Long::highestOneBit

Сподіваюся, що це законно; У мене склалося враження, що введення / вихід не повинен оцінювати як істинне / хибне в мові. Займає довгий вхід і дає один як вихідний, причому ті є істинними, а нулі - хибними у двійковому поданні. Наприклад, двійковий 00101 дорівнює 5 і повертає бінарний 00100, який дорівнює 4.

П'ять байтів завдяки @puhlen


4
Гарний підхід. Java є конкурентоспроможною‽
Adám

3
Ого, JAVA як змагальна відповідь‽
Zacharý

Не зовсім впевнений, що це справедливо для правил кодогольфа, але це можна було б покращити до 19 символів, використовуючи посилання на метод: Long::highestOneBitякий дає однаковий результат із коротшим синтаксисом
puhlen

@puhlen вирази, що оцінюють анонімні функції, дозволені.
Кіос

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! \ o /

Як це працює

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 (тобто істинний), аж до першого елемента truthy. Нарешті, логічний AND з оригінальним списком дасть нам 1 лише для першого елемента.


8

JavaScript (ES6), 33 26 байт

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

I / O знаходиться в масивах 0s і 1s.


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Ідея може мати потенціал , хоча.
Magic Octopus Urn




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. Сингл &робить елементне порівняння.


@rturnbull, на жаль, формат введення повинен бути таким же, як і вихідний.
MickyT



3

Пітон, 58 байт

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

Якщо x[i]помилково, вихід неправильний; в іншому випадку він дає чи не елемент є першим виникненням у самому масиві.



3

Perl 5, 20 байт

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

Truthy є 1і falsey є ''(порожня струна).

Пояснення:

mapпетлі над елементами його списку @_, аргументи передаються підпрограмі, встановлюючи кожен елемент на $ _ локально і повертаючи масив повернених значень, які він обчислює з кожного елемента. $_&&!$x++виводить, $_якщо $_є фальси, і !$x++якщо він є правдою. (Зверніть увагу, що && - це коротке замикання, тому !$x++не виконується, поки не буде досягнуто першого значення truthy). $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[]>. Нічого розумного насправді, просто пряме рішення.


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

c (з 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

Вводиться як аргументи командного рядка. Для eample: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

Мозок-Флак , 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

Спробуйте в Інтернеті!

Особлива подяка

Особлива вдячність пшеничному майстру та Райлі за те, що вони допомогли мені тонну з кодом!


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


Ви можете зберегти один байт, зробивши 0 for 0for.
Zacharý

Це працює для 1if та 1else, правда? Дякую!
OldBunny2800

2

Мозок-Флак , 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)
([])
{
 {}({}<>)<>([])
}<>{}

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.