From 099cc724293ef55d4c9c07e0aee2616184cbb7a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20F=C3=BCrderer?= Date: Fri, 4 Sep 2020 15:55:46 +0200 Subject: [PATCH] Redesign the algorithm to choose wrongly sorted elements - When checking the order the first time, elements above are preferred marked as wrong. - When the user corrects his solution, the newest inserted elements are preferred marked as wrong. This affects only cases, where there are multiple options for the same number of correct elements. In general, the algorithm minimizes the number of elements it needs to mark as wrong. Closes #5 --- quiz.js | 93 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 36 deletions(-) diff --git a/quiz.js b/quiz.js index abff443..893f413 100644 --- a/quiz.js +++ b/quiz.js @@ -133,47 +133,52 @@ function shuffle_cards(section) { return a; } -function choose_incorrects(idx_vals) { +function choose_incorrects(elems) { let options = { - 0: [], + "-1": [], }; - function find_longest_chain(maxkey) { - let longest = null; - for (let key in options) { - if ( - ( - maxkey == null - || key <= maxkey - ) - && ( - longest == null - || options[key].length > options[longest].length - || ( - options[key].length == options[longest].length - && Number.parseInt(key) < Number.parseInt(longest) - ) - ) - ) { - longest = key; + function chain_is_better(old_chain, new_chain) { + if (old_chain == null) { + return true; + } else if (new_chain.length > old_chain.length) { + return true; + } else if (new_chain.length < old_chain.length) { + return false; + } + let old_nums = old_chain.map(elem => elem[1]).sort((a, b) => a - b).reverse(); + let new_nums = new_chain.map(elem => elem[1]).sort((a, b) => a - b).reverse(); + for (let i=0; i old_nums[i]) { + return false; } } - return longest; } - idx_vals.forEach((val) => { - let longest = find_longest_chain(val); - let mychain = options[longest].slice(); - mychain.push(val); - options[val + 1] = mychain; - }); - let result_chain = find_longest_chain(null); - let a = []; - for (let i=0; i { - a[elem] = false; + elems.forEach(elem => { + let chain = build_chain(elem); + options[chain[chain.length - 1][0]] = chain; }); - return idx_vals.map(idx => a[idx]); + let result_chain = build_chain(null); + let corrects = result_chain.map(elem => elem[0]); + return elems.map(elem => !corrects.includes(elem[0])); } var app = new Vue({ @@ -185,6 +190,7 @@ var app = new Vue({ selected: null, items: shuffle_cards(0), }, + next_insert_num: null, solution: [], correction_visible: false, }, @@ -274,8 +280,8 @@ var app = new Vue({ return this.solution.map(elem => false); } if (this.store.section == 0) { - let idx_vals = this.solution.map(elem => elem.idx[0]); - return choose_incorrects(idx_vals); + let elems = this.solution.map(elem => [elem.idx[0], elem.insert_num]); + return choose_incorrects(elems); } else { return this.solution.map((elem, i) => { return elem.idx.length > this.store.section @@ -316,11 +322,18 @@ var app = new Vue({ store_card_visible: function(idx) { return !this.solution.some(solution => solution.idx[this.store.section] == idx); }, + calculate_insert_num: function() { + if (this.next_insert_num == null) { + return null; + } + return this.next_insert_num++; + }, store_select: function(i) { if (this.solution.length == 0) { this.solution.push({ idx: [i], got_revealed: false, + insert_num: this.calculate_insert_num(), }); } else if (i == this.store.selected) { this.store.selected = null; @@ -335,6 +348,7 @@ var app = new Vue({ this.solution.splice(0, 0, { idx: [this.store.selected], got_revealed: false, + insert_num: this.calculate_insert_num(), }); this.store.selected = null; }, @@ -349,6 +363,7 @@ var app = new Vue({ this.solution.splice(this.find_solution(elem)+1, 0, { idx: [this.store.selected], got_revealed: false, + insert_num: this.calculate_insert_num(), }); this.store.selected = null; }, @@ -360,6 +375,12 @@ var app = new Vue({ } }, show_correction: function() { + if (this.store.section == 0) { + this.solution.forEach((elem, i) => { + elem.insert_num = -i; + }); + this.next_insert_num = 1; + } this.correction_visible = true; }, open_next_column: function() {