# Detect the Nearly Perfect Licence Plates

Note: This is inspired by this question by @Willbeing where task was to count the number of perfect plates of a certain length, but it's slightly different.

We call a perfect licence plate that plate whose text satisfies the following conditions:

• It consists of characters, which can either be uppercase letters([A-Z]) or digits([0-9])
• Summing the positions of its letters in the English alphabet, 1-indexed (i.e: A=1,B=2,...,Z=26) gives an integer n
• Getting each chunk of digits, summing them and then multiplying all the results gives the same result, n
• n is a perfect square (e.g: 49 (72), 16 (42))

A nearly perfect licence plate meets the conditions for a perfect licence plate, except that n is not a perfect square.

# Input

A string representing the text of the licence plate, taken as input in any standard form, except for hardcoding.

# Output

If the given string represents a nearly perfect licence plate, return a truthy value (e.g: True / 1), otherwise return a falsy value (e.g: False / 0). Any standard form of output is accepted while taking note that this loopholes are strictly forbidden.

### Examples

licence plate -> output

A1B2C3 -> 1

A + B + C = 1 + 2 + 3 = 6
1 * 2 * 3 = 6
6 is not a perfect square, 6 = 6 => nearly perfect plate

01G61 -> 1

(0 + 1) * (6 + 1) = 7
G = 7
7 is not a perfect square, 7 = 7 => nearly perfect plate

11BB2 -> 0

(1 + 1) * 2 = 4
B + B = 2 + 2 = 4
4 = 4, but 4 is the square of 2 => perfect license plate (not what we want)

67FF1 -> 0

(6 + 7) * 1 = 13
F + F = 6 + 6 = 12
12 != 13 => not perfect at all!


## Scoring

This is , so the shortest answer in bytes wins!

• popularity-contest Apr 8 '17 at 15:34
• I think this would be better as code-golf. Apr 8 '17 at 15:35
• Let me make sure I understand this. We only output truthy if the licence plate is perfect and n is not a perfect square? Apr 8 '17 at 16:00
• @mathjunkie Yes. TL;DR: only if the licence is nearly perfect (P.S sorry for the late response) Apr 8 '17 at 16:12
• Before anyone does s/licence/license/ig on this, be aware that "licence" is the correct spelling in British English (as well as English in other parts of the world).
– user45941
Apr 8 '17 at 17:00

# Jelly, 29 28 30 bytes

+1 byte to fix a bug spotted by ChristianSievers (incorrectly dealing with substrings of only zeros) +1 byte to fix false positives for "0", "00", ... found during above fixing (0 is a perfect square).

i@€ØAS;Æ²$e€ØAœpV€€LÐfS€P;0⁼Ç  ### How? i@€ØAS;Æ²$ - Link 1: [letter-sum, letter-sum is perfect square?]: plate
i@€        - index of €ach char in plate [reversed @rguments] (1-based, 0 otherwise) in:
ØA      -     uppercase alphabet
S     - sum
$- last two links as a monad: ; - concatenate with: Æ² - is square? e€ØAœpV€€LÐfS€P;0⁼Ç - Main link: plate e.g. "11BB2" œp - partition plate at truthy values of: e€ - is in? for €ach char in plate: ØA - uppercase alphabet [['1','1'],[''],['2']] V€€ - evaluate for €ach for €ach [[1,1],[],] Ðf - filter keep: L - length [[1,1],] S€ - sum each [2,2] P - product 4 ;0 - concatenate a zero [4,0] Ç - last link (1) as a monad (taking plate) [4,1] ⁼ - equal? (non-vectorising) 0  • Wow, genius Jelly solution! Apr 8 '17 at 16:31 • What about 11AA0? Apr 9 '17 at 14:05 • @ChristianSievers, good catch. Fixed along with another, kind of related, bug and extended the test suite. Apr 9 '17 at 17:16 # MATL, 363433 35 bytes 3Y432YXU"@V!Usvp]GlY2&msy=wtQ:qUm~v  Try it at MATL Online Explanation  % Implicitly grab input as a string 3Y4 % Push the predefined literal '[A-Za-z]+' to the stack 32 % Push the literal 32 to the stack (ASCII for ' ') YX % Replace the matched regex with spaces (puts a space in place of all letters) U % Convert the string to a number. The spaces make it such that each group of % of consecutive digits is made into a number " % For each of these numbers @V!U % Break it into digits s % Sum the digits v % Vertically concatenate the entire stack p % Compute the product of this vector ] % End of for loop G % Explicitly grab the input again lY2 % Push the predefined literal 'ABCD....XYZ' to the stack &m % Check membership of each character in the input in this array and % return an array that is 0 where it wasn't a letter and the index in 'ABC..XYZ' % when it was a letter s % Sum the resulting vector y % Duplicate the product of the sums of digits result = % Compare to the sum of letter indices result w % Flip the top two stack elements Q % Add one to this value (N) t: % Duplicate and compute the array [1...N] q % Subtract 1 from this array to yield [0...N-1] U % Square all elements to create all perfect squares between 1 and N^2 m~ % Check to ensure that N is not in the array of perfect squares v % Vertically concatenate the stack. % Implicitly display the truthy/falsey result  • Yields false positives for plates consisting of only zeros, e.g. '0' or '00' (FWIW I just fixed that in my code too). Apr 9 '17 at 17:35 • @JonathanAllan Updated. Apr 10 '17 at 13:10 # Python 2, 120 118 bytes s=t=p=0;r=1 for n in input(): h=int(n,36) if h>9:s+=h-9;r*=t**p p=h<10;t=(t+h)*p print(s==r*t**p)&(int(s**.5)**2<s)  Try it online! Interprets each character as a number in base-36 (h). Converts to decimal and adds to the sum if h>9 (meaning it's a letter), otherwise adds to a variable which gets multiplied to form the running product later. # Perl 5, 80 bytes 79 bytes of code + -p flag. $.*=eval s/./+$&/gr for/\d+/g;$t-=64-ord for/\pl/g;$_=$.==$t&&($.**.5|0)**2!=$.  Try it online! $.*=eval s/./+$&/gr for/\d+/g; multiplies the sums of consecutive digits. (I'm using $. because it's initial value is 1, which mean it's the neutral element for multiplication). More precisely, for each chunk of digits (for/\d+/g), s/./+$&/gr places a + before each digit, then the string is evaluated, and multiplied with the current product. Secondly, $t-=64-ord for/\pl/g; sums in $t each letter (for/\pl/g). (ord return the ascii code for the letter, and 64-.. makes it be between 1 and 26. Finally, $.==$t checks that both values are the same, and ($.**.5|0)**2!=$. that it's nor a perfect square. # Python 2, 267 207 bytes Saved 60 bytes thanks to ovs import re def g(l):a=reduce(lambda a,b:a*b,[sum(map(int,list(i)))for i in re.sub(r'\D',' ',l).split()],1);return a==sum(sum(k)for k in[[ord(i)-64for i in x]for x in re.sub(r'\d',' ',l).split()])and a**.5%1>0  Function with usage: print(g('A1B2C3')) Try it online! # Python 3, 163 156 155 164 161 bytes from math import* m=1;s=t=p=0 for x in input(): try:t+=int(x);p=1 except:m*=[1,t][p];p=t=0;s+=ord(x.upper())-64 if p:m*=t print(m==s and sqrt(m)!=int(sqrt(m)))  Try it online! • saved 7 bytes thanks to Jonathan and Shooqie • saved 1 byte: Also Fixed the false positive issue. Thanks to Jonathan for pointing it out! • added 11 bytes: Previous edit was wrong(the multiplication of sum of digit was going on in an unwanted loop) • from math import* is shorter Apr 9 '17 at 17:22 • You don't need a, just use for x in input():. You can have false positives for plates ending with a string of zeros (e.g. 11AA00), since the final m*=t is not executed. Apr 9 '17 at 17:29 • Apparently, my code shows false positive for any string with isolated zeros in it ( 3A0B is also shown true )... Thanks for pointing that out @JonathanAllan. I will try to fix it. Apr 10 '17 at 3:03 • Check the newer version... I have added a new flag variable 'p' to decide whether or not to multiply the sum of digits. Apr 10 '17 at 3:14 # Retina, 143 bytes Returns 1 for true, 0 for false [1-9]$*
10|01
1
S_(\D)
O
{1(?=1*\n(1+))
$1 )2=1+\n [J-S] 1$+
[T-Z]
2$+ T0Lddd 1>\d+\n?$*
^((?(1)((?(2)\2(11)|111))|1))*\n

^(1*)\n\1$ Try it Online! Explanation: [1-9]$*
10|01
1


First, we replace all non-zero digits with their unary representation. We remove any zeroes with an adjacent digit so that they don't affect our unary operations

S_(\D)


Split the resulting string on letters, being careful to exclude empty lines (this is a problem when two letters are consecutive AA).

O
{1(?=1*\n(1+))
$1 )2=1+\n  Sort the string lexicographically. Then repeatedly do the following: 1) Replace each 1 with the number of 1s on the following line (this mimics multiplication) 2) Remove the second line of 1s [J-S] 1$+
[T-Z]
2$+ T0Lddd  Replace letters J-S with 1J, 1K, etc. and replace letters T-Z with 2T, 2U, etc. Then, replace each of the groups A-I, J-S, and T-Z with 1-9. We will be left with the numerical value of each letter (eg. 13 for M). 1>\d+\n?$*


Convert every line but the first into unary (the first line is already in unary). Concatenate these lines. We are now left with a string of the form <product of digits>\n<sum of letters>.

^((?(1)((?(2)\2(11)|111))|1))*\n



Replace a square number with the empty string. This uses the "difference tree" method.

^(1*)\n\1\$


Return 1 if the two strings on either side of the \n match. Otherwise, return 0.

• False positives for 11AA0, 0AA11, etc. Apr 9 '17 at 17:39
• @JonathanAllan Thanks! It cost me 11 bytes to fix Apr 9 '17 at 18:32