ref: a35484265f9fb32d9faa2064ad24d8dec99ba919
parent: 9dd5bfa3e75f9c50898d99a1168ca30691c760a2
author: qwx <qwx@sciops.net>
date: Mon Nov 1 17:02:33 EDT 2021
add sr3: tweaked s&m2, pending other modifications + misc updates
--- a/bin/sm2
+++ b/bin/sm2
@@ -2,4 +2,5 @@
rfork n
truetypefs
font=/n/ttf/unifont.ttf.16/font
-'s&m2' db0 > db1
+sr3 db0 > db1
+mv db1 db0
--- a/bin/sm2again
+++ b/bin/sm2again
@@ -1,3 +1,3 @@
#!/bin/rc -e
-'s&m2' db0 >db1
+sr3 db0 >db1
cp db1 db0
--- a/bin/sm2ger
+++ b/bin/sm2ger
@@ -1,11 +1,13 @@
#!/bin/rc -e
p=$home/p/sm2/ger
cd $p || exit
-awk -v 'nword='20 '
+awk -v 'nword='15 '
{
d[NR] = $0
}
END{
+ if(length(d) == 0)
+ exit
srand()
for(i=1; i<=nword; i++){
do
@@ -20,5 +22,5 @@
print d[i]
}' db >/tmp/sm2.$pid
mv /tmp/sm2.$pid db
-'s&m2' db0 >db1
-cp db1 db0
+sr3 db0 >db1
+#mv db1 db0
--- a/bin/sm2geradd
+++ b/bin/sm2geradd
@@ -19,3 +19,4 @@
close(last)
}
' $*
+echo remember to add to other collections!
--- /dev/null
+++ b/bin/sr3
@@ -1,0 +1,105 @@
+#!/bin/awk -f
+# tweaked version of supermemo 2 algorithm
+# usage: sr3 deck > newdeck
+# deck contains only card metadata.
+# new cards are initialized with the values: 2.5 0 0 0 filepath.
+# the script evaluates due cards, shuffles them, and shows them until all
+# responses are graded >= 4, then writes a new deck db to stdout.
+# card format is up to the user.
+# tweaks:
+# - new due date takes into account missed days
+function setef(n, q){
+ ef = c[n,"ef"] + (0.1 - (5 - q) * (0.08 + (5 - q) * 0.02))
+ if(ef < 1.3)
+ ef = 1.3
+ else if(ef > 2.5)
+ ef = 2.5
+ c[n,"ef"] = ef
+}
+function setdue(n, t, dt, day){
+ dt = time - c[n,"due"]
+ day = 60 * 60 * 24
+ if(c[n,"nrep"] == 1)
+ dt = 1 * day
+ else if(c[n,"nrep"] == 2)
+ dt = 6 * day - dt
+ else
+ dt = int((c[n,"due"] - c[n,"mtime"] - dt) / day * ef + 0.5) * day
+ if(dt < 0)
+ dt = 1 * day
+ t = time + dt
+ c[n,"mtime"] = time
+ c[n,"due"] = t
+}
+function swap(X, a, b, t){
+ t = X[a]
+ X[a] = X[b]
+ X[b] = t
+}
+function qsort(X, l, r, i, e){
+ if(l >= r)
+ return
+ swap(X, l, l + int((r - l + 1) * rand()))
+ e = l
+ for(i=l+1; i<=r; i++)
+ if(X[i] < X[l])
+ swap(X, ++e, i)
+ swap(X, l, e)
+ qsort(X, l, e-1)
+ qsort(X, e+1, r)
+}
+function shuffle( r, nr){
+ for(i in dues){
+ nr++
+ do
+ r[nr] = rand()
+ while(r[r[nr]] != 0)
+ r[r[nr]] = dues[i]
+ }
+ delete dues
+ qsort(r, 1, nr)
+ for(i=1; i<=nr; i++)
+ dues[i] = r[r[i]]
+}
+BEGIN{
+ srand()
+ "date -n" | getline time
+}
+NF != 5{
+ exit (exits = "invalid db record " NR)
+}
+{
+ c[NR,"ef"] = $1
+ c[NR,"nrep"] = $2
+ c[NR,"mtime"] = $3
+ c[NR,"due"] = $4
+ c[NR,"path"] = $5
+ if(time >= $4)
+ dues[++dc] = NR
+}
+END{
+ if(exits != ""){
+ print exits
+ exit exits
+ }
+ while(length(dues) > 0){
+ shuffle()
+ for(i in dues){
+ n = dues[i]
+ #system("proof -m 1 " c[n,"path"])
+ system("page " c[n,"path"])
+ do
+ getline q < "-"
+ while(q !~ /^[0-9]$/ || q > 5)
+ setef(n, int(q))
+ if(q >= 4){
+ delete dues[i]
+ c[n,"nrep"]++
+ setdue(n)
+ }else if(q < 3)
+ c[n,"nrep"] = 0
+ }
+ }
+ for(i=1; i<=NR; i++)
+ print c[i,"ef"], c[i,"nrep"], c[i,"mtime"], c[i,"due"], c[i,"path"]
+}