Математика это факт. Программирование не


175

В математике восклицательный знак !часто означает факториал, и он идет после аргумента.

В программировании восклицательный знак !часто означает отрицание, и он стоит перед аргументом.

Для этой задачи мы применим только эти операции к нулю и единице.

Factorial
0! = 1
1! = 1

Negation
!0 = 1
!1 = 0

Возьмите строку с нулем или более !, с последующим 0или или 1, после которого следует ноль или более !( /!*[01]!*/).
Например, ввод может быть !!!0!!!!или !!!1или !0!!или 0!или или 1.

« !До» 0или « 1отрицания» и !«после» являются факториалами.

Факториал имеет более высокий приоритет, чем отрицание, поэтому факториалы всегда применяются первыми.
Например, !!!0!!!!действительно означает !!!(0!!!!), или еще лучше !(!(!((((0!)!)!)!))).

Выведите результирующее применение всех факториалов и отрицаний. Выход всегда будет 0или 1.

Тестовые случаи

0 -> 0
1 -> 1
0! -> 1
1! -> 1
!0 -> 1
!1 -> 0
!0! -> 0
!1! -> 0
0!! -> 1
1!! -> 1
!!0 -> 0
!!1 -> 1
!0!! -> 0
!!!1 -> 0
!!!0!!!! -> 0
!!!1!!!! -> 0

Самый короткий код в байтах побеждает.


18
Но 0! = 1 !, так какой смысл обращаться с несколькими факториалами?
boboquack

30
@boboquack Потому что это проблема.
Увлечения Кэлвина

11
? <= '1'; ... исправить 75% времени в php.
Проснулся

10
Я могу ошибаться, но я не могу найти число с факториалами после того, как оно просто будет удалено и заменено на 1? Нравится 0 !!!! = 1 !! = 0 !!!!!!!! = 1 !!! = 1! = 0! = 1 и т. Д.
Альберт Реншоу

2
@AlbertRenshaw Это правильно.
Увлечения Кэлвина

Ответы:


43

Mathematica, 25 17 байт

Input[]/.!x_:>1-x

Принимает ввод из пользовательской подсказки. Предполагается, что среда Mathematica предназначена для неявной печати. Чтобы сделать его сценарием командной строки, оберните его Print[...]или сделайте его функцией без аргументов (которая затем принимает входные данные из приглашения), добавьте &.

Mathematica имеет оба обязательных оператора (с требуемым приоритетом), поэтому мы можем просто «оценить» ввод (который выполняется автоматически Input[]), но оператор логического отрицания не работает с целыми числами (поэтому он останется без оценки). Если в результате !xосталось значение, мы заменим его на 1-x.

Пара забавных фактов об оценке:

  1. Mathematica на самом деле также имеет двойной факториальный оператор !!, который вычисляет n*(n-2)*(n-4)*..., но применяется 0или 1все еще дает 1, так что не имеет значения, что 0!!!!!будет фактически проанализировано как ((0!!)!!)!.
  2. Несмотря на то, что Mathematica уходит !0и не !1оценивается, он знает, что !является самообращенным, поэтому он автоматически отменит все пары ведущих !. После того , как ToExpressionмы всегда остается одним из 0, 1, !0, !1.

3
С каких пор по умолчанию разрешен фрагмент REPL?
LegionMammal978

2
@ LegionMammal978 Видимо с декабря 2015 года, но я постоянно забываю об этом. Чтобы быть справедливым, это не «фрагмент» в том смысле, что он не предполагает, что входные данные уже хранятся где-то в памяти. И если предположить, что среда ноутбука не сильно отличается от языка с неявным выводом.
Мартин Эндер

Просто любопытно, может ли быть предоставлена ​​мета-ссылка? (Попытка найти информацию там вызывает стресс, но это еще одна проблема формата SE Q & A ...)
LegionMammal978

@ LegionMammal978 это уже в ответе.
Мартин Эндер

Чистое решение ksh x=${x/[01]!*/1};echo $(($x))- не разрешено
оставлять

28

[Bash] + утилиты Unix, 21 17 байт

sed s/.!!*$/1/|bc

Это должно быть сохранено в файле и запущено как программа. Если вы попытаетесь ввести команду непосредственно из командной строки, она не будет работать, потому что !! расширен за счет включения подстановки истории в интерактивном режиме bash. (В качестве альтернативы вы можете отключить подстановку истории с помощью set +H.)

Тестовый пример запускается:

for x in 0 1 '0!' '1!' '!0' '!1' '!0!' '!1!' '0!!' '1!!' '!!0' '!!1' '!0!!' '!!!1' '!!!0!!!!' '!!!1!!!!'; do ./excl <<<"$x"; done

0
1
1
1
1
0
0
0
1
1
0
1
0
0
0
0

Старая версия работает, а эта нет
Коровы

Я использовал ссылку Тио
Коровы шарлатан

@KritixiLithos Это работало нормально, когда я попробовал это на моем компьютере с Linux. Проблема, очевидно, заключалась в том, что TIO требует новой строки в конце моделируемой строки ввода. Это запутанная ситуация, поэтому я взял ссылку TIO. Если вы хотите попробовать его там, вот ссылка снова (но обязательно добавьте новую строку
Митчелл Спектор

2
Но что, если кто-то сбежал mkdir -p 's/.!!'{bunch,of,different,directories}\$/1? Тогда вы получите Pathname Expansion, и Sed будет пытаться читать каталоги, как если бы они были файлами, вместо чтения стандартного ввода, и он ничего не выведет! :)
Wildcard

1
@ Wildcard Я полностью согласен. В производственных сценариях я всегда использую кавычки в подобных ситуациях. (В этом случае я бы на самом деле поместил двойные кавычки вокруг аргумента sed, а не просто экранировал *. Это легче читать, чем использовать обратную косую черту, и это исключает возможность пропуска какого-либо специального символа.)
Mitchell Spector

22

Сетчатка , 20 15 14 байт

Спасибо Лео за сохранение 1 байта.

0!
1
!!

^1|!0

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

объяснение

0!
1

Превратись 0!в 1. Нам не нужны никакие другие трейлинг- !ы, итоговое число такое же, как если бы мы применили все факториалы.

!!

Отмена пар отрицаний. Это также может отменить некоторые факториалы, но это не имеет значения.

^1|!0

Посчитайте количество совпадений этого регулярного выражения, которое либо 1или, 0и дает желаемый результат.


Альтернативное решение для той же ByteCount: \d.+...
Коровы шарлатан

@KritixiLithos Нашел способ вообще избежать этого.
Мартин Эндер

Вы можете удалить ^до!0
Лев

17

Грязь , 14 12 9 байт

e`\0!~\!_

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

объяснение

Это сопоставляет ввод с шаблоном, печать 1на совпадение и 0на отсутствие совпадения.

e`\0!~\!_
e`         Match entire input against this pattern:
    !      not
  \0       a sole 0
     ~     xor
      \!   exclamation mark
        _  followed by this pattern matched recursively.

Идея заключается в следующем. Если ввод начинается с цифры, то рекурсивная часть \!_всегда дает сбой и \0!завершается успешно, если у нас нет единственного числа 0. Их xor успешен, если вход не является единственным 0. Если ввод начинается с a !, то \0!всегда успешно и \!_успешно, если рекурсивное совпадение успешно. Их xor преуспевает именно тогда, когда рекурсивное совпадение не удается, тем самым сводя его на нет.


16

Brainfuck, 85 72 (84) байта

,[>-[-----<->]<++[>++++[-<++++>]+<[[+],[[-]>-<]]]>[<<+[-->]>[<],>-]<]<+.

вернуть численно или

,[>-[-----<->]<++[>++++[-<++++>]+<[[+],[[-]>-<]]]>[<<+[-->]>[<],>-]<]-[-----<+>]<--.

для текста ASCII. > также может иметь префикс, чтобы избежать переноса памяти.

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


Loops over the input.
On 1, ends.
On "!", toggles bool a stored as 0 or 255.
On "0", toggles if there is no trailing bit, then ends.

Memory labels  | BOOL | INPUT | FLAG |

,                   first input 
[                     # loop on INPUT
  >-[-----<->]<++     subtract 49 == "1"

  [                     # case not "1"
    >++++[-<++++>]      add 16 since 49 take 16 == "!"

    +                   set FLAG
    <                   move to INPUT
    [                     # case "0"
      [+],                clear and new INPUT
      [                     # case "0!"
        [-]>-<              clear INPUT and FLAG
      ]
    ]
  ]

  >                   move to FLAG
  [                     # case "!" or "0" without tail
    <<+[-->]>[<]        not the BOOL
    ,                   take new input
    >-                  clear FLAG
  ]
  <                   move to INPUT
]

+.                    return 0 or 1

Или для текстового ответа замените последнюю строку на

-[-----<+>]<--.       add 49 for "0" or "1" conversion and return

14

Brainfuck - путь ко многим байтам (232 байта)

Явно не тот язык для победы в коде гольф. В основном я заметил отсутствие кого-либо, кто использует этот esolang. Есть хороший онлайн переводчик bf interpeter, или вы действительно можете посмотреть, что программа делает, используя этот bf визуализатор .

>>>>>,[>+++[<---------------->-]<<<<<<[-]+>[-]>>>>[-[<<[>+<<<<->>>[<<+>>-] ]<<[>>+<<-]<[>>+<<[-]]>>>>>[-]]<<<<<[>>>++<<<-]>+>>>>[-]]<<<<-[>>+<<[-]]>>>>,]<<->[<[-]+>[-]]<<[<[-]>>[<<+>>[-]]+<<[->>-<<]>-]>>[-]+++[<++++++++++++++++>-]<.

3
Вы сумасшедший человек!
Almo

Любите это, вы можете сделать это в Malbolge? XD
Стефан Нольде

Информация: ниже приведено слишком много более коротких решений.
user202729

14

Python, -44- 42 байта

Сохранено 2 байта благодаря Zgarb!

lambda x:(x[-1]=='0')^len(x.rstrip('!'))%2

Шаг за шагом:

  1. x[-1]!='0'
    если xзаканчивается на 1или !xне заканчивается 0, факторная часть должна иметь значение 1, иначе0
  2. ^len(x.rstrip('!'))%2
    эксплуатировать свойство xor как «условное не». Условие в этом случае, если длина начального !s нечетна. Однако, .rstripне удаляет число из строки, поэтому вычисленная длина смещается на 1, поэтому условие инвертируется.
  3. Смещение на 1 на шаге 2 корректируется путем изменения !=на ==шаг 1. Згарб предложил использовать оператор сравнения различий, а не применять другую инверсию, экономя 2 байта.

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


Сбой на входе !!0; это в настоящее время возвращается 1.
Чернила стоимости

@ValueInk должен работать сейчас
busukxuan

1
lambda x:(x[-1]=='0')^len(x.rstrip('!'))%2избегает дополнительной инверсии.
Згарб

15
вычеркнуто 44 все еще регулярно 44
Rɪᴋᴇʀ

3
Я думаю, он заявляет, что зачеркнутый 44 в используемом шрифте не выглядит зачеркнутым ... :) Зачеркнутая часть перекрывается с горизонтальной частью 4-х.
JeffC

13

JavaScript (ES6), 43 41 29 байт

s=>+eval(s.replace(/.!+$/,1))

Метод без регулярных выражений ( 41 31 байт)

Ниже мой первоначальный подход. Это немного интереснее, но значительно дольше и немного дольше даже после значительной оптимизации Нилом (сохранено 10 байт) .

f=([c,...s])=>1/c?c|s>'':1-f(s)

Контрольные примеры


Я могу только сохранить 10 байт из вашей без регулярных выражений методы, так что все еще слишком долго: f=([c,...s])=>1/c?c|s>'':1-f(s).
Нил

@Neil Так как это намного лучше, чем моя первая попытка в любом случае, я позволил себе включить ваше предложение.
Арно

Ха, у меня была та же идея, но ты играл в нее лучше. :)
Devsman

11

Желе , 5 байт

VeMḂ$

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

Монадическая функция, ожидающая строку. Входы с начальным !s приводят 1к тому, что по пути печатается на STDOUT, поэтому ссылка TIO, которую я даю, является тестовым жгутом, который печатает пары ввода-вывода под первой строкой вывода.

Как?

VeMḂ$ - Monadic link: string
V     - eval the string
          - the implicit input of 0 causes !...! to evaluate to 1 (which gets printed),
          - the result is the evaluation of the rest: "0"=0; "0!"=1; "1"=1; "1!"=1; ...
 e    - exists in?
    $ - last two links as a monad:
  M   -     Maximal indexes - the "0" and "1" characters are greater than "!",
                            - so this results in a list of one item [i] where
                            - i is the 1-based index of the 0 or 1 character.
   Ḃ  -     %2 (vectorises) - [i%2], so a 0 if we need to logically negate and a 1 if not
                            - hence we check equality with e rather than inequality.

10

05AB1E , 9 байтов

Код:

.V¹'!ÜgG_

Использует кодировку CP-1252 . Попробуйте онлайн! или проверьте все контрольные примеры!

Объяснение:

.V         # Evaluate the input as 05AB1E code. This computes the factorial part.
   '!Ü     # Remove trailing exclamation marks..
  ¹        # ..from the first input
      g    # Get the length of the resulting string
       G   # Do the following length - 1 times:
        _  #   Negate the number

10

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

Несколько странный подход, но он короткий и работает.

0$
!1
!!

^\d

В первых двух строках мы заменяем окончание 0на !1: с помощью этой замены мы теперь знаем, что часть нашей строки, начиная с цифры, равна 1.

Следующие две строки удаляют пары !: двойное отрицание стирает само себя, и мы уже учли факториал с предыдущего шага.

Последняя строка, соответствует цифре в начале строки и возвращает количество совпадений: если все отрицания были устранены, мы найдем совпадение (и, как мы уже говорили, мы знаем, что оно равно 1), если еще есть отрицание это не будет соответствовать.

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


1
Разве последняя цифра не всегда будет 1? В этом случае вы можете использовать, 1а не \d.

1
@ ais523 нет, потому что первая часть будет заменять только конечный 0, поэтому, например, ввод 0!останется неизменным до последней строки
Лев

1
Действительно прекрасное решение, хорошая работа! :)
Мартин Эндер

10

Рубин, 12 + 1 = 39 24 15 13 байт

Использует -nфлаг. Спасибо @GB за -9 байт!

p~/!*$|0$/%2

Поскольку вы проверяете только длину, вы можете удалить конечный ноль вместо того, чтобы сначала проверять «! 0», а затем один ноль.
GB

@GB это прекрасная идея! Тем не менее, я нашел решение, которое еще короче, изменив свое регулярное выражение для поиска позиции 0 или конца строки
Value Ink

Тогда вы можете просто проверить трейлинг '!' или ноль или конец строки: p ~ /! + $ | 0 $ | $ /% 2 - это всего 14 байтов.
GB

И тогда «0 $ | $» может стать «0? $» Для сохранения другого байта.
GB

1
А еще лучше !*$на два короче!
Value Ink

9

Perl , 20 байт

19 байт кода + -pфлаг.

s/\d!+/1/;$_=0+eval

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

Отрицание Perl возвращает undefили 1, поэтому я использую, 0+чтобы оцифровать 0+undefвозвращаемые результаты 0. Кроме того, не так много, чтобы сказать о коде.


2
Просто написал именно это. Есть +1.
прима

@primo Рад видеть, что на этот раз я не на 20 байт позади тебя! Спасибо :)
Дада

8

C 68 62 61 53 байта

c;e(char*a){for(c=1;*a<34;a++)c^=1;c=a[1]?c:*a&1^!c;}

Выжал еще несколько байтов с некоторым злоупотреблением

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


1
Я думаю , вы можете удалить intиз функции , и вы можете изменить *a==33к *a<34.
Коровы шарлатан

Увы *a%2, короче*a-48
Коровы шарлатан

Спасибо за чаевые. Я также смог исключить другого персонажа, сняв скобки вокруг возврата и назначив его.
Ahemone

Я почти уверен, что for(;*a<34;a++)можно сократить до for(;*a++<34;)1 байта
Альберт Реншоу

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

6

Perl 6 , 32 28 23 байта

{m/(\!)*(1|0.)*/.sum%2}

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

{                     }  # A lambda.
{m/            /      }  # Match the lambda argument against the regex:
   (\!)*                 #   Zero or more `!`.
                         #     (First capture will be an array with one element per negation).
        (1|0.)*          #   A `1`, or a `0` and another character, zero or more times.
                         #     (Second capture will be a one-element array if the factorial
                         #     part evaluates to 1, and an empty array otherwise.)
                .sum     # Add the lengths of the two captures,
                    %2   # and return that sum modulo 2.

6

Haskell , 39 байт

f('!':b)="10"!!read[f b]
f[a]=a
f _='1'

Определяет функцию f, которая принимает строку и возвращает символ. Попробуйте онлайн!

объяснение

Есть три случая: ввод начинается с !, длина ввода равна 1, и все остальное.

f('!':b)=    -- If input has head '!' and tail b,
 "10"!!      -- we index into the string "10"
  read[f b]  -- using f b converted to int. This essentially inverts f b.
f[a]=        -- If input has only one character, we know it's a digit,
 a           -- so we can just return it.
f _=         -- In all other cases, we know the input is a digit followed by !s,
 '1'         -- so we can return '1'.

Переход от строки к Integer в качестве возвращаемого типа: f('!':b)=[1,0]!!f b;f"0"=0;f _=1.
Ними

6

Befunge, 24 байта

~"!"-:#v_$1+
*+2%!.@>0~`

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

Это начинается с подсчета количества !символов, прочитанных со стандартного ввода. Первый символ, который не является !либо, будет либо, 0либо 1, но в процессе тестирования !мы вычтем 33, сделав его либо 15, либо 16. Затем мы прочитаем еще один символ, который будет либо !EOF, либо сравните, если это меньше 0 (т.е. EOF).

Взяв эти три точки данных - восклицательный знак ( c ), цифровое значение ( d ) и условие конца файла ( e ) - мы можем рассчитать результат следующим образом:

!((c + d*e) % 2)

Умножение значения цифры на условие конца файла означает, что оно будет преобразовано в ноль, если за цифрой следует символ «а» !, что дает ему то же значение по модулю 2, что и 1(который запоминается, был преобразован в 16). Но перед применением модуля 2 мы добавляем начальное количество восклицательных знаков, которое эффективно переключает результат по модулю 2 столько раз, сколько их !префиксов было. И, наконец, мы не результат, так как наши базовые значения для 0и 1являются противоположностью того, что нам нужно.

Рассмотрим код более подробно:

~                Read a character from stdin.
 "!"-            Subtract 33 (ASCII for '!').
     :  _        Make a duplicate and check if zero (i.e. is it a '!').
         $1+     If so, drop the duplicate, increment a counter, and repeat.
       v         Otherwise move to the second line, leaving the digit value on the stack.
       >0~`      Read one more character and check if less than 0 (i.e. EOF).
*                Multiple by the digit value, making it zero if not followed by EOF.
 +               Add to the exclamation count.
  2%             Modulo 2 the result.
    !            Then not that value.
     .@          And finally write to stdout and exit.

6

Haskell , 27 байт

f('!':b)=1-f b
f"0"=0
f _=1

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

Каждое !ведение дополняет вывод для остальной части выражения, сделанного как 1-. Мы продолжаем переключаться, пока не наберем цифру. Если остальное просто "0", результат равен 0. В противном случае, это 1или или сопровождается одним или несколькими !, так что результат равен 1.


5

Рубин, 22 21 20 байт

->s{(s=~/!*$|0$/)%2}

Объяснение:

  • Первый случай, у меня есть некоторые "!" в конце удалите их, получите длину по модулю 2.
  • Во втором случае нет '!', Если последний символ равен нулю, удалите его, получите длину по модулю 2
  • Если последний символ равен 1, вернемся к первому случаю

(Кража -1 байт, идея @Value Ink)


Круто, я смотрел на эту загадку в течение 10 минут, но у меня было немного времени, а потом забыл об этом. Теперь снова заметил это в активных вопросах и был рад видеть такой хороший подход.
Акостадинов

4

Желе , 8 байт

œr”!LḂ=V

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

Это функция (монадическая ссылка), которая принимает один аргумент и возвращает его возвращаемое значение. (Он также часто записывает ненужные файлы в стандартный вывод как побочный эффект, но нас это не волнует.)

объяснение

œr”!LḂ=V
œr”!      Take {the input}, with all trailing ! deleted
    L     Take the length of this
     Ḃ    Take the parity of that length
      =   Return 0 if unequal, 1 if equal to:
       V    the value of {the input} when eval'ed as a niladic Jelly program

Во-первых, обратите внимание, что поскольку входные данные всегда состоят из некоторого числа !, за которым следует цифра, а затем еще больше !, что, если мы удалим трейлинг !и возьмем длину, мы получим один плюс номер ведущего !в программе. Взятие четности вернет 0, если было нечетное число !, или 1, если было четное число !. Сравнение с 0 - это функция «не», тогда как сравнение с 1 - это функция тождества; таким образом, œr”!LḂ=эффективно реализуется !часть вопроса «рассматривайте ведущие как НЕ операторы».

Что касается второй половины, обработка факториалов !- это факториальная операция в Jelly, поэтому, если у программы нет ведущего !, мы можем решить проблему напрямую с помощью простого eval( V). Если у программы действительно есть ведущие !, они будут интерпретироваться как принятие факториала 0 (возможно, многократно), производящего возвращаемое значение 1, которое будет напечатано в стандартный вывод и отброшено, как только будет замечена цифра; таким образом, они не влияют на возвращаемое значение функции, которую я представляю на вопрос.


Очень хорошее и отличное объяснение.
ElPedro

4

Python, 38 байт

lambda s:(s[1::2]>s[::2])^ord(s[-1])%2

TryItOnline!

Безымянная функция, принимающая входную строку sи возвращающая целое число 0или 1.

s[1::2] это фрагмент входной строки, который начинается с индекса 1 и имеет размер шага два:
'Like this' -> 'ieti'

s[::2] аналогично, но начинается с индекса по умолчанию 0:
'Like this' -> 'Lk hs'

Тест (s[1::2]>s[::2])проверяет, является ли индекс на основе 0 нечетным '0'или то '1'есть, то есть, если мы должны дополнить.
Это работает, потому что порядок строк проверяется лексикографически с любой непустой строкой, превышающей пустую строку, и с упорядочением ASCII, так '1'>'0'>'!'. Это байт короче, чем простой s.index(max(s))%2.

В ord(s[-1])%2проверяет , чтобы увидеть , если последний символ не является '0'(для действительного входа), и результатов в целом числе ( в то время как такая же длина (s[-1]!='0')будет возвращать логическое значение).
Это работает потому , что последний символ ввода, s[-1]будет представлять собой '0', '1'или '!'которые имеют ASCII - код указывает 48, 49, и 33 соответственно, которые равны 0, 1 и 1 по модулю 2.

^Затем выполняет побитовое исключающее или операции на двух указанных выше значений, возвращая целое число , так как один вход, правый, представляет собой целое число. Если значение «Истина» соответствует значению «слева», возвращается правое дополнение, а значение «Лево» соответствует значению «Ложь», при необходимости возвращается право.


4

Java 7, 105 82 81 байт

int a(char[]a){int b=0,c=0;for(;a[b++]<34;c^=1);return(b<a.length?1:a[b-1]&1)^c;}

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

Старое регулярное выражение

int a(String a){a=a.replace("0!","1").replaceAll("1.*","1");int b=a.length()-1;return b%2^a.charAt(b)&1;}

2
c^=1супер умный Это неиспользованный оператор, если я когда-либо видел.
Эддисон Крамп

3

CJam , 12 11 байтов

r_W='0=!\~;

Попробуйте онлайн! Набор тестов (выводится 1для каждого правильного теста).

r      e# Read input.
_W='0= e# Duplicate and check whether the string ends in '0'. This is the
       e# only case in which the factorial part results in 0.
!      e# Negate this to get the actual result of the factorial part.
\      e# Swap with the input.
~      e# Evalute the input as CJam code. The leading `!` will apply the logical
       e# negations to the factorial result. The 0 or 1 will then push a junk value
       e# which is potentially negated a few times as well, by the factorials.
;      e# Discard the junk value.


3

Brainfuck, 115 байт

>,[->++++[<-------->-]<[--------------->,[<[-]+>-]<<[->-[>+<+]>[-<+>]<<]>>++++++[-<++++++++>]<.>>+<]>-[<<+>,>[-]]<]

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

Ungolfed:

% 0: inverter count
% 1: result
% 2: if/else flag; tmpspace in inner loop 0

>1,[
    ->2++++[<-------->-]<1 subtract 33 (!)
    [ 
        % we've reached the number
        ---------------
        % now it's either 0 or 1

        % check next char; If it's not 0 then it's '!'
        % 0! = 1! = 1!...! so we only need to determine if at least one ! exists
        >2,
                [<[-]+>-]<1

        % apply inversions
        <0
        [->1
            % invert cell 1 once each iteration
                       % cell 1 is 0 or 1
            -          % cell 1 is 255 or 1
            [>+<+]     % cell 1 is 0; cell 2 is 1 iff cell 1 should be 1
            >2[-<+>]<1 % cell 1 is 1 or 0
        <0]

        % print result
        >1>++++++[-<++++++++>]<1.

        >>2+< % tape={0 r 0 1}
    ]
    >2-[ % we haven't seen the number yet
        <<0+>1,>2 % add to inverter count
        [-]
    ]<1
]

2

Пакетная, 62 байта

@set/ps=
@set s=%s:0!=1%
@set s=%s:!!=%
@cmd/cset/a%s:1!=1%

Принимает участие в STDIN. Batch действительно !правильно понимает ведущие s для этой задачи, но с трейлингом !нужно разобраться , что занимает три шага:

  • Изменить 0!на1
  • Удалить пары !!(это безопасно для !!s перед цифрой тоже)
  • Удалить любой оставшийся трейлинг !(который теперь может быть только после a 1)

2

sed, 36 33 31 байт

Чистый сед, без утилит bc / shell. Работает на GNU sed <4.3; 33 байта на BSD и GNU 4.3+.

s/.!!*$/1/
:
s/!0/1/
s/!1/0/
t

Достаточно просто, если вы знакомы с sed; прокомментировал для тех, кто не:

# Since 0! == 1! == 1 and factorial has precedence, just collapse any trailing "!" 
s/.!!*$/1/
# Define an anonymous label
:
# Invert 0 if needed
s/!0/1/
# Invert 1 if needed
s/!1/0/
# If a change was made, go back to the anonymous label.
t

Контрольная работа:

% cat 109248.sed
s/.!!*$/1/
:l
s/!0/1/
s/!1/0/
tl
% wc -c 109248.sed
      33 109248.sed
% cat cases
0
1
0!
1!
!0
!1
!0!
!1!
0!!
1!!
!!0
!!1
!0!!
!!!1
!!!0!!!!
!!!1!!!!
% sed -f 109248.sed cases
0
1
1
1
1
0
0
0
1
1
0
1
0
0
0
0
% gsed -f 109248.sed cases
0
1
1
1
1
0
0
0
1
1
0
1
0
0
0
0
%

IIRC некоторые (все?) Версии sedпозволяют использовать пустую строку в качестве имени метки. Если вы сможете заставить это работать здесь, это сэкономит вам два байта. На самом деле, я не уверен, что лейбл даже нужен; если я что-то пропустил, первая строка идемпотентна, так что вы можете вернуться к началу программы, а не к метке.

@ ais523 Я тоже так думал, но, очевидно, это не работает в версиях BSD. На странице руководства написано: «Если метка не указана, переходите к концу сценария», и даже это не сработало, когда я попытался.
Кевин

GNU sed позволяет метке быть просто :(больше ошибки воспринимается как особенность), в этом случае и the, tи b! Команды переходят в положение метки. Кроме того, код sed должен работать как минимум для одной версии sed, аналогично другим языкам, поэтому вам не нужно создавать код, который также работает для BSD.
сешумара

2

PHP 7.1, 58 55 54 37 35 байт

Примечание: используется кодировка IBM-850

echo!!$argn[-1]^strspn($argn,~Ì)%2;

Запустите так:

echo '!!!0!!!!' | php -nR 'echo!!$argn[-1]^strspn($argn,~Ì)%2;';echo
> 0

объяснение

echo
  strspn($a=$argv[1],~Ì) # Count the number of leading exclamation marks.
  % 2                    # Make 0 (even) or 1 (odd).
  ^ !!$a[-1];            # Negate with factorial part (truthy value of the 
                         # last char):
                         # - "0" is considered falsy.
                         # - "1" or "!" is considered truthy.

Tweaks

  • Сохранено 3 байта с использованием кодировки IBM-850
  • Сохраненный байт, слегка изменив регулярное выражение
  • Сохранено 17 байт, новая версия без длинных имен функций и возврата
  • Сохранено 2 байта с помощью -R(что делает $argnдоступным)

1

IBM / Lotus Notes Formula - 77 байтов

@Eval(@Left(a;@If(@Like(a;"%1%");"1";"0"))+@If(@Ends(a;"!");"1";@Right(a;1)))

Там нет TIO для Формула Notes, поэтому скриншот всех тестовых случаев показан ниже:

Все тестовые случаи

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

@Eval() оценивает строку как выражение

Сначала мы проверяем, aсодержит ли входная строка в поле (input) 1или, 0и принимаем все символы слева от того, какой это будет строка !символов. Нам все равно, сколько. @Eval()позаботится об этом.

Далее мы посмотрим, есть ли !в конце строки. Если есть, мы добавляем 1к !строке ( 0!и 1!оба равны 1 - не имеет значения, сколько !символов в конце), в противном случае мы добавляем последний символ без изменений, потому что это не a !и может быть либо a, 1либо a 0.

Теперь у нас есть строка, содержащая начальные инверсии плюс число, определяемое тем, есть ли какие-либо факторные символы, чтобы мы могли передать это @Eval()и получить результаты выше.


1

Бин , 24 байта

HexDump:

00000000 26 4a c1 53 a0 17 53 d0 80 a0 5d 20 80 0a a1 80  &JÁS .SÐ. ] ..¡.
00000010 81 00 25 3a ae a1 ab 24                          ..%:®¡«$
00000018

Эквивалентный JavaScript:

+eval(a.replace(/.!+$/,1))

Извините, что наступил вам на ноги, Арно .

Объяснение:

Принимает первую строку ввода как неформатированные строки в a, и заменяет любую цифру , за которой следует один или более !с 1, так , что остальные могут быть eval«D с помощью JavaScript.

Попробуйте демо или набор тестов

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