11
\$\begingroup\$

The Rockstar programming language has "poetic number literals", allowing you to assign nonnegative, finite (at least one Rockstar interpreter supports infinity) numbers to variables without typing a single digit: just type words with length equal to each digit, modulo 10. For example,

This is a challenge

sets the variable this to 19.

So here is the challenge: given a string as input, output its value as a poetic number literal.

To calculate the value, split the string up into words (separated by one or more spaces, one or more commas, or both), then take the ones digit of the length of each word, and finally concatenate for the value. However, if there are one or more periods ., the first period is to be interpreted as a decimal point, and any other periods treated as word separators.

You can assume the input is nonempty, and will consist of nothing but letters, commas, periods and spaces. Also, you can assume there is no period before the first word.

You can ignore edge cases, like when the word is not supposed to be interpreted as a number. For example,

The news is true

will not set the variable the news to 4, because true is to be interpreted as a boolean value. However, your program should output 4 given true as an input.

Test cases:

test cases -> 45
hi -> 2
hi bye -> 23
hi , ,, ,,, bye -> 23
hi , ,, .,,, bye -> 2.3
hi, bye -> 23
hi,bye -> 23
verylongword -> 2
a verylongword -> 12
this is azerodigit -> 420
azerodigit -> 0
azerodigit.four -> 0.4
one.azerodigit one -> 3.03
azerodigit hi -> 2
hi. bye -> 2.3
hi.bye -> 2.3
hi. -> 2
hi. bye azerodigit -> 2.3
hi. bye azerodigit ha -> 2.302
hi. azerodigit -> 2
hi.bye.ha -> 2.32
hi.,,..,bye.,.,.,.,.,ha -> 2.32
hi,,..,bye.,.,.,.,.,ha -> 2.32
hi,,,bye.,.,.,.,.,ha -> 23.2
hi,,,bye,,,,,ha -> 232

This is , so fewest bytes wins!

Edit: For clarity, there cannot be trailing 0s in the decimal part, or leading 0s in the integer part of the number for valid inputs. For example, azerodigit hi. azerodigit should output 2, not 02.0, 2.0 or anything other than 2.

asked Mar 29, 2024 at 20:42
\$\endgroup\$
7
  • 1
    \$\begingroup\$ Is it guaranteed that the input contains at most one period, and that the period will always be followed by a space and another word? \$\endgroup\$ Commented Mar 29, 2024 at 20:46
  • 3
    \$\begingroup\$ Can you be more specific about "ignoring commas"? For example, can the input be foo,bar and if so how would it be interpreted? \$\endgroup\$ Commented Mar 29, 2024 at 21:02
  • 1
    \$\begingroup\$ hi,bye -> 33 should be 23, no? \$\endgroup\$ Commented Mar 30, 2024 at 8:08
  • 1
    \$\begingroup\$ Is it possible for there to be a period before the first word? \$\endgroup\$ Commented Mar 30, 2024 at 20:55
  • \$\begingroup\$ Looks like you've got some test cases in there multiple times. Also, the second to last test case has a comma after it. \$\endgroup\$ Commented Mar 31, 2024 at 11:11

12 Answers 12

5
\$\begingroup\$

JavaScript (ES6), 68 bytes

s=>+s.replace(/(?<!\..*)(\.)|\w+|(.)/g,(a,b,c)=>c?"":b||a.length%10)

Try it online!

answered Mar 29, 2024 at 23:35
\$\endgroup\$
5
\$\begingroup\$

JavaScript (Node.js), 61 bytes

s=>+s.replace(/\w+|./g,a=>a+d<1?d=a:a>'?'?a.length%10:"",d=1)

Try it online!

-2B from tsh

You can assume the input is nonempty, and will consist of nothing but letters, commas, periods and spaces.

With letter filtered, all cases can be listed as follow:

d comma period space
1 ,1 .1 1
'.' ,. .. .

Only .1 is smaller than 1

answered Mar 30, 2024 at 10:21
\$\endgroup\$
3
  • \$\begingroup\$ Note that assumption is needed, as if b=='-' then b+1<1 is also true \$\endgroup\$ Commented Mar 30, 2024 at 11:37
  • \$\begingroup\$ s=>+s.replace(/\w+|./g,a=>a+d<1?d=a:a>{}?a.length%10:"",d=1) \$\endgroup\$ Commented Apr 1, 2024 at 5:07
  • \$\begingroup\$ @tsh Is it promised that all are lowercase? \$\endgroup\$ Commented Apr 1, 2024 at 5:24
3
\$\begingroup\$

Uiua SBCS , (削除) 32 (削除ここまで) 31 bytes

⋕▽⬚0⍜⊡¬⊗@.,≥@0.⍜⊜しろいしかく(°⋕◿10∵◇⧻)⌵±.

Try it!

-1 thanks to noodle man!

⋕▽⬚0⍜⊡¬⊗@.,≥@0.⍜⊜しろいしかく(°⋕◿10∵◇⧻)⌵±.­⁡​‎⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠‎⁡⁠⁢⁤⁤‏‏​⁡⁠⁡‌⁢​‎⁠⁠⁠⁠⁠‎⁡⁠⁢⁤⁡‏⁠‎⁡⁠⁢⁤⁢‏⁠‎⁡⁠⁢⁤⁣‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁤⁤‏⁠‎⁡⁠⁢⁡⁡‏⁠‎⁡⁠⁢⁡⁢‏⁠‎⁡⁠⁢⁡⁣‏⁠‎⁡⁠⁢⁣⁤‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁢⁣⁡‏⁠‎⁡⁠⁢⁣⁢‏⁠‎⁡⁠⁢⁣⁣‏‏​⁡⁠⁡‌⁢⁡​‎‎⁡⁠⁢⁢⁢‏⁠‎⁡⁠⁢⁢⁣‏⁠‎⁡⁠⁢⁢⁤‏‏​⁡⁠⁡‌⁢⁢​‎⁠‎⁡⁠⁢⁡⁤‏⁠‎⁡⁠⁢⁢⁡‏‏​⁡⁠⁡‌⁢⁣​‎‎⁡⁠⁤⁣‏‏​⁡⁠⁡‌⁢⁤​‎⁠‎⁡⁠⁣⁤‏⁠‎⁡⁠⁤⁡‏⁠‎⁡⁠⁤⁢‏‏​⁡⁠⁡‌⁣⁡​‎‎⁡⁠⁢⁤‏⁠‎⁡⁠⁣⁡‏⁠‎⁡⁠⁣⁢‏⁠‎⁡⁠⁣⁣‏‏​⁡⁠⁡‌⁣⁢​‎‎⁡⁠⁢⁡‏⁠‎⁡⁠⁢⁢‏⁠‎⁡⁠⁢⁣‏‏​⁡⁠⁡‌⁣⁣​‎‎⁡⁠⁣‏⁠‎⁡⁠⁤‏‏​⁡⁠⁡‌⁣⁤​‎‎⁡⁠⁢‏⁠‏​⁡⁠⁡‌⁤⁡​‎‎⁡⁠⁡‏‏​⁡⁠⁡‌­
 . # ‎⁡duplicate
 ⌵± # ‎⁢mask of letters
 ⍜⊜しろいしかく( ) # ‎⁣apply function to each contiguous mask group
 ∵◇⧻ # ‎⁤lengths
 ◿10 # ‎⁢⁡modulo ten
 °⋕ # ‎⁢⁢unparse
 . # ‎⁢⁣duplicate
 ≥@0 # ‎⁢⁤mask of digits
 ⊗@., # ‎⁣⁡index of first period
 ⍜⊡¬ # ‎⁣⁢negate at index
 ⬚0 # ‎⁣⁣filling with zero if no period found
 ▽ # ‎⁣⁤keep characters given mask
⋕ # ‎⁤⁡parse to number, removing leading and trailing zeros
💎

Created with the help of Luminespire.

answered Mar 30, 2024 at 11:02
\$\endgroup\$
1
  • 1
    \$\begingroup\$ <0± can be ⌵± \$\endgroup\$ Commented Mar 30, 2024 at 12:42
3
\$\begingroup\$

Retina 0.8.2, 66 bytes

((\.)|.)*?(?=\w)(\w{10})*(\w*)
2ドル$.4
1>`\.
^0+\B|\.?0*(?<=\..*)$

Try it online! Link includes test cases. Explanation: Skips over enough non-letters to reach the next word, then skips over multiples of 10 letters, then counts any remaining letters, and captures any ., outputting the number of remaining letters and any captured .. Edit: Added an extra stage to remove insignificant zeros that don't change the value of the result. Edit: Improved the detection of .s and added an extra stage to remove .s after the first.

answered Mar 29, 2024 at 21:56
\$\endgroup\$
2
  • \$\begingroup\$ Your answer is invalid, see my latest edit. There cannot be trailing 0s in the decimal part, or leading 0s in the integer part of the number for valid inputs (so azerodigit hi should output 2 instead of 02) \$\endgroup\$ Commented Mar 29, 2024 at 22:31
  • 1
    \$\begingroup\$ @JonathanAllan Actually that's just a bug, it doesn't handle multiples of 10 correctly. \$\endgroup\$ Commented Mar 31, 2024 at 20:18
2
\$\begingroup\$

JavaScript (ES6), 93 bytes

s=>s.split(/\W+/).map(w=>++a&&w.length%10,a=0).join``/10**(a-s.match(/(?<!\..*)\w+/g).length)

Try it online! Borrows the JS test runner from Arnauld's answer.

Getting back into CodeGolf after a long time, tried a different approach than Arnauld's beautiful regex magic.

answered Mar 30, 2024 at 2:57
\$\endgroup\$
1
\$\begingroup\$

Charcoal, 36 bytes

≔⪪S.θII⪫E⟦§θ0⪫Φθκ ⟧⭆Φ⪪⪫⪪ι,¦ ¦ λ%Lλχ.

Try it online! Link is to verbose version of code. Explanation:

≔⪪S.θ

Split the input on all .s. (Charcoal doesn't have an easy way to split on just the first ..)

II⪫E⟦§θ0⪫Φθκ ⟧⭆Φ⪪⪫⪪ι,¦ ¦ λ%Lλχ.

For the first part and the join of any remaining parts on spaces, replace commas with spaces, then split on spaces, remove empty words, and replace the words with their lengths modulo 10. Join the pieces together with a ., then cast to float and back to string to remove irrelevant zeros.

answered Mar 30, 2024 at 10:03
\$\endgroup\$
1
\$\begingroup\$

Jelly, 26 bytes

".ɓœṡnŒs$Œg§ḟ0ドル%5Ḍœrƭ0ドルj9t

A full program that accepts a string and prints the Rockstar poetic number literal.

Try it online! Or see the test-suite.

How?

".ɓœṡnŒs$Œg§ḟ0ドル%5Ḍœrƭ0ドルj9t - Main Link: list of characters, Poem
".ɓ - start a new chain f(Poem, Dot='.')
 œṡ - split Poem at the first Dot
 nŒs$ - not equal swapped-case? (vectorises)
 Œg - group runs of equal elements
 (only vectorises at depth 1)
 § - sums
 ḟ0ドル - filter zeros from each
 %5 - mod ten
 € - for each:
 ƭ - alternate between:
 Ḍ - 1) convert from decimal
 -> integer part as an integer
 œr 0 - 2) trim zeros from right
 -> decimal part as a digit list
 j9 - join with a Dot
 t - trim any Dots from either side
 (removes a potential trailing dot)
 - implicit, smashing print
answered Mar 31, 2024 at 9:31
\$\endgroup\$
1
\$\begingroup\$

Regex, 97 bytes (RegRep)

Not very short, but I thought it was funny.

[A-z]/_
\b_|0_/1
1_/2
2_/3
3_/4
4_/5
5_/6
6_/7
7_/8
8_/9
9_/0
^0(?=\d)|(?<=\..*)(\.|0$)|\.$|[, ]

Commented:

[A-z]/_ Replace all chars with _ to make counting shorter
\b_|0_/1 Replace all starting _ with 1
 (\b|0)_ is longer lol
1_/2 1 -> 2
2_/3 2 -> 3
3_/4 3 -> 4, etc.
4_/5 .
5_/6 .
6_/7 .
7_/8 .
8_/9 .
9_/0 .
^0(?=\d)|(?<=\..*)(\.|0$)|\.$|[, ] removes...
| | | | | | extra chars
| | | | | trailing decimal
| | | | trailing 0...
| | | or any period...
| | but only after the first decimal point
| Leading 0s
answered Mar 31, 2024 at 23:35
\$\endgroup\$
1
\$\begingroup\$

Perl 5 -p, 55 bytes

s/\w+/(length$&)%10/ge;s/\./!$a++&&'.'/ge;y/, //d;$_+=0

Try it online!

answered Apr 1, 2024 at 16:45
\$\endgroup\$
1
\$\begingroup\$

05AB1E, (削除) 31 (削除ここまで) 30 bytes

'.©1.;1¡ε1ú.γa}ιθεgθ]J®ý1/0Ü®Ü

Try it online or verify all test cases.

Explanation:

'. '# Push "."
 © # Store it in variable `®` (without popping)
 1.; # Replace the first "." in the (implicit) input with a 1
 1¡ # Then split on that 1
 ε # Map over both parts:
 .γ } # Adjacent group by:
 a # Is alphabetic?
 ι # Uninterleave into two parts
 θ # Only keep the last part with the words
 ε # Map over the words:
 g # Pop and push its length
 θ # Pop and keep its last digit (aka mod-10)
 ] # Close the nested maps
 J # Join each inner-most lists of digits together
 ®ý # Join both parts back together with a "."-delimiter
1/ # Divide it by 1 to remove trailing/leading 0s (which also
 # adds a ".0" to any integers)
 0Ü # Remove the trailing 0
 ®Ü # Remove the trailing "."
 # (after which the result is output implicitly as result)
answered Mar 31, 2024 at 14:45
\$\endgroup\$
1
\$\begingroup\$

Google Sheets, 152 bytes

=let(f,lambda(i,join(,sort(mod(len(split(index(split(substitute(substitute(A1,".","μ",1),".",","),"μ"),,i)," ,",1,1)),10)))),--(f(1)&iferror("."&f(2))))

Put the input in cell A1 and the formula in cell B1.

poetic.png

Ungolfed:

=let( 
 parts, split(substitute(substitute(A1, ".", "μ", 1), ".", ","), "μ"), 
 get_, lambda(i, join("", index(mod(len(split(index(parts,,i), " ,", 1, 1)), 10)))), 
 value(get_(1) & iferror("." & get_(2))) 
)
answered Mar 31, 2024 at 21:30
\$\endgroup\$
1
\$\begingroup\$

Swift 6, (削除) 154 (削除ここまで) 144 bytes

let l={(0ドル+"").split{0ドル<"."}.map{"\(0ドル.count%10)"}.joined()},f={{Float(l(""+0ドル[0])+"."+l({0ドル[1...].joined}(0ドル)(" ")))!}((0ドル+"").split{0ドル=="."})}

Try it on SwiftFiddle!

This is, at its core, a similar idea to @Neil's Charcoal answer, just a lot more verbose.

answered Apr 1, 2024 at 15:08
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.