Matematika adalah fakta. Pemrograman tidak

176

Dalam matematika tanda seru !sering berarti faktorial dan muncul setelah argumen.

Dalam pemrograman tanda seru !seringkali berarti negasi dan muncul sebelum argumen.

Untuk tantangan ini, kami hanya akan menerapkan operasi ini ke nol dan satu.

Factorial
0! = 1
1! = 1

Negation
!0 = 1
!1 = 0

Ambil string nol atau lebih !, diikuti oleh 0atau 1, diikuti dengan nol atau lebih !( /!*[01]!*/).
Misalnya, inputnya mungkin !!!0!!!!atau !!!1atau !0!!atau 0!atau 1.

The !'s sebelum 0atau 1yang negations dan! berikutnya adalah faktorial.

Faktorial lebih diutamakan daripada negasi sehingga faktorial selalu diterapkan terlebih dahulu.
Misalnya, !!!0!!!!benar-benar berarti !!!(0!!!!), atau lebih baik lagi !(!(!((((0!)!)!)!))).

Keluarkan aplikasi yang dihasilkan dari semua faktorial dan negasi. Output akan selalu 0atau 1.

Uji Kasus

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

Kode terpendek dalam byte menang.

Hobi Calvin
sumber
18
Tapi 0! = 1 !, jadi apa gunanya menangani banyak faktorial?
boboquack
30
@ Boboquack Karena itu tantangannya.
Calvin Hobbies
11
<? = '1'; ... koreksi 75% dari waktu di php.
aslum
10
Saya mungkin salah di sini tetapi tidak dapat nomor apa pun dengan faktorial setelah itu hanya dihapus dan diganti dengan 1? Suka 0 !!!! = 1 !! = 0 !!!!!!!! = 1 !!! = 1! = 0! = 1 dll
Albert Renshaw
2
@AlbertRenshaw Benar.
Calvin Hobi

Jawaban:

43

Mathematica, 25 17 byte

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

Mengambil input dari prompt pengguna. Mengasumsikan lingkungan notebook Mathematica untuk pencetakan tersirat. Untuk membuatnya menjadi skrip baris perintah, bungkus dalam Print[...]atau untuk membuatnya menjadi fungsi tanpa argumen (yang kemudian mengambil input dari prompt), tambahkan &.

Mathematica memiliki kedua operator yang diperlukan (dengan prioritas yang diperlukan), jadi kita bisa "mengevaluasi" input (yang dilakukan secara otomatis oleh Input[]), tetapi operator negasi logis tidak bekerja pada bilangan bulat (sehingga akan tetap tidak dievaluasi). Jika ada yang !xtersisa di hasilnya, kami ganti dengan 1-x.

Beberapa fakta menyenangkan tentang evaluasi:

  1. Mathematica sebenarnya juga memiliki operator faktorial ganda !!, yang menghitung n*(n-2)*(n-4)*..., tetapi diterapkan 0atau 1masih memberikan 1, sehingga tidak masalah yang 0!!!!!benar-benar akan diuraikan ((0!!)!!)!.
  2. Meskipun Mathematica pergi !0dan tidak !1dievaluasi, ia tahu bahwa !itu terbalik sendiri, sehingga secara otomatis akan membatalkan semua pasangan pemimpin !. Setelah ToExpressionkita selalu meninggalkan dengan salah satu 0, 1, !0, !1.
Martin Ender
sumber
3
Sejak kapan cuplikan REPL diizinkan secara default?
LegionMammal978
2
@ LegionMammal978 Rupanya sejak Desember 2015, tapi saya terus lupa tentang itu. Agar adil, ini bukan "cuplikan" karena tidak menganggap bahwa input sudah tersimpan di suatu tempat di memori. Dan dengan asumsi lingkungan notebook tidak jauh berbeda dari memiliki bahasa dengan output implisit.
Martin Ender
Hanya ingin tahu, bisakah tautan meta disediakan? (Mencoba untuk menemukan informasi ada stres, masalah lain dari format T&J SE ...)
LegionMammal978
@ LegionMammal978 itu sudah ada dalam jawabannya.
Martin Ender
Solusi ksh murni x=${x/[01]!*/1};echo $(($x))- tidak diizinkan memposting jawaban yang tepat :(
DarkHeart
28

[Bash] + Utilitas Unix, 21 17 byte

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

Ini harus disimpan dalam file dan dijalankan sebagai program. Jika Anda mencoba memasukkan perintah langsung dari baris perintah, itu tidak akan berhasil karena !! diperluas karena penggantian sejarah diaktifkan dalam mode interaktif bash. (Atau, Anda dapat menonaktifkan substitusi riwayat denganset +H .)

Uji kasus berjalan:

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
Mitchell Spector
sumber
Versi lama berfungsi, yang ini tidak
Sapi dukun
Saya menggunakan tautan TIO
Sapi dukun
@KritixiLithos Ini bekerja dengan baik ketika saya mencobanya di kotak Linux saya. Masalahnya ternyata TIO membutuhkan baris baru di akhir jalur input yang disimulasikan. Ini situasi yang membingungkan, jadi saya mengambil tautan TIO. Jika Anda ingin mencobanya di luar sana, inilah tautannya lagi (tetapi pastikan untuk memasukkan baris baru di akhir input jika Anda mengubah input untuk mengujinya): tio.run/nexus/bash#@1@cmqJQrK @ nqKilom @ oX5OU / P @ /…
Mitchell Spector
2
Tetapi bagaimana jika seseorang telah berlari mkdir -p 's/.!!'{bunch,of,different,directories}\$/1? Maka Anda akan mendapatkan Pathname Expansion dan Sed akan mencoba membaca direktori seolah-olah itu file, bukannya membaca input standar, dan itu tidak akan menghasilkan apa-apa! :)
Wildcard
1
@ Kartu Kredit saya setuju sepenuhnya. Dalam skrip produksi, saya selalu menggunakan kutipan dalam situasi seperti ini. (Dalam hal ini, saya benar-benar akan menempatkan tanda kutip ganda di sekitar argumen untuk sed, daripada hanya melarikan diri dari *. Lebih mudah dibaca daripada menggunakan backslash, dan itu menghindari kemungkinan kehilangan beberapa karakter khusus.)
Mitchell Spector
22

Retina , 20 15 14 byte

Terima kasih kepada Leo karena telah menghemat 1 byte.

0!
1
!!

^1|!0

Cobalah online!

Penjelasan

0!
1

Berubah 0!menjadi 1. Kami tidak peduli tentang trailing lain !, angka yang dihasilkan sama dengan jika kami telah menerapkan semua faktorial.

!!

Batalkan pasangan negasi. Ini juga dapat membatalkan beberapa faktorial, tetapi itu tidak relevan.

^1|!0

Hitung jumlah kecocokan regex ini, yang merupakan 1atau 0dan memberikan hasil yang diinginkan.

Martin Ender
sumber
Solusi alternatif untuk jumlah yang sama: \d.+...
Sapi dukun
@KritixiLithos Menemukan cara untuk menghindari itu sama sekali.
Martin Ender
Anda dapat menghapus ^sebelumnya!0
Leo
17

Grime , 14 12 9 byte

e`\0!~\!_

Cobalah online!

Penjelasan

Ini cocok dengan input terhadap suatu pola, mencetak 1untuk kecocokan dan 0tanpa kecocokan.

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

Idenya adalah ini. Jika input dimulai dengan digit, maka bagian rekursif \!_selalu gagal, dan \0!berhasil kecuali kita memiliki satu 0. Xor mereka berhasil kecuali inputnya tunggal 0. Jika input dimulai dengan a !, maka \0!selalu berhasil, dan \!_berhasil jika kecocokan rekursif berhasil. Xor mereka berhasil tepat ketika pertandingan rekursif gagal, sehingga meniadakannya.

Zgarb
sumber
16

Brainfuck, 85 72 (84) byte

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

untuk mengembalikan secara numerik, atau

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

untuk teks ASCII. > juga dapat diawali untuk menghindari pembungkus memori.

Cobalah 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

Atau untuk respons teks, ganti baris terakhir dengan

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

Brainfuck - cara menuju banyak byte (232 byte)

Jelas bahasa yang salah untuk menang dalam kode golf. Terutama saya perhatikan kurangnya siapa pun yang menggunakan esolang ini. Ada juru online yang baik bf interpeter atau Anda dapat benar-benar menonton apa program ini menggunakan ini bf visualisator .

>>>>>,[>+++[<---------------->-]<<<<<<[-]+>[-]>>>>[-[<<[>+<<<<->>>[<<+>>-] ]<<[>>+<<-]<[>>+<<[-]]>>>>>[-]]<<<<<[>>>++<<<-]>+>>>>[-]]<<<<-[>>+<<[-]]>>>>,]<<->[<[-]+>[-]]<<[<[-]>>[<<+>>[-]]+<<[->>-<<]>-]>>[-]+++[<++++++++++++++++>-]<.
CodyCode
sumber
3
Kamu orang gila !!
Almo
Senang, bisakah Anda melakukannya di malbolge? XD
Stefan Nolde
Informasi: Ada solusi terlalu pendek di bawah ini.
user202729
14

Python, -44-42 byte

Disimpan 2 byte berkat Zgarb!

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

Selangkah demi selangkah:

  1. x[-1]!='0'
    jika xdiakhiri dengan 1atau !xtidak berakhir dengan 0, bagian faktorial harus memiliki nilai 1, jika tidak0
  2. ^len(x.rstrip('!'))%2
    mengeksploitasi properti xor sebagai "tidak bersyarat". Kondisi dalam kasus ini adalah jika panjang inisial !adalah ganjil. Namun, .rstriptidak menghapus nomor dari string sehingga panjang yang dihitung diimbangi oleh 1, karena itu kondisinya terbalik
  3. Offset 1 dalam langkah 2 diperbaiki dengan mengubah !=ke ==dalam langkah 1. Zgarb menyarankan menggunakan operator pembanding yang berbeda daripada menerapkan inversi lain, menghemat 2 byte.

Cobalah online!

busukxuan
sumber
Gagal pada masukan dari !!0; saat ini kembali 1.
Nilai Tinta
@ValueInk seharusnya bisa berfungsi sekarang
busukxuan
1
lambda x:(x[-1]=='0')^len(x.rstrip('!'))%2menghindari inversi tambahan.
Zgarb
15
dicoret 44 masih teratur 44
Rɪᴋᴇʀ
3
Saya pikir dia menyatakan bahwa tanda silang 44 pada font yang digunakan tidak terlihat dicoret ... :) Bagian silang tumpang tindih dengan bagian horizontal 4s.
JeffC
13

JavaScript (ES6), 43 41 29 byte

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

Metode non-regex ( 41 31 byte)

Di bawah ini adalah pendekatan awal saya. Ini sedikit lebih menarik, tetapi secara signifikan lebih lama masih sedikit lebih lama bahkan setelah optimasi yang signifikan oleh Neil (10 byte disimpan) .

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

Uji kasus

Arnauld
sumber
Saya hanya dapat menyimpan 10 byte dari metode non-regex Anda, jadi masih terlalu lama: f=([c,...s])=>1/c?c|s>'':1-f(s).
Neil
@Neil Karena itu jauh lebih baik daripada upaya pertama saya, saya mengambil kebebasan untuk memasukkan saran Anda.
Arnauld
Ha, saya punya ide yang sama tetapi Anda bermain golf lebih baik. :)
Devsman
11

Jelly , 5 byte

VeMḂ$

Cobalah online!

Fungsi monadik mengharapkan string. Input dengan !penyebab utama a1 dicetak ke STDOUT di sepanjang jalan, jadi tautan TIO yang saya berikan adalah test harness yang mencetak pasangan input-output di bawah baris pertama output.

Bagaimana?

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.
Jonathan Allan
sumber
10

05AB1E , 9 byte

Kode:

.V¹'!ÜgG_

Menggunakan pengkodean CP-1252 . Cobalah online! atau Verifikasi semua kasus uji!

Penjelasan:

.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
Adnan
sumber
10

Retina , 13 byte

Pendekatan yang agak aneh, tapi pendek dan berhasil.

0$
!1
!!

^\d

Dengan dua baris pertama kita mengganti akhiran 0dengan !1: dengan penggantian ini kita sekarang tahu bahwa bagian dari string kita dari digit ke depan sama dengan 1.

Berikutnya dua baris, hapus pasangan !: negasi ganda menghapus sendiri, dan kami sudah memperhitungkan faktorial dengan langkah sebelumnya.

Baris terakhir, cocokkan angka di awal string dan kembalikan jumlah kecocokan: jika negasi semuanya dihilangkan kita akan menemukan kecocokan (dan seperti yang kita katakan sebelumnya kita tahu ini sama dengan 1), jika masih ada negasi ini tidak akan cocok.

Cobalah online!

Leo
sumber
1
Bukankah angka terakhir selalu menjadi angka 1? Dalam hal ini, Anda bisa menggunakan 1daripada \d.
1
@ ais523 tidak, karena bagian pertama hanya akan mengganti akhiran 0, jadi misalnya input 0!akan tetap tidak berubah sampai baris terakhir
Leo
1
Solusi yang sangat bagus, kerja bagus! :)
Martin Ender
10

Ruby, 12 + 1 = 39 24 15 13 byte

Menggunakan -nbendera. Berkat @GB untuk -9 byte!

p~/!*$|0$/%2
Nilai Tinta
sumber
Karena Anda hanya memeriksa panjangnya, Anda dapat menghapus trailing nol, alih-alih memeriksa "! 0" terlebih dahulu dan nol tunggal setelahnya.
GB
@ GB itu ide yang bagus! Namun, saya menemukan solusi yang bahkan lebih pendek dengan memodifikasi regex saya untuk mencari posisi 0 atau end-of-line
Value Ink
Maka Anda bisa mengecek untuk mengikuti jejak '!' atau nol atau akhir baris: p ~ /! + $ | 0 $ | $ /% 2 hanya 14 byte.
GB
Dan kemudian "0 $ | $" bisa menjadi "0? $" Untuk menyimpan byte lain.
GB
1
Lebih baik lagi !*$lebih pendek dua!
Nilai Tinta
9

Perl , 20 byte

19 byte kode + -pbendera.

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

Cobalah online!

Negasi Perl kembali undefatau 1, jadi saya gunakan 0+untuk menghitung hasil 0+undefpengembalian 0. Selain itu, tidak banyak bicara tentang kode.

Dada
sumber
2
Baru saja menulis ini. Punya +1.
Primo
@ primo Senang melihat itu untuk sekali waktu saya bukan 20 byte di belakang Anda! Terima kasih :)
Dada
9

C, 68 62 61 53 byte

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

Diperas beberapa byte lagi dengan beberapa penyalahgunaan

Cobalah online!

Ahemone
sumber
1
Saya pikir Anda dapat menghapus intdari fungsi dan Anda dapat mengubah *a==33ke *a<34.
Sapi dukun
Alas *a%2lebih pendek dari*a-48
Sapi dukun
Terima kasih atas tipnya. Saya juga bisa menghilangkan karakter lain dengan menghapus tanda kurung di sekitar kembalinya dan menugaskannya.
Ahemone
Saya cukup yakin for(;*a<34;a++)dapat dipersingkat untuk for(;*a++<34;)menghemat 1 byte
Albert Renshaw
Sayangnya tidak, sebagai pernyataan bersyarat itu akan selalu dijalankan dan akan mendorong pointer terlalu jauh ke depan untuk mengembalikan dereference.
Ahemone
6

Perl 6 , 32 28 23 byte

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

Bagaimana itu bekerja

{                     }  # 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.
seseorang
sumber
6

Haskell , 39 byte

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

Menentukan fungsi f, yang mengambil string dan mengembalikan karakter. Cobalah online!

Penjelasan

Ada tiga kasus: input dimulai dengan !, input memiliki panjang 1, dan yang lainnya.

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'.
Zgarb
sumber
Beralih dari String ke Integer sebagai jenis kembali: f('!':b)=[1,0]!!f b;f"0"=0;f _=1.
nimi
6

Befunge, 24 byte

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

Cobalah online!

Ini dimulai dengan menghitung jumlah !karakter yang dibaca dari stdin. Karakter pertama yang bukan merupakan !salah satu 0atau 1, tetapi dalam proses pengujian untuk !kami akan mengurangi 33, membuatnya menjadi 15 atau 16. Kami kemudian membaca satu karakter lagi, yang akan menjadi !atau EOF, dan bandingkan jika itu kurang dari 0 (yaitu EOF).

Dengan mengambil ketiga titik data - penghitungan seru ( c ), nilai digit, ( d ), dan kondisi akhir file ( e ) - kita dapat menghitung hasilnya sebagai berikut:

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

Mengalikan nilai digit dengan kondisi akhir file berarti itu akan dikonversi menjadi nol jika angka tersebut diikuti oleh a !, sehingga memberikan nilai modulo 2 yang sama dengan 1(yang ingat telah dikonversi ke 16). Tetapi sebelum menerapkan modulo 2, kami menambahkan jumlah tanda seru awal, yang secara efektif mengubah hasil modulo 2 sebanyak !prefiksnya. Dan akhirnya kami bukan hasil karena nilai dasar kami untuk 0dan 1merupakan kebalikan dari apa yang kami butuhkan.

Melihat kode lebih terinci:

~                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.
James Holderness
sumber
6

Haskell , 27 byte

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

Cobalah online!

Masing-masing memimpin ! melengkapi output untuk sisa ekspresi, dilakukan sebagai 1-. Kami terus membalik sampai kami menekan angka. Jika sisanya hanya "0", hasilnya adalah 0. Jika tidak, itu adalah 1atau diikuti oleh satu atau lebih !, sehingga hasilnya adalah 1.

Tidak
sumber
5

Rubi, 22 21 20 byte

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

Penjelasan:

  • Kasus pertama, saya mendapat beberapa '!' pada akhirnya, hapus, dapatkan modulo 2 panjang.
  • Kasus kedua, tidak '!', Jika karakter terakhir adalah nol lalu hapus, dapatkan panjang modulo 2
  • Jika karakter terakhir adalah 1, kembali ke huruf pertama

(-1 byte mencuri ide @Value Ink)

GB
sumber
Luar biasa, saya melihat puzzle ini selama 10 menit tetapi tidak punya banyak waktu dan kemudian melupakannya. Sekarang melihatnya lagi dalam pertanyaan aktif dan senang melihat pendekatan yang bagus.
akostadinov
4

Jelly , 8 byte

œr”!LḂ=V

Cobalah online!

Ini adalah fungsi (tautan monadik) yang mengambil satu argumen dan kembali melalui nilai pengembaliannya. (Ini juga sering menulis sampah ke output standar sebagai efek samping, tetapi kami tidak peduli tentang itu.)

Penjelasan

œ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

Pertama, perhatikan bahwa karena input selalu terdiri dari sejumlah !, diikuti oleh digit, diikuti oleh lebih banyak !, bahwa jika kita menghapus trailing !dan mengambil panjangnya, kita akan berakhir dengan satu ditambah jumlah yang terdepan !dalam program. Mengambil paritas ini akan mengembalikan 0 jika ada angka ganjil !, atau 1 jika ada angka genap !. Membandingkan dengan 0 adalah fungsi "tidak", sedangkan membandingkan dengan 1 adalah fungsi identitas; dengan demikian œr”!LḂ=secara efektif mengimplementasikan bagian "perlakukan !sebagai operator BUKAN" dari pertanyaan.

Sedangkan untuk babak kedua, penanganan faktorial, !adalah operasi faktorial di Jelly, jadi jika program tidak memiliki pengarah !, kita dapat menyelesaikan masalah secara langsung dengan sederhana eval( V). Jika program benar - benar telah memimpin !, mereka akan ditafsirkan sebagai mengambil faktorial dari 0 (mungkin beberapa kali), menghasilkan nilai pengembalian 1, yang akan dicetak ke output standar dan dibuang setelah satu digit terlihat; dengan demikian, mereka tidak berdampak pada nilai pengembalian fungsi yang saya ajukan ke pertanyaan.


sumber
Penjelasan yang sangat bagus dan bagus.
ElPedro
4

Python, 38 byte

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

TryItOnline!

Fungsi tanpa nama mengambil string input sdan mengembalikan integer 0atau 1.

s[1::2] adalah irisan string input yang dimulai pada indeks 1 dan memiliki ukuran langkah dua:
'Like this' -> 'ieti'

s[::2] serupa tetapi dimulai pada indeks default 0:
'Like this' -> 'Lk hs'

Tes (s[1::2]>s[::2])memeriksa apakah indeks berbasis 0 '0'atau '1'ganjil, yaitu jika kita perlu melengkapi.
Ini berfungsi karena urutan string diperiksa secara leksikografis dengan string tidak kosong lebih besar dari string kosong, dan dengan urutan ASCII, jadi '1'>'0'>'!'. Ini adalah satu byte lebih pendek dari yang lebih sederhana s.index(max(s))%2.

The ord(s[-1])%2memeriksa untuk melihat apakah karakter terakhir tidak '0'(untuk input valid), dan menghasilkan integer (sedangkan panjang yang sama (s[-1]!='0')akan kembali boolean).
Ini bekerja karena karakter terakhir dari input, s[-1], akan menjadi '0', '1'atau '!'yang memiliki kode ASCII menunjuk 48, 49, dan 33 masing-masing, yang adalah 0, 1, dan 1 modulo 2.

The ^kemudian melakukan bitwise eksklusif atau operasi pada dua nilai di atas, kembali integer sejak satu input, yang benar, adalah bilangan bulat. Jika kiri adalah Benar komplemen dari kanan dikembalikan, jika kiri adalah Palsu hak dikembalikan, sesuai kebutuhan.

Jonathan Allan
sumber
4

Java 7, 105 82 81 byte

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

Cobalah online!

Solusi regex-ish lama

int a(String a){a=a.replace("0!","1").replaceAll("1.*","1");int b=a.length()-1;return b%2^a.charAt(b)&1;}
Menyodok
sumber
2
c^=1sangat pintar. Itu operator yang tidak digunakan jika saya pernah melihatnya.
Addison Crump
3

CJam , 12 11 byte

r_W='0=!\~;

Cobalah online! Test suite (mencetak a 1untuk setiap test case yang benar).

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.
Martin Ender
sumber
3

Haskell , 67 65 byte

f s|foldr(\_->not)(last s`elem`"1!")$fst.span(<'0')$s="1"|1<3="0"

Cobalah online! Pemakaian:f "!!!0!!!!"

Disimpan dua byte berkat @nimi.

Laikoni
sumber
3

Brainfuck, 115 byte

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

Cobalah online!

Tidak Terkumpul:

% 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
]
sinar
sumber
2

Batch, 62 byte

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

Mengambil input pada STDIN. Batch sebenarnya memahami memimpin !dengan benar untuk tantangan ini, tetapi trailing !perlu ditangani, yang membutuhkan tiga langkah:

  • Ubah 0!ke1
  • Hapus pasangan !!(ini aman untuk !!sebelum digit juga)
  • Hapus sisa jejak !(yang sekarang hanya bisa setelah a 1)
Neil
sumber
2

IBM / Lotus Notes Formula - 77 byte

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

Tidak ada TIO untuk Formula Catatan sehingga tangkapan layar dari semua kasus uji ditunjukkan di bawah ini:

Semua Kasus Uji

Bagaimana itu bekerja

@Eval() mengevaluasi string sebagai ekspresi

Pertama kita periksa apakah string input dalam bidang (input) aberisi 1atau 0dan mengambil semua karakter ke kiri yang mana yang merupakan string !karakter. Kami tidak peduli berapa banyak. @Eval()akan mengurusnya.

Selanjutnya kita melihat apakah ada !di bagian akhir string. Jika ada kita tambahkan 1ke !string ( 0!dan 1!keduanya 1 - tidak masalah berapa banyak !karakter yang ada di akhir) jika tidak, kita menambahkan karakter terakhir tidak berubah karena itu bukan a !dan bisa berupa a 1atau a 0.

Kami sekarang memiliki string yang berisi inversi terkemuka ditambah angka yang ditentukan oleh apakah ada karakter faktorial sehingga kami dapat memberi makan ini @Eval()dan mendapatkan hasil di atas.

ElPedro
sumber
2

sed, 36 33 31 byte

Sed murni, tidak ada peralatan bc / shell. Bekerja pada GNU sed <4.3; 33 byte pada BSD dan GNU 4.3+.

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

Cukup mudah jika Anda terbiasa sed; berkomentar untuk mereka yang tidak:

# 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

Uji:

% 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
%
Kevin
sumber
IIRC beberapa (semua?) Versi sedmemungkinkan Anda untuk menggunakan string nol sebagai nama label. Jika Anda bisa membuatnya bekerja di sini, itu akan menghemat dua byte. Sebenarnya, saya tidak yakin label itu diperlukan; kecuali saya melewatkan sesuatu, baris pertama idempoten, jadi Anda mungkin bisa melompat kembali ke awal program daripada perlu label.
@ ais523 Saya juga berpikir begitu, tapi ternyata itu tidak berfungsi dalam versi BSD. Halaman manual mengatakan "Jika tidak ada label yang ditentukan, cabang ke akhir skrip," dan bahkan itu tidak berfungsi ketika saya mencoba.
Kevin
GNU sed tidak memungkinkan label untuk menjadi hanya :(lebih dari bug diambil sebagai fitur), dalam hal baik tdan b! perintah melompat ke posisi label. Plus, kode sed harus bekerja untuk setidaknya satu versi sed, mirip dengan bahasa lain, jadi Anda tidak perlu membuat kode yang juga berfungsi untuk BSD.
seshoumara
2

PHP 7.1, 58 55 54 37 35 byte

Catatan: menggunakan pengkodean IBM-850

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

Jalankan seperti ini:

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

Penjelasan

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

  • Disimpan 3 byte dengan menggunakan pengkodean IBM-850
  • Menyimpan byte dengan mengubah regex sedikit
  • Disimpan 17 byte, versi baru tanpa nama fungsi panjang dan kembali
  • Disimpan 2 byte dengan menggunakan -R(yang menyediakan $argn)
aross
sumber
1

Bean , 24 byte

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

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

Maaf karena menginjak kakimu , Arnauld .

Penjelasan:

Membawa baris pertama masukan sebagai string diformat dalam a, dan menggantikan setiap digit diikuti oleh satu atau lebih !dengan 1, sehingga sisanya bisa eval'd oleh JavaScript.

Coba demo , atau test suite

Patrick Roberts
sumber