And here is an AppleScript solution that prevents repetition of lesson pairs:
Usage:
- Copy-paste script into Script Editor (in Applications > Utility folder).
- Click the triangle 'run' button.
- Click once in a target Numbers cell (in the posted example cell A3 of Πίνακας 1 on the 'Lessons - extra table for pasting sheet')
- From the menu in Numbers choose Edit > Paste and Match Style.
Here's what it does. First. it makes a list of all possible pairs of lessons. Then it makes a random selection from the list and adds that selection to a new list if it's not already in the new list and does not contain a lesson that is supposed to be skipped for that day. Then it makes another random selection, and repeats the process. Once it has assembled the new list it checks to make sure each lesson is read enough times. If not it starts over. The number of lessons, number of days, days to exclude, etc. can be changed in the statements at the start of the script.
SG
set numDiffLessons to 8
set numLessonDays to 30
set minTimesRead to 5
set excludeList to {{1, 5}, {1, 10}, {2, 1}, {2, 3}, {5, 22}, {6, 23}, {6, 24}}
-- enter as {{lesson,day to exclude it},{lesson,day to exclude it}}
-- make list of all possible pairs
set possiblePairs to {}
repeat with i from 1 to numDiffLessons
repeat with j from 1 to numDiffLessons
if i ≠ j then ¬
set end of possiblePairs to (i & j)
(* or if want to lesson i,j to be treated as repetition of j,i then use this instead:
if i ≠ j and {j & i} is not in possiblePairs then ¬
set end of possiblePairs to (i & j)
*)
end repeat
end repeat
--warn and halt if not enough pairs to fill schedule
if (countpossiblePairs) < numLessonDays then ¬
display dialog "Not enough lesson pairs to fill schedule without repeating" buttons "Cancel"
set minFreqOK to false
set loopCtr to 0
repeat until minFreqOK
set loopCtr to loopCtr + 1
if loopCtr > 100 then display dialog "No solution. Try again?" buttons "Cancel"
set selectedPairs to {}
repeat until (countselectedPairs) = numLessonDays
set dayCounter to (countselectedPairs) + 1
-- select a random pair from list of all possible pairs
set randomSelection to random numberfrom 1 tocountpossiblePairs
set thisPair to possiblePairs'sitemrandomSelection
-- is it already selected?
set alreadySelected to {thisPair} is in selectedPairs
-- is it on exclude list?
set onExcludeList to checkExcludeList(excludeList, thisPair, dayCounter)
-- add to list if not already selected and not on exclude list for that day
if not alreadySelected and not onExcludeList then ¬
copy thisPair to end of selectedPairs
end repeat
-- after list is complete, check if minimums are met
set minFreqOK to checkFreq(selectedPairs, numDiffLessons, minTimesRead)
end repeat
set the clipboard tomakeTabbedStr(selectedPairs)
return the clipboard
to checkExcludeList(excludeList, aPair, dayCounter)
--check if either member of pair is on the exclude list for that day
repeat with i in aPair
if getValue(excludeList, i'scontents) = dayCounter then return true
end repeat
return false
end checkExcludeList
to getValue(keyValueList, findKey)
-- get value associated with a key-- similar to LOOKUP
repeat with i in keyValueList
set {thisKey, thisValue} to i
if thisKey = findKey then return thisValue
end repeat
return "" -- return null if no match
end getValue
to checkFreq(pairsSelected, numLessons, minFreq)
-- checks that each lesson is read the minimum number of times
repeat with i from 1 to numLessons
set n to 0
repeat with j from 1 to count pairsSelected
if (pairsSelected's item j as string) contains i then ¬
set n to n + 1
end repeat
if n < minFreq then return false
end repeat
return true
end checkFreq
to makeTabbedStr(aListofLists)
--converts to tab-delimited data for pasting to Numbers
set tabbedStr to ""
set AppleScript'stext item delimiters to tab
repeat with i from 1 to count aListofLists
set tabbedStr to (tabbedStr & i & tab & aListofLists'sitemi as string) & return
end repeat
set AppleScript'stext item delimiters to ""
return tabbedStr
end makeTabbedStr