Emojicode 0.5, 204 201 bytes
🐋🚂🍇🐖🅰️➡🚂🍇🍊⬅🐕1🍇🍎1🍉🍮s 0🔂k⏩0🐕🍇🍦t➖🐕k🍮r t🔂i⏩1 t🍇🍊😛🚮t i 0🍇🍮➕r i🍉🍉🍮➕s✖r🅰️k🍉🍎➗s🐕🍉🍉
Try it online!
-3 bytes by using "less than or equal to 1" instead of "less than 2" because the "less than" emoji has a quite long UTF-8 encoding. Also made t
a frozen to silence a warning without affecting the byte count.
Extends the 🚂 (integer) class with a method named 🅰️. You can write a simple program that takes a number from the input, calls 🅰️ on the number and prints the result like this:
🏁🍇
🍦str🔷🔡😯🔤Please enter a number🔤
🍊🍦num🚂str 10🍇
😀🔡🅰️num 10
🍉🍓🍇
😀🔤Learn what a number is, you moron!🔤
🍉
🍉
This part could be golfed a lot by omitting the messages and error handling, but it's not included in the score, so I prefer to show more features of Emojicode instead, while improving readability along the way.
Ungolfed
🐋🚂🍇
🐖🅰️➡🚂🍇
🍊◀️🐕2🍇
🍎1
🍉
🍮sum 0
🔂k⏩0🐕🍇
🍦nmk➖🐕k
🍮sig nmk
🔂i⏩1 nmk🍇
🍊😛🚮nmk i 0🍇
🍮➕sig i
🍉
🍉
🍮➕sum✖sig🅰️k
🍉
🍎➗sum🐕
🍉
🍉
Explanation
Note: a lot of emoji choice doesn't make much sense in emojicode 0.5. It's 0.x, after all. 0.6 will fix this.
Emojicode is an object-oriented programming language featuring generics, protocols, optionals and closures, but this program uses no closures and all generics and protocols can be considered implicit, while the only optional appears in the I/O stub.
The program operates on only a few types: 🚂 is the integer type, 🔡 is the string type and ⏩ is the range type. A few booleans (👌) appear too, but they are only used in conditions. Booleans can take a value of 👍 or 👎, which correspond to true and false, respectively.
There are currently no operators in Emojicode, so addition, comparsions and other operations that are normally operators are implemented as functions, effectively making the expressions use prefix notation. Operators are also planned in 0.6.
Let's tackle the test program first.
🏁
This is the 🏁 block, which can be compared to main from other languages.
🍇 ... 🍉
Grapes and watermelons declare code blocks in emojicode.
🍦str🔷🔡😯🔤Please enter a number🔤
This declares a "frozen" named str
and sets it value to a new string created using the initializer (constructor) 😯, which takes a prompt as a string and then inputs a line from the user. Why use a frozen instead of a variable? It won't change, so a variable would emit a warning.
🍊🍦num🚂str 10
Let's break it down. 🚂str 10
calls the 🚂 method on the str
frozen with the argument 10. By convention, methods named with the name of a type convert the object to that type. 10 is the base to use for integer conversion. This method returns an optional, 🍬🚂
. Optionals can contain a value of the base type or nothingness, ⚡. When the string doesn't contain a number, ⚡ is returned. To use the value, one has to unwrap the optional using 🍺, which raises a runtime error if the value is ⚡. Therefore, it is good practice to check for nothingness before unwrapping an optional. It is so common, in fact, that Emojicode has a shorthand for that. Normally, 🍊
is an "if". 🍊🍦 variable expression
means: evaluate the expression. If the optional contains nothingness, the condition evaluates to 👎 (false). Otherwise, a frozen named variable
is created with the unwrapped value of the optional, and the condition evaluates to 👍, (true). Therefore, in normal usage, the 🍇 ... 🍉
block following the conditional is entered.
😀🔡🅰️num 10
🅰️ is the method the main code adds to 🚂 using 🐋 that calculates the number of partitions. This calls 🅰️ on the num
frozen we declared in the conditional and converts the result to a string using base 10 by the 🔡 method. Then, 😀 prints the result.
🍓🍇 ... 🍉
🍓 means "else", so this block is entered when the user did not enter a number correctly.
😀🔤Learn what a number is, you moron!🔤
Prints the string literal.
Now, let's look at the main program. I'll explain the ungolfed version; the golfed version just had the whitespace removed and variables renamed to single letter names.
🐋🚂🍇 ... 🍉
Extend the 🚂 class. This is a feature that is not commonly found in programming languages. Instead of creating a new class with 🚂 as the superclass, 🐋 modifies 🚂 directly.
🐖🅰️➡🚂🍇 ... 🍉
Creates a new method named 🅰️ that returns a 🚂. It returns the number of partitions calculated using the formula a(n) = (1/n) * Sum_{k=0..n-1} sigma(n-k)*a(k)
🍊⬅🐕1🍇
🍎1
🍉
🐕 is similar to this
or self
from other languages and refers to the object the method was called on. This implementation is recursive, so this is the terminating condition: if the number the method was called on is less than or equal 1, return 1.
🍮sum 0
Create a new variable sum
and set it to 0. Implicitly assumes type 🚂.
🔂k⏩0🐕
🔂 iterates over anything that implements the 🔂🐚⚪️ protocol, while ⏩ is a range literal that happens to implement 🔂🐚🚂. A range has a start value, a stop value and a step value, which is assumed to be 1 if start < stop
, or -1 otherwise. One can also specify the step value by using the ⏭ to create the range literal. The start value is inclusive, while the stop value is exclusive, so this is equivalent to for k in range(n)
or the Sum_{k=0..n-1}
in the formula.
🍦nmk➖🐕k
We need to calculate sigma(n - k), or the sum of divisors of n - k
in other words, and the argument is needed a few times, so this stores n - k
in the variable nmk
to save some bytes.
🍮sig nmk
🔂i⏩1 nmk
This sets the sig
variable to the argument of sigma and iterates over all numbers from 1 to nmk - 1
. I could initialize the variable to 0 and iterate over 1..nmk but doing it this way is shorter.
🍊😛🚮nmk i 0
🚮 calculates the remainder, or modulus and 😛 checks for equality, so the condition will be 👍 if i
is a divider of nmk
.
🍮➕sig i
This is an assignment by call, similar to the += -= >>=
operator family in some of the inferior, emoji-free languages. This line can be also written as 🍮 sig ➕ sig i
. Therefore, after the inner loop finishes, sig
will contain the sum of divisors of n - k
, or sigma(n - k)
🍮➕sum✖sig🅰️k
Another assignment by call, so this adds sigma(n - k) * A(k)
to the total, just as in the formula.
🍎➗sum🐕
Finally, the sum is divided by n and the quotient is returned. This explanation probably took thrice as much time as writing the code itself...