[Question]
  [
[Toki Pona](https://tokipona.org) is a constructed language with 137ish words, designed to constrain the speaker to expressing ideas in a simple and straightforward manner, reducing ideas to more essential forms.
Often, people attempt to avoid directly expressing numeric quantities in Toki Pona, opting to express them in more practical terms. if one has a very large amount of money ("mani mute mute"), does it matter if it is $3,532,123 or $3,532,124?
However, Toki Pona does have a basic additive number system, (as well as some others that people have proposed but are not widely used) which is capable of expressing exact quantities.
Toki Pona uses the follow words for numbers:
| word | value |
| --- | --- |
| ala | 0 |
| wan | 1 |
| tu | 2 |
| luka | 5 |
| mute | 20 |
| ale | 100 |
The quantity expressed by a series of these words is the sum of all of their values.
A quantity must be expressed in as few words as possible, with the words ordered from greatest value to least. for instance, simply summing the values of the words, 6 could be expressed "tu tu tu", "luka wan", "wan luka", "wan wan wan wan wan wan", or some other variation. however, a valid program will only generate "luka wan" for 6.
# Challenge
Write a program which takes as input a non-negative integer and outputs this integer expressed in the Toki Pona number system.
Standard [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") rules apply. Spaces are required.
# Examples
| input | output |
| --- | --- |
| 0 | ala |
| 1 | wan |
| 2 | tu |
| 28 | mute luka tu wan |
| 137 | ale mute luka luka luka tu |
| 1000 | ale ale ale ale ale ale ale ale ale ale |
 
  
[Answer]
# [Python 2](https://docs.python.org/2/), 81 bytes
```
lambda n:n/100*'ale '+n/20%5*'mute '+n/5%4*'luka '+n%5/2*'tu '+n%5%2*'wan'or'ala'
```
[Try it online!](https://tio.run/##JYtBCsIwEEX3nmI2YTQWMo2GSsGbuBnRYDGdlJBQevoYKXwe7y3@suVPFFv9/VEDz88Xg4xieiKNHN6AZzGWlNM4l7ynU1eNoXz5X8oZqzGX3VXzlQVjamfG6mMCgUmAOug7sG23ZpehgYjGAyxpkgz@KKf6Aw "Python 2 – Try It Online")
The naive approach is surprisingly effective. The overhead of an iterative or recursive method seems too high, though I'd like to be proven wrong.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~41~~ 39 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
-2 thanks to [Unrelated String](https://codegolf.stackexchange.com/users/85334/unrelated-string)! (Golfed the method of "coin counting".)
```
;%\:ɗ“dÞ¦£‘Jx$ȯWị“&ḍṘṭ.½6²EmSFʂ5ȥṙẠ»Ḳ¤K
```
**[Try it online!](https://tio.run/##y0rNyan8/99aNcbq5PRHDXNSDs87tOzQ4kcNM7wqVE6sV3q4uxsoqvZwR@/DnTMe7lyrd2iv2aFNrrnBbqeaTE8sfbhz5sNdCw7tfrhj06El3v8Pt2tG/v9voKNgqKNgBEQWQJaxOZAwMDAAAA "Jelly – Try It Online")**
### How?
```
;%\:ɗ“dÞ¦£‘Jx$ȯWị“...»Ḳ¤K - Link: non-negative integer, n
     “dÞ¦£‘               - [100,20,5,2]
    ɗ                     - last three links as a dyad - f(n, [100,20,5,2]):
;                         -   (n) concatenate ([100,20,5,2]) -> [n,100,20,5,2]
  \                       -   cumulative reduce by:
 %                        -     modulo -> [n, n%100, n%100%20, n%100%20%5, n%100%20%5%2]
   :                      -     integer divide ([100,20,5,2]) -> [n//100, n%100//20, n%100%20//5, n%100%20%5//2, n%100%20%5%2]
           Jx$            - repeat indices - e.g. [0,3,2,2,0] -> [2,2,2,3,3,4,4]
               W          - wrap -> [n]
              ȯ           - logical OR (if n was 0 we now get [0] in place of [])
                 “...»Ḳ¤  - ["ale","mute","luka","tu","wan","ala"]
                ị         - index into (1-indexed and modular)
                        K - join with spaces
```
[Answer]
# [Pip](https://github.com/dloscutoff/pip), 63 bytes
```
Yay?{x:y//aYy%ab.sRLx}MZ[h20 5 2o]"ale mute luka tu wan"^s"ala"
```
Takes the number as a command-line argument. [Try it online!](https://tio.run/##K8gs@P8/MrHSvrrCqlJfPzGyUjUxSa84yKei1jcqOsPIQMFUwSg/VikxJ1Uht7QkVSGnNDtRoaRUoTwxTymuGCieqPT//39DY3MA "Pip – Try It Online")
### Explanation
Yay?
```
; Copy the command-line argument from local variable a into global variable y
Ya
; If y is nonzero (truthy),
y?
  ; Take this function (explained below)
  {x:y//aYy%ab.sRLx}
 ; and map it to pairs of items from
 MZ
  ; this list of numbers
  [100 20 5 2 1]
  ; and this string of words, split on spaces
  "ale mute luka tu wan" ^ s
 ; Else (if y is zero), output ala
 "ala"
```
The mapping function gets a number as its first argument `a` and the corresponding word as its second argument `b`:
```
{
 ; Set x to y (the input number) int-divided by a (the Toki Pona number)
 x: y//a
 ; Update y to be y mod a
 Y y%a
 ; Concatenate b (the Toki Pona word) with space...
 b . s
 ; ... and return a list of x copies of that string
  RL x
}
```
[Answer]
# [Ruby](https://www.ruby-lang.org/), 92 bytes
```
->n{n<1?"ala":[100,20,5,2,1].map{|i|n-=i*j=n/i;"#{%w{luka wan tu mute ale}[i%12%5]} "*j}*""}
```
[Try it online!](https://tio.run/##BcHRCsIgFADQXxHDF3FLhb1U1oeIDzdw4FIZS5mhfrudc@T3b6xqTM9Y40O8MHjANy04Z5KzhUkmzBxgr821OClHNxWv7o4vlZzV5w@gEyJKGYWcLAJvu3ZESLKYjjDdOsW4D8nFnFyw39pK25EubNXFmD7@ "Ruby – Try It Online")
Saved some bytes by iterating directly through `100,20,5,2,1` and using the formula `i%12%5` to generate a unique index in the range `0..4`for each in order to lookup the word.
I'm pleasantly surprised that `n-=i*(j=n/i)` works as intended without brackets.
# [Ruby](https://www.ruby-lang.org/), 105 bytes
```
->n{n<1?a=["ala"]:5.times{|i|a=*a,"#{%w{ale mute luka tu wan}[i]} "*j=n/k=[100,20,5,2,1][i];n-=j*k}
a*""}
```
[Try it online!](https://tio.run/##NcxBCgIhFADQfaf4GG3EKRVmU1kHERc/cMBxRqKUMdSzW5vWD94rPT59Un24hRKu4o5KE1yQmPN4jG6171JdRUWRkX05bAUXC2uKFpbkEWKCDUPTzjQgdFbh5JUWnDPJ2cgkE@ZHlzComfq2Q0pI65KL/5zrE3Rmk87GtP4F "Ruby – Try It Online")
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal) `s`, 38 bytes
```
521f20p₁p(nḋ÷)WṪ«øßṀ∞HĊ∴ǑTṄ‟7«⌈ð+*‛Ż₅⟑
```
[Try it Online!](https://lyxal.pythonanywhere.com?flags=s&code=521f20p%E2%82%81p%28n%E1%B8%8B%C3%B7%29W%E1%B9%AA%C2%AB%C3%B8%C3%9F%E1%B9%80%E2%88%9EH%C4%8A%E2%88%B4%C7%91T%E1%B9%84%E2%80%9F7%C2%AB%E2%8C%88%C3%B0%2B*%E2%80%9B%C5%BB%E2%82%85%E2%9F%91&inputs=8&header=&footer=)
```
                         ‛Ż₅⟑ # Handle the base case 0 -> ala
521f20p₁p                     # Create the list 100,20,5,2,1
         (n  )                # Iterate over, pushing each time
           ḋ÷                 # Divmod ToS (initially input) by current number, and iterate - remainder becomes new ToS
              WṪ              # Wrap, getting all the divisions
                        *     # Dot product with
                «...«⌈ð+      # Words, each with a space appended
```
[Answer]
# [Retina 0.8.2](https://github.com/m-ender/retina/wiki/The-Language/a950ad7d925ec9316e3e2fb2cf5d49fd15d23e3d), 60 bytes
```
.+
$*
1{100}
ale 
1{20}
mute 
1{5}
luka 
11
tu 
1
wan
^$
ala
```
[Try it online!](https://tio.run/##K0otycxL/K@q4Z7wX0@bS0WLy7Da0MCglisxJ1UByDYCMnNLS8Bs01qunNLsRCDTkKukFEhxlSfmccWpANUm/v9vAOQbcRlZcBkam3MBjTAAAA "Retina 0.8.2 – Try It Online") Link includes test cases. Explanation:
```
.+
$*
```
Convert to unary.
```
1{100}
ale 
1{20}
mute 
1{5}
luka 
11
tu 
1
wan
```
Greedily match the appropriate numbers. `wan` doesn't need a space since it can only appear once.
```
^$
ala
```
Fix `0` separately.
[Answer]
# [JavaScript (V8)](https://v8.dev/), ~~109~~ 96 bytes
```
x=>(g=s=>n=>(s+" ").repeat(x/n,x%=n))`ale`(100)+g`mute`(20)+g`luka`(5)+g`tu`(2)+g`wan`(1)||"ala"
```
[Try it online!](https://tio.run/##Tc7LCsIwEAXQvV8hAWGG@kgrajfpt2SQtFTTUPKoWfTfYyoI2Z17uQPzooXc046zPy1t6kWKooNBONGZDFexPcOzVbMiD/FijvEgDKIkrSTUnGM1yCn4HJqfdXiThNtGH3K54UMmb3FdGWliabaj8dADR9z9XRduCt/Lvi0Pro8y8fwJpi8 "JavaScript (V8) – Try It Online")
[Answer]
# Scratch, 46 blocks
```
set [output v] to [] // setup
set [count v] to [1]
if <(input) = [0]> then
set [output v] to [ala] // 0 in toki pona
else
repeat [5] // every number word
repeat ([floor v] of ((input) / (item (count) of [value v] // repeats every word in order
set [output v] to (join (output) (item (count) of [number v] // the script that generates the number
set [input v] to ((input) - (([floor v] of ((input) / (item (count) of [value v]))) * (item (count) of [value v]) // the script that updates the loop by finding a number
end
change [count v] by [1] // it makes sure that it will move on to the next word
```
[Try it online!](https://scratch.mit.edu/projects/566429457/)
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), 90 bytes
```
(n,r,t='0ala1wan2tu5luka20mute100ale'.match(n+'(\\D+)|$')[1])=>t?r?t+' '+f(r):t:f(n-1,-~r)
```
[Try it online!](https://tio.run/##jZDLDoIwEEX3fkUXJm3DsxijwSAb/0JcNFh8QWvKVDfGX8ciJOJjYZN2Med25mSO/MLrXB/O4Em1FU2RNES62oUEh7zk7MplBGZamhOPwsqAYKGtC@xXHPI9kQ4mWbZy6G2M6ZptaLKEVKfgYISdgmgaQ1wQ6THXu2va5ErWqhR@qXakICGidIHsCQJkZ43eKRtQa/FBowEF8wnnPbWwdUatvo396MMmsy77dBCD@Ov56m930Ln3n/64zQM "JavaScript (Node.js) – Try It Online")
---
# [JavaScript (Node.js)](https://nodejs.org), 91 bytes
```
n=>'100ale 20mute 5luka 2tu 1wan'.replace(/(\d+)(\D+)/g,(_,a,b)=>b.repeat(n/a,n%=a))||'ala'
```
[Try it online!](https://tio.run/##jZBBDoIwEEX3nqIb0zYiLRijiSkrj0FiBihErYVAqxvujrWaoLBxkpnN@zP/Zy5why5vz41Z67qQQykGLRIccQ5KopjfrJFoq@wVUGwsih6gcdjKRkEuCSNpsaIkPa4oqwJyCiDIqEiyl0CCIZpBoJcCKO17DArwkNe6q5UMVV2RknBKD8gVY8jRxS@MRuhMJzAeobFTtn9Dx3x6H95ln1@JNjsv9f7ySz2O2XX3GR/7s/NHD08 "JavaScript (Node.js) – Try It Online")
This solution may introduce a trailing space, while the first one won't.
[Answer]
# [APL (Dyalog Unicode)](https://www.dyalog.com/), 69 [bytes](https://github.com/abrudz/SBCS)
```
{×⍵:1↓∊(∊(⊂0 2∘⊤)@4⊢0 5 4 5⊤⍵)/' '(=⊂⊢)' ale mute luka tu wan'⋄'ala'}
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT///v/rw9Ee9W60MH7VNftTRpQHGXU0GCkaPOmY86lqi6WDyqGuRgYKpgomCKZAPVKupr66grmELVAWU0VRXSMxJVcgtLUlVyCnNTlQoKVUoT8xTf9Tdop6Yk6he@z/tUduER719j/qmevo/6mo@tN74UdtEIC84yBlIhnh4Bv8HCqQdWqFgoGCoYKRgZKFgaGyuYGhgYAAA "APL (Dyalog Unicode) – Try It Online")
`×⍵` if `⍵` is positive:  
`' '(=⊂⊢)' ale ...'` split into a list of substrings, where each starts with a space.  
`0 5 4 5⊤⍵` Mixed radix decode, this results in a length 4 vector, where the first three are the 100, 20 and 5 places, and the fourth encodes the 1 and 2 places  
`∊(⊂0 2∘⊤)@4` split the last into two numbers  
`/` repeat each string from the previously generated list this many times  
`1↓∊` join into a single string and remove leading space
`⋄'ala'` if the input was 0, return this string
[Answer]
# [Python 3](https://docs.python.org/3/), 143 142 132 bytes
```
def c(s):
 d,x={100:'ale',20:'mute',5:'luka',2:'tu',1:'wan'},''
 if s==0:x+='ala'
 else:
  for i in d:
   x+=s//i*(d[i]+' ')
   s%=i
 print(x)
```
[Try it online!](https://tio.run/##JYzBCsIwDIbve4pcJK0rbFM8rNAnEQ9l7TA4u7G2OBGfvWaYQ/jy8f9Z3uk@h3Mpzo8wiCh1BU5t5tO1rUY7eVQnhmdOTBeNU35YVhpTRtVpfNmAX4VYAY0QjWn1VhvuWTZ@ip7fwTivQEAB3H4BB2LT0FG4K91qBJS7jQdDFSwrhSQ2Wf4wiH1TWHISkqf0ffkB "Python 3 – Try It Online")
Previous submission:
# [Python 3](https://docs.python.org/3/), 143 bytes
```
def c(s):
 if s==0:
  print('ala')
 else:
  d = {100:'ale',20:'mute',5:'luka',2:'tu',1:'wan'}
  for i in d:
   print(s//i*d[i],end=' ')
   s%=i
```
[Try it online!](https://tio.run/##LY3BCsIwEETv/Yq9yKZSaKp4aCBfIh5Ck@BiTUuTUET89rhB9zA8Zmdn11e6L@FcinUeJhFb1QB5iFpLJlg3CkmgmQ22Dbg5uupa0PAepFS8cNidGJ45MV0Uzvlh2FKYMnaDwt0E/PCNXzYgoAC2NvyLY9/T0V7p1rlgNUJ9AhAPmsovMImqFNacRMtTxrF8AQ "Python 3 – Try It Online")
Thank you Jo King for pointing out non inclusion of whitespace  
emanresu A, have provided the links now  
Thank you Kevin Cruijssen and Jo King♦ for the `if s==0` contraction
**Jo King♦'s solution:**
# [Python 3](https://docs.python.org/3/), 116 bytes
```
def c(s,d={100:'ale',20:'mute',5:'luka',2:'tu',1:'wan'},x=''):
 for i in d:x+=s//i*(d[i]+' ');s%=i
 print(x or'ala')
```
[Try it online!](https://tio.run/##FYxLCsIwFAD3PcXbyEtsoK3ioik5ibgITYsPaxrywYh49hhnNcxi3Dved3suxSwrzCwIoz5D30vU24LiVOWZYrWLxC09dE0SY0IxSHxpi1@RFSKXDay7BwKyYGRuVeg6OjJzpVuLgHwKB0UNOE82sgy7r3uNvLCZ/QtZlyLjlTKO5Qc "Python 3 – Try It Online")
[Answer]
# [Python 3](https://docs.python.org/3/), 191 bytes
```
def f(x):
	k=[[]]+[0]*x
	for i in range(1,1+x):
		for j,q in[[1,"wan"],[2,"tu"],[5,"luka"],[20,"mute"],[100,"ale"]]:
			if j<=i:p=k[i-j]+[q];k[i]=min(k[i]or p,p,key=len)
	return k[x]or["ala"]
```
[Try it online!](https://tio.run/##HY9BbsMgEEXX5hSIFU4mEjiqUqXhFt0hFpaKG4xDCAKFXKAH6BF7EXfw7s38mf9n4itf7@G4rl92ohOv/Zl0XmltzF4Ls6ukm@6JOuoCTWP4tlyC3G9TmzDDAyWtJbDnGJgBPQDLpcEbsKX4cesJYLeSbWMpsBgXZNNMOjfR@aLcOSqv3WHG2If5QDTq5gJvgDERInj7UosNPemSzSUF6nVFTaMZhqzPq1ss/UzFom2lCs/K3IVYMu9xJ6ZWV6Ds7@eXAd21X/tVEEkGMrwTeTwRPE38Aw "Python 3 – Try It Online")
This is definitely not the shortest approach but it works in linear time using dynamic programming which was my intent. Even then, there is almost certainly a shorter linear approach, and more so probably a shorter dynamic programming method anyway.
**Edit**: never mind, I'm pretty sure [this solution](https://codegolf.stackexchange.com/a/234997/68942) is straight up constant time. You may as well just go upvote that instead; I haven't golfed in a while and tunneled on the wrong approach.
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 56 bytes
```
Ｎθ¿¬θala«Ｆ⪪”→"jρ§φ|XºM″℅^§¶⬤]r⊗x｜Ｋ” ¿Σι≧÷Ｉιφ«×⁺ι ÷θφ≧﹪φθ
```
[Try it online!](https://tio.run/##XY/NagMxDITP3qcQPmnBhbb0J9BTaC85JISmL6Am3kREa2/WdnooeXZXS2gPvYiB0XwjbQ80biNJrYswlLwq/acf8dS@NNwBrmJW3cJ65JDRkpBVx0vy8N2YLo6Am0FYrbtbIPHwCH3JHh5AypHgHnLR8UXBOrBglTRRN6VHVr2kYZ4S78M77w8ZFyG/8Zl33sErpawrDjqtM7995nrGB/c@4VpKQr5iHfxl8TSF2ilm/vGXcVckqu1g@s9cmkutT8@zenOWHw "Charcoal – Try It Online") Link is to verbose version of code. Explanation:
```
Ｎθ
```
Input `n`.
```
¿¬θala«
```
If `n` is zero then just print `ala`, otherwise:
```
Ｆ⪪”→"jρ§φ|XºM″℅^§¶⬤]r⊗x｜Ｋ” 
```
Split the compressed string `10 ale 5 mute 4 luka 2 tu 2 wan` on spaces and loop through the substrings.
```
¿Σι
```
If this substring is numeric, ...
```
≧÷Ｉιφ«
```
... integer divide the predefined variable `1000` by its value, otherwise:
```
×⁺ι ÷θφ
```
Integer divide the input by the predefined variable and print the space-suffixed current string that many times.
```
≧﹪φθ
```
Reduce the input modulo the predefined variable.
[Answer]
# [05AB1E (legacy)](https://github.com/Adriandmen/05AB1E/wiki/Commands), 39 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
т20 5Y)vy‰`}).•Ð‰#¬êAš’ŒÞƒÜ•#ð«*J¨'ãà‚à
```
[Try it online](https://tio.run/##AU8AsP8wNWFiMWX//9GCMjAgNVkpdnnigLBgfSku4oCiw5DigLAjwqzDqkHFoeKAmcWSw57GksOc4oCiI8OwwqsqSsKoJ8Ojw6DigJrDoP//MTM3) or [verify all test cases](https://tio.run/##MzBNTDJM/V9Waa@k8KhtkoKS/f@LTUYGCqaRmpXFZZWPGjYk1GrqPWpYdHgCkK18aM3hVY5HFz5qmHl00uF5xyYdngOUUj684dBqLa9DK9QPLz684FHDrMML/uv8jzbQMdQx0jHVMTLQMbLQMTQA8o3NQbRBLAA).
Uses the legacy version of 05AB1E (built in Python), because the new version of 05AB1E (built in Elixir) can't take the maximum on strings for \$n=0\$. This would be [**40 bytes** in the new version with an if/else construction](https://tio.run/##AU8AsP9vc2FiaWX//19pJ8Ojw6DDq9GCMjAgNVkpdnnigLBgfSku4oCiw5DigLAjwqzDqkHFoeKAmcWSw57GksOc4oCiI8OwwqvDl0rCqP//MTM3).
**Explanation:**
```
т                  # Push 100
 20                # Push 20
    5              # Push 5
     Y             # Push 2
      )            # Wrap all values into a list: [100,20,5,2]
       v           # Foreach `y` over these values:
        y‰         #  Divmod the (implicit) input or previous value by `y`
          `        #  Pop and push the n//y and n%y separated to the stack
       })          # After the loop: wrap all values on the stack into a list
.•Ð‰#¬êAš’ŒÞƒÜ•    # Push compressed string "ale mute luka tu wan "
               #   # Split it on spaces: ["ale","mute","luka","tu","wan",""]
                ð« # Append a space to each
*                  # Repeat these strings the previous calculated values amount of times
 J                 # Join this list of strings to a single string
  ¨                # Remove the trailing space
   'ãà‚           '# Pair it with dictionary string "ala"
       à           # Pop and push the maximum string of this pair
                   # (after which it is output implicitly as result)
```
[See this 05AB1E tip of mine (sections *How to use the dictionary?* and *How to compress strings not part of the dictionary?*)](https://codegolf.stackexchange.com/a/166851/52210) to understand why `.•Ð‰#¬êAš’ŒÞƒÜ•` is `"ale mute luka tu wan "` and `'ãà` is `"ala"`.
[Answer]
# [MathGolf](https://github.com/maxbergmark/mathgolf/blob/master/math_golf.txt), ~~44~~ 42 [bytes](https://github.com/maxbergmark/mathgolf/blob/master/code_page.py)
```
k♀I52ΓÉ‼/%]╖)☺ÿmuteÿluka╢→Γùwan▐ +m*y╡╖) ╙
```
[Try it online.](https://tio.run/##y00syUjPz0n7/z/70cwGT1Ojc5MPdz5q2KOvGvto6jTNRzN2Hd6fW1qSenh/Tml24qOpix61TQIq2VmemPdo2gQF7VytykdTF4KUKjyaOvP/fwMuQy4jLlMuIwMuIwsuQwMg39gcRBsAAA)
**Explanation:**
```
k             # Push the input-integer
 ♀            # Push 100
  I           # Push 20
   5          # Push 5
    2         # Push 2
     Γ        # Wrap the top four values into a list: [100,20,5,2]
      É       # Foreach over this list, using three characters as inner code-block:
       ‼      #  Apply the following two characters separated to the stack
        /     #   Integer-divide
        %     #   Modulo
       ]      # After the loop, wrap all (five) values on the stack into a list
╖)☺           # Push compressed string "ale"
ÿmute         # Push string "mute"
ÿluka         # Push string "luka"
╢→            # Push compressed string "tu"
     Γ        # Wrap all four values into a list: ["ale","mute","luka","tu"]
      ùwan▐   # Append "wan": ["ale","mute","luka","tu","wan"]
            + # Append a space to each: ["ale ","mute ","luka ","tu ","wan "]
m*            # Repeat each string the values amount of times
  y           # Join this list of strings together
   ╡          # Remove the trailing space
    ╖)        # Push compressed string "ala"
       ╙      # Only leave the maximum of the top two strings on the stack
              # (after which the stack joined together is output implicitly as result)
```
[Answer]
# TI-Basic, ~~163~~ ~~160~~ 152 bytes
```
"ale mutelukatu  wan→Str2
{ᴇ2,20,5,2,1→A
{3,4,4,2,3→B
"ala→Str1
Input N
If N:Then
For(I,1,5
While N≥ʟA(I
N-ʟA(I→N
Str1+" "+sub(Str2,4I-3,ʟB(I→Str1
End
End
sub(Ans,5,length(Ans)-4
```
-3 bytes for not storing the final output to `Str1`.  
-8 bytes thanks to [MarcMush](https://codegolf.stackexchange.com/users/98541/marcmush).
The output is stored in `Ans`.
[Answer]
# [jq](https://stedolan.github.io/jq/), ~~78~~ 77 bytes
```
./100%.?*"ale "+./20%5*"mute "+./5%4*"luka "+.%5/2%5*"tu "+.%5%2*"wan"//"ala"
```
[Try it online!](https://tio.run/##JcxLCoNAEIThq0hDg5kU0w@dRVY5SHDRi2wSDQk4ePyJ4q4@Cv7Xry3x7VsWU@WcKOZnR9csrlwSLXU9WXhMNNd3HOIifrxrPcWeaIsP3TuRPRDULu2hMDgGjCiwfSrcYD7gpj79AQ "jq – Try It Online")
A translation of dingledooper's Python approach.
In jq, `/` division is floaty but `%` seems to floor the result: `123.789%100` is `23`. Thus we write something like `.%5/2%5` to get the amount of "tu"s.
Slightly clever: `./100%.` will cause an error when the input is zero, and the `?` catches this and replaces with `null`, to which the `//` alternative-operator then provides `"ala"` as a fallback output. This is actually pretty useful because `""//"ala"` is not `"ala"` (i.e. `""` is not falsey in jq.)
Michael Chatiskatzi saved a byte, by moving `?` around so that I don't need whitespace between `?` and `//`. Thanks!
[Answer]
# [C (gcc)](https://gcc.gnu.org/), ~~118~~ 109 bytes
```
f(i){printf(i?(i-=99)>0?"ale ":(i+=80)>0?"mute ":(i+=15)>0?"luka ":(i+=3)>0?"tu ":"wan ":"ala");--i<1?:f(i);}
```
[Try it online!](https://tio.run/##jVHRboMgFH3vV9yYNIEqGa5Z1kqtH7L1gSB2ZNY2imkz46/PAaLuZckMXi7nwL2HgyBnIYahQAp3t1pV2mQZUiTd7/GRZgEvJQQJUmG6ow64tHpC4heHlO0n98jWAbo1y@DOKzvxkgeYEaIOcZbYNqwfTBu4cFUhDN0KzGcBLRvdvJ0ghY5GEEfwbMbOZNtXEyilPXN7xQevNyAfNym0zMcDrksEtqeddGujU@rEGUGesddZ8CWMJyz7jz/wSoprDchKV1UuH0YHZT49QKO@5LVAk0z85IHNjDAIQ7d7MmE2wlQazXD0ic2sf6BgnQM5glGs8UIW6PfKu2RKzU79VW0WmcC6we/WJ@kr9at@@BZFyc/NQO4/ "C (gcc) – Try It Online")
New best for C.
Thanks for Jo King finding 4 bytes for me.
[Answer]
# [Python 3.8 (pre-release)](https://docs.python.org/3.8/), 125 bytes
```
f=lambda n,b=1,l={1:'wan',2:'tu',5:'luka',20:'mute',100:'ale'}:n and(l[(a:=max(b for b in l if b<=n))]+' '+f(n-a,0))or'ala'*b
```
[Try it online!](https://tio.run/##DctBCsIwEEDRq8xuEhshrQhlaE4iLia0wWIyDSFFRTx77O6/xc@f@tjkMubSWnCRk58ZxHjXm@i@PeGLBc1AWHc0V8K4P/mwJUx7XdD09kiOC/5IgGVW8aaYXOK38hC2Ah5WgQhrAD850freIWAXlJzZWK23ctyMJ99yWaWqoIZR6/YH "Python 3.8 (pre-release) – Try It Online")
Definitely not the shortest approach, but is the only recursive Python solution AFAIK.
## Explanation
Takes in `n`, the number to translate, and two other utilities: `b` is used to indicate whether `ala` should be appended: it starts at 1 (if the original n is 0, then output `ala`, but is explicitly passed as 0 to exclude `ala` once `n` hits zero in a recursive call.
An additional dictionary `l` is produced, with the numbers being mapped to the Toki Pona translations. In the body of the function, an `and` expression produces the translation with maxima if `n` is truthy, if n is zero then it jumps to the `or` expression and outputs `ala` or `''` depending on the value of `b`. This ends the recursion.
If n is at least 1, we return the dictionary value with the maximal key below or equal to `n`, add a space, and then recall `f` with a reduced `n` accordingly.
[Answer]
# [Python 3](https://docs.python.org/3/), ~~154~~ 138 bytes
```
def f(n,p={100:'ale',20:'mute',5:'luka',2:'tu',1:'wan'},o=''):
	while n:t=[i for i in p if i<=n][0];n-=t;o+=p[t]+' '
	return o[:-1]or'ala'
```
[Try it online!](https://tio.run/##JY7BCoMwEETP5iv2tkojJEppic2XiAehBkPtJoQNUkq/3aZ0DsNjDjMTX7wG6o/jvjhwNclo31opg/O2oOwKPDMXOhvc8mMukUHOKLXBfSb8yGARGyOqffXbAmTYjh5cSODBE0TwDvzN0jSqaaDW8hBONo48nRBQVGnhnAjCaFo9hVRWZzz@VdrE5IlrV//cU8xcN0WHElp0orsK3V9E@aq@ "Python 3 – Try It Online")
-16 bytes thanks to [Jo King](https://codegolf.stackexchange.com/users/76162/jo-king).
---
This is an adaptation of [dingledooper](https://codegolf.stackexchange.com/users/88546/dingledooper)'s answer for Python 3 and with no space at the end:
# [Python 3](https://docs.python.org/3/), 93 bytes
```
lambda n:(n//100*'ale '+n//20%5*'mute '+n//5%4*'luka '+n%5//2*'tu '+n%5%2*'wan ')[:-1]or'ala'
```
[Try it online!](https://tio.run/##LY1BCsIwFET3OUU24acRaZIaKgFPoi4iWlpMf0NJKJ4@/qKzGObBMJM@eVywq8PlVmOYH8/A0UtsW6O1ghBfHA5EVgunYC75z06cFMTyDjsKRwUFufxAUN4Ccmiu/mjuy0ozAeo2TrRmfFonzHKQu0@YSpYNqWpmmGX2zEzXMzrXXw "Python 3 – Try It Online")
[Answer]
# [C (gcc)](https://gcc.gnu.org/), ~~138~~ \$\cdots\$ ~~121~~ 118 bytes
```
i;*v=L"\1\2\5\24d";f(n){n||puts("ala");for(i=4;~i;)n/v[i]?printf("wan \0$tu \0$$luka \0mute \0ale "+6*i),n-=v[i]:i--;}
```
[Try it online!](https://tio.run/##jZBbbsIwEEX/WcXIAsnOQ4SUPoSbdgPdAcmHlTjUajCIOIAK6dKbjvOiP5Vq2ePxXM/o6Kb@Jk2bRnHnGL2ReBGH8X0cLjPCc6rZRV@v@8qUlIhCEMbz3YGqaMm/FGd6flyr5HV/UNrklJyEhjiYmsrGaVF9CEy2lZF4iUICcR8cxTztR7ZtpXyf1w22wlYoTRlcJoDLFowsTblOIIJL4MHCgxD3E2Z3jxiCIKh5@zd9FwcH5HkvUyOzrqHl9MDS2MtUNrYULRHS9YpFutVvoeuw6j8O6UnQFqAWXelMnpEj4H36DKX6lLucDphs3hecscLBddvfgwmjETipM6OVEz6qg@mzDPwXQGLDbmJOf796l3DU6NRf00bIFcxKFlufZD@pntTNd5oXYlM2/ukH "C (gcc) – Try It Online")
*Saved 4 bytes thanks to [ErikF](https://codegolf.stackexchange.com/users/79060/erikf)!!!*  
*Saved ~~14~~ 17 bytes thanks to [AZTECCO](https://codegolf.stackexchange.com/users/84844/aztecco)!!!*  
[Answer]
# x86-16 machine code, PC DOS, 69 bytes
```
00000000: be1c 01ba 2101 85db 740b 83c2 06ac 983b  ....!...t......;
00000010: d872 f72b d8b4 09cd 2175 f3c3 6414 0502  .|.+....!u..d...
00000020: 0161 6c61 2024 2061 6c65 2024 206d 7574  .ala $ ale $ mut
00000030: 6520 246c 756b 6120 2474 7520 2420 2077  e $luka $tu $  w
00000040: 616e 2024 20                             an $
```
Listing:
```
BE 011C     MOV  SI, OFFSET V   ; quantity values to [SI]  
BA 0121     MOV  DX, OFFSET W   ; quantity words to [DX] 
85 DB       TEST BX, BX         ; check for zero case 
74 0B       JZ   QOUT           ; if zero, display 'ala' and exit 
        QNEXT: 
83 C2 06    ADD  DX, 6          ; skip to next output string index 
AC          LODSB               ; next quantity to check into AL 
        QLOOP: 
98          CBW                 ; clear AH 
3B D8       CMP  BX, AX         ; is input less than this quantity? 
72 F7       JB   QNEXT          ; if so, check next lowest 
2B D8       SUB  BX, AX         ; otherwise reduce input by quantity 
        QOUT: 
B4 09       MOV  AH, 9          ; display quantity string 
CD 21       INT  21H            ; write to stdout 
75 F3       JNZ  QLOOP          ; loop if value has not been reduced to zero 
C3          RET                 ; return to caller/DOS
                 
V       DB  100, 20, 5, 2, 1 
W       DB  'ala $ ','ale $ ','mute $','luka $','tu $  ','wan $ '
```
Callable function, input value in `BX` output to DOS `STDOUT`.
Maybe not the most elegant or byte efficient way to handle output of the variable-length strings...
Sample output using DEBUG (note input values are in hex):
[![enter image description here](https://i.stack.imgur.com/Uwq8v.png)](https://i.stack.imgur.com/Uwq8v.png)
[![enter image description here](https://i.stack.imgur.com/7qMl6.png)](https://i.stack.imgur.com/7qMl6.png)
[Answer]
# Excel, 116 bytes
## Formula, 83 bytes
```
=IF(A1,CONCAT(REPT(C1:C4,MOD(A1,D1:D4)/D2:D5))&IF(MOD(MOD(A1,5),2),"wan",""),"ala")
```
## C1:D5, 33 bytes
```
C1: "ale "  D1: =9^9
C2: "mute " D2: 100
C3: "luka " D3: 20
C4: "tu "   D4: 5
            D5: 2
```
[Link to Spreadsheet](http://Link%20to%20Spreaadsheet)
[Answer]
# [Python 3](https://docs.python.org/3/), 117 bytes
```
lambda x:S(S(S(S(S(x*Q,Q*100,"ale "),Q*20,"mute "),Q*5,"luka "),Q*2,"tu ",),Q,"wan ")[:-1]or"ala"
S,Q=str.replace,"q"
```
[Try it online!](https://tio.run/##NY3LDoIwEEX3fsVkVi0ZSQsxGhI@grBUF1UhNhaopUT8@joxmrs5Zx65/h3v01imvj4lZ4bLzcBateKfNWuoybRShMZ1gJKtYBmW@LMdoVse5rcijAsgMRO@zMjTY7XV5ynwu8FNS009x5CHzjtz7QifmPopgAXLtwo0FFAcQJd74E6F@eydjUJWPtgxCkvQiy9IKdMH "Python 3 – Try It Online")
An obvious find and replace one. Confuses the syntax highlighter - `something or"string"` should be parsed the same as `something or "string"`, not `something o r"string"`.
[Answer]
# [Scala](https://scala-lang.org/), 303 bytes
[Try it online!](https://tio.run/##VVA9b4MwEN3zK04Wg5041CB1qeJKHSO1U4cOURS5YBoDORA2LSrit1MHFKp48J39Pu7ZNlGlGqvPXCcO3pRB0J3TmFp4qWvox1RnkNETPu3RMdmvwK9v1QDKE04Hk1HcRezVWEeJ9yJMl1bPxBtZySt8eHeNwa8jZQs4qSIheCz4I495xMJfU38Yd95jqrswqxqtknOfKKtpwQ2Tz4t2Ni8hl/hQ3N2qzUZSS4L@FkoTTi6tu5ayLZQvrvXbj0LCqGEDkHXOQluXxtOBsDs3hK2EfP0/Ylg6FV6K@VGrGRhG3/jQQDvYbUGAqyAWgsH8H7WnuhJ9tkPQcQj6jHZsOE4DvXg1/gE)
```
def f(_n:Int)={
    var n=_n
    if(n<1)List("ala")else{
        var a=List[String]()
        List(100,20,5,2,1).zipWithIndex.foreach{case(k,i)=>
            val j=n/k
            a++=(s"${List("ale","mute","luka","tu","wan")(i)} "*j).split(" ")
            n -= j*k
        }
        a.mkString
    }
}
```
Ungolfed version
```
object Main extends App {
  def f(_n: Int): String = {
    var n=_n
    if (n < 1) {
      val a = List("ala")
      a.mkString("")
    } else {
      var a = List[String]()
      val denominations = List(100, 20, 5, 2, 1)
      for ((k, i) <- denominations.zipWithIndex) {
        val j = n / k
        val word = List("ale", "mute", "luka", "tu", "wan")(i)
        val repeatedWord = s"$word " * j
        a ++= repeatedWord.split(" ")
        n -= j * k
      }
      a.mkString("")
    }
  }
  for (x <- 0 to 200) {
    println(s"[$x, ${f(x)}]")
  }
}
```
[Answer]
# [PHP](https://php.net/), 134 bytes
```
fn($x)=>$x?($g=fn($s,$n,&$y)=>str_repeat("$s ",$y/$n+0*$y%=$n))(ale,100,$x).$g(mute,20,$x).$g(luka,5,$x).$g(tu,2,$x).$g(wan,1,$x):ala;
```
[Try it online!](https://tio.run/##jY/hCsIgFIX/9xSXcQtXl9wWUbRWLxKEhGvQMmlK29MvJdakXwlXPH7Xc4@60v3@qCs9wbLoS8WwjYsDtkeG18LLhlDRDDt325jn@Sm1FIZF2EBE2HFUi2SO3bRAFcdM1JLSJCFnssQru1sjKfvK2t4ErQdlLGXD@SUUpV7sRC3yXl6qB2DJkhiWEJ1UlINbnDs4GVj6w5zFl2U/zNgRbUPGuY8IPhgYC6FHutoEnX62hLF53AJv9/Mg8efJH9W/AQ "PHP – Try It Online")
This is the best I could do so far.. too bad `$x` has to be passed explicitly for a PHP arrow function to be able to modify it by reference..
[Answer]
# [Perl 5](https://www.perl.org/), 85 bytes
```
$_="@{[map{$c=$F[0]/$_;$F[0]%=$_;(/\D+/g)x$c}qw(100ale 20mute 5luka 2tu 1wan)]}"||ala
```
[Try it online!](https://tio.run/##K0gtyjH9/18l3lbJoTo6N7GgWiXZVsUt2iBWXyXeGsxQtQWyNPRjXLT10zUrVJJrC8s1DA0MEnNSFYwMcktLUhVMc0qzExWMSkoVDMsT8zRja5VqahJzEv//N@Ay5DLiMrLgMjQ25wLqMQARxv/yC0oy8/OK/@smFuQAAA "Perl 5 – Try It Online")
[Answer]
# [Haskell](https://www.haskell.org/), 111 bytes
```
t@((x,w):y)#n|n>=x=w++' ':t#(n-x)|1<2=y#n
_#n=""
f 0="ala"
f n=zip[100,20,5,2,1](words"ale mute luka tu wan")#n
```
[Try it online!](https://tio.run/##FY3RCoIwFEDf/YrL9uCGt9iEoKRFP9AXiMQgJXHeRCfT8N@XvZ2HwzlvO3W1czH6uxALBlmsktNGN7OYkGUppIXngg6L3PQ1Nyun5MnJMJY0oAyzzv6JzLcdSq0U5gpPmKOuRPiMr2kXauhnX4ObOwt@hmCJ7YfY25bAQG@HB4hhbMkfGwmlPl9w7yjUqKr4Aw "Haskell – Try It Online")
[Answer]
# [PHP](https://php.net/), ~~108~~ 104 bytes
```
foreach([100=>ale,20=>mute,5=>luka,2=>tu,1=>wan]as$v=>$w)for(;$argn>=$v;$argn-=$v)$o.="$w ";echo$o?:ala;
```
[Try it online!](https://tio.run/##JYtBC8IgHMXvfooRHjZwoVYUme5UdAjaPSL@DGvRUtl0@/aZETze@/0Oz7Uu7iqX@m57DU2bXxilUkGnCU/7Dl6TlVRdeAHhUvlAmFQTmCsMeJQKT0U65gJD/zBK4vFPZaIC27mc4SmbCd20FttqCx2I@JOsPta3/fkkUDCD9jm2hYgUMcQRo4inbNAy8WKdnNKPdf5pzRDLwxc "PHP – Try It Online")
I'm so super rusty at PHP on CG, but here it is just for fun... more or less a port of my other answer.
Iterates through the each word's value and reduces the input number by that amount. Keeps reducing as long as the result is positive, each time adding the word to the output. Nothing fancy here, just the only operation used is subtraction.
[Answer]
# [Raku](https://github.com/nxadm/rakudo-pkg), 76 bytes
```
->\n {~flat(<ale mute luka tu wan>Zxx(n/100,n/20%5,n/5%4,n%5/2,n%2))||"ala"}
```
[Try it online!](https://tio.run/##Rc3BjoIwGATg8/IUE1a0JGiRUA/q@hLeNmbNn9huNvwUom2UVHx1hNMeZub2TauvvBk@EcJx@ysXd7IYs5DOy14Y/mthmBz2lu6gyjO08zU00@H78cCqbbirm8sWQmVlptL0@YyJKe6jusPc4GtYHk4W4TUpYk@sUXunwb4iOD99TZCwcp3nmZVFnqhxVFJmNlGyGLv4R4ddZJorfop8jRB93KhDPDsjGDE7p328i/rhDQ "Perl 6 – Try It Online")
]