Saya ingin kembali True
jika dan hanya jika 3 dari 4 nilai boolean benar.
Yang paling dekat yang saya dapatkan adalah (x ^ y) ^ (a ^ b)
:
Apa yang harus saya lakukan?
boolean-logic
Simon Kuang
sumber
sumber
not a ^ not b ^ not c ^ not d
benar ketika salah satu dari nilai yang dinegasikan itu benar. Ini berarti, dari nilai-nilai asli, tepatnya satu itu salah.(!a&&b&&c&&d) || (a&&!b&&c&&d) || (a&&b&&!c&&d) || (a&&b&&c&&!d)
.Jawaban:
Saya sarankan menulis kode dengan cara yang menunjukkan apa yang Anda maksud. Jika Anda ingin 3 nilai menjadi benar, tampaknya wajar bagi saya bahwa nilai 3 muncul di suatu tempat.
Misalnya, di
C++
:Ini didefinisikan dengan baik dalam
C++
: yangstandard (§4.7/4)
menunjukkan bahwa konversibool
untukint
memberikan nilai yang diharapkan 0 atau 1.Di Java dan C #, Anda dapat menggunakan konstruk berikut:
sumber
if (!!a + !!b + !!c + !!d == 3)
lebih mudah untuk menulis, walaupun saya tidak tahu apakah kompiler mengoptimalkan ini atau tidak# 1: Menggunakan operasi percabangan?: 3 atau 4
# 2 Tanpa Cabang, 7 operasi
Kembali ketika saya gunakan untuk profil segalanya, saya menemukan solusi non-cabang agak lebih cepat operasi-untuk-operasi karena CPU dapat memprediksi jalur kode yang lebih baik, dan menjalankan lebih banyak operasi secara bersamaan. Ada sekitar 50% lebih sedikit pekerjaan dalam pernyataan percabangan di sini.
sumber
Jika ini Python, saya akan menulis
Atau
Atau
Atau
Atau
Atau
Atau
Semua ini bekerja, karena Boolean adalah subclass dari integer dengan Python.
Atau, terinspirasi oleh trik yang rapi ini ,
sumber
a=5;not not a == 1
. Kerugian dari tidak memiliki tipe boolean nyata.bool
:)Bentuk normal yang panjang tapi sangat sederhana, (disjuntive):
Ini mungkin disederhanakan tetapi itu membutuhkan lebih banyak pemikiran: P
sumber
(a & b & (c ^ d)) | ((a ^ b) & c & d)
?Tidak yakin itu lebih sederhana, tapi mungkin.
((x xor y) and (a and b)) or ((x and y) and (a xor b))
sumber
Jika Anda ingin menggunakan logika ini dalam bahasa pemrograman, saran saya adalah
Atau jika Anda mau, Anda bisa meletakkan semua ini dalam satu baris:
Anda juga dapat menggeneralisasi masalah ini ke
n of m
:sumber
Jawaban ini tergantung pada sistem representasi, tetapi jika 0 adalah satu-satunya nilai yang ditafsirkan sebagai salah, dan
not(false)
selalu mengembalikan nilai numerik yang sama, makanot(a) + not(b) + not(c) + not(d) = not(0)
harus melakukan trik.sumber
Perlu diingat bahwa SO jika untuk pertanyaan pemrograman, bukan hanya masalah logis, jawabannya jelas tergantung pada pilihan bahasa pemrograman. Beberapa bahasa mendukung fitur yang tidak biasa bagi orang lain.
Misalnya, dalam C ++ Anda dapat menguji kondisi Anda dengan:
Ini harus menjadi cara tercepat untuk melakukan pemeriksaan dalam bahasa yang mendukung konversi otomatis (level rendah) dari tipe boolean ke integer. Tetapi sekali lagi, tidak ada jawaban umum untuk masalah itu.
sumber
Yang terbaik yang bisa saya lakukan adalah
((x ^ y) ^ (a ^ b)) && ((a || x) && (b || y))
sumber
Ekspresi pertama mencari 1 atau 3
true
dari 4. Yang kedua menghilangkan 0 atau 1 (dan kadang-kadang 2)true
dari 4.sumber
Java 8, memfilter nilai palsu, dan menghitung nilai sebenarnya yang tersisa:
Maka Anda dapat menggunakannya sebagai berikut:
Mudah generalizes untuk memeriksa
n
darim
item menjadi benar.sumber
Untuk memeriksa setidaknya
n
semuaBoolean
itu benar, (n harus kurang dari atau sama dengan jumlah totalBoolean
: p)Sunting : Setelah komentar @ Cruncher
Untuk memeriksa 3
boolean
dari 4Yang lainnya :
((c & d) & (a ^ b)) | ((a & b) & (c ^ d))
( Detail )sumber
Inilah cara Anda bisa menyelesaikannya dalam C # dengan LINQ:
sumber
Itu adalah fungsi Boolean simetris
S₃(4)
. Fungsi Boolean simetris adalah fungsi boolean yang hanya bergantung pada jumlah input yang ditetapkan, tetapi tidak bergantung pada input mana yang mereka inputkan. Knuth menyebutkan fungsi jenis ini di bagian 7.1.2 di Volume 4 dari The Art of Computer Programming.S₃(4)
dapat dihitung dengan 7 operasi sebagai berikut:Knuth menunjukkan bahwa ini optimal, artinya Anda tidak dapat melakukan ini dalam kurang dari 7 operasi menggunakan operator normal:
&&, || , ^, <,
dan>
.Namun jika Anda ingin menggunakan ini dalam bahasa yang menggunakan
1
benar dan0
salah, Anda juga dapat menggunakan tambahan dengan mudah:yang membuat niat Anda cukup jelas.
sumber
Dari sudut pandang logika murni inilah yang saya temukan.
Dengan prinsip lubang merpati, jika tepat 3 benar, maka a dan b benar, atau c dan d benar. Maka itu hanya masalah anding masing-masing kasus dengan tepat satu dari yang lain 2.
Tabel kebenaran Wolfram
sumber
mine <=> his
maka saya tidak tahu harus berkata apa karena ini yang diharapkan.Jika Anda menggunakan alat visualisasi logika seperti Karnaugh Maps, Anda melihat bahwa ini adalah masalah di mana Anda tidak dapat menghindari istilah logika penuh sesak jika Anda ingin menulisnya dalam satu baris if (...). Lopina sudah menunjukkannya, tidak mungkin untuk menulisnya dengan lebih sederhana. Anda dapat sedikit faktor, tetapi akan tetap sulit dibaca untuk Anda DAN untuk mesin.
Menghitung solusi tidak buruk dan mereka menunjukkan apa yang benar-benar Anda cari. Cara Anda menghitung secara efisien tergantung pada bahasa pemrograman Anda. Solusi array dengan Python oder LinQ bagus untuk dilihat, tetapi berhati-hatilah, ini PERLAHAN. Wolf's (a + b + x + y) == 3 akan bekerja dengan baik dan cepat, tetapi hanya jika bahasa Anda menyamakan "true" dengan 1. Jika "true" diwakili oleh -1, Anda harus menguji -3: )
Jika bahasa Anda menggunakan boolean sejati, Anda dapat mencoba memprogramnya secara eksplisit (saya menggunakan! = Sebagai tes XOR):
"x! = y" hanya berfungsi jika x, y adalah tipe boolean. Jika mereka adalah tipe lain di mana 0 salah dan yang lainnya benar, ini bisa gagal. Kemudian gunakan boolean XOR, atau ((bool) x! = (Bool) y), atau tulis "jika (x) kembali (y == salah) lain kembali (y == benar);", yang sedikit lebih bekerja untuk komputer.
Jika bahasa pemrograman Anda menyediakan operator ternary?:, Anda dapat mempersingkatnya menjadi
yang membuat sedikit mudah dibaca, atau memotongnya secara agresif
Kode ini melakukan persis tiga tes logika (keadaan a, keadaan b, perbandingan x dan y) dan harus lebih cepat daripada sebagian besar jawaban lain di sini. Tapi Anda perlu berkomentar, atau Anda tidak akan memahaminya setelah 3 bulan :)
sumber
Ada banyak jawaban bagus di sini; berikut adalah formulasi alternatif yang belum diposting oleh orang lain:
sumber
Mirip dengan jawaban pertama, tetapi Java murni:
Saya lebih suka menghitungnya sebagai bilangan bulat karena membuat kode lebih mudah dibaca.
sumber
Dalam Python , untuk melihat berapa banyak dari elemen yang dapat diubah Benar, gunakan
sum
(cukup mudah):Mempersiapkan
Tes Aktual
Keluaran
sumber
Jika Anda mencari solusi on-the-paper (non-pemrograman), maka K-maps dan algoritma Quine-McCluskey adalah yang Anda cari, mereka membantu Anda memperkecil fungsi boolean Anda.
Dalam kasus Anda, hasilnya adalah
Jika Anda ingin melakukan ini secara program, jumlah variabel yang tidak tetap dan "ambang" kustom, maka cukup iterasi melalui daftar nilai boolean dan menghitung kejadian "benar" cukup sederhana dan mudah.
sumber
Dengan 4 nilai boolean, a, b, x, y, tugas ini diterjemahkan ke dalam pernyataan C berikut:
sumber
true
sama dengan 1. Ini tidak benar (tidak ada kata pun dimaksudkan) dalam semua bahasa / kasus. blogs.msdn.com/b/oldnewthing/archive/2004/12/22/329884.aspxadalah apa yang kamu inginkan. Pada dasarnya saya mengambil kode Anda dan menambahkan memeriksa apakah 3 benar dan 3 tidak salah.
sumber
Pertanyaan pemrograman tanpa jawaban yang melibatkan rekursi? Tak terbayangkan!
Ada cukup jawaban "tepat 3 dari 4 tanda", tetapi inilah versi umum (Java) untuk "persisnya keluar dari tanda" (jika rekursi tidak benar-benar layak) hanya karena Anda dapat:
Ini bisa disebut dengan sesuatu seperti:
yang harus dikembalikan
true
(karena 5 dari 8 nilai benar, seperti yang diharapkan). Tidak cukup senang dengan kata-kata "trues" dan "falses", tetapi tidak dapat memikirkan nama yang lebih baik sekarang .... Perhatikan bahwa rekursi berhenti ketika terlalu banyaktrue
atau terlalu banyakfalse
nilai telah ditemukan.sumber
true
. Mungkin kira-kira seperti itucontainsNumberOfTrueValues()
. Sebagai samping: Smalltalk ini penamaan akan jauh lebih cocok untuk ini, meskipun:doesArray: someBooleans startingAt: anIndex containNumberOfTrueValues: anExpectedNumber foundSofar: aNumberFoundSoFar
. Mungkin terlalu lama untuk selera beberapa devs Jawa, tetapi Smalltalkers tidak pernah takut penamaan yang tepat ;-)containsTruth
berarti "mengandung sejumlah kebenaran yang tidak diungkapkan", secara literal, jadi saya yakin itu tidak apa-apa.Karena keterbacaan adalah masalah besar, Anda bisa menggunakan panggilan fungsi deskriptif (membungkus salah satu implementasi yang disarankan). Jika perhitungan ini perlu dilakukan di banyak tempat, pemanggilan fungsi adalah cara terbaik untuk mencapai penggunaan kembali, dan memperjelas apa yang Anda lakukan.
sumber
Di PHP, buatlah lebih dinamis (kalau-kalau Anda mengubah sejumlah kondisi, dll.):
sumber
Sementara saya bisa menunjukkan bahwa ini adalah solusi yang baik, jawaban Sam Hocevar mudah untuk ditulis dan dipahami kemudian. Dalam buku saya itu membuatnya lebih baik.
sumber
Berikut adalah beberapa kode c # yang baru saja saya tulis karena Anda telah menginspirasi saya:
Dibutuhkan sejumlah argumen dan akan memberi tahu Anda jika tidak ada yang benar.
dan Anda menyebutnya seperti itu:
Jadi sekarang Anda dapat menguji 7/9 atau 15/100 seperti yang Anda mau.
sumber