Genera un'equazione valida usando numeri specificati dall'utente


10

Questo è basato su un gioco che uno dei miei insegnanti di matematica giocava alle scuole medie. Scriverebbe 5 numeri casuali di una cifra sulla lavagna, quindi un numero casuale di due cifre. Proveremmo a creare un'equazione che utilizzava tutti e 5 i numeri di una cifra per produrre il numero di due cifre. Ecco alcuni esempi con soluzioni per spiegarlo meglio:

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

Questa sfida è quella di scrivere un programma in grado di generare tali equazioni per un dato input. L'input può essere fornito tramite la riga di comando o tramite un prompt. I 5 numeri a una cifra verranno sempre inseriti per primi (in nessun ordine particolare), seguiti dal numero a due cifre. Il programma quindi stamperà un'equazione della soluzione trovata; non è necessario gestire situazioni in cui non esiste soluzione. La funzione deve essere in grado di utilizzare le seguenti operazioni nell'equazione: addizione, sottrazione, moltiplicazione e divisione. Se desideri consentire ulteriori operazioni di base, va bene purché rimangano nello spirito della sfida (negazione, esponenziazione e modulo sarebbero delle belle aggiunte). L'ordine delle operazioni segue le regole matematiche standard, quindi saranno necessarie le parentesi per il raggruppamento.

I programmi verranno valutati in base alla lunghezza del codice (incluso lo spazio richiesto). Nota: la divisione deve essere esatta, non arrotondata o troncata al numero intero più vicino.



Questo è un compito molto simile, ma penso che il termine aggiuntivo e nessuna restrizione sul modo in cui le espressioni sono raggruppate dovrebbero espandere il problema abbastanza da renderlo interessante in modo diverso. Inoltre, questa è una sfida di golf invece di una sfida di codice, che richiederà diverse soluzioni.
Sir_Lagsalot,

E la concatenazione? ad es. se dato 7 5 4 8 4 34, sarebbe consentita l'uscita 7 + 54/8 * 4?
Patrick Roberts,

Risposte:


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

Fornisce un errore (chiamando la funzione sconosciuta b) sulla soluzione.

Fondamentalmente, è una gigantesca forza bruta. Prende l'input, lo divide per i suoi spazi ( 1 2 -> [1,2]) e quindi lo consente attraverso quell'elenco. Con ogni permutazione, itererà attraverso tutte le possibili stringhe di lunghezza 5 usando i caratteri +-*/. Con ognuna di queste iterazioni, genererà le combinazioni della lunghezza 2 dell'elenco [1,3,5,7,9,11], intrecciando insieme la permutazione e la stringa ( 12345 *-/+- -> 1*2-3/4+5-) e inserendo le parentesi. Infine, lo valuterà e se la risposta e l'equazione sono vere, quindi stampa l'equazione e si ferma.

Questo è orribilmente inefficiente, circa O(n!/(n-5)!)=O(n^5), ma funziona in un tempo ragionevole per gli input di test.


1
La matematica dei numeri interi può causare un output errato quando si utilizza la divisione. Ad esempio, l'ingresso "3 6 8 7 1 29" produce "(3 + 8/6) * 7 + 1", che equivale a 31 1/3, non 29. Aggiornerò la descrizione per renderlo esplicito.
Sir_Lagsalot,

Mi dà (3/6)*8*7+1.
beary605,

Ok, lo segnerò come un problema con l'interprete che ho usato.
Sir_Lagsalot,

3

Scala 368:

Il 2 ° g = -Line è più facile da testare, il primo è flessibile per prendere argomenti di comando ed entrambi hanno la stessa lunghezza, quindi conto solo dal secondo - rimuovilo per fare passare gli argomenti:

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

Esempio di output (potresti avere una domanda in questo momento - solo un momento):

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

Che dire di questa cosa 5D7? D1? È esadecimale? C'è Q1, Q3 - che cos'è.

Sir_Lagsalot ha consentito nuove operazioni di base nello spirito della sfida e, sì, si tratta di operazioni di base, Delta e Quoziente.

Sono diversi da a / b e ab in quanto aQb significa b / a e aDb significa ba. Chiamiamola notazione ucraina.

Così

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

si intende

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

Alla domanda più interessante di come e perché: all'inizio mi sono arrabbiato per le possibilità di posizionare le parentesi e se (a + b) -c = a + bc = (a + bc) = ((a + b ) -c) = (b + a) -c e così via. Puoi arrabbiarti con questa domanda, ma se annoti le possibili combinazioni di parentesi, a volte butti via il foglio da grattare e affronti il ​​fatto: esegui sempre 4 operazioni tra 5 valori e inizi sempre con una di esse. Se lo schema è sempre(((_x_)x_)x_)x_ ?= _ (x essendo uno dei 4 operatori) e consente la direzione opposta (xb) e (bxa), hai indicato tutte le possibilità.

Ora per a + b e a * b non abbiamo bisogno di una direzione opposta, sono commutativi. Così ho inventato l'operatore D e Q, che cambia semplicemente direzione. Ora ho 2 operatori in più, ma non ho bisogno di cambiare direzione. Bene - è fatto nella funzione Sequenza:

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

La mia comprensione preliminare prende i valori dall'array g e li distribuisce su un ae, quindi seleziono 4 indici per selezionare la funzione e successivamente il simbolo dell'operatore associato (solo per indice). Devo rilevare errori div / 0, poiché la sottrazione può portare a zeri, mentre i dati di input del campione non contengono uno 0.


Gli operatori Delta e Quoziente stanno bene. Se hai intenzione di giocare a golf, tuttavia, dovrai aggiungere parentesi all'output.
Sir_Lagsalot,

L'output ora stampa la parentesi.
utente sconosciuto
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.