Matematik gerçektir. Programlama değil


175

Matematikte ünlem işareti !genellikle faktoring anlamına gelir ve tartışmadan sonra gelir.

Bir ünlem işareti programlanırken !genellikle olumsuzluk anlamına gelir ve bu argümandan önce gelir.

Bu zorluk için bu işlemleri yalnızca sıfıra ve bire uygulanacaktır.

Factorial
0! = 1
1! = 1

Negation
!0 = 1
!1 = 0

Sıfır veya daha fazla !'s dizisini alın , ardından 0veya 1, ardından sıfır veya daha fazla !' s ( /!*[01]!*/) ile takip edin.
Örneğin, giriş olabilir !!!0!!!!ya da !!!1ya da !0!!ya da 0!ya da 1.

!'Önce lar 0ya 1olan negations ve !sonra s' faktoriyel vardır.

Faktoring, olumsuzluktan daha yüksek önceliğe sahiptir, bu nedenle faktörler her zaman önce uygulanır.
Örneğin, !!!0!!!!gerçekten anlamına gelir !!!(0!!!!)veya daha iyisi !(!(!((((0!)!)!)!))).

Bütün faktörlerin ve olumsuzlukların sonuçta ortaya çıkan uygulamasını çıkarınız. Çıkış her zaman 0veya olacaktır 1.

Test Kılıfları

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

Bayt cinsinden en kısa kod kazanır.


18
Fakat 0! = 1!, Peki birden fazla faktörü ele almanın amacı nedir?
boboquack

30
@boboquack Çünkü zorluk budur.
Calvin'in Hobileri,

11
? <= '1'; ... php cinsinden zamanın% 75'ini düzelt.
17’de,

10
Burada yanlış olabilirim, ancak basitçe çıkarılıp 1 ile değiştirildikten sonra herhangi bir factorial ile bir sayı olamaz mı? 0 gibi !!!! = 1 !! = 0 !!!!!!!! = 1 !!! = 1! = 0! = 1 etc
Albert Renshaw

2
@AlbertRenshaw Bu doğru.
Calvin'in Hobileri

Yanıtlar:


43

Mathematica, 25 17 bayt

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

Bir kullanıcı komut isteminden girdi alır. Mathematica'nın notebook ortamını örtük baskı için alıyor. Komut satırı betiği yapmak için, içine sarın Print[...]veya bağımsız bir işlev haline getirmek için (daha sonra istemden girdi alan) ekleyin &.

Mathematica, gerekli operatörlerin her ikisine de sahiptir (gerekli önceliğe sahip), bu nedenle girişi ("tarafından otomatik olarak yapılır Input[]) " "değerlendirebiliriz" , ancak mantıksal olumsuzlama operatörü tamsayılar üzerinde çalışmaz (bu nedenle değerlenmeden kalır). !xSonuçta bir sol varsa , onunla değiştiririz 1-x.

Değerlendirme hakkında birkaç eğlenceli gerçek:

  1. Mathematica aslında aynı zamanda!! hesaplayan n*(n-2)*(n-4)*..., ancak uyguladığı 0veya 1hala verdiği çift ​​faktörlü bir operatöre sahiptir , bu 1yüzden 0!!!!!aslında olarak ayrıştırılacağı önemli değildir ((0!!)!!)!.
  2. Mathematica ayrılsa !0ve !1değerlenmemiş olsa da , bunun !kendinin ters olduğunu biliyor , bu yüzden tüm lider çiftleri otomatik olarak iptal edecek !. Sonra ToExpressionbiz ediyoruz hep biriyle sol 0, 1, !0, !1.

3
Ne zamandan beri bir REPL pasajına varsayılan olarak izin verildi?
LegionMammal978

2
@ LegionMammal978 Görünüşe göre Aralık 2015'ten beri, ama unutmaya devam ediyorum. Dürüst olmak gerekirse, girişin bellekte bir yerde depolanmış olduğunu varsaymaması, bu bir "pasaj" değildir. Üstelik, notebook ortamının örtük çıktılı bir dile sahip olmasından çok farklı olmadığını varsayalım.
Martin Ender

Merak ediyorum, bir meta link sağlanabilir mi? (Orada bilgi bulmaya çalışıyorum, SE Q&A formatının başka bir sorunu daha stresli ...)
LegionMammal978

@ LegionMammal978 zaten cevabında.
Martin Ender

Saf ksh çözümü x=${x/[01]!*/1};echo $(($x))- uygun bir cevap göndermesine izin verilmiyor :(
DarkHeart

28

[Bash] + Unix yardımcı programları, 21 17 bayt

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

Bu bir dosyaya kaydedilmeli ve bir program olarak çalıştırılmalıdır. Komutu doğrudan komut satırından girmeye çalışırsanız, işe yaramaz çünkü !! bash etkileşimli modunda geçmiş sübstitüsyonun etkinleştirilmesi nedeniyle genişletilir. (Alternatif olarak, geçmiş değişimini ile devre dışı bırakabilirsiniz set +H.)

Test durumu çalışır:

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

Eski versiyon işe yarıyor, bu işe yaramıyor
İnekler,

TIO bağlantısını kullandım
Cows

@KritixiLithos Linux kutumda denediğimde iyi çalıştı. Sorun, görünüşe göre simüle edilmiş giriş hattının sonunda TIO'nun yeni bir hat gerektirmesiydi. Bu kafa karıştırıcı bir durum, bu yüzden TIO bağlantısını çıkardım. Eğer orada denemek istiyorsanız, işte tekrar bağlantı (ancak test etmek için girişi değiştirirseniz, girişin sonuna yeni bir satır eklemeyi unutmayın): tio.run/nexus/bash#@1@cmqJQrK @ nqKilom @ oX5OU / P @ /…
Mitchell Spector

2
Ama ya biri kaçarsa mkdir -p 's/.!!'{bunch,of,different,directories}\$/1? Ardından Pathname Expansion'ı elde edersiniz ve Sed, standart girdi okumak yerine, dizinmiş gibi dosyalar gibi okunmaya çalışır ve hiçbir şey çıkarmaz! :)
Wildcard

1
@Wildcard Tamamen katılıyorum. Yapım komut dosyalarında, böyle durumlarda her zaman tırnak kullanırım. (Bu durumda, aslında sadece * 'dan kaçmak yerine baştan sava iki tırnak koyardım. Ters eğik çizgi kullanmaktan okumak kolaydır, ve bazı özel karakterlerin bulunma ihtimalini de önler.)
Mitchell Spector

22

Retina , 20 15 14 bayt

Leo'ya 1 byte kaydettiğin için teşekkürler.

0!
1
!!

^1|!0

Çevrimiçi deneyin!

açıklama

0!
1

Çevirin 0!içine 1. Diğer izleri umursamayız !, sonuçta elde edilen sayı, tüm factorialleri uyguladığımız gibi aynıdır.

!!

Olumsuz çiftleri iptal et. Bu, bazı faktörleri de iptal edebilir, ancak bu konu dışı.

^1|!0

Bu regex'in eşleşme sayısını sayın ya 1da 0bu istenen sonucu verir.


Aynı bytecount için alternatif bir çözüm: \d.+...
İnekler

@KritixiLithos Bunu tamamen engellemenin bir yolunu buldum.
Martin Ender

Sen kaldırabilirsiniz ^önce!0
Leo

17

Grime , 14 12 9 bayt

e`\0!~\!_

Çevrimiçi deneyin!

açıklama

Bu, girdiyi bir kalıpla 1eşleştirir , eşleşme 0için yazdırır ve eşleşme olmaz.

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

Fikir şudur. Giriş bir rakamla başlıyorsa, özyinelemeli kısım \!_her zaman başarısız olur ve bir \0!taneye sahip olmadıkça başarılı olur 0. Xor, giriş tek olmadığı sürece başarılı olur 0. Girdi a ile başlarsa !, o \0!zaman daima başarılı \!_olur ve özyinelemeli maç başarılı olursa başarılı olur. Onların xor özyinelemeli maç başarısız olduğunda tam olarak başarılı, bu yüzden onu olumsuzlar.


16

Brainfuck, 85 72 (84) bayt

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

sayısal olarak geri dönmek

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

ASCII metni için. > bellek sarılmasını önlemek için önceden eklenmiş olabilir.

Çevrimiçi deneyin!


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

Veya metin yanıtı için son satırı yerine

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

14

Brainfuck - birçok bayt (232 bayt)

Açıkça kod golf kazanmak için yanlış bir dil. Temelde bu esolang kullanan birinin eksikliğini fark ettim. İyi bir çevrimiçi tercüman bf yorumlayıcısı var veya programın bu bf görüntüleyiciyi kullanarak ne yaptığını gerçekten izleyebilirsiniz .

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

3
Seni deli adam!!
Almo

Sevdim, bunu malbolge'da yapabilir misin? XD
Stefan Nolde

Bilgi: Aşağıda çok daha kısa çözümler var.
user202729

14

Python, -44-42 bayt

Zgarb sayesinde 2 bayt kaydedildi!

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

Adım adım:

  1. x[-1]!='0'
    eğer xile biter 1ya !xile bitmez 0, faktöryel kısmı değere sahip olmalıdır 1, başka0
  2. ^len(x.rstrip('!'))%2
    xor'ın mülkiyetini "şartlı değil" olarak sömürme. Bu durumda koşul, ilk !s'nin uzunluğunun tuhaf olmasıdır. Bununla birlikte, .rstripsayıyı dizgeden çıkarmaz , böylece hesaplanan uzunluk 1 ile dengelenir, bu nedenle koşul tersine çevrilir
  3. Adım 2'de 1 ile telafi değiştirilerek düzeltilir !=için ==1. adımda Zgarb 2 bayt tasarruf fark karşılaştırma operatörü kullanılarak yerine başka bir inversiyon uygulanması önerilmektedir.

Çevrimiçi deneyin!


Girişinde başarısız !!0; şu anda geri dönüyor 1.
Value Ink,

@ValueInk şu anda çalışıyor olmalı
busukxuan

1
lambda x:(x[-1]=='0')^len(x.rstrip('!'))%2Fazladan inversiyonu önler.
Zgarb

15
44 çarpı hala düzenli 44
Rɪᴋᴇʀ

3
Bence kullanılan yazı tipinde bir çarpı 44'ün çarpı görünmediğini belirtiyor ... :) Çarpıyan kısım 4'lerin yatay kısmıyla örtüşüyor.
JeffC

13

JavaScript (ES6), 43 41 29 bayt

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

Regex olmayan yöntem ( 41 31 bayt)

Aşağıda benim ilk yaklaşımım. Biraz daha ilginç, ama bu artık önemli ölçüde (10 bayt kaydedilir) bile Neil tarafından önemli bir optimizasyon sonrasında hala biraz daha uzun .

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

Test durumları


Yalnızca senin olmayan regex yönteminden 10 bayt kaydedebilir, bu nedenle çok uzun hala: f=([c,...s])=>1/c?c|s>'':1-f(s).
Neil

@Neil Zaten benim ilk denememden çok daha iyi olduğu için, önerinizi dahil etme özgürlüğünü kullandım.
Arnauld

Ha, ben de aynı şeyi düşündüm ama sen daha iyi golf oynadın. :)
Devsman

11

Jöle , 5 bayt

VeMḂ$

Çevrimiçi deneyin!

Bir dize bekliyor Monadic işlevi. Önde gelen girişler !a a 1yol boyunca STDOUT'a basılmasına neden olur , bu yüzden verdiğim TIO bağlantısı, ilk çıkış çizgisinin altındaki giriş-çıkış çiftlerini basan bir test kablo demetidir.

Nasıl?

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 bayt

Kod:

.V¹'!ÜgG_

CP-1252 kodlamasını kullanır . Çevrimiçi deneyin! veya Tüm test durumlarını doğrulayın!

Açıklama:

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

Biraz garip bir yaklaşım, ama kısa ve işe yarıyor.

0$
!1
!!

^\d

İlk iki satır ile biz bir bitiş yerini 0ile !1: Bu değiştirme ile artık haneli bizim dize parçası itibaren 1'e eşit olduğunu biliyoruz.

Sonraki iki satırda, çiftleri kaldırın !: çift olumsuzlama kendini siliyor ve biz zaten önceki adımla ilgili faktoringi açıkladık.

Son satır, dizenin başlangıcındaki bir rakamla eşleştirin ve eşleşme sayısını döndürün: Negatiflerin tümü elenirse bir eşleşme buluruz (ve bunun 1'e eşit olduğunu bilmeden önce söylediğimiz gibi), eğer hala Bir olumsuzlama bu eşleşmeyecek.

Çevrimiçi deneyin!


1
Son hane her zaman mutlaka 1 olmaz mı? Bu durumda, 1yerine kullanabilirsiniz \d.

1
@ ais523 hayır, çünkü ilk bölüm sadece son 0 ile değiştirilecek, bu nedenle örneğin giriş 0!son satıra kadar değişmeden kalacaktır
Leo

1
Gerçekten güzel bir çözüm, iyi iş! :)
Martin Ender

10

Ruby, 12 + 1 = 39 24 15 13 bayt

-nBayrağı kullanır . -9 baytlık @GB'ye teşekkürler !

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

Sadece uzunluğu kontrol ettiğiniz için, önce "! 0" 'ı kontrol etmek yerine izleyen sıfırı ve ondan sonra tek sıfırı silebilirsiniz.
GB

@GB bu harika bir fikir! Ancak, regex'imi satır sonu 0 veya satır sonu aramaya göre değiştirerek daha da kısa olan bir çözüm buldum
Value Ink

Sonra sadece '!' İzini kontrol edebilirsiniz. veya sıfır veya satırın sonu: p ~ /! + $ | 0 $ | $ /% 2 sadece 14 bayttır.
GB

Ve sonra "0 $ | $" başka bir bayttan tasarruf etmek için "0? $" Olabilir.
GB

1
Daha da iyisi !*$ikiye kısaltmak!
Value Ink

9

Perl , 20 bayt

19 bayt kodu + -pbayrak.

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

Çevrimiçi deneyin!

Perl'in ihmali döner undefya da sonuç iadelerini doğrulamak için 1kullanırım . Bunun yanında, kod hakkında söylenecek fazla bir şey yok.0+0+undef0


2
Sadece tam olarak bunu yazdım. + 1'leyin.
primo

@primo Bunu bir kez olsun geride bıraktığım 20 byte değilim! Thanks :)
Dada

9

C, 68 62 61 53 bayt

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

Biraz suistimal ile birkaç bayt sıkılmış

Çevrimiçi deneyin!


1
Sanırım intfonksiyondan onu kaldırabilir ve *a==33için değiştirebilirsiniz *a<34.
İnekler

Ne yazık ki *a%2daha kısadır*a-48
İnekler, 18

Bahşiş için teşekkürler. Ayrıca geri dönüşün etrafındaki parantezleri söküp atayarak başka bir karakteri ortadan kaldırabiliyordum.
Ahemone,

Ben 1 byte tasarruf for(;*a<34;a++)kısaltılabilir eminimfor(;*a++<34;)
Albert Renshaw 22

Maalesef şartlı ifade olarak her zaman çalışacak ve dönüş göstergesinde işaretçi çok ileri itecektir.
Ahemone

6

Perl 6 , 32 28 23 bayt

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

Nasıl çalışır

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

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

fBir dize alan ve bir karakter döndüren bir işlevi tanımlar . Çevrimiçi deneyin!

açıklama

Üç durum vardır: giriş ile başlar !, giriş uzunluğu 1'dir ve diğer her şey.

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

Dönüş türü olarak tamsayı dize geçiş yapma: f('!':b)=[1,0]!!f b;f"0"=0;f _=1.
nimi

6

Befunge, 24 bayt

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

Çevrimiçi deneyin!

Bu !stdin'den okunan karakter sayısını sayarak başlar . Bir değil ilk karakter !irade olması ya 0ya 1, ama test sürecinde yönelik !bunu yapma, 33 çıkarılır olacak ya bir olacak ya 15 ya Sonra bir tane daha karakter okuma 16., !veya EOF ve Bunun 0'dan küçük olması durumunda karşılaştırın (örn. EOF).

Bu üç veri noktasını alarak - ünlem işareti ( c ), sayı değeri, ( d ) ve dosya sonu koşulu ( e ) - sonucu şu şekilde hesaplayabiliriz:

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

Hane değerinin dosya sonu koşulu ile çarpılması, hanenin a ile takip edilmesi durumunda sıfıra dönüştürüleceği anlamına gelir !, bu şekilde a ile aynı modulo2 değerini 1(16'ya dönüştürüldüğünü hatırlar) verir. Fakat modulo 2'yi uygulamadan önce, modulo 2 sonucunu !önekleri kadar etkili bir şekilde değiştiren ilk ünlem sayımını ekledik. Ve nihayet sonuç değiliz çünkü temel değerlerimiz ihtiyaç duyduğumuz şeyin karşıt 0ve değerleridir 1.

Koda daha ayrıntılı bir şekilde bakmak:

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

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

Çevrimiçi deneyin!

Her lider !, olarak yapılan ifadenin geri kalanı için çıktıyı tamamlar 1-. Bir basamağa kadar çevirmeye devam ediyoruz. Kalan sadece "0"ise, sonuç 0 olur. Aksi takdirde, a 1veya bir veya daha fazla takip edilir !, sonuç 1 olur.


5

Ruby, 22 21 20 bayt

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

Açıklama:

  • İlk vaka, biraz '!' sonunda, onları çıkarın, uzunluk modulo 2 olsun.
  • İkinci durumda, '!' Yok, eğer son karakter sıfırsa onu kaldırın, uzunluk modulo alın
  • Son karakter 1 ise, ilk duruma geri dön

(-1 bayt @ Değer Mürekkep fikrini çalmak)


Müthiş, bu bilmeceye 10 dakika baktım ama fazla zamanım olmadı ve sonra unutmuştum Şimdi aktif sorularda tekrar tespit ettim ve böyle güzel bir yaklaşım görmekten memnun oldum.
akostadinov

4

Jöle , 8 bayt

œr”!LḂ=V

Çevrimiçi deneyin!

Bu, bir argüman alan ve dönüş değeri ile dönen bir işlevdir (monadik bağlantı). (Aynı zamanda sık sık yan etkisi olarak standart çıktıya önemsiz yazılar yazar, ancak bunu umursamıyoruz.)

açıklama

œ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

Birincisi, girdi her zaman !bir sayı, ardından bir rakam, ardından daha fazlası !olmak üzere, izlemeyi silip !uzunluğu alırsak !, programda bir artı ile sonuçlanacağımıza dikkat edin. Bunun eşliğini almak, tek bir sayı varsa 0, çift sayı ise !1 olacaktır !. 0 ile karşılaştırmak bir "değil" işlevi iken 1 ile karşılaştırmak ise kimlik işlevidir; bu nedenle , sorunun "NOT operatörleri olarak œr”!LḂ=lider davranmasını" etkili bir şekilde uygular !.

İkinci yarıda ise, factorials ile uğraşmak, Jelly'de yapılan !bir faktoring çalışmasıdır, bu nedenle eğer programın öncüsü yoksa !, sorunu doğrudan basit bir şekilde eval( V) çözebiliriz . Programın önderliği varsa !, bunlar 0 değerini (muhtemelen birden çok kez) alarak, standart çıktıya yazdırılacak ve bir basamak göründüğünde atılacak olan 1 dönüş değeri üretecek şekilde yorumlanacaktır; bu nedenle, soruya sunduğum işlevin geri dönüş değeri üzerinde etkisi yoktur.


Çok güzel ve harika bir açıklama.
ElPedro

4

Python, 38 bayt

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

TryItOnline!

İsmi açıklanmayan fonksiyonu bir giriş dizesi alarak sve bir tamsayı dönen 0ya 1.

s[1::2] İndeks 1'de başlayan ve iki adım adım büyüklüğüne sahip olan giriş dizesinin bir dilimidir:
'Like this' -> 'ieti'

s[::2] benzer ancak 0 varsayılan dizininde başlar:
'Like this' -> 'Lk hs'

Test (s[1::2]>s[::2]), 0-temelli indeksinin '0'ya '1'da tek olup olmadığını, yani tamamlamamız gerekip gerekmediğini kontrol eder.
Bu, dizelerin sıralamasını, boş dizgiden daha büyük boş olmayan herhangi bir dizeyle ve ASCII dizilimi ile, sözlüksel olarak kontrol ettiği için çalışır '1'>'0'>'!'. Bu basitten daha kısa bir bayttır s.index(max(s))%2.

ord(s[-1])%2Son karakter değilse kontrol eder '0', bir tamsayı (geçerli giriş için) ve sonuçlar, (aynı uzunlukta ise (s[-1]!='0')bir mantıksal dönmek).
Giriş son karakteri, Bunun nedeni, çalışır s[-1]bir olacaktır '0', '1'ya da '!'0, 1 ve 1 modül 2 olan ASCII kod sırası ile 48, 49 ve 33 işaret sahip olan,.

Ardından ^, yukarıdaki iki değer üzerinde bitsel bir özel işlem veya işlem gerçekleştirir, bir girdi, doğru olanı bir tamsayı olduğundan tamsayı döndürür. Sol Doğru ise, sağın tamamlayıcısı, sol Yanlış ise sağ, gerektiği şekilde iade edilir.


4

Java 7, 105 82 81 bayt

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

Çevrimiçi deneyin!

Eski regex-ish çözümü

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^=1süper zeki. Görmedim, hiç kullanılmamış bir operatör.
Addison Crump,

3

CJam , 12 11 bayt

r_W='0=!\~;

Çevrimiçi deneyin! Test paketi ( 1her doğru test durumu için a yazdırır ).

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 bayt

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

Çevrimiçi deneyin!

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

Toplu iş, 62 bayt

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

STDIN'de girişi ele alır. Batch aslında !bu zorluk için liderlerin doğru olduğunu anlıyor , ancak !izlemenin ele alınması gerekiyor, bu üç adım atıyor:

  • Değişim 0!için1
  • Çiftlerini sil !!(bu !!rakamlardan önce s için de güvenlidir )
  • Kalan izleri silin !(şu ana kadar yalnızca bir saat sonra olabilir 1)

2

IBM / Lotus Notes Formülü - 77 bayt

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

Notes Formülü için TIO yoktur, bu nedenle tüm test vakalarının ekran görüntüsü aşağıda gösterilmiştir:

Tüm Test Kılıfları

Nasıl çalışır

@Eval() bir dizeyi ifade olarak değerlendirir

Öncelikle alan (giriş) giriş dizesi olmadığını kontrol aiçeren 1veya 0ve bir dize olacaktır hangi hangisi solundaki tüm karakterleri almak !karakterler. Kaç tane umrumda değil. @Eval()bununla ilgilenecek.

Daha !sonra dizenin sonunda bir tane olup olmadığını göreceğiz . Biz ekleme varsa 1için !(dize 0!ve 1!- kaç önemli değil her ikisi de 1 olduğu !değil bir nedeni, aksi takdirde biz değişmeden son karakteri ekler sonunda orada karakter) !ve a ya olabilir 1veya 0.

Şimdi önde gelen çevrimleri içeren bir dizgenin yanı sıra herhangi bir faktör karakterinin olup olmadığı ile tanımlanan bir sayıya sahibiz, böylece bunu besleyebilir @Eval()ve sonuçları alabiliriz.


2

sed, 36 33 31 bayt

Saf sed, hiçbir bc / shell utils. GNU'da çalışır sed <4.3; BSD ve GNU 4.3+ sürümlerinde 33 bayt.

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

Aşina olduğunuzda yeterince basit sed; olmayanlar için yorum yaptı:

# 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

Ölçek:

% 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 bazı (tümü?) Sürümleri sed, boş dizeyi etiket adı olarak kullanmanıza izin verir. Bunu burada çalıştırabilirsen, iki bayt kurtarır. Aslında, etiketin gerekli olduğundan bile emin değilim; Bir şeyi kaçırmadığım sürece, ilk satır kesin değildir, bu nedenle bir etikete ihtiyaç duymak yerine programın başlangıcına geri dönebilirsiniz.

@ ais523 Ben de öyle düşündüm, ama açıkça BSD versiyonlarında çalışmıyor. Man sayfası "Eğer bir etiket belirtilmemişse, betiğin sonuna dallanır" der ve denedim bile çalışmadı.
Kevin,

GNU sed bir etiket sadece olmasına izin yok :bu durumda hem, (özellik olarak alınan bir hata daha fazlası) tve b! komutlar etiketin konumuna atlar. Ayrıca, bir sed kod, diğer dillere benzer şekilde sed'in en az bir sürümü için çalışmalıdır, böylece BSD için de çalışan kod oluşturmanız gerekmez.
seshoumara

2

PHP 7.1, 58 55 54 37 35 bayt

Not: IBM-850 kodlamasını kullanır

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

Bu şekilde koş:

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

açıklama

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.

Düzenlemeler

  • IBM-850 kodlamasını kullanarak 3 bayt kaydedildi
  • Düzenli ifadeyi biraz değiştirerek bir bayt kaydedildi
  • 17 byte kaydedildi, uzun işlev isimleri olmadan yeni sürüm ve dönüş
  • Kullanılarak 2 bayt Kaydedilen -R(ki yapar $argnedilebilir)

1

Fasulye , 24 bayt

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

Eşdeğer JavaScript:

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

Parmaklarına bastığım için üzgünüm, Arnauld .

Açıklama:

İlk girdi satırını biçimlendirilmemiş bir dizge olarak aalır ve geri kalanı JavaScript ile yazabilmek için bir veya daha fazla !olan herhangi bir rakamı değiştirir .1eval

Demoyu veya test takımını deneyin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.