Hasilkan persamaan yang valid menggunakan angka yang ditentukan pengguna

10

Ini didasarkan pada permainan yang dulu dimainkan guru matematika saya di sekolah menengah. Dia akan menulis 5 angka acak satu digit di papan tulis, dan kemudian angka acak dua digit. Kami akan mencoba membuat persamaan yang menggunakan semua 5 dari angka satu digit untuk menghasilkan angka dua digit. Berikut adalah beberapa contoh dengan solusi untuk menjelaskan ini dengan lebih baik:

Input:           Solution:
7 5 4 8 4 34     5*8-7+4/4 = 34
3 1 5 7 6 54     (7+3)*6-5-1 = 54
3 9 2 1 6 87     9*(2+1)*3+6 = 87
2 1 6 9 7 16     (9-7+6*1)*2 = 16
2 4 5 8 6 96     8*(5+6)+2*4 = 96
3 8 4 5 4 49     8*(4+4)-3*5 = 49

Tantangan ini adalah menulis program yang dapat menghasilkan persamaan untuk input yang diberikan. Input dapat diberikan melalui baris perintah atau melalui prompt. 5 nomor satu digit akan selalu dimasukkan terlebih dahulu (tanpa urutan tertentu), diikuti oleh nomor dua digit. Program kemudian akan mencetak persamaan solusi yang ditemukannya; Anda tidak harus menangani situasi di mana tidak ada solusi. Fungsi harus mampu menggunakan operasi berikut dalam persamaan: penjumlahan, pengurangan, perkalian, dan pembagian. Jika Anda ingin mengizinkan operasi dasar tambahan, itu bagus selama mereka tetap dalam semangat tantangan (negasi, eksponensial, dan modulus akan menjadi tambahan yang bagus). Urutan operasi mengikuti aturan matematika standar, sehingga tanda kurung akan diperlukan untuk pengelompokan.

Program akan dinilai berdasarkan panjang kode (termasuk spasi yang dibutuhkan). Catatan: pembagian harus tepat, tidak bulat atau terpotong ke bilangan bulat terdekat.

Sir_Lagsalot
sumber
Itu adalah tugas yang sangat mirip, tetapi saya pikir istilah tambahan dan tidak ada batasan tentang bagaimana ekspresi dikelompokkan harus memperluas masalah yang cukup berbeda. Selain itu, ini adalah tantangan golf alih-alih tantangan kode, yang akan membutuhkan solusi berbeda.
Sir_Lagsalot
Bagaimana dengan penggabungan? mis. jika diberikan 7 5 4 8 4 34, output 7 + 54/8 * 4 akan diizinkan?
Patrick Roberts

Jawaban:

7

Python 2.7 (284), Python 3.x (253)

from __future__ import division #(Remove for Python 3.x)
from itertools import *
a=raw_input().split()
for i in permutations(a[:-1],5):
 for j in product('+-*/',repeat=5):
  for k,l in combinations(range(1,12,2),2):
   d=''.join(sum(zip(i,j),()))[:-1];d='('+d[:l]+')'+d[l:]
   if eval(d)==int(a[-1]):print d;b

Ini memberikan kesalahan (memanggil fungsi yang tidak dikenal b) pada solusi.

Pada dasarnya, ini adalah kekuatan brutal raksasa. Itu mengambil input, membaginya dengan spasi ( 1 2 -> [1,2]), dan kemudian permutasi melalui daftar itu. Dengan setiap permutasi, itu akan beralih melalui semua string sepanjang 5 yang mungkin menggunakan karakter +-*/. Dengan masing-masing iterasi, itu akan menghasilkan kombinasi panjang 2 daftar [1,3,5,7,9,11], menjalin permutasi dan string bersama ( 12345 *-/+- -> 1*2-3/4+5-), dan dimasukkan ke dalam tanda kurung. Akhirnya, itu akan mengevaluasi itu, dan jika jawaban dan persamaan itu benar, maka ia mencetak persamaan dan berhenti.

Ini sangat tidak efisien, O(n!/(n-5)!)=O(n^5)tetapi berjalan dalam waktu yang wajar untuk input pengujian.

beary605
sumber
1
Matematika integer dapat menyebabkan output yang salah saat menggunakan pembagian. Misalnya, input "3 6 8 7 1 29" menghasilkan "(3 + 8/6) * 7 + 1", yang sama dengan 31 1/3, bukan 29. Saya akan memperbarui deskripsi untuk menjadikan ini eksplisit.
Sir_Lagsalot
Ini memberi (3/6)*8*7+1saya.
beary605
Ok, saya akan menganggapnya sebagai masalah dengan juru bahasa yang saya gunakan.
Sir_Lagsalot
3

Scala 368:

2nd g = -Line lebih mudah untuk diuji, yang pertama fleksibel untuk mengambil argumen perintah, dan keduanya memiliki panjang yang sama, jadi saya hanya menghitung dari yang kedua - hapus untuk melakukan args yang lewat:

val g=(args.map(_.toDouble))
val g=Array(3,9,2, 1, 6, 87)
val k="+*/-DQ"
val i=(0 to 5)
val f:Seq[(Double,Double)=>Double]=Seq(_+_,_*_,_/_,_-_,(a,b)=>b-a,(a,b)=>b/a)
val h=g.init.permutations;
for(j<-h;o<-i;p<-i;q<-i;r<-i;z=try{f(r)(f(q)(f(p)(f(o)(j(0),j(1)),j(2)),j(3)),j(4))}catch{case _ => 0}
if(z==g(5)))printf("(((%d%c%d)%c%d)%c%d)%c%d=%d\n",j(0),k(o),j(1),k(p),j(2),k(q),j(3),k(r),j(4),g(5))

Contoh hasil (Anda mungkin punya pertanyaan sekarang - sebentar):

(((5+7)/1)+6)*3=54
(((5-7)D1)*6)*3=54
(((5D7)+1)*6)*3=54
(((5+7)+6)Q1)Q3=54

Bagaimana dengan hal 5D7 ini? D1? Apakah hex? Ada Q1, Q3 - apa itu.

Sir_Lagsalot mengizinkan operasi dasar baru dalam semangat tantangan, dan ya, ini adalah operasi dasar, Delta dan Quotient.

Mereka berbeda dari a / b dan ab dalam aQb berarti b / a dan aDb berarti ba. Sebut saja notasi Ukraina.

Begitu

(((5-7)D1)*6)*3=54

cara

((1-(5-7))*6)*3=54
 (1-(-2))*6*3
   3*6*3 = 18*3=54

Untuk pertanyaan yang lebih menarik tentang bagaimana dan mengapa: Pada awalnya saya marah tentang kemungkinan untuk menempatkan tanda kurung, dan apakah (a + b) -c = a + bc = (a + bc) = ((a + b ) -c) = (b + a) -c dan sebagainya. Anda bisa marah dengan pertanyaan ini, tetapi jika Anda menuliskan kombinasi kurung yang mungkin, Anda kadang-kadang membuang lembar awal dan menghadapi kenyataan: Anda selalu melakukan 4 operasi antara 5 nilai, dan Anda selalu mulai dengan salah satu dari mereka. Jika polanya selalu (((_x_)x_)x_)x_ ?= _(x menjadi salah satu dari 4 operator) dan memungkinkan arah yang berlawanan (xb) dan (bxa), Anda mengatasi setiap kemungkinan.

Sekarang untuk a + b dan a * b kita tidak perlu arah yang berlawanan, mereka komutatif. Jadi saya menemukan operator D dan Q, yang hanya mengubah arah. Saya sekarang memiliki 2 operator lebih banyak, tetapi tidak perlu beralih arah. Nah - itu dilakukan dalam urutan fungsi:

 (a,b)=>b-a,(a,b)=>b/a

Pemahaman saya mengambil nilai dari Array g, dan mendistribusikannya pada a ke e, lalu saya memilih 4 indeks untuk memilih fungsi dan kemudian simbol operator terkait (hanya dengan indeks). Saya harus menangkap kesalahan div / 0, karena pengurangan dapat menyebabkan nol, sedangkan data input sampel tidak mengandung 0.

Pengguna tidak diketahui
sumber
Operator Delta dan Quotient baik-baik saja. Jika Anda berencana bermain golf, Anda harus menambahkan tanda kurung ke output.
Sir_Lagsalot
Output sekarang mencetak tanda kurung.
pengguna tidak diketahui