[Question]
  [
## Introduction
A decimal is terminating if it has a finite number of decimal digits. For example, 0.4 (2/5) is terminating because it has one decimal digit.
A decimal is purely periodic if it has an infinite number of decimal digits and has no decimal digits before its repetent (the part of the decimal that repeats.) For example, 0.142857142857142… (1/7) is purely periodic because it has a repetend 142857, which starts repeating immediately after the decimal point.
A decimal is eventually periodic if it has an infinite number of decimal digits and has a finite number of decimal digits before its repetent (the part of the decimal that repeats.) For example, 0.166666666666666… (1/6) is eventually periodic because its repetend 6 starts repeating after a 1.
## Your task
Write a program or function that, when given numbers *p* and *q* (integers, 0 <= *p* < *q* <= 100), will determine if the decimal representation of *p*/*q* is terminating, purely periodic, or eventually periodic.
You must output `a` if it's Terminating (i.e. 0.1), `b` if it's Purely Periodic (i.e. 0.333...), or `c` if it's Eventually Periodic (i.e. 0.166...), where `a`, `b`, and `c` are any distinct, constant strings of your choice.
## Test cases
```
0/1 => Terminating
0/2 => Terminating
1/2 => Terminating
0/3 => Terminating
1/3 => Purely Periodic
2/3 => Purely Periodic
0/4 => Terminating
1/4 => Terminating
2/4 => Terminating
3/4 => Terminating
0/5 => Terminating
1/5 => Terminating
2/5 => Terminating
3/5 => Terminating
4/5 => Terminating
0/6 => Terminating
1/6 => Eventually Periodic
2/6 => Purely Periodic
3/6 => Terminating
4/6 => Purely Periodic
5/6 => Eventually Periodic
0/7 => Terminating
1/7 => Purely Periodic
2/7 => Purely Periodic
3/7 => Purely Periodic
4/7 => Purely Periodic
5/7 => Purely Periodic
6/7 => Purely Periodic
0/8 => Terminating
1/8 => Terminating
2/8 => Terminating
3/8 => Terminating
4/8 => Terminating
5/8 => Terminating
6/8 => Terminating
7/8 => Terminating
0/9 => Terminating
1/9 => Purely Periodic
2/9 => Purely Periodic
3/9 => Purely Periodic
4/9 => Purely Periodic
5/9 => Purely Periodic
6/9 => Purely Periodic
7/9 => Purely Periodic
8/9 => Purely Periodic
0/10 => Terminating
1/10 => Terminating
2/10 => Terminating
3/10 => Terminating
4/10 => Terminating
5/10 => Terminating
6/10 => Terminating
7/10 => Terminating
8/10 => Terminating
9/10 => Terminating
0/11 => Terminating
1/11 => Purely Periodic
2/11 => Purely Periodic
3/11 => Purely Periodic
4/11 => Purely Periodic
5/11 => Purely Periodic
6/11 => Purely Periodic
7/11 => Purely Periodic
8/11 => Purely Periodic
9/11 => Purely Periodic
10/11 => Purely Periodic
0/12 => Terminating
1/12 => Eventually Periodic
2/12 => Eventually Periodic
3/12 => Terminating
4/12 => Purely Periodic
5/12 => Eventually Periodic
6/12 => Terminating
7/12 => Eventually Periodic
8/12 => Purely Periodic
9/12 => Terminating
10/12 => Eventually Periodic
11/12 => Eventually Periodic
0/13 => Terminating
1/13 => Purely Periodic
2/13 => Purely Periodic
3/13 => Purely Periodic
4/13 => Purely Periodic
5/13 => Purely Periodic
6/13 => Purely Periodic
7/13 => Purely Periodic
8/13 => Purely Periodic
9/13 => Purely Periodic
10/13 => Purely Periodic
11/13 => Purely Periodic
12/13 => Purely Periodic
0/14 => Terminating
1/14 => Eventually Periodic
2/14 => Purely Periodic
3/14 => Eventually Periodic
4/14 => Purely Periodic
5/14 => Eventually Periodic
6/14 => Purely Periodic
7/14 => Terminating
8/14 => Purely Periodic
9/14 => Eventually Periodic
10/14 => Purely Periodic
11/14 => Eventually Periodic
12/14 => Purely Periodic
13/14 => Eventually Periodic
0/15 => Terminating
1/15 => Eventually Periodic
2/15 => Eventually Periodic
3/15 => Terminating
4/15 => Eventually Periodic
5/15 => Purely Periodic
6/15 => Terminating
7/15 => Eventually Periodic
8/15 => Eventually Periodic
9/15 => Terminating
10/15 => Purely Periodic
11/15 => Eventually Periodic
12/15 => Terminating
13/15 => Eventually Periodic
14/15 => Eventually Periodic
```
You can find all test cases [here](http://pastebin.com/raw/We01u4eF).
You are allowed to choose your own 3 values for the output, but it must be clear as to which one it is.
Remember, this is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the code with the smallest number of bytes wins.
## Hints
Terminating:
> 
>  The prime factorization of a terminating decimal's denominator in simplest form consists only of 2s and 5s.
> 
> 
> 
Purely Periodic:
> 
>  The prime factorization of a purely periodic decimal's denominator in simplest form does not include any 2s or 5s.
> 
> 
> 
Eventually Periodic:
> 
>  The prime factorization of an eventually periodic decimal's denominator in simplest form includes at least one 2 or 5, but also includes other numbers.
> 
> 
> 
## Leaderboards
Here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language.
To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:
```
# Language Name, N bytes
```
where `N` is the size of your submission. If you improve your score, you *can* keep old scores in the headline, by striking them through. For instance:
```
# Ruby, <s>104</s> <s>101</s> 96 bytes
```
If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the *last* number in the header:
```
# Perl, 43 + 2 (-p flag) = 45 bytes
```
You can also make the language name a link which will then show up in the leaderboard snippet:
```
# [><>](http://esolangs.org/wiki/Fish), 121 bytes
```
```
var QUESTION_ID=95926,OVERRIDE_USER=12537;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
```
```
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
```
```
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>
```
  
[Answer]
## JavaScript (ES6), ~~70~~ .. ~~68~~ 53 bytes
```
f=(a,b,s=[],x)=>a?(s[a]^=a)?f(a*10%b,b,s,x||a):x==a:0
```
Returns **0** for terminating, **true** for purely periodic and **false** for eventually periodic.
### How it works
What we're doing here is actually simulating a division by hand:
1. `a?...:0` - If the numerator is zero, we stop here and return `0`. The sequence is *terminating*.
2. `(s[a]^=a)?...:x==a` - If we've already encountered this numerator before, it means that the sequence is periodic and is going to repeat forever. We stop here and return either `true` if `a` is equal to the first value `x` of the sequence (*purely periodic*) or `false` if it's not (*eventually periodic*).
3. `f(a*10%b,b,s,x||a)` - Else, we multiply the numerator `a` by 10. We compute the remainder of the division by the denominator `b`. And we repeat the process by using this remainder as the new numerator. (We also pass `a` as the first value of the sequence if it's not already stored in `x`.)
### Example
* **Blue**: numerator = 1
* **Green**: denominator = 7
* **Red**: multiplications by 10
* **Black**: remainders
* **Gray**: quotient digits (we don't really care about them here, and the above code is not computing them at all)
[![division](https://i.stack.imgur.com/UfB9t.png)](https://i.stack.imgur.com/UfB9t.png)
[Answer]
# Python, ~~62~~ ~~61~~ 59 bytes
```
f=lambda n,d,r=[0,0]:(r[:3]+r).count(n)or f(10*n%d,d,r+[n])
```
Prints **1** for eventually periodic, **2** for purely periodic, and **4** for terminating.
Verify all test cases on [repl.it](https://repl.it/Dt9c/3).
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 10 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
:gÆfḍ⁵ṢQ¬Ḅ
```
Accepts denominator and numerator (in that order) as arguments. Returns **0** for terminating, **1** for purely periodic, and **2** for eventually periodic. [Try it online!](http://jelly.tryitonline.net/#code=OmfDhmbhuI3igbXhuaJRwqzhuIQ&input=&args=MTE+NA) or [verify all test cases](http://jelly.tryitonline.net/#code=OmfDhmbhuI3igbXhuaJRwqzhuIQKw6ci4oG8xpM&input=MCwwLDAsMCwxLDEsMCwwLDAsMCwwLDAsMCwwLDAsMCwyLDEsMCwxLDIsMCwxLDEsMSwxLDEsMSwwLDAsMCwwLDAsMCwwLDAsMCwxLDEsMSwxLDEsMSwxLDEsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDEsMSwxLDEsMSwxLDEsMSwxLDEsMCwyLDIsMCwxLDIsMCwyLDEsMCwyLDIsMCwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwwLDIsMSwyLDEsMiwxLDAsMSwyLDEsMiwxLDIsMCwyLDIsMCwyLDEsMCwyLDIsMCwxLDIsMCwyLDIsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMCwyLDEsMiwxLDIsMSwyLDEsMCwxLDIsMSwyLDEsMiwxLDIsMCwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDA&args=MSwyLDIsMywzLDMsNCw0LDQsNCw1LDUsNSw1LDUsNiw2LDYsNiw2LDYsNyw3LDcsNyw3LDcsNyw4LDgsOCw4LDgsOCw4LDgsOSw5LDksOSw5LDksOSw5LDksMTAsMTAsMTAsMTAsMTAsMTAsMTAsMTAsMTAsMTAsMTEsMTEsMTEsMTEsMTEsMTEsMTEsMTEsMTEsMTEsMTEsMTIsMTIsMTIsMTIsMTIsMTIsMTIsMTIsMTIsMTIsMTIsMTIsMTMsMTMsMTMsMTMsMTMsMTMsMTMsMTMsMTMsMTMsMTMsMTMsMTMsMTQsMTQsMTQsMTQsMTQsMTQsMTQsMTQsMTQsMTQsMTQsMTQsMTQsMTQsMTUsMTUsMTUsMTUsMTUsMTUsMTUsMTUsMTUsMTUsMTUsMTUsMTUsMTUsMTUsMTYsMTYsMTYsMTYsMTYsMTYsMTYsMTYsMTYsMTYsMTYsMTYsMTYsMTYsMTYsMTYsMTcsMTcsMTcsMTcsMTcsMTcsMTcsMTcsMTcsMTcsMTcsMTcsMTcsMTcsMTcsMTcsMTcsMTgsMTgsMTgsMTgsMTgsMTgsMTgsMTgsMTgsMTgsMTgsMTgsMTgsMTgsMTgsMTgsMTgsMTgsMTksMTksMTksMTksMTksMTksMTksMTksMTksMTksMTksMTksMTksMTksMTksMTksMTksMTksMTksMjAsMjAsMjAsMjAsMjAsMjAsMjAsMjAsMjAsMjAsMjAsMjAsMjAsMjAsMjAsMjAsMjAsMjAsMjAsMjA+MCwwLDEsMCwxLDIsMCwxLDIsMywwLDEsMiwzLDQsMCwxLDIsMyw0LDUsMCwxLDIsMyw0LDUsNiwwLDEsMiwzLDQsNSw2LDcsMCwxLDIsMyw0LDUsNiw3LDgsMCwxLDIsMyw0LDUsNiw3LDgsOSwwLDEsMiwzLDQsNSw2LDcsOCw5LDEwLDAsMSwyLDMsNCw1LDYsNyw4LDksMTAsMTEsMCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwwLDEsMiwzLDQsNSw2LDcsOCw5LDEwLDExLDEyLDEzLDAsMSwyLDMsNCw1LDYsNyw4LDksMTAsMTEsMTIsMTMsMTQsMCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwwLDEsMiwzLDQsNSw2LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDAsMSwyLDMsNCw1LDYsNyw4LDksMTAsMTEsMTIsMTMsMTQsMTUsMTYsMTcsMCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwwLDEsMiwzLDQsNSw2LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5).
### How it works
```
:gÆfḍ⁵ṢQ¬Ḅ  Main link. Arguments: d (denominator), n (numerator)
 g          Compute the GCD of d and n.
:           Divide d by the GCD, yielding the denominator of the simplified form.
  Æf        Yield all prime factors of the previous result.
    ḍ⁵      Test 10 for divisibility by each prime factor.
            This yields 1 for 2 and 5, 0 for all other primes.
      Ṣ     Sort the resulting Booleans.
       Q    Unique; deduplicate the sorted Booleans.
        ¬   Logical NOT; replace 0 with 1 and vice versa to yield one of the
            following arrays.
              [    ]  <- no prime factors (denominator 1)
              [   0]  <- only 2 and 5
              [1   ]  <- neither 2 nor 5
              [1, 0]  <- mixed
         Ḅ  Unbinary; convert from base 2 to integer.
            This maps [] and [0] to 0, [1] to 1, and [1, 0] to 2.
```
[Answer]
# Perl, ~~49~~ ~~46~~ 45 bytes
Includes +3 for `-p`
Based on [Dennis](https://codegolf.stackexchange.com/users/12012/dennis)'s elegant idea but implemented in a perlish way
Give input numbers on STDIN
```
terminating.pl <<< "2 26"
```
`termninating.pl`:
```
#!/usr/bin/perl -p
/ /;1until$a{$_=$_*10%$' or$`}++;$_=$a{$`}
```
Prints a 2 if terminating. 1 if periodic and nothing if eventually periodic
[Answer]
## Batch, 247 bytes
```
@set/af=%1,g=%2
:g
@if not %f%==0 set/ah=g,g=f,f=h%%g&goto g
@set/ae=d=%2/g
:l
@set/ag=-~!(d%%2)*(!(d%%5)*4+1)
@if not %g%==1 set/ad/=g&goto l
@if %d%==1 (echo Terminating)else if %d%==%e% (echo Purely Periodic)else echo Eventually Periodic
```
Uses my fast gcd10 trick from [Fraction to exact decimal](https://codegolf.stackexchange.com/questions/89215/fraction-to-exact-decimal). Obviously I could save a bunch of bytes by using a custom output format.
[Answer]
# JavaScript (ES6), ~~91~~ ~~88~~ ~~85~~ ~~79~~ ~~75~~ ~~74~~ 78 bytes
```
f=(n,d,g=(a,b)=>b?g(b,a%b):a,t=g(d/=c=g(n,d),10))=>n*~-d?t-1?f(n/c,d/t)/0:1:+f
```
Outputs `NaN` for terminating, `1` for purely periodic, and `Infinity` for eventually periodic.
### Test snippet
```
f=(n,d,g=(a,b)=>b?g(b,a%b):a,t=g(d/=c=g(n,d),10))=>n*~-d?t-1?f(n/c,d/t)/0:1:+f
l=(n,d)=>console.log(n+"/"+d+":",f(n,d))
for(i=1;i<10;i++)for(j=0;j<i;j++)l(j,i);
```
## Explanation
First, we divide both **n** and **d** by **gcd(d,n)**, to reduce the fraction to its simplest form. This lets us avoid situations like **2/6** where the result would otherwise be calculated as purely periodic. We also define variable **t** as **gcd(d,10)**; this will be used later.
The first check is whether **n** is **0** or **d** is **1**. If **n\*(d-1)** is 0, we return `+f`, or **NaN**: the fraction is **terminating**.
The next check is whether **t** is **1**. If so, we return **1**: the fraction is **purely periodic**.
If **t** is *not* **1**, we divide **d** by **t**, run the whole function again, and divide by 0. If **n/(d/t)** is terminating, this returns **NaN/0 = NaN**: the fraction is **terminating**. Otherwise, it returns **1/0 = Infinity**: the fraction is **eventually periodic**.
[Answer]
# Mathematica, 41 bytes
```
Ordering@{d=Denominator@#,GCD[d,10^d],1}&
```
Outputs `{3,1,2}` if the input has a terminating decimal expansion, `{2,3,1}` if the input has a purely periodic decimal expansion, and `{3,2,1}` if the input has an eventually periodic decimal expansion. 
Based on the sneaky trick: if `d` is the denominator of a fraction in lowest terms, then the greatest common divisor of `d` and `10^d` equals `d` if `d` has only 2s and 5s in its prime factorization; equals `1` if `d` has neither 2s nor 5s in its prime factorization; and equals some integer in between if `d` has 2s/5s and other primes.
The `Ordering` function just reports where the smallest, next smallest, and largest elements of the triple are, with ties broken left-to-right.
Flaw: returns the variant output `{1,2,3}` instead of `{3,1,2}` if the input is 0.
# Mathematica, 46 bytes, perverse
```
b[a][[Log[d=Denominator@#,GCD[d,10^d]]]][[1]]&
```
Returns `a[[1]]` if the input has a terminating decimal expansion, `b[[1]]` if the input has a purely periodic decimal expansion, and `b[a]` if the input has an eventually periodic decimal expansion. Throws an error in all cases!
As above, we want to know whether that greatest common divisor equals 1, d, or somewhere in between. The base-d logarithm of that gcd equals 0, 1, or something in between.
Now we start torturing Mathematica. `b[a][[n]]` denotes the `n`th part of the expression `b[a]`. So `b[a][[1]]` returns `a`; `b[a][[0]]` returns `b`; and `b[a][[x]]`, where `x` is a number between 0 and 1, makes Mathematica throw the error "Part::pkspec1: The expression `x` cannot be used as a part specification." and returns `b[a][[x]]` unevaluated.
This already distinguishes the three cases appropriately, except that the output for the eventually periodic case is `b[a][[x]]`, which is non-constant because `x` is the actual logarithm of something. So then we apply `[[1]]` to the outputs already described. Because of how Mathematica internally represents `b[a][[x]]`, the result of `b[a][[x]][[1]]` is simply `b[a]`. On the other hand, applying `[[1]]` to `a` results in a different error "Part::partd: Part specification a[[1]] is longer than depth of object." and returns `a[[1]]` unevaluated (and similarly for `b`).
Flaw: lies about the input 0, returning `b[a]` instead of `a[[1]]`.
[Answer]
# C 173 Bytes
Takes two integers from stdin, prints 1 for purely periodic, -1 for eventually periodic, and 0 for terminating.
```
int r;main(_,n,d){_-1?_-2?d-1?d%2&&d%5?r=1:d%2?main(3,n,d/5):main(3,n,d/2),r=r?-1:0:r=0:d?main(2,d,n%d):r=n:scanf("%d %d",&n,&d),main(2,n,d),main(3,n/r,d/r),printf("%d",r);}
```
Ungolfed:
```
// returns 1 for periodic, 0 for terminating, <0 for eventually periodic
int periodic(int num, int den) { // 3
    if (den == 1) return 0;
    if (den % 2 && den % 5) // pure periodic
        return 1;
    if (den % 2) return periodic(num,den/5) ? -1 : 0;
    return periodic(num,den/2) ? -1 : 0;
}
int gcd(int num, int den) { // 2
    if (den) 
        return gcd(den,num%den);
    return num;
}
int main(n,d) // 1
{
    scanf("%d %d",&n,&d);
    printf("%d",periodic(n/gcd(n,d),d/gcd(n,d)));
    return 0;
}   
```
Half-golfed:
```
int r;main(_,n,d){
    _-1? 
    _-2?
    // periodic
    d-1?
        d%2&&d%5?
            r=1:
                d%2?
                    main(3,n,d/5): //periodic
                    main(3,n,d/2), //periodic
                        r=r?-1:0:
                r=0
    // gcd
    :d?main(2,d,n%d):r=n // gcd
    // main
    :scanf("%d %d",&n,&d),
     main(2,n,d), // gcd
     main(3,n/r,d/r), // periodic
     printf("%d",r);
}
```
[Answer]
# [Actually](http://github.com/Mego/Seriously), 15 bytes
This is based on [Dennis' Jelly answer](https://codegolf.stackexchange.com/a/95934/47581). **0** is terminating, **1** is purely periodic, and **2** is eventually periodic. Golfing suggestions welcome. [Try it online!](http://actually.tryitonline.net/#code=4pa8Tnk5deKZgCVTUuKZgmLilZQyQMK_&input=WzEsMjBd)
```
▼Ny9u♀%SR♂b╔2@¿
```
**Ungolfing**
```
      Implicit input [a, b].
▼     Divide a and b by gcd(a,b).
Ny    Get the unique prime divisors of the reduced denominator.
9u    Push 10.
♀%    10 mod every member of uniq_p_d.
SR    Sort the mods and reverse.
♂b    Logical buffer. Converts every (10 % p != 0) to 1, and everything else to 0.
        Meaning if 2 or 5 divided b, they are now 0, and every other prime is now 1.
╔     Uniquify the list.
        If terminating, return [0].
        If purely periodic, return [1].
        If eventually periodic, return [1, 0].
        Else, (if b was 1), return [].
2@¿   Convert from binary to decimal. Return 0, 1, or 2.
      Implicit return.
```
[Answer]
# Mathematica, 44 bytes
```
If[ListQ@Last@#,Length@#==1]&@@RealDigits@#&
```
Returns `Null` for Terminating, `True` for purely periodic, and `False` for eventually periodic.
# Explanation
```
RealDigits
```
Find the decimal expansion of N. (repeated digits are surrounded by an extra head `List {}`).
```
ListQ@Last@#
```
Check whether the last element of the decimal expansion is a `List`.
```
Length@#==1
```
If the above condition is `True`, check whether the entire decimal expansion consists of one thing. (A `List` counts as one entity). (returns `True` or `False`)
(If the condition is `False`, then a `Null` is returned because there is no third argument for `If`)
[Answer]
# [Pyth](https://github.com/isaacg1/pyth), ~~31~~ 27 bytes
```
AQ={P/HiGH?l@H=j25T?l-HT1Z2
```
Input
```
4,12
```
You can try it [here](https://pyth.herokuapp.com/?code=AQ%3D%7BP%2FHiGH%3Fl%40H%3Dj25T%3Fl-HT1Z2&input=4%2C12&debug=0). Prints **1** for eventually periodic, **2** for purely periodic, and **0** for terminating. This is my first time answering in codegolf. Any suggestions are welcome.
## Explanation
```
AQ                                              // 1st element to G and 2nd element to H
    ={P                                         // Assign unique prime factors to H
        /H                                      // Simplify denominator
            iGH                                 // Find GCD
                ?l                              // Check length of filtered H
                    @H                          // Filter H by Y
                        =j25T                   // Assign a set [2,5] to T
                                ?l-HT           // Check length of H - T
                                        1Z2     // Print result
                                    
```
Note that [2,3] filtered by [2,5] = [2] but [2,3,5] - [2,5] = [3].
[Answer]
## PARI/GP, 64 bytes
```
f(x,y)=if(setminus(factor(y=y/gcd(x,y))[,1]~,[2,5]),gcd(y,10)>1)
```
Outputs nothing for terminating, 0 for purely and 1 for eventually periodic.
Not very fancy, I hoped for something better when I started.
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), ~~16~~ 11 bytes
Saved 5 bytes thanks to @Adnan!
```
¿²r/fTrÖbÙJ
```
Prints 0 for Purely Periodic, 1 for Terminating, and 10 for Eventually Periodic.
Explanation:
```
                 # Implicit input
                 # Implicit input
  ¿              # Take GCD of numbers
   ²             # Push top value from input register
    r            # Reverse stack order
     /           # Divide (denominator by GCD)
      f          # Find unique prime factors
       TrÖ       # Test 10 for divisibility
          b      # Convert (True -> 1, False -> 0)
           Ù     # Deduplicate array
            J    # Join chars in array
                 # Implicit print
```
Input is taken as *p* newline *q*.
[Try it online!](http://05ab1e.tryitonline.net/#code=wr_CsnIvZlRyw5Ziw5lK&input=MQoz)
[Answer]
# PHP, 126 Bytes
```
$d=$argv[2];$a[]=$n=$argv[1];while($n%$d&&!$t){$n*=10;$t=in_array($n%=$d,$a);$a[]=$n;}if($a[1]&&$t)$t+=$a[0]!=end($a);echo+$t;
```
Prints 0 for terminated and 1 for purely periodic
2 for eventually.
Let me explain if a numerator is twice in the array here starts the periodic session
if it is terminated the `echo end($a);` value is `0`
If you not trust me put `$t=count($a)>$d?2:0;` in the loop
To make it more clear please add
`print_r($a);` or `var_dump($a);` or `json_encode($a);` after the loop
you can see one numerator twice or a zero at the end of the array
if a numerator is twice count the items between the two items and you can get the length of the periodic 
and you can see the position by the first numerator where the periodic begins
So after that we can find the position and the length of the periodic sequence with `if($t){echo $p=array_search(end($a),$a);echo $l=count($a)-$p-1;}`
## Visualize the periodic
```
$d=$argv[2];
$a[]=$n=$argv[1]; #array numerator
$r[]=$n/$d^0; #array result of the division
$r[]=".";
while($n%$d&&!$t){
    $n*=10; 
    $n-=$d*$r[]=$n/$d^0;
    $t=in_array($n%=$d,$a); #stop if numerator is twice 
    $a[]=$n;
}
if($a[1]&&$t)$t+=$a[0]!=end($a); #periodic term starts directly?
if($t){
    echo $p=array_search(end($a),$a)."\n"; #output the beginning position of the periodic term
    echo $l=count($a)-$p-1; #output the length of the periodic term
    echo "\n";
    echo str_repeat(" ",2+$p).str_repeat("_",$l-1)."\n"; #visualize the periodic term
    #echo join(array_slice($r,0,1+$p)).join(array_slice($r,1+$p))."\n";# if you want only the periodic term 
    echo join($r); #result if the division
}
echo+$t; # 0 terminated 1+2 periodic 2 periodic start not directly
```
## Output visualize the periodic term
```
1/18
   _
0.05
1/12
    _
0.083
1/13
  ______
0.076923
1/14
   ______
0.0714285
```
An other way with 130 Bytes
```
$r=bcdiv(($z=$argv)[1],$z[2],400);for($p=2;$i++<200;)if(substr($r,2,$i)==substr($r,2+$i,$i))$p=1;echo strlen(rtrim($r,0))<50?0:$p;
```
Expanded Version
```
$r=bcdiv(($z=$argv)[1],$z[2],400); # 100 is the maximal denominator 
# we need a string length with the double value of the sum the length from 1 until the denominator
for($p=2;$i++<200;)if(substr($r,2,$i)==substr($r,2+$i,$i))$p=1;
# all results begin with 0. 
#take two substrings with the same length after that and comparize both. 
#if we found 2 same substrings we have a periodic which starts at the first decimal place
echo strlen(rtrim($r,0))<50?0:$p; 
# if we can trim the length of the result we have a terminated result
```
]