g | x | w | all
Bytes Lang Time Link
099Swift 6240318T001247ZmacOSist
087Python 3.8 prerelease240319T205526Zmovatica
112Python 3.8240115T083955ZSevC_10
062TIBASIC240116T224438ZYouserna
010Jelly240111T204755ZNick Ken
082Perl 5 F240112T201835ZXcali
039R240112T184659ZNick Ken
043JavaScript Node.js240112T005219Zl4m2
023Vyxal 3240112T170310Zmath sca
060APL+WIN240112T141021ZGraham
021Charcoal240112T002352ZNeil
078Haskell240112T105713Zmatteo_c
029Retina240112T000639ZNeil
02305AB1E240112T083955ZKevin Cr
064JavaScript ES6240111T194111ZArnauld

Swift 6, 124 99 bytes

{n in{$0(9)&&$0(10)}{i in{$0<2 ?0:11-$0}((0..<i).reduce(0){$0+(n as[Int])[$1]*(i-$1+1)}%11)==n[i]}}

Try it on SwiftFiddle!

A port of this Python answer by @SevC_10.

Python 3.8 (pre-release), 87 bytes

lambda n:all(((s:=sum(n[j]*(i-j+1)for j in range(i))%11)>1)*(11-s)==n[i]for i in(10,9))

Try it online!

This is a seriously golfed down version of the other Python 3.8 answer. Repost, because the original post seems dormant.

Python 3.8, 122 116 112 bytes

The function takes as input the list of the digits of the CPF number.

It returns 0 for true cases, None for false ones.

def f(n):
 for i in 10,9:
  s=sum(n[j]*(i-j+1)for j in range(i))%11
  if 0if s<2else 11-s!=n[i]:return
 return 0

Try it online!


Brief explanation

The for loop is to check the 2 last digits.

s computes the sum of products, takes modulo 11 and finally the (corrected) value is compared to the corresponding last digit of the CPF number.

If the values are different, the function returns None, else continues on the next loop. If both checks are ok, the function returns 0.

TI-BASIC, 62 bytes

Prompt N
For(X,11,12
X-cumSum(1 or ʟN
11-11fPart(11⁻¹sum(ʟNAns*(Ans>1
If Ans≤9≠Ans⁻¹ʟN(X
13→X
End
Ans≤9

Takes input as a list of digits.

Jelly, 10 bytes

ÄÄ%11>¬ṫ-Ẹ

Try it online!

A Jelly translation of l4m2’s clever JavaScript answer; be sure to upvote that one!

A monadic link that takes a list of digits and returns 0 for true and 1 for false.

Explanation

ÄÄ         | Cumulative sum twice
  %11      | Mod 11
     >¬    | Greater than not the original argument
       ṫ-  | Last two
         Ẹ | Any true

Why does this work?

The (sum of the cumulative sum of the first 10 digits) mod 11 is equivalent to (the answer to step 2 in the question plus the tenth digit) mod 11.

For a valid CPF number, this should be zero unless the result from step 2 was one, in which case it will be one (and the tenth digit will be zero). As such, this can be checked to see if it is greater than the result of not (tenth digit); for valid CPF numbers, this comparison will return false.

The same applies for checking the final digit, so in practice it’s possible to do the cumulative sum twice and then just take the final two values, as implemented above.

To extend the table given in the question:

c 1 1 1 4 4 4 7 7 7 3 5
10 9 8 7 6 5 4 3 2
result 10 9 8 28 24 20 28 21 14
cumsum c 1 2 3 7 11 15 22 29 36 39 44
cs cs c 1 3 6 13 24 39 61 90 126 165 209

\$ 165 \bmod 11 = 0 \$

\$ 209 \bmod 11 = 0 \$

Therefore this number was valid.

Alternative Jelly, 21 17 bytes

J‘Uḋị⁵ḶUݤṭ
ḣ9ÇÇ⁼

Try it online!

A pair of links which is called as a monad with a list of 11 decimal digits as its argument and returns one true and zero for false.

Thanks to @JonathanAllan for saving 4 bytes!

Explanation

J‘Uḋị⁵ḶUݤṭ     | Helper link, takes a list of integers and appends the next check digit
J               | Indices
 ‘              | Add 1
  U             | Reverse order
   ḋ            | Dot product with original link argument
    ị           | Modular index into:
     ⁵ḶUݤ      | [0,9,…,2,1,0]
             ṭ  | Concatenate to end of link argument

ḣ9ÇÇ⁼ | Main link, takes a list of integers and returns 1 if valid and 0 if not
ḣ9    | Head 9 (first 9 integers)
  ÇÇ  | Call helper link twice
    ⁼ | Is this equal to original argument?

Perl 5 -F, 82 bytes

say"@{[map{$m=$_+2;($c=(sum map$_*$m--,@F[0..$_])%11)>1?11-$c:0}8,9]}"eq"@F[9,10]"

Try it online!

R, 39 bytes

\(x,`+`=cumsum)any((++x%%11>!x)[10:11])

Attempt This Online!

An R translation of my Jelly answer, itself a translation of l4m2’s JavaScript answer. A function that takes a list of digits and returns a logical value, with FALSE for valid and TRUE for invalid.

JavaScript (Node.js), 43 bytes

a=>a.some((v,i)=>i>8&(y+=x+=v)%11>!v,x=y=0)

Try it online!

-1 bug from Nick Kennedy

Inversed output, 1 byte to invert

Vyxal 3, 23 bytes

9Θ2(DκṚꜝ×∑11%9z0JṚṙiJ}₌

Try it Online!

9Θ2(DκṚꜝ×∑11%9z0JṚṙiJ}₌­⁡​‎‎⁡⁠⁡‏⁠‎⁡⁠⁢‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁣‏⁠‎⁡⁠⁤‏⁠‎⁡⁠⁢⁢⁢‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁢⁡‏⁠‎⁡⁠⁢⁢‏‏​⁡⁠⁡‌⁤​‎⁠‎⁡⁠⁢⁣‏⁠‎⁡⁠⁢⁤‏⁠‎⁡⁠⁣⁡‏‏​⁡⁠⁡‌⁢⁡​‎‎⁡⁠⁣⁢‏⁠‎⁡⁠⁣⁣‏⁠‎⁡⁠⁣⁤‏⁠‎⁡⁠⁤⁡‏‏​⁡⁠⁡‌⁢⁢​‎‎⁡⁠⁤⁢‏⁠‎⁡⁠⁤⁣‏⁠‎⁡⁠⁤⁤‏⁠‎⁡⁠⁢⁡⁡‏⁠‎⁡⁠⁢⁡⁢‏⁠‎⁡⁠⁢⁡⁣‏‏​⁡⁠⁡‌⁢⁣​‎‎⁡⁠⁢⁡⁤‏‏​⁡⁠⁡‌⁢⁤​‎‎⁡⁠⁢⁢⁡‏⁠‏​⁡⁠⁡‌⁣⁡​‎‎⁡⁠⁢⁢⁣‏‏​⁡⁠⁡‌­
9Θ                       # ‎⁡Slice list from 0 to index 9
  2(                 }   # ‎⁢Repeat twice
    Dκ                   # ‎⁣ Triplicate top element and push range [1, length]
      Ṛꜝ×                # ‎⁤ Reverse, increment and multiply range with list
         ∑11%            # ‎⁢⁡ Sum list and mod 11
             9z0JṚṙ      # ‎⁢⁢ Push range [0,9], append 0, reverse and rotate list right => [0, 0, 9, 8, ..., 1]
                   i     # ‎⁢⁣ Index result into list
                    J    # ‎⁢⁤ Append to initial list
                      ₌  # ‎⁣⁡Is equal to input?
💎

Created with the help of Luminespire.

APL+WIN, 61 60 bytes

Prompts for a vector of 11 digits and returns 1 if valid 0 if invalid.

e=+/c=v,e-e|+/(e,n)×v←v,(r>2)×e-r←(e←11)|+/(v←9↑c←⎕)×n←⌽1+⍳9

Try it online! Thanks to Dyalog Classic

Charcoal, 24 21 bytes

⊙θ∧›κ⁹›﹪Σ⭆⊕κ…θ⊕λ¹¹¬Iι

Try it online! Link is to verbose version of code. Outputs an inverted Charcoal boolean, i.e. - for invalid, nothing for invalid. Explanation: Now a port of @l4m2's JavaScript answer.

 θ                      Input string
⊙                       Any digit satisfies
    κ                   Current index
   ›                    Is greater than
     ⁹                  Literal integer `9`
  ∧                     Logical And
           κ            Current index
          ⊕             Incremented
         ⭆              Map over implicit range and join
             θ          Input string
            …           Truncated to length
               λ        Current value
              ⊕         Incremented
        Σ               Take the digital sum
       ﹪                Modulo
                ¹¹      Literal integer `11`
      ›                 Is greater than
                    ι   Current digit
                   I    Cast to integer
                  ¬     Logical Not
                        Implicitly print

Haskell, 78 bytes

x#s|r<-mod(sum$zipWith(*)x[s+1,s..2])11=x!!s==last(0:[11-r|r>1])
f x=x#9&&x#10

Try it online!

Retina, 29 bytes

.$
¶$=
.
*$<%'
.{11}

^0?¶0?$

Try it online! Link includes test cases. Takes input as a string of 11 digits. Explanation: Same idea as @Arnauld's previous answer.

.$
¶$=

Duplicate the input, but without the last digit.

.
*$<%'

For each digit, repeats the substring starting at that digit by that many times.

.{11}

Reduce modulo 11.

^0?¶0?$

Only a single 0 is allowed to be left over each time.

05AB1E, 23 bytes

¨¨2FDā>R*O11%11αDT‹*ª}Q

Input as a list of digits.

Try it online or verify all test cases.

Explanation:

¨¨                    # Remove the last two digits of the (implicit) input-list
  2F                  # Loop 2 times:
    D                 #  Duplicate the current list
     ā                #  Push a list in the range [1,length] (without popping)
      >               #  Increase each by 1 to range [2,length+1]
       R              #  Reverse it to range [length+1,2]
        *             #  Multiply the values of the two lists at the same positions together
         O            #  Sum
          11%         #  Modulo-11
             11α      #  Absolute difference with 11
                D     #  Duplicate this value
                 T‹   #  Pop the copy, and check that it's smaller than 10
                      #  (1 if its [1,9]; 0 if it's 10 or 11)
                   *  #  Multiply that to the value
                    ª #  Append it to the list
   }                  # After the loop:
    Q                 # Check whether this list equals the (implicit) input-list
                      # (after which the result is output implicitly)

JavaScript (ES6), 64 bytes

Expects an array of digits. Returns \$0\$ or \$1\$.

a=>(g=k=>a[k]==(a.map(v=>x-=k&&v*~k--,x=0)|10*x%11%10))(9)&g(10)

Try it online!