The Spacial-Repetition-System (SRS) uses the theory that the brain forgets information over time and must be ‘refreshed’ at determined time intervals in order to imprint the information more permanently.
I have been working on a ANKI style flash-card app for Android and iPhone (StudyNWalk, if you are interested) and I required an algorithm for selecting cards to present to the user. After looking at various algorithms with varying complexity, I decided to have a go and implement my own simplified version.
I’d like to call my implementation “Bucket-SRS” because it doesn’t care about the time between each repetition, rather than a random selection based on the answers. In fact, I found it to be quite similar to the Leitner system
Each card is given an individual “status” or put in to one of 4 buckets.
- 0 Unseen
- 1 Repeat Once
- 2 Repeat Twice
- 3 Completed
At the start, all cards are set to Unseen, and the client application will select a card at random and present it to the user.
The user then changes the status of the card depending on their answer to the card, and continue by showing the next randomly selected card. The process is complete when all the cards are in the 3 Completed bucket. One of Two answers may be given to a card, Good or Bad. Good means the user knew the card’s information and could recall with little difficulty, Bad means the user had trouble recalling the information or didn’t know at all.
The random selection of a card is governed by the following rules:
A selection variable is set by counting the number of cards with a 2 Repeat Twice and 1 Repeat Once status. A 2 Repeat Twice card is counted with double value.
iSelection = (2 x “2 Repeat Twice”) + “1 Repeat Once”
if this variable iSelection is < 10, the next random selected card will be a 0 Unseen card.
if the variable iSelection is > 20, the next random selected card can only be a 1 Repeat Once or 2 Repeat Twice card.
if the number lies between 10 and 20, a random selection for any of the 3 types is done.
When answering a card, the status is changed according to its current status and answer given.
If “BAD” is answered, the status is set to 2 Repeat Twice each time.
If “GOOD” is answered, the status is changed according to its current status:
0 Unseen -> 1 Repeat Once
1 Repeat Once -> 3 Completed
2 Repeat Twice -> 1 Repeat Once
The main features of this algorithm is that it controls the number of new cards vs repetitions of old cards introduced depending on the user’s skill level. If the user continually doesn’t know the answer, only 10 cards are shown until the user begins to learn them. If the user knows all the cards (i.e. for practise only) each card is only shown twice and the user can get through the list of cards as quickly as possible. If the user knows _some_ of the cards but has difficulty with others, the words with difficulty are retained for repeating, whilst allowing the known words to pass through quickly. The difficulty level therefore will always match the user’s ability.
My current implementation uses SQLITE database to hold the card data and statuses, with JAVA and Objective-C clients to access the data for the relevant platforms.
Currently I am using this Algorithm in my own Flashcard app on Android and App-Store and it largely functions as required. A problem I have found however is that due to the random selection of the cards, the chance that the same is selected two or three times in a row is quite high. In a deck of 150 cards that has happened to me at least 5 times. A fix in future might be to ensure the same card is not picked twice if possible.