import Exercice from '../Exercice.js'
import { context } from '../../modules/context.js'
import { listeQuestionsToContenu, randint, shuffle, combinaisonListesSansChangerOrdre, nombreAvecEspace, texteEnCouleurEtGras, modalPdf, modalVideo, cribleEratostheneN, warnMessage } from '../../modules/outils.js'
import { propositionsQcm } from '../../modules/interactif/questionQcm.js'
export const titre = 'Indiquer si des nombres sont premiers ou pas' // EE : J'ai mis indiqué pour que ce titre convienne à AMC.
export const interactifReady = true
export const interactifType = 'qcm'
export const amcReady = true
export const amcType = 'qcmMono'
/**
* Justifier la non primalité réinvestissement des critères de divisibilité
* Nombres à 3 ou 4 chiffres, un multiple de 2, de 3, de 5, de 7, de 11, sous forme d'un produit de deux nombres premiers inférieurs à 100
* et un nombre premier inferieur à 529
* dans cet exo on n'utilise pas les critères par 7 et 11
* @author Sébastien Lozano + Jean-Claude Lhote pour l'interactivité.
* Référence 3A10-1
*/
export const uuid = 'bba55'
export const ref = '3A10-1'
export default function PremierOuPas () {
Exercice.call(this) // Héritage de la classe Exercice()
// pas de différence entre la version html et la version latex pour la consigne
this.consigne = 'Justifier que les nombres suivants sont premiers ou pas.'
context.isHtml ? this.spacing = 1 : this.spacing = 2
context.isHtml ? this.spacingCorr = 2 : this.spacingCorr = 1
// this.correctionDetailleeDisponible = true;
this.nbCols = 2
this.nbColsCorr = 1
this.nbQuestions = 5
this.sup = 1
this.sup2 = false // Par défaut on n'affiche pas la liste des nombres premiers
// this.nbQuestionsModifiable = false (EE : bloquant pour AMC sinon)
this.listePackages = 'bclogo'
const prems = cribleEratostheneN(529) // constante contenant tous les nombres premiers jusqu'à 529...
this.nouvelleVersion = function () {
let typesDeQuestions
if (context.isHtml) { // les boutons d'aide uniquement pour la version html
// this.boutonAide = '';
this.boutonAide = modalPdf(this.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
let typesDeQuestionsDisponibles // = [1, 2, 3, 6, 7];
if (Number(this.sup) === 1) {
typesDeQuestionsDisponibles = [1, 2, 3, 8]
} else {
typesDeQuestionsDisponibles = [1, 2, 3, 6, 7]
}
typesDeQuestionsDisponibles = shuffle(typesDeQuestionsDisponibles) // on mélange l'ordre des questions
const listeTypeDeQuestions = combinaisonListesSansChangerOrdre(typesDeQuestionsDisponibles, this.nbQuestions)
let stringRappel = 'Cette liste des nombres premiers inférieurs à 100 pourra être utile : <br>' + prems[0]
for (let k = 1; k < 25; k++) {
stringRappel += ', ' + prems[k]
};
stringRappel += '.'
for (let i = 0, texte, texteCorr, r1, r2, prime1, prime2, cpt = 0; i < this.nbQuestions && cpt < 50;) {
typesDeQuestions = listeTypeDeQuestions[i]
let N // le nombre de la question
let r
let tabPremiersATester
let sum
let Nlongueur // pour la taille du string N
let N1 // pour la repetiton du critère
let N1longueur // pour la taille du string N1
let sum1 // pour la somme de la répétition du critère
let evenSum // pour la somme des chiffres de rang impair
let oddSum // pour la somme des chiffres de rang pair
let bonneReponse
this.introduction = warnMessage('Penser aux critères de divisibilité.', 'nombres', 'Coup de pouce')
if (this.sup2) {
this.introduction += warnMessage(stringRappel, 'nombres', 'Coup de pouce')
} else this.introduction += ''
switch (typesDeQuestions) {
case 1: // nombre pair
N = 2 * randint(51, 4999)
texte = nombreAvecEspace(N)
texteCorr = `Comme ${nombreAvecEspace(N)} est pair, il admet donc au moins trois diviseurs qui sont 1, 2 et lui-même, `
texteCorr += texteEnCouleurEtGras(nombreAvecEspace(N) + ' n\'est donc pas premier.')
bonneReponse = 'non'
break
case 2: // Multiple de 3
sum = 0 // pour la valeur de la somme;
N = 3 * randint(34, 3333) // on initialise avant la boucle car on a peut être de la chance
while ((N % 2 === 0) || (N % 5 === 0)) {
N = 3 * randint(34, 3333)
};
texte = nombreAvecEspace(N)
texteCorr = 'Comme ' + N.toString().charAt(0)
sum = Number(N.toString().charAt(0))
for (let k = 1; k < N.toString().length; k++) {
texteCorr += ' + ' + N.toString().charAt(k)
sum += Number(N.toString().charAt(k))
};
texteCorr += ` = ${sum} est un multiple de 3 donc ${nombreAvecEspace(N)} aussi, il admet donc au moins trois diviseurs qui sont 1, 3 et lui-même, `
texteCorr += texteEnCouleurEtGras(nombreAvecEspace(N) + ' n\'est donc pas premier.')
bonneReponse = 'non'
break
case 3: // Multiple de 5
N = 5 * randint(20, 1999)
texte = nombreAvecEspace(N)
texteCorr = `Comme le dernier chiffre de ${nombreAvecEspace(N)} est un ${N.toString().charAt(N.toString().length - 1)}, alors ${nombreAvecEspace(N)} est divisible par 5, `
texteCorr += 'il admet donc au moins trois diviseurs qui sont 1, 5 et lui-même, '
texteCorr += texteEnCouleurEtGras(nombreAvecEspace(N) + ' n\'est donc pas premier.')
bonneReponse = 'non'
break
case 4: // Multiple de 7
N = 7 * randint(15, 1428)
texte = nombreAvecEspace(N)
Nlongueur = N.toString().length
texteCorr = ` 7 divise ${nombreAvecEspace(N)}, en effet : `
texteCorr += '<br>'
N1 = N
N1longueur = Nlongueur
sum1 = Number(N1.toString().substring(0, N1longueur - 1)) + 5 * Number(N1.toString().charAt(N1longueur - 1))
while (sum1 >= 56) {
texteCorr += `${N1.toString().substring(0, N1longueur - 1)} + 5$\\times$${N1.toString().charAt(N1longueur - 1)}`
texteCorr += ` = ${Number(N1.toString().substring(0, N1longueur - 1)) + 5 * Number(N1.toString().charAt(N1longueur - 1))}`
texteCorr += '<br>'
N1 = sum1
N1longueur = N1.toString().length
sum1 = Number(N1.toString().substring(0, N1longueur - 1)) + 5 * Number(N1.toString().charAt(N1longueur - 1))
};
texteCorr += `Comme ${N1.toString().substring(0, N1longueur - 1)} + 5$\\times$${N1.toString().charAt(N1longueur - 1)} = ${sum1} est un multiple de 7 alors 7 divise ${N} aussi `
texteCorr += 'qui admet donc au moins trois diviseurs : 1, 7 et lui-même, '
texteCorr += texteEnCouleurEtGras(nombreAvecEspace(N) + ' n\'est donc pas premier.')
bonneReponse = 'non'
break
case 5: // multiple de 11
N = 11 * randint(10, 909)
texte = nombreAvecEspace(N)
texteCorr = `D'une part, la somme des chiffres de rang impair de ${nombreAvecEspace(N)} vaut `
if (Number(N.toString().length) % 2 === 0) { // si N a un nombre pair de chiffres
evenSum = Number(N.toString().charAt(1))
texteCorr += N.toString().charAt(1)
for (let k = 3; k < N.toString().length; k++) {
if (k % 2 === 1) {
texteCorr += ' + ' + N.toString().charAt(k)
evenSum += Number(N.toString().charAt(k))
};
};
texteCorr += ' = ' + evenSum + ' <br> '
} else { // sinon N a un nombre impair de chiffres
evenSum = Number(N.toString().charAt(0))
texteCorr += N.toString().charAt(0)
for (let m = 1; m < N.toString().length; m++) {
if (m % 2 === 0) {
texteCorr += ' + ' + N.toString().charAt(m)
evenSum += Number(N.toString().charAt(m))
};
};
texteCorr += ' = ' + evenSum + '<br> '
};
texteCorr += `d'autre part, la somme des chiffres de rang pair de ${nombreAvecEspace(N)} vaut `
if (Number(N.toString().length) % 2 === 0) { // si N a un nombre pair de chiffres
oddSum = Number(N.toString().charAt(0))
texteCorr += N.toString().charAt(0)
for (let k = 1; k < N.toString().length; k++) {
if (k % 2 === 0) {
texteCorr += ' + ' + N.toString().charAt(k)
oddSum += Number(N.toString().charAt(k))
};
};
texteCorr += ' = ' + oddSum + ' <br> '
} else { // sinon N a un nombre impair de chiffres
oddSum = Number(N.toString().charAt(1))
texteCorr += N.toString().charAt(1)
for (let m = 3; m < N.toString().length; m++) {
if (m % 2 === 1) {
texteCorr += ' + ' + N.toString().charAt(m)
oddSum += Number(N.toString().charAt(m))
};
};
texteCorr += ' = ' + oddSum + '<br> '
};
texteCorr += 'la différence entre la somme des chiffres de rangs pairs et celle des chiffres de rangs impairs vaut '
if ((oddSum - evenSum) === 0) {
texteCorr += `${oddSum - evenSum}, `
} else {
texteCorr += `${Math.abs(oddSum - evenSum)} qui est un multiple de 11, `
};
texteCorr += '<br>'
texteCorr += ` cela signifie que ${nombreAvecEspace(N)} est divisible par 11, il admet donc au moins trois diviseurs qui sont 1, 11 et lui-même,`
texteCorr += texteEnCouleurEtGras(nombreAvecEspace(N) + ' n\'est donc pas premier.')
bonneReponse = 'non'
break
case 6: // produit de deux nombres premiers inférieurs à 100
// rang du premier facteur premier
r1 = randint(0, 24)
// rang du second facteur premier
r2 = randint(0, 24)
prime1 = prems[r1] // on tire un nombre premier inférieur à 100, il n'y en a que 25!
prime2 = prems[r2] // on tire un autre nombre premier inférieur à 100, ça peut être le même qu'avant!
N = prime1 + '$\\times$' + prime2
texte = N
texteCorr = `${N} est le produit de ${prime1} et de ${prime2}, il admet donc au moins `
if (prime1 === prime2) {
texteCorr += `trois divisieurs qui sont 1, ${prime1} et lui-même ${N}=${nombreAvecEspace(prime1 * prime2)}, `
} else {
texteCorr += `quatre diviseurs qui sont 1, ${prime1}, ${prime2} et lui-même ${N}=${nombreAvecEspace(prime1 * prime2)}, `
};
texteCorr += texteEnCouleurEtGras(`${N} = ` + nombreAvecEspace(prime1 * prime2) + ' n\'est donc pas premier.')
bonneReponse = 'non'
break
case 7: // nombre premier inférieur à 529, si le nombre premier dépasse 100 on affiche le coup de pouce
// rang du nombre premier choisi
r = randint(6, prems.length - 1)
N = prems[r] // on choisit un nombre premier inférieur à 529
if (N > 100) {
this.sup2 = true
} else {
this.sup2 = false
}
texte = N + ''
r = 0
tabPremiersATester = []
while (prems[r] ** 2 < N) {
tabPremiersATester.push(prems[r])
r++
}
texteCorr = `En effectuant la division euclidienne de ${N} par tous les nombres premiers inférieurs à $\\sqrt{${N}}$, c'est-à-dire par `
if (N === 2 || N === 3) {
texteCorr += 'aucun nombre dans le cas présent, le reste n\'est jamais nul,'
} else {
texteCorr += 'les nombres '
texteCorr += tabPremiersATester[0]
for (let k = 1; k < tabPremiersATester.length - 1; k++) {
texteCorr += ', ' + tabPremiersATester[k]
};
texteCorr += ' et ' + tabPremiersATester[tabPremiersATester.length - 1]
texteCorr += ', le reste n\'est jamais nul,'
}
texteCorr += ' ' + texteEnCouleurEtGras(nombreAvecEspace(N) + ' est donc un nombre premier.')
bonneReponse = 'oui'
break
case 8: // nombre premier inférieur à 100 pour permettre les tests de divisibilité sans calculatrice
// rang du nombre premier choisi
r = randint(6, 24)
N = prems[r] // on choisit un nombre premier inférieur à 100
texte = N + ''
r = 0
tabPremiersATester = []
while (prems[r] ** 2 < N) {
tabPremiersATester.push(prems[r])
r++
}
texteCorr = `En effectuant la division euclidienne de ${N} par tous les nombres premiers inférieurs à $\\sqrt{${N}}$, c'est-à-dire par `
if (N === 2 || N === 3) {
texteCorr += 'aucun nombre dans le cas présent, le reste n\'est jamais nul,'
} else {
texteCorr += 'les nombres '
texteCorr += tabPremiersATester[0]
for (let k = 1; k < tabPremiersATester.length - 1; k++) {
texteCorr += ', ' + tabPremiersATester[k]
};
texteCorr += ' et ' + tabPremiersATester[tabPremiersATester.length - 1]
texteCorr += ', le reste n\'est jamais nul,'
}
texteCorr += ' ' + texteEnCouleurEtGras(nombreAvecEspace(N) + ' est donc un nombre premier.')
bonneReponse = 'oui'
break
};
if (this.interactif || context.isAmc) {
this.autoCorrection[i] = {}
this.autoCorrection[i].options = { ordered: true }
this.autoCorrection[i].enonce = `${texte}\n`
this.autoCorrection[i].propositions = [
{
texte: 'est premier',
statut: bonneReponse !== 'non'
},
{
texte: 'n\'est pas premier',
statut: bonneReponse !== 'oui'
}
]
if (this.interactif) {
texte += propositionsQcm(this, i).texte
}
}
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.besoinFormulaireNumerique = ['Niveau de difficulté', 2, '1 : Sans Calculatrice\n2 : Avec calculatrice']
this.besoinFormulaire2CaseACocher = ['Afficher la liste des nombres premiers inférieurs à 100']
}