สร้างสมการที่ถูกต้องโดยใช้หมายเลขที่ผู้ใช้ระบุ


10

นี่เป็นเกมที่ครูคณิตศาสตร์คนหนึ่งของฉันเคยเล่นในโรงเรียนมัธยม เขาจะเขียนตัวเลขหนึ่งหลักสุ่ม 5 ตัวบนกระดานจากนั้นก็เป็นตัวเลขสองหลักแบบสุ่ม เราจะพยายามสร้างสมการที่ใช้ทั้ง 5 ของตัวเลขหนึ่งหลักเพื่อให้ได้ตัวเลขสองหลัก ต่อไปนี้เป็นตัวอย่างบางส่วนที่มีวิธีแก้ปัญหาเพื่ออธิบายสิ่งที่ดีกว่านี้:

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

ความท้าทายนี้คือการเขียนโปรแกรมที่สามารถสร้างสมการดังกล่าวสำหรับอินพุตที่กำหนด อินพุตสามารถให้ผ่านทางบรรทัดคำสั่งหรือผ่านทางพรอมต์ หมายเลข 5 หลักหนึ่งตัวจะถูกป้อนก่อนเสมอ (ตามลำดับโดยเฉพาะ) ตามด้วยหมายเลขสองหลัก โปรแกรมจะพิมพ์สมการทางออกที่พบ คุณไม่ต้องจัดการกับสถานการณ์ที่ไม่มีวิธีแก้ปัญหา ฟังก์ชันต้องสามารถใช้การดำเนินการต่อไปนี้ในสมการ: การบวกการลบการคูณและการหาร หากคุณต้องการอนุญาตการดำเนินงานขั้นพื้นฐานเพิ่มเติมก็สามารถทำได้ตราบใดที่พวกเขายังคงอยู่ในจิตวิญญาณของความท้าทาย ลำดับการดำเนินการเป็นไปตามกฎคณิตศาสตร์มาตรฐานดังนั้นจะต้องใช้วงเล็บในการจัดกลุ่ม

โปรแกรมจะได้คะแนนตามความยาวของรหัส (รวมถึงช่องว่างที่จำเป็น) หมายเหตุ: การหารจะต้องตรงทุกประการไม่ถูกปัดเศษหรือถูกปัดเศษเป็นจำนวนเต็มที่ใกล้เคียงที่สุด



นั่นเป็นงานที่คล้ายกันมาก แต่ฉันคิดว่าคำเพิ่มเติมและไม่มีข้อ จำกัด เกี่ยวกับวิธีการจัดกลุ่มนิพจน์ควรขยายปัญหาให้เพียงพอเพื่อให้มีความแตกต่างที่น่าสนใจ นอกจากนี้นี่คือความท้าทายในการเล่นกอล์ฟแทนการใช้รหัสท้าทายซึ่งจะเรียกหาวิธีแก้ไขปัญหาที่แตกต่างกัน
Sir_Lagsalot

สิ่งที่เกี่ยวกับการเรียงต่อกัน? เช่นถ้าได้รับ 7 5 4 8 4 34 จะอนุญาตให้เอาท์พุท 7 + 54/8 * 4?
Patrick Roberts

คำตอบ:


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

มันให้ข้อผิดพลาด (เรียกฟังก์ชั่นที่ไม่รู้จักb) ในการแก้ปัญหา

โดยพื้นฐานแล้วมันเป็นเดรัจฉานขนาดมหึมา มันจะใช้เวลาในการป้อนข้อมูลแยกตามช่องว่างของมัน ( 1 2 -> [1,2]) แล้วเปลี่ยนผ่านรายการ ทุกครั้งที่มีการเปลี่ยนแปลงก็จะย้ำผ่านสตริงเป็นไปได้ทั้งหมดของความยาว 5 +-*/โดยใช้ตัวอักษรที่ ด้วยการวนซ้ำแต่ละครั้งมันจะสร้างการรวมกันของความยาว 2 ของรายการ[1,3,5,7,9,11]สอดแทรกการเรียงสับเปลี่ยนและสตริงเข้าด้วยกัน ( 12345 *-/+- -> 1*2-3/4+5-) และใส่ในวงเล็บ ในที่สุดมันจะประเมินมันและถ้าคำตอบและสมการเป็นจริงแล้วมันจะพิมพ์สมการและหยุด

นี่เป็นเรื่องไม่มีประสิทธิภาพอย่างน่ากลัวO(n!/(n-5)!)=O(n^5)แต่มันทำงานในเวลาที่เหมาะสมสำหรับอินพุตทดสอบ


1
คณิตศาสตร์จำนวนเต็มอาจทำให้เกิดผลลัพธ์ที่ไม่ถูกต้องเมื่อใช้การหาร ตัวอย่างเช่นอินพุต "3 6 8 7 1 29" อัตราผลตอบแทน "(3 + 8/6) * 7 + 1" ซึ่งเท่ากับ 31 1/3 ไม่ใช่ 29 ฉันจะอัปเดตคำอธิบายเพื่อทำให้ชัดเจน
Sir_Lagsalot

มันให้(3/6)*8*7+1สำหรับฉัน
beary605

ตกลงฉันจะชอล์คว่าเป็นปัญหากับล่ามที่ฉันใช้
Sir_Lagsalot

3

สกาลา 368:

2nd g = -Line ง่ายต่อการทดสอบส่วนแรกมีความยืดหยุ่นในการรับอาร์กิวเมนต์คำสั่งและทั้งสองมีความยาวเท่ากันดังนั้นฉันจะนับจากอันที่สองเท่านั้น - ลบออกเพื่อทำ args ผ่าน:

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))

ตัวอย่างผลลัพธ์ (คุณอาจมีคำถามตอนนี้ - สักครู่):

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

สิ่งที่เกี่ยวกับ 5D7 นี้ D1? มันเป็น hex หรือไม่? มี Q1, Q3 - นั่นคืออะไร

Sir_Lagsalot อนุญาตการดำเนินงานขั้นพื้นฐานใหม่ด้วยจิตวิญญาณแห่งความท้าทายและใช่สิ่งเหล่านี้คือการดำเนินงานขั้นพื้นฐาน Delta และ Quotient

พวกเขาแตกต่างจาก a / b และ ab ใน aQb หมายถึง b / a และ aDb หมายถึง ba ลองเรียกมันว่าสัญลักษณ์ยูเครน

ดังนั้น

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

วิธี

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

สำหรับคำถามที่น่าสนใจเกี่ยวกับวิธีการและเหตุผล: ในตอนแรกฉันโกรธเกี่ยวกับความเป็นไปได้ที่จะใส่วงเล็บและ (a + b) -c = a + bc = (a + bc) = ((a + b ) -c) = (b + a) -c และอื่น ๆ คุณอาจโมโหกับคำถามนี้ แต่ถ้าคุณเขียนชุดวงเล็บที่เป็นไปได้บางครั้งคุณก็ทิ้งแผ่นรอยขีดข่วนและเผชิญกับความจริง: คุณมักจะทำการดำเนินการ 4 อย่างระหว่าง 5 ค่าและคุณมักจะเริ่มด้วยหนึ่งในนั้น หากรูปแบบอยู่เสมอ(((_x_)x_)x_)x_ ?= _(x เป็นหนึ่งใน 4 ตัวดำเนินการ) และอนุญาตให้มีทิศทางตรงกันข้าม (xb) และ (bxa) แสดงถึงความเป็นไปได้ทุกประการ

ทีนี้สำหรับ a + b และ a * b เราไม่ต้องการทิศทางตรงข้ามพวกมันสลับกัน ดังนั้นฉันจึงคิดค้นตัวดำเนินการ D และ Q ซึ่งเพิ่งเปลี่ยนทิศทาง ตอนนี้ฉันมีผู้ให้บริการ 2 ราย แต่ไม่จำเป็นต้องเปลี่ยนทิศทาง ดี - มันทำในฟังก์ชัน Sequence:

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

สำหรับความเข้าใจของฉันใช้ค่าจาก Array g และกระจายพวกเขาไป a ถึง e จากนั้นฉันเลือก 4 ดัชนีเพื่อเลือกฟังก์ชั่นและต่อมาสัญลักษณ์ตัวดำเนินการที่เกี่ยวข้อง (โดยดัชนีเท่านั้น) ฉันต้องตรวจจับข้อผิดพลาด div / 0 เนื่องจากการลบอาจนำไปสู่ศูนย์ในขณะที่ข้อมูลอินพุตตัวอย่างไม่มี 0


ตัวดำเนินการ Delta และ Quotient นั้นใช้ได้ หากคุณวางแผนที่จะตีกอล์ฟคุณจะต้องเพิ่มวงเล็บในเอาต์พุต
Sir_Lagsalot

ตอนนี้เอาต์พุตจะพิมพ์วงเล็บ
ผู้ใช้ที่ไม่รู้จัก
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.