Matemática é fato. A programação não é


176

Na matemática, um ponto de exclamação !geralmente significa fatorial e vem depois da discussão.

Na programação, um ponto de exclamação !geralmente significa negação e vem antes do argumento.

Para esse desafio, aplicaremos essas operações apenas a zero e um.

Factorial
0! = 1
1! = 1

Negation
!0 = 1
!1 = 0

Pegue uma sequência de zero ou mais !'s, seguida por 0ou 1, seguida de zero ou mais !' s ( /!*[01]!*/).
Por exemplo, a entrada pode ser !!!0!!!!ou !!!1ou !0!!ou 0!ou 1.

O !antes 0ou depois das 1negações e o !depois são fatoriais.

O fatorial tem maior precedência do que a negação, portanto, os fatoriais são sempre aplicados primeiro.
Por exemplo, !!!0!!!!realmente significa !!!(0!!!!), ou melhor ainda !(!(!((((0!)!)!)!))).

Saída da aplicação resultante de todos os fatoriais e negações. A saída será sempre 0ou 1.

Casos de teste

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

O código mais curto em bytes vence.


18
Mas 0! = 1 !, então qual é o sentido de lidar com múltiplos fatoriais?
boboquack

30
@boboquack Porque esse é o desafio.
Hobbies de Calvin

11
<? = '1'; ... corrigir 75% do tempo em php.
aslum 6/02

10
Eu posso estar errado aqui, mas não é possível qualquer número com fatoriais depois de simplesmente ser removido e substituído por 1? Like 0 !!!! = 1 !! = 0 !!!!!!!! = 1 !!! = 1! = 0! = 1 etc
Albert Renshaw

2
@AlbertRenshaw Isso está correto.
Calvin Passatempos

Respostas:


43

Mathematica, 25 17 bytes

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

Recebe entrada de um prompt do usuário. Assume o ambiente de notebook do Mathematica para impressão implícita. Para torná-lo um script de linha de comando, envolvê-lo Print[...]ou torná-lo uma função sem argumentos (que então recebe entrada do prompt), acrescente &.

O Mathematica possui os dois operadores necessários (com a precedência necessária), para que possamos "avaliar" a entrada (o que é feito automaticamente por Input[]), mas o operador de negação lógica não funciona em números inteiros (portanto, ele não será avaliado). Se !xsobrar um resultado, substituí-lo por 1-x.

Alguns fatos interessantes sobre a avaliação:

  1. Na verdade, o Mathematica também possui o operador fatorial duplo !!, que calcula n*(n-2)*(n-4)*..., mas é aplicado a 0ou 1ainda fornece 1, portanto, não importa que 0!!!!!seja realmente analisado ((0!!)!!)!.
  2. Embora o Mathematica saia !0e !1não seja avaliado, ele sabe que !é auto-inverso e, por isso, cancela automaticamente todos os pares de liderança !. Depois do ToExpressionque estamos sempre deixou com um dos 0, 1, !0, !1.

3
Desde quando um snippet REPL foi permitido por padrão?
LegionMammal978

2
@ LegionMammal978 Aparentemente desde dezembro de 2015, mas continuo esquecendo. Para ser justo, não é um "trecho", pois não assume que a entrada já esteja armazenada em algum lugar da memória. E supondo que o ambiente do notebook não seja muito diferente de ter uma linguagem com saída implícita.
Martin Ender

Apenas curioso, poderia ser fornecido um meta link? (Tentando encontrar informações lá é estressante, mais um problema do formato de perguntas e respostas do SE ...) #
7897

@ LegionMammal978 já está na resposta.
Martin Ender

Solução ksh puro x=${x/[01]!*/1};echo $(($x))- não tem permissão para postar uma resposta adequada :(
darkheart

28

[Bash] + Utilitários Unix, 21 17 bytes

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

Isso deve ser salvo em um arquivo e executado como um programa. Se você tentar digitar o comando diretamente da linha de comando, não funcionará porque !! é expandido devido à substituição do histórico ser ativada no modo interativo do bash. (Como alternativa, você pode desativar a substituição do histórico com set +H.)

O caso de teste é executado:

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

A versão antiga funciona, este não faz
Vacas quack

Eu usei o link TIO
Vacas quack

@KritixiLithos Funcionou bem quando tentei na minha caixa Linux. Aparentemente, o problema era que o TIO requer uma nova linha no final da linha de entrada simulada. É uma situação confusa, então peguei o link do TIO. Se você quiser experimentá-lo, aqui está o link novamente (mas não se esqueça de incluir uma nova linha no final da entrada, se você alterar a entrada para testá-la): tio.run/nexus/bash#@1@cmqJQrK @ nqKilom @ oX5OU / P @ /…
Mitchell Spector

2
Mas e se alguém tiver fugido mkdir -p 's/.!!'{bunch,of,different,directories}\$/1? Então você receberá o Pathname Expansion e o Sed tentará ler os diretórios como se fossem arquivos, em vez de ler a entrada padrão, e ela não produzirá nada! :)
Curinga

1
@Wildcard Eu concordo completamente. Nos scripts de produção, eu sempre uso aspas em situações como essa. (Nesse caso, eu colocaria aspas duplas em torno do argumento para sed, em vez de apenas escapar do *. É mais fácil de ler do que usar barras invertidas e evita a possibilidade de perder algum caractere especial.)
Mitchell Spector

22

Retina , 20 15 14 bytes

Agradecemos a Leo por economizar 1 byte.

0!
1
!!

^1|!0

Experimente online!

Explicação

0!
1

Transformar 0!em 1. Não nos importamos com nenhum outro !s final , o número resultante é o mesmo como se tivéssemos aplicado todos os fatoriais.

!!

Cancele pares de negações. Isso também pode cancelar alguns fatoriais, mas isso é irrelevante.

^1|!0

Conte o número de correspondências dessa regex, que é ou 1ou 0e fornece o resultado desejado.


Solução alternativa para o mesmo bytecount: \d.+...
Vacas quack

@KritixiLithos Encontrei uma maneira de evitar isso completamente.
Martin Ender

Você pode remover o ^anterior!0
Leo

17

Grime , 14 12 9 bytes

e`\0!~\!_

Experimente online!

Explicação

Isso corresponde à entrada em relação a um padrão, imprimindo 1para correspondência e 0sem correspondência.

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

A ideia é essa. Se a entrada começa com um dígito, a parte recursiva \!_sempre falha e \0!é bem - sucedida, a menos que tenhamos um único 0. O xor deles é bem-sucedido, a menos que a entrada seja única 0. Se a entrada começar com a !, \0!sempre será bem- \!_sucedida e se a correspondência recursiva for bem-sucedida. O xor deles é bem-sucedido exatamente quando a correspondência recursiva falha, negando-a.


16

Brainfuck, 85 72 (84) bytes

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

para retornar numericamente ou

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

para texto ASCII. > também pode ser prefixado para evitar quebra de memória.

Experimente online!


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

Ou, para resposta em texto, substitua a última linha por

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

14

Brainfuck - caminho para muitos bytes (232 bytes)

Claramente o idioma errado para ganhar no código de golfe. Notei principalmente a falta de alguém usando esse esolang. Existe um bom interpretador on-line bf interpeter ou você pode realmente assistir ao que o programa faz usando esse visualizador bf .

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

3
Seu homem louco !!
Almo

Amor, você pode fazer isso em Malbolge? XD
Stefan Nolde

Informação: Existem soluções muito mais curtas abaixo.
usar o seguinte comando

14

Python, -44- 42 bytes

Economizou 2 bytes graças ao Zgarb!

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

Passo a passo:

  1. x[-1]!='0'
    se xtermina com 1ou !xnão termina com 0, a parte fatorial deve ter valor 1, caso contrário0
  2. ^len(x.rstrip('!'))%2
    explorar a propriedade do xor como um "não condicional". A condição nesse caso é se o comprimento de !s inicial for ímpar. No entanto, .rstripnão remove o número da sequência, portanto o comprimento calculado é compensado por 1; portanto, a condição é invertida
  3. O deslocamento de 1 na etapa 2 é corrigido alterando !=para a ==etapa 1. O Zgarb sugeriu o uso de um operador de comparação de diferenças em vez de aplicar outra inversão, economizando 2 bytes.

Experimente online!


Falha em uma entrada de !!0; está retornando no momento 1.
Value Ink

@ValueInk deveria estar trabalhando agora
busukxuan

1
lambda x:(x[-1]=='0')^len(x.rstrip('!'))%2evita a inversão extra.
Zgarb 6/02

15
riscado 44 ainda é regular 44 #
066

3
Eu acho que ele está afirmando que um 44 riscado na fonte usada não parece riscado ... :) A parte riscada se sobrepõe à porção horizontal dos 4s.
JeffC

13

JavaScript (ES6), 43 41 29 bytes

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

Método não regex ( 41 31 bytes)

Abaixo está minha abordagem inicial. É um pouco mais interessante, mas significativamente mais longo ainda mais após uma otimização significativa do Neil (10 bytes salvos) .

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

Casos de teste


Eu só pode salvar 10 bytes de seu método não-regex, por isso ainda é muito longo: f=([c,...s])=>1/c?c|s>'':1-f(s).
Neil

@ Neil Desde que é muito melhor do que a minha primeira tentativa de qualquer maneira, tomei a liberdade de incluir a sua sugestão.
Arnauld 06/02

Tive a mesma ideia, mas você jogou melhor. :)
Devsman

11

Geléia , 5 bytes

VeMḂ$

Experimente online!

Função monádica esperando uma string. Entradas com !s iniciais fazem com que 1a seja impressa em STDOUT ao longo do caminho, de modo que o link TIO fornecido é um equipamento de teste que imprime os pares de entrada e saída abaixo da primeira linha de saída.

Quão?

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 bytes

Código:

.V¹'!ÜgG_

Usa a codificação CP-1252 . Experimente online! ou Verifique todos os casos de teste!

Explicação:

.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

Retina , 13 bytes

Uma abordagem um pouco estranha, mas é curta e funciona.

0$
!1
!!

^\d

Nas duas primeiras linhas, substituímos um final 0por !1: com essa substituição, sabemos agora que a parte da nossa string do dígito em diante é igual a 1.

Nas próximas duas linhas, remova os pares de !: dupla negação se apaga e já contabilizamos o fatorial na etapa anterior.

Última linha, combine um dígito no início da string e retorne o número de correspondências: se todas as negações tiverem sido eliminadas, encontraremos uma correspondência (e, como dissemos antes, sabemos que isso é igual a 1), se ainda houver uma negação que não corresponde.

Experimente online!


1
O dígito final não seria necessariamente sempre um 1? Nesse caso, você poderia usar em 1vez de \d.

1
@ ais523 não, porque a primeira parte substituirá apenas o final 0, então, por exemplo, a entrada 0!permanecerá inalterada até a última linha #
Leo

1
Solução realmente adorável, bom trabalho! :)
Martin Enders

10

Ruby, 12 + 1 = 39 24 15 13 bytes

Usa a -nbandeira. Graças a @GB por -9 bytes!

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

Como você só verifica o comprimento, é possível excluir o zero à direita, em vez de marcar "! 0" primeiro e um único zero depois.
GB

@ GB que ideia maravilhosa! No entanto, encontrei uma solução ainda mais curta, modificando meu regex para procurar a posição 0 ou o fim de linha
Value Ink

Então você pode simplesmente procurar por '!' ou zero ou final de linha: p ~ /! + $ | 0 $ | $ /% 2 são apenas 14 bytes.
GB

E então "0 $ | $" pode se tornar "0? $" Para salvar outro byte.
GB

1
Melhor ainda !*$é mais curto por dois!
Value Ink

9

Perl , 20 bytes

19 bytes de código + -psinalizador.

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

Experimente online!

A negação de Perl retorna undefou 1, então eu uso 0+para numerar os 0+undefretornos do resultado 0. Além disso, não há muito a dizer sobre o código.


2
Apenas escrevi exatamente isso. Tenha um +1.
primo

@primo Fico feliz em ver que, pela primeira vez, não estou 20 bytes atrás de você! Obrigado :)
Dada

9

C, 68 62 61 53 bytes

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

Espremido mais alguns bytes com algum abuso

Experimente online!


1
Eu acho que você pode remover o intda função e você pode alterar o *a==33para *a<34.
Vacas

Infelizmente *a%2é mais curto do que*a-48
Vacas quack

Obrigado pela dica. Também pude eliminar outro personagem removendo os colchetes no retorno e atribuindo-o.
Ahemone

Tenho a certeza que for(;*a<34;a++)pode ser encurtado para for(;*a++<34;)salvar 1 byte
Albert Renshaw

Infelizmente, não, como a declaração condicional será sempre executada e, portanto, empurrará o ponteiro muito à frente para a desreferência de retorno.
Ahemone

6

Perl 6 , 32 28 23 bytes

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

Como funciona

{                     }  # 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 bytes

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

Define uma função f, que pega uma string e retorna um caractere. Experimente online!

Explicação

Existem três casos: a entrada começa com !, a entrada tem comprimento 1 e tudo mais.

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'.

Mudar de String para Integer como o tipo de retorno: f('!':b)=[1,0]!!f b;f"0"=0;f _=1.
nimi

6

Befunge, 24 bytes

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

Experimente online!

Isso começa contando o número de !caracteres lidos no stdin. O primeiro caractere que não é a !será 0ou 1, mas, no processo de teste !, teremos subtraído 33, tornando-o em 15 ou 16. Em seguida, lemos mais um caractere, que será um !ou EOF, e compare se isso é menor que 0 (ou seja, EOF).

Tomando esses três pontos de dados - a contagem de exclamação ( c ), o valor do dígito ( d ) e a condição de fim de arquivo ( e ) - podemos calcular o resultado da seguinte forma:

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

Multiplicar o valor do dígito pela condição de final do arquivo significa que ele será convertido para zero se o dígito for seguido por a !, fornecendo, assim, o mesmo valor do módulo 2 que um 1(que lembra que foi convertido em 16). Porém, antes de aplicar o módulo 2, adicionamos a contagem de exclamação inicial, que efetivamente alterna o resultado do módulo 2 quantas vezes forem os !prefixos. E, finalmente, não somos o resultado, já que nossos valores de linha de base são 0e 1são o oposto do que precisamos.

Observando o código com mais detalhes:

~                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 bytes

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

Experimente online!

Cada líder !complementa a saída para o restante da expressão, feita como 1-. Continuamos lançando até atingir um dígito. Se o restante for justo "0", o resultado será 0. Caso contrário, é um 1ou é seguido por um ou mais !, portanto, o resultado é 1.


5

Ruby, 22 21 20 bytes

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

Explicação:

  • Primeiro caso, eu tenho alguns '!' no final, remova-os, obtenha o comprimento módulo 2.
  • Segundo caso, não '!', Se o último caractere for zero, remova-o, obtenha o comprimento módulo 2
  • Se o último caractere for 1, volte ao primeiro caso

(-1 byte roubando a idéia da @Value Ink)


Impressionante, olhei para esse quebra-cabeça por 10 minutos, mas não tive muito tempo e esqueci. Agora, ele o viu novamente em perguntas ativas e ficou encantado ao ver uma abordagem tão agradável.
22417 akostadinov

4

Gelatina , 8 bytes

œr”!LḂ=V

Experimente online!

Esta é uma função (link monádico) que recebe um argumento e retorna por seu valor de retorno. (Também costuma gravar lixo na saída padrão como efeito colateral, mas não nos importamos com isso.)

Explicação

œ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

Primeiro, observe que, como a entrada sempre consiste em algum número de !, seguido por um dígito, seguido por mais !, que, se excluirmos o final !e o comprimento, terminaremos com um mais o número de líderes !no programa. Tomar a paridade disso retornará 0 se houver um número ímpar de !, ou 1 se houver um número par de !. Comparar com 0 é uma função "não", enquanto comparar com 1 é a função de identidade; assim, œr”!LḂ=efetivamente implementa a parte "tratar líderes !como NÃO operadores" da questão.

Quanto ao segundo semestre, manipular fatoriais, !é uma operação fatorial em Jelly; portanto, se o programa não tiver liderança !, podemos resolver o problema diretamente com um simples eval( V). Se o programa não tem que conduz !, aqueles será interpretada como tendo o factorial de 0 (possivelmente várias vezes), produzindo um valor de retorno 1, o qual vai ser impressa na saída padrão e descartado uma vez um dígito é visto; portanto, eles não têm impacto no valor de retorno da função que é minha submissão à pergunta.


Explicação muito agradável e ótima.
ElPedro

4

Python, 38 bytes

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

TryItOnline!

Uma função sem nome que pega uma sequência de entrada se retorna um número inteiro 0ou 1.

s[1::2] é uma fatia da sequência de entrada que começa no índice 1 e tem um tamanho de etapa de dois:
'Like this' -> 'ieti'

s[::2] é semelhante, mas inicia no índice padrão 0:
'Like this' -> 'Lk hs'

O teste (s[1::2]>s[::2])verifica se o índice baseado em 0 do '0'ou '1'é ímpar, ou seja, se precisamos complementar.
Isso funciona porque a ordem das cadeias é verificada lexicograficamente com qualquer cadeia não vazia maior que a cadeia vazia e com a ordenação ASCII '1'>'0'>'!'. Este é um byte mais curto que o mais simples s.index(max(s))%2.

As ord(s[-1])%2verificações para ver se o último caractere não é um '0'(para a entrada válida), e resulta em um inteiro (ao passo que o mesmo comprimento (s[-1]!='0')retornaria um boolean).
Isso funciona porque o último caractere da entrada,, s[-1]será a '0', '1'ou '!'que possui os pontos de código ASCII 48, 49 e 33, respectivamente, que são 0, 1 e 1 módulo 2.

Em ^seguida, executa uma operação ou exclusiva bit a bit nos dois valores acima, retornando um número inteiro, pois uma entrada, a correta, é um número inteiro. Se a esquerda for True, o complemento da direita será retornado; se a esquerda for False, a direita será retornada, conforme necessário.


4

Java 7, 105 82 81 bytes

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

Experimente online!

Solução antiga regex-ish

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é super inteligente. Esse é um operador não utilizado, se eu já vi um.
Addison Crump

3

CJam , 12 11 bytes

r_W='0=!\~;

Experimente online! Conjunto de testes (imprime a 1para cada caso de teste correto).

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 bytes

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

Experimente online!

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

Lote, 62 bytes

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

Recebe entrada em STDIN. O lote realmente entende os principais !s corretamente para esse desafio, mas os últimos !precisam ser tratados, o que leva três etapas:

  • Mude 0!para1
  • Excluir pares de !!(isso também é seguro para os !!s antes do dígito)
  • Excluir qualquer restante restante !(que agora só pode ser após a 1)

2

Fórmula IBM / Lotus Notes - 77 bytes

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

Não há TIO para a Fórmula do Notes, portanto, uma captura de tela de todos os casos de teste é mostrada abaixo:

Todos os casos de teste

Como funciona

@Eval() avalia uma string como uma expressão

Primeiro, verificamos se a sequência de entrada no campo (entrada) acontém 1ou 0levamos todos os caracteres à esquerda de qualquer que seja, que será uma sequência de !caracteres. Nós não nos importamos com quantos. @Eval()vai cuidar disso.

A seguir, veremos se existe um !no final da string. Se houver, anexamos 1à !string ( 0!e 1!somos ambos 1 - não importa quantos !caracteres existem no final), caso contrário, anexamos o último caractere inalterado porque não é um !e pode ser um 1ou a 0.

Agora, temos uma sequência contendo as inversões iniciais mais um número definido pela existência de caracteres fatoriais para que possamos alimentar isso @Eval()e obter os resultados acima.


2

sed, 36 33 31 bytes

Sed puro, sem utilitários bc / shell. Trabalhos em GNU sed <4.3; 33 bytes no BSD e GNU 4.3+.

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

Simples o suficiente se você estiver familiarizado sed; comentou para quem não é:

# 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

Teste:

% 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 algumas (todas?) Versões do sedpermitem usar a cadeia nula como um nome de rótulo. Se você conseguir que isso funcione aqui, você economizará dois bytes. Na verdade, não tenho certeza se o rótulo é necessário; a menos que eu tenha perdido alguma coisa, a primeira linha é idempotente; portanto, você poderá voltar ao início do programa em vez de precisar de um rótulo.

@ ais523 Eu também pensava assim, mas evidentemente não funciona nas versões BSD. A página do manual diz "Se nenhum rótulo for especificado, ramifique até o final do script" e até isso não estava funcionando quando tentei.
22717 Kevin

O GNU sed permite que um rótulo seja apenas :(mais um bug usado como recurso); nesse caso, o te b! comandos saltam para a posição do rótulo. Além disso, um código sed deve funcionar para pelo menos uma versão do sed, semelhante a outros idiomas, para que você não precise criar código que funcione também para o BSD.
seshoumara

2

PHP 7.1, 58 55 54 37 35 bytes

Nota: usa codificação IBM-850

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

Execute assim:

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

Explicação

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

  • Salva 3 bytes usando a codificação IBM-850
  • Salvo um byte, alterando ligeiramente a regex
  • Salva 17 bytes, nova versão sem nomes longos de funções e retorna
  • 2 bytes salvos usando -R(que $argndisponibiliza)

1

Bean , 24 bytes

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 equivalente:

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

Desculpe por pisar no seu pé, Arnauld .

Explicação:

Coloca a primeira linha de entrada como string não formatada ae substitui qualquer dígito seguido por um ou mais! por 1, para que o restante possa ser encontrado evalpor JavaScript.

Experimente a demonstração ou a suíte de testes

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.