- Nov 27, 2016

- 994

- 235

- 53

- Discord Username
- BaeFell

After remembering yesterday, then forgetting and remembering now, here are the winners of the second skUnity Skript Challenge! There weren't many entries this time (to be honest, it was slightly more complex), but there were some amazing ones anyway! I've also got the medal system up and running, and have created a medal for the people who win a Skript Challenge! The 3 winners from #1 were award their medals earlier.

Anyway, without further ado, here are the winners:

In

**first place**is @SwiKZiiK - a French Skripter who created the shortest way of doing it, while not using any loops, addons or splitting!

code_language.skript:

```
set {_num} to "Put your number here."
length of {_num} <= 2:
return {_num}
else if length of {_num} = 3:
return "%first character of {_num}% hundred and %last 2 characters of {_num}%"
else if length of {_num} <= 6:
return "%first (length of {_num} - 3) characters of {_num}% thousand, %subtext of {_num} from (length of {_num} - 2) and (length of {_num} - 2)% hundred and %last 2 characters of {_num}%"
else if length of {_num} <= 9:
return "%first (length of {_num} - 6) characters of {_num}% million, %subtext of {_num} from (length of {_num} - 5) and (length of {_num} - 3)% thousand, %subtext of {_num} from (length of {_num} - 2) and (length of {_num} - 2)% hundred and %last 2 characters of {_num}%"
```

In

**join-second place**is @Rezz - a beautiful and well crafted solution to the challenge. Massively extensive and covers a wide range of features.

code_language.skript:

```
options:
TABLE: number-to-name
ERROR: [Error]
ENABLE_LARGE_NUMBER_NAMES: true
# Define all masks in a string with pattern:name pairs.
function defineMasksIn(values: text):
set {_pairs::*} to {_values} split at " "
loop {_pairs::*}:
set {_pair::*} to loop-value split at ":"
set {{@TABLE}::%{_pair::1}%} to {_pair::2}
on script load:
defineMasksIn("1:one 2:two 3:three 4:four 5:five 6:six 7:seven 8:eight 9:nine")
defineMasksIn("10:ten 11:eleven 12:twelve 13:thirteen 14:fourteen 15:fifteen 16:sixteen 17:seventeen 18:eighteen 19:nineteen")
defineMasksIn("2.:twenty 3.:thirty 4.:forty 5.:fifty 6.:sixty 7.:seventy 8.:eighty 9.:ninety")
defineMasksIn(".__:hundred ...___:thousand ...______:million ..._________:billion ...____________:trillion ..._______________:quadrillion")
{@ENABLE_LARGE_NUMBER_NAMES} is true
# Number names from: https://en.wikipedia.org/wiki/Names_of_large_numbers
defineMasksIn("...__________________:quintillion ..._____________________:sextillion ...________________________:septillion")
defineMasksIn("...___________________________:octillion ...______________________________:nonillion ..._________________________________:decillion")
defineMasksIn("...____________________________________:undecillion ..._______________________________________:duodecillion")
defineMasksIn("...__________________________________________:tredecillion ..._____________________________________________:quattuordecillion")
defineMasksIn("...________________________________________________:quindecillion ...___________________________________________________:sexdecillion")
on script unload:
delete {{@TABLE}::*}
# Returns the matching mask for a string of digits or an error if nothing is found.
function findMaskFor(number: text) :: text:
set {_length} to length of {_number}
set {_digits::*} to {_number} split at ""
loop {{@TABLE}::*}:
if {_skip} is set:
delete {_skip}
set {_mask} to loop-index
set {_mask-length} to length of {_mask}
set {_minimum-length} to {_mask-length}
set {_chars::*} to {_mask} split at ""
loop {_chars::*}:
{_skip} is not set
set {_char} to loop-value-2
set {_digit} to {_digits::%loop-index-2%}
if {_char} is ".":
set {_minimum-length} to {_minimum-length} - 1
else:
if {_minimum-length} is greater than {_length}:
set {_skip} to true
else if {_char} is not {_digit} or "_":
set {_skip} to true
{_skip} is not set
if {_mask-length} is {_length}:
return {_mask}
else if {_length} is less than {_mask-length}:
if {_length} is greater than {_minimum-length}:
return {_mask}
return "{@ERROR} Unsupported value: '%{_number}%' with length %{_length}%"
# Determine whether a string starts with another.
function startsWith(start-text: text, full-text: text) :: boolean:
if the first (length of {_start-text}) characters of {_full-text} is {_start-text}:
return true
return false
# Determine whether a string ends with another.
function endsWith(end-text: text, full-text: text) :: boolean:
if the last (length of {_end-text}) characters of {_full-text} is {_end-text}:
return true
return false
# Insert a string into another at a specified index.
function insert(insertion: text, index: number, text: text) :: text:
set {_left} to the first {_index} characters of {_text}
set {_right} to the last (length of {_text} - {_index}) characters of {_text}
return "%{_left}%%{_insertion}%%{_right}%"
# Count the occurrences of a character in a string.
function occurrencesOf(char: text, in: text) :: number:
set {_count} to 0
set {_characters::*} to {_in} split at ""
loop {_characters::*}:
if "%loop-value%" is {_char}:
add 1 to {_count}
return {_count}
# Strip all leading zeroes from a string of digits.
function stripLeadingZeroes(number: text) :: text:
while startsWith("0", {_number}) is true:
if length of {_number} is 1:
set {_number} to ""
else:
set {_number} to the last (length of {_number} - 1) characters of {_number}
return {_number}
# Returns the full name of all digits in a string.
function nameOfDigits(number: text) :: text:
if {_number} is "0":
return "zero"
set {_number} to stripLeadingZeroes({_number})
set {_length} to length of {_number}
if {_length} is 0:
return ""
set {_mask} to findMaskFor({_number})
if startsWith("{@ERROR}", {_mask}) is true:
return {_mask}
set {_mask-length} to length of {_mask}
set {_mask-cutoff} to {_mask-length} - {_length}
set {_active-mask} to the last ({_mask-length} - {_mask-cutoff}) characters of {_mask}
if startsWith(".", {_active-mask}) is true:
set {_left-side-components} to occurrencesOf(".", {_active-mask})
set {_split-number::*} to insert(":", {_left-side-components}, {_number}) split at ":"
set {_left} to nameOfDigits({_split-number::1})
set {_right} to nameOfDigits({_split-number::2})
set {_name} to {{@TABLE}::%{_mask}%}
if {_right} is "zero" or "":
return "%{_left}% %{_name}%"
else if {_name} is "hundred":
return "%{_left}% %{_name}% %{_right}%"
else:
return "%{_left}% %{_name}%, %{_right}%"
else if endsWith(".", {_active-mask}) is true:
set {_left} to {{@TABLE}::%{_mask}%}
set {_digit} to the last character of {_number}
set {_right} to nameOfDigits({_digit})
if {_right} is "zero" or "":
return "%{_left}%"
else:
return "%{_left}%-%{_right}%"
else:
return {{@TABLE}::%{_mask}%}
# Converts an integer to a string and returns the result of nameOfDigits()
function nameOfNumber(number: integer) :: text:
return nameOfDigits("%{_number}%")
command /nameof <integer>:
trigger:
set {_result} to nameOfNumber(arg-1)
send "%arg-1%: &a%{_result}%"
# A function to ensure a string only contains numeric characters.
function validateDigitsOf(text: text) :: boolean:
set {_chars::*} to {_text} split at ""
loop {_chars::*}:
if "0123456789" doesn't contain "%loop-value%":
return false
return true
command /nameofdigits <text>:
trigger:
if validateDigitsOf(arg-1) is true:
set {_result} to nameOfDigits(arg-1)
send "%arg-1%: &a%{_result}%"
else:
send "&cThe only characters allowed are: 0-9"
```

In

**joint-second place**is @Tlatoani - his answer is also very extensive and even converts the numbers themselves into words: 2009 -> two thousand and nine

code_language.skript:

```
on load:
set {small numbers::*} to "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
set {multiples of ten::*} to "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"
set {powers of thousand::*} to "thousand", "million", "billion", "trillion", "quadrillion", "quintillion"
function modulus(num: number, by: number) :: number:
return {_num} - {_by} * rounded down {_num} / {_by}
function smallNumToEnglish(num: number) :: string:
if {_num} < 20:
return {small numbers::%{_num}%}
if {_num} < 100:
set {_tens} to rounded down {_num}/10
set {_result} to {multiples of ten::%{_tens}%}
if modulus({_num}, 10) > 0:
set {_result} to "%{_result}%-%smallNumToEnglish(modulus({_num}, 10))%"
return {_result}
set {_result} to "%smallNumToEnglish(rounded down {_num}/100)% hundred"
if modulus({_num}, 100) > 0:
set {_result} to "%{_result}% and %smallNumToEnglish(modulus({_num}, 100))%"
return {_result}
function numToEnglish(num: number) :: string:
if {_num} is 0:
return "zero"
set {_power of thousand} to 0
while {_num} > 0:
if modulus({_num}, 1000) > 0:
set {_number name} to {powers of thousand::%{_power of thousand}%}
set {_result} to "%smallNumToEnglish(modulus({_num}, 1000))% %{_number name}%, %{_result}%"
set {_num} to rounded down {_num} / 1000
add 1 to {_power of thousand}
if {_result} contains ">,":
return first length of {_result} - 15 characters of {_result} #Removes the extra " <none>, <none>" at the end of the string
else:
return first length of {_result} - 8 characters of {_result} #Removes the extra ", <none>" at the end of the string
```

Also in

**joint-second place**is @xXAndrew28Xx - another amazing submission which deserves to be appreciated.

code_language.skript:

```
function modulo(dividend: integer, divisor: integer) :: number:
set {_quotient} to {_dividend} / {_divisor}
set {_floor} to floor({_quotient})
return {_dividend} - ({_floor} * {_divisor})
function wholeDivision(dividend: integer, divisor: integer) :: number:
set {_quotient} to {_dividend} / {_divisor}
set {_floor} to floor({_quotient})
return {_floor}
function expandedForm(number: integer) :: text:
#Letter Prefixes so it loops in the correct order
set {_format::a-quadrillion} to 1000000000000000
set {_format::b-trillion} to 1000000000000
set {_format::c-billion} to 1000000000
set {_format::d-million} to 1000000
set {_format::e-thousand} to 1000
set {_format::f-hundred} to 100
while {_number} is not 0:
if {_number} < 100:
#set {_lowerNumberFormats::*} to "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", and "nineteen"
#set {_tensFormats::*} to "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", and "ninty"
#if {_number} < 20:
# set {_numberFormatted} to {_lowerNumberFormats::%{_number}%}
#else if {_number} is 100:
# set {_numberFormatted} to "one hundred"
#else:
# set {_tensFormatsIndex} to (wholeDivision({_number}, and 10)) - 1
# set {_numberFormatted} to {_tensFormats::%{_tensFormatsIndex}%}
# if modulo({_number},10) is not 0:
# set {_digitNumber} to modulo({_number}, and 10)
# set {_digitNumberFormatted} to {_lowerNumberFormats::%{_digitNumber}%}
# set {_numberFormatted} to "%{_numberFormatted}% %{_digitNumberFormatted}%"
#broadcast "ADDED %{_numberFormatted}%"
set {_numberFormatted} to "%{_number}%"
add {_numberFormatted} to {_values::*}
exit loop
loop {_format::*}:
set {_place} to loop-value
#EVALUATE because {_whole} isn't changing after the first time without it
evaluate "set {_whole} to wholeDivision(%{_number}%, and %{_place}%)"
if {_whole} > 0:
if {_place} is 100:
if {_whole} > 9:
exit 3 sections
set {_number} to {_number} - ({_whole} * {_place})
set {_placeName} to loop-index
set {_placeName} to subtext of {_placeName} from characters 3 to length of {_placeName}
if {_whole} is not 0:
set {_formattedWhole} to {_whole} #Will update later
add "%{_formattedWhole}% %{_placeName}%" to {_values::*}
return "%{_values::*}%"
```

I won't normally have 3 joint-seconds or anything like that, but the answers were all amazing but similar in idea, that they all deserved it.

In

**third place**is @Getreidemonster - a submission so beautiful that I cried too much reading it to be able to put it any higher. It had the most winner ratings and even solves the issue of world hunger.

code_language.skript:

```
command /SkriptChallenge:
trigger:
send "§oDo you really though that I'm posting here the task? ;)"
send "§a§oOkay, let's start!"
shutdown server
```

A huge thanks to everyone who took part in the second skUnity Skript Challenge! I hope to set up some more soon.

And I also hope you all enjoyed this Skript challenge! If you have an idea for the next one, PM me and I'll see what I can do.

Thanks,

BaeFell