import Exercice from '../Exercice.js'
import { context } from '../../modules/context.js'
import { listeQuestionsToContenu, randint, obtenirListeFacteursPremiers, texNombre, miseEnEvidence, modalPdf, modalVideo, cribleEratostheneN, premiersEntreBornes, warnMessage, rangeMinMax, contraindreValeur, compteOccurences, combinaisonListes } from '../../modules/outils.js'
import { setReponse } from '../../modules/gestionInteractif.js'
import { ajouteChampTexteMathLive } from '../../modules/interactif/questionMathLive.js'
export const interactifReady = true
export const interactifType = 'mathLive'
export const amcReady = true
export const amcType = 'AMCOpen'
export const titre = 'Décomposer un entier en produit de facteurs premiers'
/**
* Décomposer un nombre en facteurs premiers et compter son nombre de diviseurs à partir d'un tableau
* plusieurs type de nombres à décomposer
* type 1 : 3 à 5 facteurs premiers max, multiplicités 0,1,2 ou 3 max à préciser
* type 2 : un produit de deux premiers entre 30 et 100, multiplicité 1 ... suffisamment de possibilités?
* type 3 : un grand nombre premier au delà de 1000 et inférieur à 2 000
* @author Sébastien Lozano (Rajout par EE du this.sup2 et de l'AMC)
* Référence 3A10-3
*/
export const uuid = '32f33'
export const ref = '3A10-3'
export default function DecompositionFacteursPremiers () {
'use strict'
Exercice.call(this) // Héritage de la classe Exercice()
this.titre = titre
// pas de différence entre la version html et la version latex pour la consigne
// mais une différence selon que l'exo est affiché en interactif ou non
this.consigne = ''
context.isHtml ? this.spacing = 2 : this.spacing = 2
context.isHtml ? this.spacingCorr = 2 : this.spacingCorr = 1
this.nbQuestions = 3
// this.correctionDetailleeDisponible = true;
this.nbCols = 1
this.nbColsCorr = 1
this.listePackages = 'bclogo'
this.besoinFormulaireCaseACocher = ['Afficher la liste des nombres premiers inférieurs à 100']
this.besoinFormulaire2Texte = ['Choix des décompositions', 'Nombres séparés par des tirets\n1 : 3 à 5 petits facteurs premiers max\n2 : 2 facteurs premiers entre 30 et 100\n3 : Un seul grand nombre premier\n4 : Mélange']
this.sup = true
this.sup2 = 4
this.nouvelleVersion = function (numeroExercice) {
let typesDeQuestions
if (context.isHtml) { // les boutons d'aide uniquement pour la version html
// this.boutonAide = '';
this.boutonAide = modalPdf(numeroExercice, 'assets/pdf/FicheArithmetique-3A11.pdf', 'Aide mémoire sur les nombres premiers (Sébastien Lozano)', 'Aide mémoire')
this.boutonAide += modalVideo('conteMathsNombresPremiers', 'https://coopmaths.fr/videos/LesNombresPremiers.mp4', 'Petit conte mathématique - Les Nombres Premiers', 'Intro Vidéo')
} else { // sortie LaTeX
};
this.listeQuestions = [] // Liste de questions
this.listeCorrections = [] // Liste de questions corrigées
this.autoCorrection = []
this.contenu = '' // Liste de questions
this.contenuCorrection = '' // Liste de questions corrigées
/* From Sebastien Lozano
let typesDeQuestionsDisponibles = [1, 2, 3]
typesDeQuestionsDisponibles = shuffle(typesDeQuestionsDisponibles) // on mélange l'ordre des questions
// let typesDeQuestionsDisponibles = [1];
const listeTypeDeQuestions = combinaisonListesSansChangerOrdre(typesDeQuestionsDisponibles, this.nbQuestions)
*/
let stringRappel = 'Cette liste des nombres premiers inférieurs à 100 pourra être utile : <br>' + cribleEratostheneN(100)[0]
for (let k = 1; k < cribleEratostheneN(100).length; k++) {
stringRappel += ', ' + cribleEratostheneN(100)[k]
};
stringRappel += '.'
if (this.sup) {
this.introduction = warnMessage(stringRappel, 'nombres', 'Coup de pouce')
} else {
this.introduction = ''
}
// Rajout EE
let listeDesProblemes = []
if (!this.sup2) { // Si aucune liste n'est saisie
listeDesProblemes = rangeMinMax(1, 4)
} else {
if (typeof (this.sup2) === 'number') { // Si c'est un nombre c'est que le nombre a été saisi dans la barre d'adresses
listeDesProblemes[0] = contraindreValeur(1, 4, this.sup2, 4)
} else {
listeDesProblemes = this.sup2.split('-')// Sinon on créé un tableau à partir des valeurs séparées par des -
for (let i = 0; i < listeDesProblemes.length; i++) { // on a un tableau avec des strings : ['1', '1', '2']
listeDesProblemes[i] = contraindreValeur(1, 4, parseInt(listeDesProblemes[i]), 4) // parseInt en fait un tableau d'entiers
}
}
}
if (compteOccurences(listeDesProblemes, 4) > 0) listeDesProblemes = rangeMinMax(1, 3) // Teste si l'utilisateur a choisi tout
listeDesProblemes = combinaisonListes(listeDesProblemes, this.nbQuestions)
// Fin du rajout EE
for (let i = 0, texte, texteCorr, cpt = 0; i < this.nbQuestions && cpt < 50;) {
typesDeQuestions = listeDesProblemes[i]
let nombre, reponse
switch (typesDeQuestions) {
case 1: // 3 à 5 facteurs premiers max compris entre 0 et 30, de multiplicité 1,2 ou 3 max
{
// on fixe le nombre de facteurs premier entre 3 et 5
const nbDePremiers = randint(3, 5)
// on fixe la limite pour le choix des premiers
const maxPremier = 11
// on fixe le rang max pour le choix des premiers
const rgMax = cribleEratostheneN(maxPremier).length - 1
// on choisit les rangs pour les nombres premiers
const tabRangs = []
const tabRangsExclus = []
for (let k = 0; k < (nbDePremiers); k++) {
for (let m = 0; m < k; m++) {
tabRangsExclus.push(tabRangs[m])
}
tabRangs[k] = randint(0, rgMax, tabRangsExclus)
};
// on choisit les premiers
const tabPremiers = []
for (let k = 0; k < tabRangs.length; k++) {
tabPremiers[k] = cribleEratostheneN(maxPremier)[tabRangs[k]]
};
// on range les facteurs premiers dans l'ordre croissant
tabPremiers.sort(function (a, b) {
return a - b
})
// on choisit les multiplicités
const tabMultiplicites = []
for (let k = 0; k < tabRangs.length; k++) {
tabMultiplicites[k] = randint(1, 2)
};
// yapluka écrire le nombre dans l'énoncé et sa décomposition dans la correction
texte = 'À l\'aide de la calculatrice, si c\'est possible, décomposer '
let nombreTodecompose = 1
for (let k = 0; k < tabRangs.length; k++) {
for (let m = 0; m < tabMultiplicites[k]; m++) {
nombreTodecompose = nombreTodecompose * tabPremiers[k]
};
};
const racinePremier1 = Math.trunc(Math.sqrt(nombreTodecompose))
texte += `$${texNombre(nombreTodecompose)}$ en produit de facteurs premiers.`
// correction
texteCorr = `Nous allons successivement tester la divisibilité de $${texNombre(nombreTodecompose)}$ par tous les nombres premiers inférieurs à `
texteCorr += `$${texNombre(nombreTodecompose)}$ en commençant par 2, 3, 5, 7, ...<br>`
texteCorr = `Il est suffisant de tester la divisibilité de $${texNombre(nombreTodecompose)}$ par tous les nombres premiers inférieurs ou égaux à $\\sqrt{${texNombre(nombreTodecompose)}}$, c'est-à-dire inférieurs à $${texNombre(racinePremier1)}$.<br>`
texteCorr += 'Ce sont les nombres de la liste : <br>'
texteCorr += '$' + cribleEratostheneN(racinePremier1)[0] + '$ ; '
for (let k = 1; k < cribleEratostheneN(racinePremier1).length; k++) {
texteCorr += '$' + cribleEratostheneN(racinePremier1)[k] + '$'
if (k !== cribleEratostheneN(racinePremier1).length - 1) {
texteCorr += ' ; '
} else {
texteCorr += '.'
}
if (k % 15 === 0) {
texteCorr += '<br>'
}
};
texteCorr += '<br>'
const listeFacteursPremiers = obtenirListeFacteursPremiers(nombreTodecompose)
let quotientIntermediaire = nombreTodecompose
for (let k = 0; k < listeFacteursPremiers.length; k++) {
texteCorr += `$${texNombre(quotientIntermediaire)}\\div${miseEnEvidence(listeFacteursPremiers[k])} = ${texNombre(quotientIntermediaire / listeFacteursPremiers[k])}$<br>`
quotientIntermediaire = quotientIntermediaire / listeFacteursPremiers[k]
};
texteCorr += `Finalement, on obtient la décomposition suivante : $ ${texNombre(nombreTodecompose)} = `
if (tabMultiplicites[0] === 1) {
texteCorr += `${tabPremiers[0]}`
reponse = `${tabPremiers[0]}`
} else {
texteCorr += `${tabPremiers[0]}^{${tabMultiplicites[0]}}`
reponse = `${tabPremiers[0]}^{${tabMultiplicites[0]}}`
};
for (let k = 1; k < tabPremiers.length; k++) {
if (tabMultiplicites[k] === 1) {
texteCorr += `\\times${tabPremiers[k]}`
reponse += `\\times${tabPremiers[k]}`
} else {
texteCorr += `\\times${tabPremiers[k]}^{${tabMultiplicites[k]}}`
reponse += `\\times${tabPremiers[k]}^{${tabMultiplicites[k]}}`
};
};
texteCorr += '$.'
nombre = nombreTodecompose
setReponse(this, i, reponse)
}
break
case 2: // deux premiers compris entre 30 et 100 de multiplicité 1
{
// on choisit un rang différent pour chaque premier entre 30 et 100
const r1 = randint(0, premiersEntreBornes(30, 100).length - 1)
const r2 = randint(0, premiersEntreBornes(30, 100).length - 1, r1)
let premier1 = premiersEntreBornes(30, 100)[r1]
let premier2 = premiersEntreBornes(30, 100)[r2]
if (premier1 > premier2) { // on inverse p1 et p2 si p1 est supérieur à p2
const p = premier1
premier1 = premier2
premier2 = p
};
texte = `À l'aide de la calculatrice, si c'est possible, décomposer $${texNombre(premier1 * premier2)}$ en produit de facteurs premiers.`
const racinePrem = Math.trunc(Math.sqrt(premier1 * premier2))
texteCorr = `Il est suffisant de tester la divisibilité de $${texNombre(premier1 * premier2)}$ par tous les nombres premiers inférieurs ou égaux à $\\sqrt{${texNombre(premier1 * premier2)}}$, c'est-à-dire inférieurs à $${texNombre(racinePrem)}$.<br>`
texteCorr += 'Ce sont les nombres de la liste suivante : <br>$'
texteCorr += cribleEratostheneN(racinePrem)[0]
for (let k = 1; k < cribleEratostheneN(racinePrem).length; k++) {
texteCorr += '; ' + cribleEratostheneN(racinePrem)[k]
};
texteCorr += '.$<br>'
const listeFacteursPremiers = obtenirListeFacteursPremiers(premier1 * premier2)
let quotientIntermediaire = premier1 * premier2
for (let k = 0; k < listeFacteursPremiers.length; k++) {
texteCorr += `$${texNombre(quotientIntermediaire)}\\div${miseEnEvidence(listeFacteursPremiers[k])} = ${texNombre(quotientIntermediaire / listeFacteursPremiers[k])}$<br>`
quotientIntermediaire = quotientIntermediaire / listeFacteursPremiers[k]
};
texteCorr += ` D'où $${texNombre(premier1 * premier2)} = ${texNombre(premier1)}\\times${texNombre(premier2)}$.`
reponse = `${premier1}\\times${premier2}`
nombre = premier1 * premier2
setReponse(this, i, reponse)
}
break
case 3: // un gros premier entre 1000 et 2000
{
// on choisit un rang pour le nombre premier entre 1000 et 2000
const r = randint(0, premiersEntreBornes(1000, 2000).length - 1)
const premier = premiersEntreBornes(1000, 2000)[r]
const racinePremier = Math.trunc(Math.sqrt(premier))
texte = `À l'aide de la calculatrice, si c'est possible, décomposer $${texNombre(premier)}$ en produit de facteurs premiers.`
texteCorr = `Il est suffisant de tester la divisibilité de $${texNombre(premier)}$ par tous les nombres premiers inférieurs ou égaux à $\\sqrt{${texNombre(premier)}}$, c'est-à-dire inférieurs à $${racinePremier}$.<br>`
texteCorr += 'Ce sont les nombres de la liste $'
texteCorr += cribleEratostheneN(racinePremier)[0]
for (let k = 1; k < cribleEratostheneN(racinePremier).length; k++) {
texteCorr += '; ' + cribleEratostheneN(racinePremier)[k]
};
texteCorr += '$, '
texteCorr += `on se rend compte que $${texNombre(premier)}$ n'est divisible par aucun de ces nombres et donc est un nombre premier.<br>Aucune décomposition en produit de nombres premiers n'est possible et donc `
texteCorr += `$${texNombre(premier)} = ${texNombre(premier)}$.`
reponse = `${premier}`
nombre = premier
setReponse(this, i, reponse)
}
break
}
texte += ajouteChampTexteMathLive(this, i, 'largeur20 inline', { texte: `<br> <b>Écrire les facteurs premiers dans l'ordre croissant et la décomposition à l'aide de puissances lorsque l'exposant est supérieur ou égal à deux.</b> <br> La décomposition de $${texNombre(nombre)}$ est : ` })
if (context.isAmc) {
this.autoCorrection[i] = {
enonce: texte,
propositions: [
{ statut: 3, sanscadre: false, pointilles: false }
]
}
}
if (this.listeQuestions.indexOf(texte) === -1) { // Si la question n'a jamais été posée, on en créé une autre
this.listeQuestions.push(texte)
this.listeCorrections.push(texteCorr)
i++
}
cpt++
}
listeQuestionsToContenu(this)
}
// this.besoinFormulaireCaseACocher = ['Afficher la liste des nombres premiers inférieurs à 100']
// this.besoinFormulaire2Texte = ['Choix des problèmes', 'Nombres séparés par des tirets\n1 : Trouver une échelle\n2 : Trouver une distance réelle\n3 : Trouver une longueur sur le plan\n4 : Mélange']
}