Challenge: Ugly Numbers
A number is ‘ugly’ if it is divisible by any of the one-digit primes (2, 3, 5 or 7). Note that 0 is ugly. Also note that negative numbers can also be ugly.
If you have a string of D digits there are 3^(D-1) expressions you can make if you are allowed to insert plus or minus signs between the digits. Between each two adjacent digits you may choose put a plus sign, a minus sign, or nothing. Note that it is fine to have leading zeros for a number, E.g. if the string is '01023', then '01023', '0+1-02+3' and '01-023' are legal expressions.
Create a VI that will count how many of the 3^(D-1) expressions evaluate to an ugly number.
The input will be a single line containing a non-empty string of decimal digits. Each string will be no more than 13 characters long.
I took on this challenge after a talk about trends in UI design at the 2015 CLD Summit so I thought I would use it as a chance to play with the flat design (basically use a simple colour palette on the classic controls). The colour palette was chosen with this tool set to complementary colours https://color.adobe.com/create/color-wheel/
I attempted to do the ugly number counting as each permutation of the input string was generated to reduce the amount to data duplicates that LabVIEW has to maintain.
The key VI to my solution is the "Insert Before Digit n" as this makes it easy to expand the input strings in a nested loop structure.
Another big performance boost comes from using my own VI to convert a string expression into a number - this executes 27 times faster than the built-in LV one (but only works for this problem).
I am pretty pleased with how it all works but if anyone has any feedback or questions feel free to send them my way.
I like the calculating on the fly method - you just add the +/- and the 'nothings' take care of themselves.
The flat UI is nice too!
Although I missed the meeting I had a quick go at this.
The method is as follows:
- Find all the permutations for a 13 digit string - i.e. the maximum we need to handle
- Check the size of the input string and calculate how many operators we need and how many permutations are possible
- Select this sub-set of permutations from the maximum for 13 digits
- Build the expressuions
- Evaluate the expressions
- Test if each result is 'ugly'
- Display number and % of uglies
-Generating the permutations for 13 digits is slow. I tried making a constant but it was so big I was unable to save the vi!
I should really find a better way of doing it.
- Some error handling is needed for 0 or >13 digit entries
My (revamped) attempt attached.
It was all the string manipulation in the functional global that was taking all the time so I have removed the need to search the string to see if the expression already exists and moved the formula evaluation out of the FG. The FG now just keeps a count of the number of 'uglies'.
Zero points for front panel aesthetics!
Whats the sense of putting all these +- inside a sequence of numeric digits.
Either a number is pos or neg but whats 100-5+4? Whats the sense?
Wouldn't that be common logic to check string validity before counting
such strange expressions?