DataWeave programming challenge #3: Count palindrome phrases using the Strings module
Review each of the input phrases and find those that are palindromes. Then, retrieve the character count and sum the total characters.
DataWeave Programming Challenges· Part 3 of 8
- 1.DataWeave programming challenge #1: Add numbers separated by paragraphs and get the max number
- 2.DataWeave programming challenge #2: Rock Paper Scissors game score system
- 3.DataWeave programming challenge #3: Count palindrome phrases using the Strings module
- 4.DataWeave programming challenge #4: Solve the Tower of Hanoi mathematical puzzle
- 5.DataWeave programming challenge #5: Reverse a phrase's words, but keep the punctuation
- 6.DataWeave programming challenge #6: Using tail-recursion to get the factorial of a number
- 7.DataWeave programming challenge #7: Modify certain values from a JSON structure
- 8.DataWeave programming challenge #8: Sum all digits to get a 1-digit number
Try to solve this challenge on your own to maximize learning. We recommend you refer to the DataWeave documentation only. Try to avoid using Google or asking others so you can learn on your own and become a DataWeave expert!
Solve on the PlaygroundTip
For this challenge, we encourage you to make use of the Strings module’s functions.
Input
Consider the following input payload (can be of txt format):
this is not a palindrome
blue
Mr. Owl ate my metal worm
Was it a car or a cat I saw?
you're doing great!
mug
Rats live on no evil star
what's taking so long?
kayak
Live on time, emit no evil
Step on no pets
boat
Anna
2020/02/02
15/03/2001
01/02/2010
Explanation of the problem
Each line of the input payload is considered a different phrase. Review each phrase and find those that are palindromes. Notice that punctuation, spaces, or special characters should not be considered to ensure a phrase is a palindrome.
For example,
- Anna in reverse is anna - this is a palindrome.
- 2020/02/02 in reverse is 20200202 - this is a palindrome.
- Mr. Owl ate my metal worm in reverse is mrowlatemymetalworm - this is a palindrome.
After that, retrieve the character count of the original phrase. Including punctuation, spaces, and special characters.
For example,
- Anna is 4.
- 2020/02/02 is 10.
- Mr. Owl ate my metal worm is 25.
Return the total sum of all the palindrome’s character count.
Expected output
In this case, the expected output would be:
148
The result for each of the phrases (whether they’re palindrome or not) should be:
- false
- false
- true
- true
- false
- false
- true
- false
- true
- true
- true
- false
- true
- true
- false
- true
Clues
If you’re stuck with your solution, feel free to check out some of these clues to give you ideas on how to solve it!
Clue #1
Read the documentation of the Strings module to make yourself familiar with the existing functions.
Clue #2
If you’ve been following the previous challenges, we’ve learned that payload splitBy "\n" can be replaced with the lines() function from the Strings module.
Clue #3
Use the lower() function to make sure all the characters can be compared in lower-case.
Clue #4
Instead of using map() to iterate through the string’s characters, you can use mapString() from the Strings module.
Clue #5
You don’t need to use regex to find the alphanumeric characters. You can use isAlphanumeric() from the Strings module.
Clue #6
Instead of using selectors, you can use the reverse() function from the Strings module.
Clue #7
Use sizeOf() and sum() to retrieve the character count in an array and then sum the complete array of numbers.
Answer
If you haven’t solved this challenge yet, we encourage you to keep trying! It’s ok if it’s taking longer than you thought. We all have to start somewhere ✨ Check out the clues and read the docs before giving up. You got this!! 💙
There are many ways to solve this challenge, but you can find here one of our solutions so you can compare your result with us.
Solution #1
%dw 2.0
import lines, isAlphanumeric, mapString, reverse from dw::core::Strings
output application/json
---
sum(lines(payload) map (line) -> do {
var clearLine = lower(line) mapString (
if (isAlphanumeric($)) $
else ""
)
var isPalindrome = clearLine == reverse(clearLine)
---
if (isPalindrome) sizeOf(line)
else 0
})
Subscribe to receive notifications as soon as new content is published ✨
Reader notes
Helpful comments preserved from the original post.
- Kevin Medina · Feb 23, 2024
%dw 2.0 import * from dw::core::Strings import * from dw::core::Arrays output application/json fun getPalindromCount(text) = (lines(text) map ((sentence, index) -> do{ var cleanedSentence = lower(sentence mapString if (!isAlphanumeric($)) "" else $) --- if(reverse(cleanedSentence) == cleanedSentence) sizeOf(sentence) else 0 }))sumBy $ --- getPalindromCount(payload) - Kelvin Fernandes · Oct 23, 2023
%dw 2.0 import * from dw::core::Strings var payloadLines = lines(payload) var payloadLinesOnlyLetterAndNumbers = payloadLines map ( lower( $ replace /[^A-Za-z0-9]/ with "" ) ) var areTheyPalindromes = payloadLinesOnlyLetterAndNumbers map ( $ == reverse($) ) var onlyPalindromesLines = (areTheyPalindromes map ( if($) ( payloadLines[$$] ) else ( null ) )) filter $ != null output application/json --- /* Expected output: 148 */ sizeOf(onlyPalindromesLines joinBy "") - Victor Manuel Rodriguez · Jul 11, 2023
%dw 2.0 import * from dw::core::Strings fun isPalindrome(word) = word == reverse(word) fun formatWord(word) = lower(word replace /[^\w\d]/ with "") output application/json --- sum(lines(payload) map(if(isPalindrome(formatWord($))) sizeOf($) else 0)) - shwetabh singh · May 6, 2023
Here is my approach:
%dw 2.0 fun checkPalindrome(a)= do{ import * from dw::core::Strings var originalString = lower(a) replace /[\/,.'?!\s]/ with "" var reverseString = reverse(originalString) --- if(reverseString == originalString) "Palindrome" else "Not Palindrome" } import * from dw::core::Strings output application/json --- sum((lines(payload) map ((item, index) ->{ isPalindrome: checkPalindrome(item), size: sizeOf(item) } ) filter $.isPalindrome == "Palindrome").size) - tafkamw · May 2, 2023
%dw 2.0 output application/json import * from dw::core::Strings var cleanString = (aString) -> lower (aString mapString if( !isAlphanumeric($)) "" else $) --- lines(payload) map ( sizeOf( if (cleanString($) == reverse(cleanString($))) $ else "" ) ) reduce ($$ + $) - mysg147 · Apr 22, 2023
%dw 2.0 import * from dw::core::Strings output application/json fun str(inputstring) = lower(inputstring mapString if(isAlphanumeric($)) $ else "") var x = payload splitBy('\n') var y = x map((val,in) -> if(reverse(str(val)) == str(val)) sizeOf(val) else 0 ) --- sum(y) - Sudiptaa · Mar 28, 2023
%dw 2.0 output json import * from dw::core::Strings fun isPalindrome(s) = do { var str = lower(s) replace /[^a-zA-Z0-9]/ with "" var revStr = lower(reverse(s)) replace /[^a-zA-Z0-9]/ with "" --- str == revStr } --- sum((payload splitBy("\n") map { inputString : $, countChars: sizeOf($), isPalindrome: isPalindrome($) } filter($.isPalindrome)).countChars) - Monika Soni · Mar 22, 2023
%dw 2.0 output application/json import * from dw::core::Strings fun charcterstring(str) = lower(str mapString (if(isAlphanumeric($)) $ else "" )) --- sum((lines(payload) map ( if (charcterstring($)== reverse(charcterstring($))) sizeOf($) else 0))) - armandomejiam · Mar 10, 2023
👌 This was my first approach, I was avoiding the usage of regex... then I checked your solution and I remember the existence of "isAlphanumeric" function, so I refactored my solution to make it a bit more clean:
%dw 2.0 import * from dw::core::Strings output application/json fun clearLine (line:String) = lower(line filter (isAlphanumeric ($))) fun isPalindrome(line: String) = line == reverse(line) --- lines(payload) filter (isPalindrome(clearLine($))) reduce ((line, acc=0) -> acc+sizeOf(line)) - Abhijeet Kumar · Mar 7, 2023
%dw 2.0 import * from dw::core::Strings output application/json fun replaceSpecial(data:String) = (data replace /[^a-z0-9A-Z]/ with "") fun isPalindrome(data:String)= if(lower(reverse(replaceSpecial(data))) == lower(replaceSpecial(data))) data else 0 --- sum(payload splitBy("\n") map ((item, index) -> if(isPalindrome(item) == 0 ) 0 else sizeOf(item) )) - Felix Schnabel · Mar 7, 2023
My solution:
%dw 2.0 output application/json import * from dw::core::Arrays import * from dw::core::Strings --- lines(payload) filter( lower($ filter isAlphanumeric($)) then $ == $[-1 to 0] ) map sizeOf($) then sum($) - Shyam Raj Prasad · Mar 7, 2023
My approach for this.
%dw 2.0 import lines, isAlphanumeric, reverse from dw::core::Strings output application/json --- lines(payload) reduce ((item, accumulator = 0) -> do { var text = lower(item filter (isAlphanumeric($))) --- if(text == reverse(text)) sizeOf(item) + accumulator else accumulator + 0 } ) - Stefano Bernardini · Mar 7, 2023
I can do better than this, but it works! 😅
%dw 2.0 output application/json fun removeStuff(p: String) = upper(p) then $ replace /[^a-z0-9A-Z ]/ with "" then $ replace " " with "" fun isPalindrome(p: String) = removeStuff(p) == removeStuff(p[-1 to 0]) --- ( payload splitBy "\n" map (item, index) -> { "paly" : isPalindrome(item), "size" : sizeOf(item) }) filter $.paly then sum($.size) - prasadrnithin · Mar 7, 2023
%dw 2.0 output application/json import * from dw::core::Strings var split_phrases = lines(payload) var alpha_numeric_strings = split_phrases map ((item, index) -> item filter (isAlphanumeric($))) --- sum(alpha_numeric_strings map ((item, index) -> if(lower(item) == lower(item)[-1 to 0]) sizeOf(split_phrases[index]) else 0))
FAQs
Frequently asked questions about this post.
-
What does this DataWeave challenge ask you to do?
Each line of the input payload is treated as a separate phrase, and you review every phrase to find the ones that are palindromes, ignoring punctuation, spaces, and special characters. Then you retrieve the character count of the original phrase (including its punctuation, spaces, and special characters) and return the total sum of all the palindromes' character counts.
-
How is the expected output of 148 calculated?
It is the sum of the character counts of every palindrome phrase in the input, counting each original phrase in full. For example
Annacounts as 4,2020/02/02counts as 10, andMr. Owl ate my metal wormcounts as 25, and adding up the lengths of all the palindrome lines gives 148. -
Why is `Mr. Owl ate my metal worm` considered a palindrome here?
Because punctuation and spaces are not considered when checking for a palindrome, so once you strip them out it becomes
mrowlatemymetalworm, which reads the same in reverse. The character count, though, is taken from the original phrase including its spaces and the period, which is 25. -
Which DataWeave functions does the sample solution use?
The solution imports
lines,isAlphanumeric,mapString, andreversefromdw::core::Strings, then useslowerto normalize case,mapStringwithisAlphanumericto drop non-alphanumeric characters,reverseto compare the cleaned line against itself, andsizeOfplussumto count and total the characters. -
Do I need to use regex to remove the special characters?
No, the clues note that you do not need regex to find the alphanumeric characters because you can use
isAlphanumeric()from the Strings module, and you can iterate through a string's characters withmapString()instead ofmap(). -
How can I replace `payload splitBy "\n"` in this challenge?
One of the clues points out that
payload splitBy "\n"can be replaced with thelines()function from the Strings module, which splits the input payload into its individual phrases.
More from this series
DataWeave Programming Challenges· Part 3 of 8
- 1.DataWeave programming challenge #1: Add numbers separated by paragraphs and get the max number
- 2.DataWeave programming challenge #2: Rock Paper Scissors game score system
- 3.DataWeave programming challenge #3: Count palindrome phrases using the Strings module
- 4.DataWeave programming challenge #4: Solve the Tower of Hanoi mathematical puzzle
- 5.DataWeave programming challenge #5: Reverse a phrase's words, but keep the punctuation
- 6.DataWeave programming challenge #6: Using tail-recursion to get the factorial of a number
- 7.DataWeave programming challenge #7: Modify certain values from a JSON structure
- 8.DataWeave programming challenge #8: Sum all digits to get a 1-digit number
