Математика - це факт. Програмування - ні


175

У математиці знак оклику !часто означає фактор, і він настає після аргументу.

У програмуванні знак оклику !часто означає заперечення, і це ставиться перед аргументом.

Для цього виклику ми застосуємо лише ці операції до нуля та однієї.

Factorial
0! = 1
1! = 1

Negation
!0 = 1
!1 = 0

Візьміть рядок нуля або більше !'s, за яким 0або 1, за ним нуль або більше !' s ( /!*[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.
aslum

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

2
@AlbertRenshaw Це правильно.
Захоплення Кальвіна

Відповіді:


43

Математика, 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 ...)
LegionMammal978

@ LegionMammal978 це вже у відповіді.
Мартін Ендер

Чисте рішення ksh x=${x/[01]!*/1};echo $(($x))- заборонено публікувати належну відповідь :(
DarkHeart

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

Стара версія працює, ця
Корови кракають

Я скористався посиланням TIO
корови брязкають

@KritixiLithos Це спрацювало чудово, коли я спробував це на своїй скриньці Linux. Очевидно, проблема полягала в тому, що TIO вимагає нового рядка в кінці імітованого рядка введення. Це заплутана ситуація, тому я взяв посилання TIO. Якщо ви хочете спробувати його, ось ще раз посилання (але обов'язково додайте новий рядок в кінці входу, якщо ви змінили вхід, щоб перевірити його): tio.run/nexus/bash#@1@cmqJQrK @ nqKilom @ oX5OU / P @ /…
Мітчелл Спектор

2
Але що робити, якщо хтось біг mkdir -p 's/.!!'{bunch,of,different,directories}\$/1? Тоді ви отримаєте розширення Pathname і Sed буде намагатися читати каталоги так, ніби вони були файлами, замість того, щоб читати стандартний вхід, і він нічого не виведе! :)
Wildcard

1
@Wildcard Я повністю згоден. У виробничих сценаріях я завжди використовую цитати в таких ситуаціях. (У цьому випадку я б фактично поставив подвійні лапки навколо аргументу sed, а не просто уникнути *. Це легше читати, ніж використовувати зворотні косої риси, і це уникає можливості пропуску якогось спеціального символу.)
Мітчелл Спектор

22

Сітківка , 20 15 14 байт

Дякуємо Лео за збереження 1 байта.

0!
1
!!

^1|!0

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

Пояснення

0!
1

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

!!

Скасуйте пари відмов. Це також може скасувати деякі фактичні факти, але це не має значення.

^1|!0

Порахуйте кількість збігів цього регулярного виразу, що є 1або 0дає бажаний результат.


Альтернативне рішення для цього ж рахунку: \d.+...
корови

@KritixiLithos знайшов спосіб уникнути цього взагалі.
Мартін Ендер

Ви можете видалити ^раніше!0
Лев

17

Grime , 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. Якщо введення починається з а !, то \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 байти)

Очевидно неправильна мова для перемоги в коді гольфу. В основному я помітив відсутність у когось, хто використовує цей езоланг. Є хороший інтерпретатор інтерфейсу bf, або ви можете насправді дивитися, що програма робить за допомогою цього візуалізатора .

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

3
Ти божевільна людина !!
Алмо

Любіть це, чи можете ви це зробити в malbolge? XD
Стефан Нолде

Інформація: Нижче є занадто багато коротших рішень.
користувач202729

14

Пітон, -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 у використаному шрифті не виглядає закресленим ... :) Перекреслена частина перекривається горизонтальною частиною 4s.
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 Оскільки це набагато краще, ніж моя перша спроба, все одно я взяв на себе вашу пропозицію.
Арнольд

Ха, у мене була така ж ідея, але ти краще пограв у неї. :)
Девсман

11

Желе , 5 байт

VeMḂ$

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

Монадічна функція очікує рядок. Введення з ведучими !s викликають 1друк a в 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 це чудова ідея! Однак я знайшов ще коротше рішення, змінивши свій регекс, щоб шукати позицію 0 або кінець рядка
Value Ink

Тоді ви можете просто перевірити наявність "!" або нуль або кінець рядка: p ~ /! + $ | 0 $ | $ /% 2 - це лише 14 байт.
GB

І тоді "0 $ | $" може стати "0? $", Щоб зберегти ще один байт.
ГБ

1
Ще краще !*$коротше на два!
Значення чорнила

9

Perl , 20 байт

19 байт коду + -pпрапор.

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

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

Заперечення повертається в Perl undefабо 1, так що я використовую , 0+щоб numerify результуючі 0+undefповертається 0. Крім того, про код не багато сказати.


2
Просто написав саме це. Майте +1.
примо

@primo Радий бачити, що я один раз не на 20 байт позаду тебе! Дякую :)
Дада,

9

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
корови гукають

Дякую за пораду. Я також зміг усунути іншого персонажа, видаливши дужки навколо повернення та призначивши його.
Агемон

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

На жаль, ні, оскільки умовне висловлювання воно завжди буде виконуватися і так підштовхне вказівник занадто далеко вперед, щоб повернути відвід.
Агемон

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

Хаскелл , 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~`

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

Це починається з підрахунку кількості !прочитаних символів з stdin. Першим символом, який не є !волею, є 0або1 , але в процесі тестування !ми віднімемо 33, зробивши це або 15, або 16. Потім ми прочитаємо ще один символ, який буде !або EOF, і порівняйте, якщо це менше 0 (тобто EOF).

Беручи до уваги ці три точки даних - знак оклику ( с ), значення цифри ( d ) та стан кінця файлу ( e ) - результат можна обчислити так:

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

Помноження значення цифри на умову кінця файлу означає, що воно буде перетворене в нуль, якщо за цифрою слідує a !, таким чином надаючи йому те саме значення модуля 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 байт крадіжки @ ідея чорнила)


Дивовижно, я дивився на цю головоломку 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

Пітон, 38 байт

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

СпробуйтеItOnline!

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

s[1::2] - це фрагмент вхідного рядка, який починається з індексу 1 і має розмір кроку два:
'Like this' -> 'ieti'

s[::2] подібний, але починається з індексу за замовчуванням 0:
'Like this' -> 'Lk hs'

Тест (s[1::2]>s[::2])перевіряє, чи 0 чи індекс на основі 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.

^Потім виконує побітовое виключає або операції на двох зазначених вище значень, повертаючи ціле число , тому що один вхід, правий, являє собою ціле число. Якщо зліва - True, то праворуч повертається доповнення, якщо ліворуч - False, праворуч повертається, як потрібно.


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

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

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

Безголовки:

% 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

Формула IBM / Lotus Notes - 77 байт

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

Для Формули Нотаток немає TIO, тому нижче показано скріншот усіх тестових випадків:

Усі тестові справи

Як це працює

@Eval() оцінює рядок як вираз

Спершу ми перевіряємо, чи aмістить рядок введення в полі (введення) 1або 0переносимо всі символи ліворуч від того, який це буде рядок !символів. Нам все одно, скільки.@Eval()подбає про це.

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

Тепер у нас є рядок, що містить провідні інверсії плюс число, яке визначається тим, чи є якісь факторні символи, щоб ми могли подати це @Eval()та отримати результати вище.


2

sed, 36 33 31 байт

Чистий sed, без утиліти для оболонки / оболонки. Працює на 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 дійсно дозволяє мітці бути просто :(більше помилка, взята як функція), в цьому випадку і tі b! команди переходять до положення мітки. Крім того, код sed повинен працювати щонайменше для однієї версії sed, подібно до інших мов, тому вам не потрібно створювати код, який також працює для BSD.
seshoumara

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.

Налаштування

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

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тим, щоб решта могла бути evalJavaScript.

Спробуйте демонстрацію або тестовий набір

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