사용자 지정 숫자를 사용하여 유효한 방정식 생성


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 2018 년

연결은 어떻습니까? 예를 들어 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"을 생성합니다. 이는 29가 아니라 31 1/3과 같습니다.이 설명을 업데이트하여 명시 적으로 설명하겠습니다.
Sir_Lagsalot

그것은 (3/6)*8*7+1나를 위해 준다.
beary605

좋아, 나는 내가 사용한 통역사와의 문제로 그것을 정리할 것이다.
Sir_Lagsalot

3

스칼라 368 :

두 번째 g = -Line은 테스트하기가 쉽고, 첫 번째는 명령 인수를 유연하게 사용할 수 있으며 둘 다 길이가 동일하므로 두 번째 것만 계산합니다.

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? 16 진수인가요? Q1, Q3이 있습니다.

Sir_Lagsalot은 도전 정신으로 새로운 기본 작업을 허용했으며, 기본 작업 인 Delta 및 Quotient입니다.

aQb는 b / a를 의미하고 aDb는 ba를 의미한다는 점에서 a / b 및 ab와 다릅니다. 그것을 우크라이나어 표기법이라고합시다.

그래서

(((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 등. 이 질문에 화를 낼 수는 있지만 가능한 괄호 조합을 적어두면 스크래치 시트를 버리고 사실에 직면하게됩니다. 패턴이 항상 (((_x_)x_)x_)x_ ?= _(x는 4 개의 연산자 중 하나임) 반대 방향 (xb) 및 (bxa)를 허용하는 경우 모든 가능성을 해결했습니다.

이제 a + b와 a * b의 경우 반대 방향이 필요하지 않습니다. 그래서 방향을 바꾸는 D와 Q 연산자를 발명했습니다. 이제 2 명의 운영자가 더 있지만 방향을 전환 할 필요는 없습니다. 음-시퀀스 기능에서 수행됩니다.

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

내 이해력은 Array g에서 값을 가져 와서 a에서 e로 분배 한 다음 4 개의 인덱스를 선택하여 함수를 선택하고 나중에 (인덱스 만) 관련 연산자 기호를 선택합니다. 뺄셈은 0으로 이어질 수 있지만 샘플 입력 데이터에는 0이 없으므로 div / 0 오류를 잡아야합니다.


델타 및 쿼티 엔트 연산자는 괜찮습니다. 그러나 골프를 계획하고 있다면 출력에 괄호를 추가해야합니다.
Sir_Lagsalot

출력은 이제 괄호를 인쇄합니다.
사용자 알 수 없음
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.