1. Welcome to skUnity!

    Welcome to skUnity! This is a forum where members of the Skript community can communicate and interact. Skript Resource Creators can post their Resources for all to see and use.

    If you haven't done so already, feel free to join our official Discord server to expand your level of interaction with the comminuty!

    Now, what are you waiting for? Join the community now!

Dismiss Notice
This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

[#2] Skript Challenge - Numbers to Words

Discussion in 'Skript Challenge' started by BaeFell, Feb 9, 2017.

Thread Status:
Not open for further replies.
  1. BaeFell

    BaeFell I'm Poppy
    Admin

    Joined:
    Nov 27, 2016
    Messages:
    318
    Likes Received:
    199
    Hi everyone,

    Welcome to another Skript Challenge! I did post a poll on the first Skript Challenge, and the vast majority of users who voted, liked Skript Challenges!
    [​IMG]

    So here's the second one! If you have any suggestions for #3 or general improvements, let me know :emoji_slight_smile:

    This Skript Challenge is another number related one! Basically, you must turn numbers into their word versions. Example:
    58654 -> 58 thousand, 6 hundred and 54 OR
    58654 -> fifty-eight thousand, six hundred and fifty-four
    Commas and string formatting isn't important, but extra points for making it pretty

    The rules are as follows (note: rules may change between challenge):
    - Your code must be in [code]<code>[/code] tags so that I can easily read it.
    - You can use addons, but, you're not allowed to use a feature from an addon which does this (don't think any do) and the addon must of been released publicly prior to the creation of this thread. So not, you cannot use a feature like "output {_number} in word form" or whatever.
    - You can use another user's code, but please don't edit your messages. I can see all message history and you'll not be counted at all. Remember: this one is about quality, not just length. So trying to cut variable names from someone elses code will lose points!
    - WebAPI's or using an external source (outside of Skript), to get your result in not allowed. All submissions must actually do the conversions themselves.

    Challenge details (specifics about this challenge):
    - Your code must accept any length of number inputted from 0 to 999 million (if you can easily support higher, go for it).
    - You do not have to message it back to the player
    - It can be a function, command or just a block of code. Just explain where you're getting the input if it's not obvious to me.

    How answers will be judged:
    Unlike others, the winner for this one, will be judged based on quality. I and others (who I'm yet to pick), will go around and find the best answers. I'm not sure on the specifics of how the scoring will work, the final judgement and most other things, but I've got a week to figure that out!

    Important
    If you don't understand how your answer will be judged here is an explanation:
    Better code quality = more points. I'm very anti-addon with some things. If you're using an addon for what can be done normally in Skript, then you're not Skripting right. Variable names, code structure, use of functions and code readability matters for this challenge. I'm specifically looking for the best code, not the smallest, but you shouldn't have code that is far too long, otherwise it's unlikely to be efficient.

    The closing date is 7 days from now -> 16th of February, at 00:06 GMT! Have fun!
     
    #1 BaeFell, Feb 9, 2017
    Last edited: Feb 9, 2017
    • Funny Funny x 1
    • Winner Winner x 1
    • Creative Creative x 1
  2. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
  3. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
    • Agree Agree x 2
    • Informative Informative x 1
  4. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
    Code (Skript):
    1. command /num <integer>:
    2.     trigger:
    3.         set {_} to "%arg% tick" parsed as timespan
    4.         set {_} to "%{_}%"
    5.         replace all "seconds" or "second" with "" in {_}
    6.         replace all "minutes" or "minute" with "hundred" in {_}
    7.         replace all "hours" or "hour" with "thousand" in {_}
    8.         broadcast "%{_}%"
    Code (Skript):
    1. set {_} to "INPUT tick" parsed as timespan
    2. set {_} to "%{_}%"
    3. replace all "seconds" or "second" with "" in {_}
    4. replace all "minutes" or "minute" with "hundred" in {_}
    5. replace all "hours" or "hour" with "thousand" in {_}
    Code (Skript):
    1. set {_} to "INPUT tick" parsed as timespan
    2. set {_} to "%{_}%"
    3. replace all "seconds" or "second" with "" in {_}
    4. replace all "minute" with "hundred" in {_}
    5. replace all "hour" with "thousand" in {_}
     
  5. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
    I don't think that goes up to 999 million
     
  6. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
    It can if you add replace all "day" or "days" with "million" in {_}
     
  7. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
    It also doesn't work, /num 777777 should return

    "seven hundred seventy seven thousand seventy seven"

    not

    [​IMG]
     
  8. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
    It converts it to a lower number
     
  9. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
    My submission, I will later submit a version that changes 1 to one and 23 to twenty three.
    Code (Skript):
    1. function modulo(dividend: integer, divisor: integer) :: number:
    2.   set {_quotient} to {_dividend} / {_divisor}
    3.   set {_floor} to floor({_quotient})
    4.   return {_dividend} - ({_floor} * {_divisor})
    5. function wholeDivision(dividend: integer, divisor: integer) :: number:
    6.   set {_quotient} to {_dividend} / {_divisor}
    7.   set {_floor} to floor({_quotient})
    8.   return {_floor}
    9. function expandedForm(number: integer) :: text:
    10.   #Letter Prefixes so it loops in the correct order
    11.   set {_format::a-quadrillion} to 1000000000000000
    12.   set {_format::b-trillion} to 1000000000000
    13.   set {_format::c-billion} to 1000000000
    14.   set {_format::d-million} to 1000000
    15.   set {_format::e-thousand} to 1000
    16.   set {_format::f-hundred} to 100
    17.   while {_number} is not 0:
    18.     if {_number} < 100:
    19.       #set {_lowerNumberFormats::*} to "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", and "nineteen"
    20.       #set {_tensFormats::*} to "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", and "ninty"
    21.       #if {_number} < 20:
    22.       #  set {_numberFormatted} to {_lowerNumberFormats::%{_number}%}
    23.       #else if {_number} is 100:
    24.       #  set {_numberFormatted} to "one hundred"
    25.       #else:
    26.       #  set {_tensFormatsIndex} to (wholeDivision({_number}, and 10)) - 1
    27.       #  set {_numberFormatted} to {_tensFormats::%{_tensFormatsIndex}%}
    28.       #  if modulo({_number},10) is not 0:
    29.       #    set {_digitNumber} to modulo({_number}, and 10)
    30.       #    set {_digitNumberFormatted} to {_lowerNumberFormats::%{_digitNumber}%}
    31.       #    set {_numberFormatted} to "%{_numberFormatted}% %{_digitNumberFormatted}%"
    32.       #broadcast "ADDED %{_numberFormatted}%"
    33.       set {_numberFormatted} to "%{_number}%"
    34.       add {_numberFormatted} to {_values::*}
    35.       exit loop
    36.     loop {_format::*}:
    37.       set {_place} to loop-value
    38.       #EVALUATE because {_whole} isn't changing after the first time without it
    39.       evaluate "set {_whole} to wholeDivision(%{_number}%, and %{_place}%)"
    40.       if {_whole} > 0:
    41.         if {_place} is 100:
    42.           if {_whole} > 9:
    43.             exit 3 sections
    44.         set {_number} to {_number} - ({_whole} * {_place})
    45.         set {_placeName} to loop-index
    46.         set {_placeName} to subtext of {_placeName} from characters 3 to length of {_placeName}
    47.         if {_whole} is not 0:
    48.           set {_formattedWhole} to {_whole} #Will update later
    49.           add "%{_formattedWhole}% %{_placeName}%" to {_values::*}
    50.   return  "%{_values::*}%"
    23 -> 23
    [​IMG]
     
    • Winner Winner x 1
    • Friendly Friendly x 1
  10. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
    Code (Skript):
    1.  
    2. on load:
    3.   set {large numbers::*} to "thousand", "million", "billion", "trillion", "quadrillion"
    4.  
    5. function modulus(num: number, by: number) :: number:
    6.   return {_num} - {_by} * rounded down {_num} / {_by}
    7.  
    8. function smallNumToEnglish(num: number) :: string:
    9.   if {_num} < 100:
    10.     return "%{_num}%"
    11.   else:
    12.     return "%rounded down {_num} / 100% hundred and %modulus({_num}, 100)%"
    13.  
    14. function numToEnglish(num: number) :: string:
    15.   set {_result} to "%smallNumToEnglish(modulus({_num}, 1000))%"
    16.   set {_num} to rounded down {_num} / 1000
    17.   set {_power of thousand} to 1
    18.   while {_num} > 0:
    19.     set {_number name} to {large numbers::%{_power of thousand}%}
    20.     set {_result} to "%smallNumToEnglish(modulus({_num}, 1000))% %{_number name}%, %{_result}%"
    21.     set {_num} to rounded down {_num} / 1000
    22.     add 1 to {_power of thousand}
    23.   return {_result}
    24.  
    Accepts the input number through the numToEnglish() function.
    [​IMG]
     
  11. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
    Numbers to names, featuring recursion.
    Code (Skript):
    1. options:
    2.     TABLE: number-to-name
    3.     ERROR: [Error]
    4.  
    5. function define(values: text):
    6.     set {_pairs::*} to {_values} split at " "
    7.  
    8.     loop {_pairs::*}:
    9.         set {_pair::*} to loop-value split at ":"
    10.         set {{@TABLE}::%{_pair::1}%} to {_pair::2}
    11.  
    12. on script load:
    13.     define("1:one 2:two 3:three 4:four 5:five 6:six 7:seven 8:eight 9:nine")
    14.     define("10:ten 11:eleven 12:twelve 13:thirteen 14:fourteen 15:fifteen 16:sixteen 17:seventeen 18:eighteen 19:nineteen")
    15.     define("2.:twenty 3.:thirty 4.:fourty 5.:fifty 6.:sixty 7.:seventy 8.:eighty 9.:ninety")
    16.     define(".__:hundred ...___:thousand ...______:million ..._________:billion ...____________:trillion ..._______________:quadrillion")
    17.  
    18. on script unload:
    19.     delete {{@TABLE}::*}
    20.  
    21. function findMaskFor(number: text) :: text:
    22.     set {_length} to length of {_number}
    23.     set {_digits::*} to {_number} split at ""
    24.  
    25.     loop {{@TABLE}::*}:
    26.  
    27.         if {_skip} is set:
    28.             delete {_skip}
    29.  
    30.         set {_mask} to loop-index
    31.         set {_mask-length} to length of {_mask}
    32.         set {_minimum-length} to {_mask-length}
    33.         set {_chars::*} to {_mask} split at ""
    34.  
    35.         loop {_chars::*}:
    36.      
    37.             {_skip} is not set
    38.      
    39.             set {_char} to loop-value-2
    40.             set {_digit} to {_digits::%loop-index-2%}
    41.                  
    42.             if {_char} is ".":
    43.                 set {_minimum-length} to {_minimum-length} - 1
    44.             else:
    45.      
    46.                 if {_minimum-length} is greater than {_length}:
    47.                     set {_skip} to true
    48.                 else if {_char} is not {_digit} or "_":
    49.                     set {_skip} to true
    50.  
    51.         {_skip} is not set
    52.  
    53.         if {_mask-length} is {_length}:
    54.             return {_mask}
    55.         else if {_length} is less than {_mask-length}:
    56.              
    57.             if {_length} is greater than {_minimum-length}:
    58.                 return {_mask}
    59.              
    60.     return "{@ERROR} Unsupported number length: %{_length}%"
    61.  
    62. function startsWith(start-text: text, full-text: text) :: boolean:
    63.     if the first (length of {_start-text}) characters of {_full-text} is {_start-text}:
    64.         return true
    65.     else:
    66.         return false
    67.  
    68. function endsWith(end-text: text, full-text: text) :: boolean:
    69.     if the last (length of {_end-text}) characters of {_full-text} is {_end-text}:
    70.         return true
    71.     else:
    72.         return false
    73.  
    74. function insert(insertion: text, index: number, text: text) :: text:
    75.     set {_left} to the first {_index} characters of {_text}
    76.     set {_right} to the last (length of {_text} - {_index}) characters of {_text}
    77.  
    78.     return "%{_left}%%{_insertion}%%{_right}%"
    79.  
    80. function occurrencesOf(char: text, in: text) :: number:
    81.     set {_count} to 0
    82.     set {_characters::*} to {_in} split at ""
    83.  
    84.     loop {_characters::*}:
    85.  
    86.         if "%loop-value%" is {_char}:
    87.             add 1 to {_count}
    88.      
    89.     return {_count}
    90.  
    91. function stripLeadingZeroes(number: text) :: text:
    92.     while startsWith("0", {_number}):
    93.         if length of {_number} is 1:
    94.             set {_number} to ""
    95.         else:
    96.             set {_number} to the last (length of {_number} - 1) characters of {_number}
    97.  
    98.     return {_number}
    99.  
    100. function nameOfDigits(number: text) :: text:
    101.     if {_number} is "0":
    102.         return "zero"
    103.  
    104.     set {_number} to stripLeadingZeroes({_number})
    105.     set {_length} to length of {_number}
    106.  
    107.     if {_length} is 0:
    108.         return ""
    109.  
    110.     set {_mask} to findMaskFor({_number})
    111.  
    112.     if startsWith("{@ERROR}", {_mask}):
    113.         return {_mask}
    114.  
    115.     set {_mask-length} to length of {_mask}
    116.     set {_cut} to {_mask-length} - {_length}
    117.     set {_active-mask} to the last ({_mask-length} - {_cut}) characters of {_mask}
    118.  
    119.     if startsWith(".", {_active-mask}):
    120.         set {_components} to occurrencesOf(".", {_active-mask})
    121.         set {_split-mask::*} to insert(":", {_components}, {_active-mask}) split at ":"
    122.         set {_split-number::*} to insert(":", {_components}, {_number}) split at ":"
    123.  
    124.         set {_left} to nameOfDigits({_split-number::1})
    125.         set {_right} to nameOfDigits({_split-number::2})
    126.         set {_name} to {{@TABLE}::%{_mask}%}
    127.  
    128.         if {_right} is "zero" or "":
    129.             return "%{_left}% %{_name}%"
    130.         else if {_name} is "hundred":
    131.             return "%{_left}% %{_name}% %{_right}%"
    132.         else:
    133.             return "%{_left}% %{_name}%, %{_right}%"
    134.  
    135.     else if endsWith(".", {_active-mask}):
    136.         set {_left} to {{@TABLE}::%{_mask}%}
    137.         set {_digit} to the last character of {_number}
    138.         set {_right} to nameOfDigits({_digit})
    139.  
    140.         if {_right} is "zero" or "":
    141.             return "%{_left}%"
    142.         else:
    143.             return "%{_left}%-%{_right}%"
    144.  
    145.     else:
    146.         return {{@TABLE}::%{_mask}%}
    147.  
    148. function nameOfNumber(number: integer) :: text:
    149.     return nameOfDigits("%{_number}%")
    150.  
    151. command /nameof <integer>:
    152.     trigger:
    153.         set {_result} to nameOfNumber(arg-1)
    154.         send "%arg-1%: &a%{_result}%"
    155.    

    Usage:

    • call nameOfDigits() with a string argument
    • or call nameOfNumber() with an integer argument
    • or execute /nameof <integer>

    [​IMG]

    And since I'm dealing with strings...

    ...you can expand it to extremely large numbers.
    [​IMG]

    Just modify the script a little.
    Add this to the on script enable event:
    Code (Skript):
    1.     define("...__________________:quintillion ..._____________________:sextillion ...________________________:septillion")
    2.     define("...___________________________:octillion ...______________________________:nonillion ..._________________________________:decillion")
    3.     define("...____________________________________:undecillion ..._______________________________________:duodecillion")
    And add this anywhere:
    Code (Skript):
    1. function validateDigitsOf(text: text) :: boolean:
    2.     set {_chars::*} to {_text} split at ""
    3.  
    4.     loop {_chars::*}:
    5.         if "0123456789" doesn't contain "%loop-value%":
    6.             return false
    7.        
    8.     return true
    9.  
    10. command /nameofdigits <text>:
    11.     trigger:
    12.         if validateDigitsOf(arg-1):
    13.             set {_result} to nameOfDigits(arg-1)
    14.             send "%arg-1%: &a%{_result}%"
    15.         else:
    16.             send "&cThe only characters allowed are: 0-9"
     
    #11 ShaneBee, Feb 9, 2017
    Last edited by a moderator: Feb 13, 2017
    • Winner Winner x 3
    • Agree Agree x 1
  12. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
    Code (Skript):
    1. function NumbersToWords(num: number) :: text:
    2.     set {_num} to "%{_num}%"
    3.     length of {_num} <= 2:
    4.         return {_num}
    5.     else if length of {_num} = 3:
    6.         return "%first character of {_num}% hundred and %last 2 characters of {_num}%"
    7.     else if length of {_num} <= 6:
    8.         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}%"
    9.     else if length of {_num} <= 9:
    10.         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}%"
    11.  
    12. command /test <number>:
    13.     trigger:
    14.         send NumbersToWords(arg)
    >> The function is 'NumbersToWords(NumberToTransform)'.
    >> No need for addon.

    - The code without the function :

    Code (Skript):
    1.  
    2.     set {_num} to "Put your number here."
    3.     length of {_num} <= 2:
    4.         return {_num}
    5.     else if length of {_num} = 3:
    6.         return "%first character of {_num}% hundred and %last 2 characters of {_num}%"
    7.     else if length of {_num} <= 6:
    8.         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}%"
    9.     else if length of {_num} <= 9:
    10.         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}%"
    11.  

    [​IMG]
    Sorry for my bad english, I'm french.
     
    #12 ShaneBee, Feb 9, 2017
    Last edited by a moderator: Feb 9, 2017
    • Like Like x 2
  13. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
    I think I will win due to my code has less lines as those above my reply (idk whether that's correct grammar, if not sry :3)

    Code (Skript):
    1.  
    2. command /SkriptChallenge:
    3.     trigger:
    4.         send "§oDo you really though that I'm posting here the task? ;)"
    5.         send "§a§oOkay, let's start!"
    6.         shutdown server
    7.  
    EDIT: Due to so many people rated this as "Winner", I should really win, right?
    I will just tag @BaeFell, and he could make me win, correct? :emoji_stuck_out_tongue: (Or are we living in America where Trump would "banning" me (from America) - In this case, @BaeFell would delete my WINNER REPLY 'cause he don't have a prizzzeee for meeee :3)
     
    #13 ShaneBee, Feb 9, 2017
    Last edited by a moderator: Feb 10, 2017
    • Winner Winner x 9
    • Funny Funny x 3
    • Like Like x 1
    • Useful Useful x 1
  14. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
    4 days until this closes! Get your submissions in :emoji_heart:

    And thanks to everyone who is making the scripts for my unannounced server :emoji_heart::emoji_heart:
     
    • Funny Funny x 1
    • Winner Winner x 1
  15. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
    Made an updated submission, this one is now fully in words, and also removes unnecessary parts (ex. 9000 will translate as nine thousand instead of 9 thousand, 0)

    Code (Skript):
    1.  
    2. on load:
    3.   set {small numbers::*} to "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
    4.   set {multiples of ten::*} to "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"
    5.   set {powers of thousand::*} to "thousand", "million", "billion", "trillion", "quadrillion", "quintillion"
    6.  
    7. function modulus(num: number, by: number) :: number:
    8.   return {_num} - {_by} * rounded down {_num} / {_by}
    9.  
    10. function smallNumToEnglish(num: number) :: string:
    11.   if {_num} < 20:
    12.     return {small numbers::%{_num}%}
    13.   if {_num} < 100:
    14.     set {_tens} to rounded down {_num}/10
    15.     set {_result} to {multiples of ten::%{_tens}%}
    16.     if modulus({_num}, 10) > 0:
    17.       set {_result} to "%{_result}%-%smallNumToEnglish(modulus({_num}, 10))%"
    18.     return {_result}
    19.   set {_result} to "%smallNumToEnglish(rounded down {_num}/100)% hundred"
    20.   if modulus({_num}, 100) > 0:
    21.     set {_result} to "%{_result}% and %smallNumToEnglish(modulus({_num}, 100))%"
    22.   return {_result}
    23.  
    24. function numToEnglish(num: number) :: string:
    25.   if {_num} is 0:
    26.     return "zero"
    27.   set {_power of thousand} to 0
    28.   while {_num} > 0:
    29.     if modulus({_num}, 1000) > 0:
    30.       set {_number name} to {powers of thousand::%{_power of thousand}%}
    31.       set {_result} to "%smallNumToEnglish(modulus({_num}, 1000))% %{_number name}%, %{_result}%"
    32.     set {_num} to rounded down {_num} / 1000
    33.     add 1 to {_power of thousand}
    34.   if {_result} contains ">,":
    35.     return first length of {_result} - 15 characters of {_result} #Removes the extra " <none>, <none>" at the end of the string
    36.   else:
    37.     return first length of {_result} - 8 characters of {_result} #Removes the extra ", <none>" at the end of the string
    The image below uses this command to access the function:

    Code (Skript):
    1.  
    2. command /englishnum <number>:
    3.   trigger:
    4.     send "%numToEnglish(arg)%"
    [​IMG]
     
    • Winner Winner x 1
  16. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
    Why not just use the mod(number, number) function of vanilla Skript lol
     
    #16 ShaneBee, Feb 13, 2017
    Last edited by a moderator: Feb 13, 2017
  17. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
    Ha bah on est pas les seuls :emoji_wink:
     
  18. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
    Updating mine to improve readability. It also now runs on pure Skript 2.2 (it was using some SkQuery syntax features before).

    Code (Skript):
    1. options:
    2.     TABLE: number-to-name
    3.     ERROR: [Error]
    4.     ENABLE_LARGE_NUMBER_NAMES: true
    5.  
    6. # Define all masks in a string with pattern:name pairs.
    7.  
    8. function defineMasksIn(values: text):
    9.  
    10.     set {_pairs::*} to {_values} split at " "
    11.    
    12.     loop {_pairs::*}:
    13.    
    14.         set {_pair::*} to loop-value split at ":"
    15.         set {{@TABLE}::%{_pair::1}%} to {_pair::2}
    16.        
    17. on script load:
    18.  
    19.     defineMasksIn("1:one 2:two 3:three 4:four 5:five 6:six 7:seven 8:eight 9:nine")
    20.     defineMasksIn("10:ten 11:eleven 12:twelve 13:thirteen 14:fourteen 15:fifteen 16:sixteen 17:seventeen 18:eighteen 19:nineteen")
    21.     defineMasksIn("2.:twenty 3.:thirty 4.:forty 5.:fifty 6.:sixty 7.:seventy 8.:eighty 9.:ninety")
    22.     defineMasksIn(".__:hundred ...___:thousand ...______:million ..._________:billion ...____________:trillion ..._______________:quadrillion")
    23.    
    24.     {@ENABLE_LARGE_NUMBER_NAMES} is true
    25.    
    26.     # Number names from: https://en.wikipedia.org/wiki/Names_of_large_numbers
    27.    
    28.     defineMasksIn("...__________________:quintillion ..._____________________:sextillion ...________________________:septillion")
    29.     defineMasksIn("...___________________________:octillion ...______________________________:nonillion ..._________________________________:decillion")
    30.    
    31.     defineMasksIn("...____________________________________:undecillion ..._______________________________________:duodecillion")
    32.     defineMasksIn("...__________________________________________:tredecillion ..._____________________________________________:quattuordecillion")
    33.     defineMasksIn("...________________________________________________:quindecillion ...___________________________________________________:sexdecillion")
    34.    
    35. on script unload:
    36.  
    37.     delete {{@TABLE}::*}
    38.    
    39. # Returns the matching mask for a string of digits or an error if nothing is found.
    40.    
    41. function findMaskFor(number: text) :: text:
    42.  
    43.     set {_length} to length of {_number}
    44.     set {_digits::*} to {_number} split at ""
    45.    
    46.     loop {{@TABLE}::*}:
    47.    
    48.         if {_skip} is set:
    49.        
    50.             delete {_skip}
    51.        
    52.         set {_mask} to loop-index
    53.         set {_mask-length} to length of {_mask}
    54.         set {_minimum-length} to {_mask-length}
    55.         set {_chars::*} to {_mask} split at ""
    56.        
    57.         loop {_chars::*}:
    58.            
    59.             {_skip} is not set
    60.            
    61.             set {_char} to loop-value-2
    62.             set {_digit} to {_digits::%loop-index-2%}
    63.                        
    64.             if {_char} is ".":
    65.            
    66.                 set {_minimum-length} to {_minimum-length} - 1
    67.                
    68.             else:
    69.            
    70.                 if {_minimum-length} is greater than {_length}:
    71.                
    72.                     set {_skip} to true
    73.                    
    74.                 else if {_char} is not {_digit} or "_":
    75.                
    76.                     set {_skip} to true
    77.        
    78.         {_skip} is not set
    79.        
    80.         if {_mask-length} is {_length}:
    81.        
    82.             return {_mask}
    83.            
    84.         else if {_length} is less than {_mask-length}:
    85.            
    86.             if {_length} is greater than {_minimum-length}:
    87.            
    88.                 return {_mask}
    89.            
    90.     return "{@ERROR} Unsupported value: '%{_number}%' with length %{_length}%"
    91.  
    92. # Determine whether a string starts with another.
    93.  
    94. function startsWith(start-text: text, full-text: text) :: boolean:
    95.  
    96.     if the first (length of {_start-text}) characters of {_full-text} is {_start-text}:
    97.         return true
    98.     return false
    99.  
    100. # Determine whether a string ends with another.
    101.  
    102. function endsWith(end-text: text, full-text: text) :: boolean:
    103.  
    104.     if the last (length of {_end-text}) characters of {_full-text} is {_end-text}:
    105.         return true
    106.     return false
    107.  
    108. # Insert a string into another at a specified index.
    109.  
    110. function insert(insertion: text, index: number, text: text) :: text:
    111.  
    112.     set {_left} to the first {_index} characters of {_text}
    113.     set {_right} to the last (length of {_text} - {_index}) characters of {_text}
    114.    
    115.     return "%{_left}%%{_insertion}%%{_right}%"
    116.    
    117. # Count the occurrences of a character in a string.
    118.    
    119. function occurrencesOf(char: text, in: text) :: number:
    120.  
    121.     set {_count} to 0
    122.     set {_characters::*} to {_in} split at ""
    123.    
    124.     loop {_characters::*}:
    125.    
    126.         if "%loop-value%" is {_char}:
    127.        
    128.             add 1 to {_count}
    129.            
    130.     return {_count}
    131.    
    132. # Strip all leading zeroes from a string of digits.
    133.    
    134. function stripLeadingZeroes(number: text) :: text:
    135.  
    136.     while startsWith("0", {_number}) is true:
    137.    
    138.         if length of {_number} is 1:
    139.             set {_number} to ""
    140.         else:
    141.             set {_number} to the last (length of {_number} - 1) characters of {_number}
    142.  
    143.     return {_number}
    144.    
    145. # Returns the full name of all digits in a string.
    146.    
    147. function nameOfDigits(number: text) :: text:
    148.  
    149.     if {_number} is "0":
    150.    
    151.         return "zero"
    152.  
    153.     set {_number} to stripLeadingZeroes({_number})
    154.     set {_length} to length of {_number}
    155.    
    156.     if {_length} is 0:
    157.    
    158.         return ""
    159.    
    160.     set {_mask} to findMaskFor({_number})
    161.        
    162.     if startsWith("{@ERROR}", {_mask}) is true:
    163.    
    164.         return {_mask}
    165.        
    166.     set {_mask-length} to length of {_mask}
    167.     set {_mask-cutoff} to {_mask-length} - {_length}
    168.     set {_active-mask} to the last ({_mask-length} - {_mask-cutoff}) characters of {_mask}
    169.        
    170.     if startsWith(".", {_active-mask}) is true:
    171.    
    172.         set {_left-side-components} to occurrencesOf(".", {_active-mask})
    173.         set {_split-number::*} to insert(":", {_left-side-components}, {_number}) split at ":"
    174.        
    175.         set {_left} to nameOfDigits({_split-number::1})      
    176.         set {_right} to nameOfDigits({_split-number::2})      
    177.         set {_name} to {{@TABLE}::%{_mask}%}
    178.        
    179.         if {_right} is "zero" or "":
    180.             return "%{_left}% %{_name}%"
    181.         else if {_name} is "hundred":
    182.             return "%{_left}% %{_name}% %{_right}%"
    183.         else:
    184.             return "%{_left}% %{_name}%, %{_right}%"
    185.    
    186.     else if endsWith(".", {_active-mask}) is true:
    187.    
    188.         set {_left} to {{@TABLE}::%{_mask}%}
    189.         set {_digit} to the last character of {_number}
    190.         set {_right} to nameOfDigits({_digit})
    191.        
    192.         if {_right} is "zero" or "":
    193.             return "%{_left}%"
    194.         else:
    195.             return "%{_left}%-%{_right}%"
    196.        
    197.     else:
    198.    
    199.         return {{@TABLE}::%{_mask}%}
    200.        
    201. # Converts an integer to a string and returns the result of nameOfDigits()
    202.  
    203. function nameOfNumber(number: integer) :: text:
    204.  
    205.     return nameOfDigits("%{_number}%")
    206.  
    207. command /nameof <integer>:
    208.     trigger:
    209.    
    210.         set {_result} to nameOfNumber(arg-1)
    211.         send "%arg-1%: &a%{_result}%"
    212.        
    213. # A function to ensure a string only contains numeric characters.
    214.  
    215. function validateDigitsOf(text: text) :: boolean:
    216.  
    217.     set {_chars::*} to {_text} split at ""
    218.    
    219.     loop {_chars::*}:
    220.         if "0123456789" doesn't contain "%loop-value%":
    221.             return false
    222.            
    223.     return true
    224.    
    225. command /nameofdigits <text>:
    226.     trigger:
    227.    
    228.         if validateDigitsOf(arg-1) is true:
    229.        
    230.             set {_result} to nameOfDigits(arg-1)
    231.             send "%arg-1%: &a%{_result}%"
    232.            
    233.         else:
    234.        
    235.             send "&cThe only characters allowed are: 0-9"
    236.  
    Usage:
    • call nameOfDigits() with a string argument
    • or call nameOfNumber() with an integer argument
    • or execute /nameof <integer>
    • or execute /nameofdigits <text>
    [​IMG]
     
    #18 ShaneBee, Feb 14, 2017
    Last edited by a moderator: Feb 14, 2017
    • Winner Winner x 1
  19. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
    When you realize that this is one hundred twenty-three sexdecillion times better than anything you could ever make:

     
    • Agree Agree x 1
    • Funny Funny x 1
  20. ShaneBee

    Supporter +

    Joined:
    Sep 7, 2017
    Messages:
    1,288
    Likes Received:
    79
    Offtopic: Nice image! :emoji_grinning:
    --- Double Post Merged, Feb 16, 2017, Original Post Date: Feb 16, 2017 ---
    It's announced now. xD
     
Thread Status:
Not open for further replies.
Loading...