This commit is contained in:
2025-09-30 12:21:27 +02:00
parent 95845e8af8
commit b804a85f4d
10 changed files with 403 additions and 58 deletions

View File

@ -1,41 +1,143 @@
const operators = ['&', '|', '^', '+', '-', '*', '%']
const shifts = ['>>', '<<']
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 25, 32, 42, 63, 64, 127, 128, 255]
interface Template {
pattern: string
weight: number
}
const SHIFT_LOW = [4, 5, 6, 7]
const SHIFT_MID = [8, 9, 10, 11, 12]
const SHIFT_HIGH = [13, 14, 15, 16]
const SHIFTS = [...SHIFT_LOW, ...SHIFT_MID, ...SHIFT_HIGH]
const MASKS = [1, 2, 3, 4, 5, 7, 8, 11, 13, 15, 16, 31, 32, 42, 63, 64, 127, 128, 255]
const MULTIPLIERS = [2, 3, 5, 7, 11, 13]
const SMALL_NUMS = [1, 2, 3, 4, 5, 6, 7, 8]
const TEMPLATES: Template[] = [
{ pattern: "t*(N&t>>S)", weight: 8 },
{ pattern: "t*((t>>S)&N)", weight: 8 },
{ pattern: "t*(N|(t>>S))", weight: 5 },
{ pattern: "(t*M&t>>S1)|(t*M2&t>>S2)", weight: 10 },
{ pattern: "t*(t>>S1|t>>S2)", weight: 10 },
{ pattern: "t*(t>>S1&t>>S2)", weight: 8 },
{ pattern: "(t>>S1)|(t>>S2)", weight: 7 },
{ pattern: "(t>>S1)&(t>>S2)", weight: 7 },
{ pattern: "t&t>>S", weight: 6 },
{ pattern: "(t&t>>S1)*(t>>S2|t>>S3)", weight: 8 },
{ pattern: "(t>>S)&N", weight: 5 },
{ pattern: "t*(t>>S)", weight: 4 },
{ pattern: "(t*M)&(t>>S)", weight: 6 },
{ pattern: "t^(t>>S)", weight: 5 },
{ pattern: "(t>>S1)^(t>>S2)", weight: 6 },
{ pattern: "t*(N&(t>>S1|t>>S2))", weight: 7 },
{ pattern: "((t>>S1)&N)*(t>>S2)", weight: 6 },
{ pattern: "t*((t>>S1)|(t>>S2))&N", weight: 7 },
{ pattern: "(t&(t>>S1))^(t>>S2)", weight: 5 },
{ pattern: "t/(t%(t>>S|t>>S2))", weight: 3 },
{ pattern: "t<<((t>>S1|t>>S2)^(t>>S3))", weight: 4 },
{ pattern: "(t>>S)%(N)", weight: 3 },
{ pattern: "t%(N)+(t>>S)", weight: 4 },
{ pattern: "(t*M&t>>S1)^(t>>S2)", weight: 5 },
{ pattern: "((t>>S1)|(t>>S2))&((t>>S3)|(t>>S4))", weight: 6 }
]
const TOTAL_WEIGHT = TEMPLATES.reduce((sum, t) => sum + t.weight, 0)
function randomElement<T>(arr: T[]): T {
return arr[Math.floor(Math.random() * arr.length)]
}
function generateTerm(depth: number = 0): string {
if (depth > 2 || Math.random() < 0.3) {
const shift = randomElement(shifts)
const num = randomElement(numbers)
return `(t${shift}${num})`
function pickTemplate(): Template {
let random = Math.random() * TOTAL_WEIGHT
for (const template of TEMPLATES) {
random -= template.weight
if (random <= 0) {
return template
}
}
const op = randomElement(operators)
const left = generateTerm(depth + 1)
const right = Math.random() < 0.5 ? generateTerm(depth + 1) : randomElement(numbers).toString()
return `(${left}${op}${right})`
return TEMPLATES[0]
}
export function generateRandomFormula(): string {
const numTerms = Math.floor(Math.random() * 3) + 1
const terms: string[] = []
function fillTemplate(pattern: string): string {
let formula = pattern
for (let i = 0; i < numTerms; i++) {
terms.push(generateTerm())
}
const sMatches = formula.match(/S\d*/g) || []
const uniqueShifts = [...new Set(sMatches)]
uniqueShifts.forEach(placeholder => {
const shift = randomElement(SHIFTS)
formula = formula.replace(new RegExp(placeholder, 'g'), shift.toString())
})
return terms.join(randomElement(operators))
const nMatches = formula.match(/N\d*/g) || []
const uniqueMasks = [...new Set(nMatches)]
uniqueMasks.forEach(placeholder => {
const mask = randomElement(MASKS)
formula = formula.replace(new RegExp(placeholder, 'g'), mask.toString())
})
const mMatches = formula.match(/M\d*/g) || []
const uniqueMults = [...new Set(mMatches)]
uniqueMults.forEach(placeholder => {
const mult = randomElement(MULTIPLIERS)
formula = formula.replace(new RegExp(placeholder, 'g'), mult.toString())
})
return formula
}
export function generateFormulaGrid(rows: number, cols: number): string[][] {
export function generateRandomFormula(complexity: number = 1): string {
const complexityWeights = [
{ simple: 0.6, medium: 0.3, complex: 0.1 },
{ simple: 0.3, medium: 0.5, complex: 0.2 },
{ simple: 0.1, medium: 0.3, complex: 0.6 }
]
const weights = complexityWeights[complexity] || complexityWeights[1]
const filteredTemplates = TEMPLATES.map(t => {
const patternComplexity = (t.pattern.match(/[S|N|M]\d*/g) || []).length
let weight = t.weight
if (patternComplexity <= 2) {
weight *= weights.simple
} else if (patternComplexity <= 4) {
weight *= weights.medium
} else {
weight *= weights.complex
}
return { ...t, weight }
})
const totalWeight = filteredTemplates.reduce((sum, t) => sum + t.weight, 0)
let random = Math.random() * totalWeight
let selectedTemplate = filteredTemplates[0]
for (const template of filteredTemplates) {
random -= template.weight
if (random <= 0) {
selectedTemplate = template
break
}
}
let formula = fillTemplate(selectedTemplate.pattern)
const extraLayerChance = complexity === 0 ? 0.05 : complexity === 1 ? 0.15 : 0.25
if (Math.random() < extraLayerChance) {
const op = randomElement(['&', '|', '^'])
const num = randomElement(SMALL_NUMS)
formula = `(${formula})${op}${num}`
}
return formula
}
export function generateFormulaGrid(rows: number, cols: number, complexity: number = 1): string[][] {
const grid: string[][] = []
for (let i = 0; i < rows; i++) {
const row: string[] = []
for (let j = 0; j < cols; j++) {
row.push(generateRandomFormula())
row.push(generateRandomFormula(complexity))
}
grid.push(row)
}