How many points does my license plate give?

31

2

(This is my first code-golf question)

When I was a child, my dad and I invented a game where the license plate we see on cars can give certain points based on some rather simple rules:

X amount of the same letter or number give X-1 points, examples:

22 = 1 point
aa = 1 point
5555 = 3 points

The numbers must be next to eachother, so 3353 only gives 1 point, as the 5 breaks the sequence of 3's.

A sequence of X numbers in ascending or descending order, at a minimum of 3, give X points, examples:

123 = 3 points
9753 = 4 points
147 = 3 points

The point system only works for 1-digit-numbers, so 1919 doesn't give points, and 14710 only give 3, (147).

Sequences can be combined to make more points, examples:

1135 = 4 points (1 point for 11 and 3 points for 135)
34543 = 6 points (3 points for 345 and 3 points for 543)

You are however not allowed to chop a larger sequence into 2 smaller sequences for extra points: 1234 = 123, 234 (6 points) is not allowed.

Your task is, given a sequence, to determine the number of points the license plate gives.

In Denmark, the license plates are structured like this: CC II III, where C is character and I is integer, and thus my example inputs will reflect this structure. If you wish, you may make the sequence fit your own structure, or, if you feel really adventurous, let the program analyze the structure of the license plate and thus have it work on any type of license plate around the world. Explicitly state the structure you decide to use in your answer though.

You may take the input in any way you please, either a string or an array seem to make most sense to me.

Test input | output:

AA 11 111 | 5
AB 15 436 | 3
OJ 82 645 | 0
UI 65 456 | 6
HH 45 670 | 5
YH 00 244 | 5
AJ 00 754 | 1

Due to the nature of choosing your own structure, or even covering all structures, I dont necessarily see how a winner can be explicitly determined. I suppose the winner will be the shortest bytes on the structure one has decided. (And don't take an input like C I C I C, just to make it easy for yourself)

EDIT:

Due to comments asking, I have a few extra pieces of information to share: A sequence of ascending or descending numbers refers to an arithmetic sequence, so X +/- a * 0, X +/- a * 1, ... X +/- a * n etc. So 3-5-7 for example is 3 + 2 * 0, 3 + 2 * 1, 3 + 2 * 2. The sequence does not, however, need to start from 0 nor end in 0.

MORE EDIT:

You may give the input in any way you please, you dont need to input spaces, dashes or any other thing that makes a license plate more readable. If you can save bytes by only accepting capital letters or something like that, you may do that aswell. The only requirement is that your program can take a string/array/anything containing both characters and numbers, and output the correct amount of points according to the rules stated.

Troels M. B. Jensen

Posted 2017-09-05T09:44:58.710

Reputation: 711

Loosely related. Welcome to PPCG and nice first question! – Mr. Xcoder – 2017-09-05T10:01:57.173

Suggested test case: XX 87 654. I came up with something that was correct for all your test cases but somehow incorrect for this one.. Working on fixing it. – Kevin Cruijssen – 2017-09-05T11:35:33.047

7I strongly suggest you fix a certain structure (I suggest CCIIIII, no spaces), or else this problem lacks an objective win criterion, which we require around here. As-is, “(And don't take an input like C I C I C, just to make it easy for yourself)” is very subjective. What is and isn’t an admissible structure? – Lynn – 2017-09-05T11:37:29.563

1@Lynn An admissible structure is one that can actually yield points, CICIC will never have a sequence that yields any points, therefore it is not admissible. And on top of that, why is 'shortest answer in bytes on the chosen programming language and chosen structure' not a clear, objective win criteria? This win criteria has a straight, easy to follow rule, yet gives the developer freedom to choose what kind of structure they want it to work with. Granted it may have a lot of different winners, but, really, so what? – Troels M. B. Jensen – 2017-09-05T11:41:33.670

3Test case: IA99999 (contains a decreasing sequence of code points, but not numbers). – Zgarb – 2017-09-05T13:10:03.367

RE: allowing us to choose any input "that can actually yield points": CC would be acceptable and has a very simple 2-byte Jelly answer and perhaps even just 1 byte in another language. It just feels like abusing the specification to me though. Hence I also suggest fixing the input format as CCIIIII.

– Jonathan Allan – 2017-09-05T19:37:11.887

...just to add that if we also need to have characters and numbers in the input like in the "MORE EDIT" we may still do something like this for CCII. (Also not that adding addenda like "EDIT" and "MORE EDIT" is a poor alternative to changing the specification in the body of the post itself. )

– Jonathan Allan – 2017-09-05T19:52:32.443

@JonathanAllan If someone wants to make a CC or CCII answer using 2 or 1 byte, they are welcome to do so, as that is a legitimate structure that they may choose, I honestly dont see the point in limiting what the developer can choose to develop. This is a challenge, it has rules and it has answer-variants, if you solve the problem within these rules, it's an accepted answer. It is not my task as a question-giver to make the question as complicated as possible, it's the challenged developer who may choose how difficult he wants the task to be. By letting the goal be a bit more open than ... – Troels M. B. Jensen – 2017-09-06T07:12:07.767

@JonathanAllan ... just CCIIIII, the challenged developer may choose the path to success, if you find a solution such as the ones you have linked satisfactory for how challenged you were by the question, thats completely fine, but as the answers below show, people like to take the more challenging path to this question than just the easiest solution. I honestly dont see the point in restricting a question, as opposed to give the challenged developer free-roam over where they want to take it – Troels M. B. Jensen – 2017-09-06T07:14:32.623

Answers

7

05AB1E, 25 22 20 18 bytes

Accepts a string of lower-case alphabetic chars and numbers with no spaces.

Ç¥0Kγ€gXK>OIγ€g<OO

Try it online! or as a Test Suite

Emigna

Posted 2017-09-05T09:44:58.710

Reputation: 50 798

I can't read 05AB1E without an explanation ;) But can you save bytes by getting the input without spaces? – Kevin Cruijssen – 2017-09-05T10:27:23.053

@Mr.Xcoder I doubt it as well. But I personally can't read 05AB1E, so I thought perhaps Emigna had added any code to get rid of/ignore the spaces. Probably it does this implicitly without any extra bytes, but I just asked in case it didn't. – Kevin Cruijssen – 2017-09-05T10:31:29.617

I just took your code for a swing, and holy crap, it actually works for any length or sequence! The only 'issue' is that it also gives 3 points for ABC, which in and of itself isn't wrong, I just did not account for it, as in Denmark we only have 2 letters next to eachother. – Troels M. B. Jensen – 2017-09-05T10:40:33.003

2@KevinCruijssen: No spaces in the input would save several bytes yes. I missed the part where we could decide that ourselves. Thanks for the heads up. (An explanation is coming as well). – Emigna – 2017-09-05T11:02:01.420

@Emigna I hadn't stated it in the question explicitly, I thought I hinted enough at it when I wrote You may take the input in any way you please, either a string or an array seem to make most sense to me.. – Troels M. B. Jensen – 2017-09-05T11:07:58.630

@TroelsM.B.Jensen: Yeah, I have a bad habit of skimming over information at times. Re-reading it after Kevin's comment I noticed it :P – Emigna – 2017-09-05T11:16:03.600

@Emigna I know what you mean, and I could possibly have been more specific in my explanations; when you write (or tell) something, you generally have a tendency to skip specific details because you find it 'obvious' to the listener, which it often times isn't. – Troels M. B. Jensen – 2017-09-05T11:19:38.500

Seems to fail on IA99999. – Zgarb – 2017-09-05T13:10:52.013

@Zgarb: Ah yes, thanks for the heads up. Was able to fix with just the input format. – Emigna – 2017-09-05T13:18:57.377

7

Husk, 20 16 15 bytes

-1 byte thanks to @Zgarb

Takes input without spaces and in lower case.

ṁ??¬o→LεL←gẊ¤-c

Try it online!

Explanation

           Ẋ      Map over all adjacent pairs
            ¤-c   get the difference of their codepoints
          g       Split into groups of equal elements
ṁ                 Map then sum
 ?       ←          If the head of the list is truthy (not 0)
  ?    ε              If the length of the list is 1
   ¬                    return 0
                       Else
    o→L                 return the length + 1
                     Else
        L             return the length

H.PWiz

Posted 2017-09-05T09:44:58.710

Reputation: 10 962

I think K0 can be ¬ here. – Zgarb – 2017-09-05T11:55:04.830

Hmm, this seems to fail on IA99999. – Zgarb – 2017-09-05T13:10:16.937

@Zgarb, changed input format to lower case. – H.PWiz – 2017-09-05T13:39:11.340

5

Python 3, 193 85 bytes

-3 bytes thanks to Lynn

Takes input as a byte-string with lowercase letters as: b'aa11111'.

def f(s):
 d=l=L=p=0
 for c in s:C=0!=d==c-l;p+=(c==l)+C*L;L=3>>C;d=c-l;l=c
 return p

Try it online!

Felipe Nardi Batista

Posted 2017-09-05T09:44:58.710

Reputation: 2 345

131 bytes – Mr. Xcoder – 2017-09-05T12:45:07.897

1C=0!=d==c-l is even shorter. – Lynn – 2017-09-05T13:31:13.530

2

Java 8, 195 bytes

a->{int r=a[0]==a[1]?1:0,i=3,j,p=a[2],x,y,z;for(;i<7;p=a[i++])for(r+=(x=a[i])==p?1:0,j=-4;++j<4;r+=j==0?0:i<6&&p+j==x&x+j==(y=a[i+1])?++i<6&&y+j==(z=a[i+1])?++i<6&&z+j==a[i+1]?5:4:3:0);return r;}

Can definitely be golfed some more by using another technique to check for sequences.

Explanation:

Try it here.

a->{                      // Method with character-array parameter and integer return-type
  int r=                  //  Result-integer
        a[0]==a[1]?       //   If the two letters are equal:
         1                //    Start this result-integer at 1
        :                 //   Else:
         0,               //    Start the result-integer at 0 instead
      i=3,j,              //  Index-integers
      p=a[2],x,y,z;       //  Temp integers
   for(;i<7;              //  Loop (1) from index 3 to 7 (exclusive)
       p=a[i++])          //    And after every iteration: Set `p` and raise `i` by 1
     for(r+=(x=a[i])==p?  //   If the current digit (now `x`) equals the previous `p`:
             1            //    Raise the result-integer by 1
            :             //   Else:
             0,           //    Keep the result-integer the same
         j=-4;++j<4;      //   Inner loop (2) from -3 to 3 (inclusive)
       r+=j==0?           //    If `j` is 0:
           0              //     Skip it, so keep the result-integer the same
          :i<6            //    Else-if `i` is not 6,
           &&p+j==x       //    and the previous digit `p` + `j` equals the current digit,
           &x+j==(y=a[i+1])?
                          //    and the current digit `x` + `j` equals the next digit `y`:
            ++            //     Raise index `i` by 1 first,
              i<6         //     and check if `i` is not 6 again,
              &&y+j==(z=a[i+1])?
                          //     and if the new current digit `y` + `j` equals the next digit `z`:
               ++         //      Raise index `i` by 1 first again,
                 i<6      //      and check if `i` is not 6 again,
                 &&z+j==a[i+1]?
                          //      and if the new current digit `z` + `j` equals the next digit:
                  5       //       Raise the result-integer by 5
                 :        //      Else:
                  4       //       Raise it by 4 instead
              :           //     Else:
               3          //      Raise it by 3 instead
           :              //    Else:
            0             //     Keep it the same
     );                   //   End of inner loop (2)
                          //  End of loop (1) (implicit / single-line body)
  return r;               //  Return the result-integer
}                         // End of method

Kevin Cruijssen

Posted 2017-09-05T09:44:58.710

Reputation: 67 575

1

Pyth,  51  50 bytes (staggering)

+/|R0.+QZslM.MlZ+kfTsmm?&!-K.+sMkhK.AKkY.:>Q2d}3 5

Verify all test cases or Try it here.

Mr. Xcoder

Posted 2017-09-05T09:44:58.710

Reputation: 39 774

I now realize I can make it shorter, but will update if I am able to golf it consistently. – Mr. Xcoder – 2017-09-05T12:00:36.390

1

R, 153, 145, 143 bytes

function(x){p=0;s=sum;if(x[1]==x[2])p=1;a=diff(strtoi(x[3:7]));p=p+s(a==0);l=sort(table(a[a!=0]),T);(p=p+s(l[(l[((s(l)>0)&(l[1]>1))]+1)>2]+1))}

Anonymous function that takes a character vector and returns an integer.
Expected input z(c("A", "A", "1", "1", "1", "1", "1"))

Try it online!

Ungolfed version

function(x){
  pnt <- 0; s <- sum
  if(x[1] == x[2]) pnt <- 1
  a <- diff(strtoi(x[3:7]))
  pnt <- pnt + s(a == 0)
  l <- sort(table(a[a!=0]), T)
  (pnt <- pnt + s(l[(l[((s(l) > 0) & (l[1] > 1))] + 1) > 2] + 1))
}

AndriusZ

Posted 2017-09-05T09:44:58.710

Reputation: 219

0

C (gcc), 91 bytes

f(p,r,d,D,s,l)char*p;{for(r=D=0;d=p[1]-*p,*++p;D=d){s=d&&d==D;r+=!d+s*l;l=3-2*s;}return r;}

Try it online!

Idea stolen from Felipe Nardi Batista's Python answer.

nwellnhof

Posted 2017-09-05T09:44:58.710

Reputation: 10 037

0

Pyth, 48 42 bytes

Direct port from my python answer. Takes input as a byte-string with lowercase letters as: b'aa11111'.

This is my first time coding in Pyth, so any tips are welcome :D

KJ=b0VQ=d&KqK-NJ=+b+qNJ*dZ=Z-3yd=K-NJ=JN;b

Try it here

Felipe Nardi Batista

Posted 2017-09-05T09:44:58.710

Reputation: 2 345

0

JavaScript, 216 192 186 202 201 bytes

function f(s){var a=s.split(" "),c=a[1],a=a[0],r,h=b=i=p=0;for(i=0;i<4;i++){if(i<2&(r=a[i+1]-a[i]==a[i+2]-a[i+1])){p++;b=2}if(i>0){if(a[i]==a[i-1]){p++;h++}if(i<3&c[i]==c[i-1])p++}}return h==4?p+b:p-b}

Unminified

function f(s){
    var a=s.split(" "),c=a[1],a=a[0],r,h=b=i=p=0;
    for(i=0;i<4;i++){
        if(i<2&(r=a[i+1]-a[i]==a[i+2]-a[i+1])){
            p++;
            b=2
        }
        if(i>0){
            if(a[i]==a[i-1]){
                p++;
                h++;
            }
            if(i<3&c[i]==c[i-1]) 
                p++;
        }
    }

    return h==4?p+b:p-b
}

Edit history:

  • Narrowed down the code to only work with 0000 XXX format. (-24 bytes)
  • Edits as suggested by @Titus. (-6 bytes)
  • fixed a bug where four identical numbers gave a score of 7 instead of 3. (+16 bytes)
  • Removed last semi-colon. (-1 byte)
  • Fixed a typo in the code. (no byte change)

Brian H.

Posted 2017-09-05T09:44:58.710

Reputation: 513

How do i count the bytes? – Brian H. – 2017-09-12T08:09:18.793

1Byte counter – H.PWiz – 2017-09-12T08:12:37.570

im really hating the fact that the code block isn't recognizing the language... – Brian H. – 2017-09-12T08:14:00.280

Do want syntax highlighting? – H.PWiz – 2017-09-12T08:15:42.770

btw, 0000 gives 7 points, is that correct? (it's getting read as an arithmetic sequence and a repeated number sequence at the same time) – Brian H. – 2017-09-12T08:24:33.230

0000 should score 3 points. – H.PWiz – 2017-09-12T08:26:31.443

Welcome to PPCG! Try <!-- language: lang-javascript -->. You could golf this further down with b=i=p=0, q instead of ap, b=2 and return p+b. You can probably also use & instead of &&. p+=(condition) instead of if(condition)p++ might also work. Where do You use j? – Titus – 2017-09-12T08:27:15.813