| Bytes | Lang | Time | Link |
|---|---|---|---|
| 099 | Swift 6 | 240318T001247Z | macOSist |
| 087 | Python 3.8 prerelease | 240319T205526Z | movatica |
| 112 | Python 3.8 | 240115T083955Z | SevC_10 |
| 062 | TIBASIC | 240116T224438Z | Youserna |
| 010 | Jelly | 240111T204755Z | Nick Ken |
| 082 | Perl 5 F | 240112T201835Z | Xcali |
| 039 | R | 240112T184659Z | Nick Ken |
| 043 | JavaScript Node.js | 240112T005219Z | l4m2 |
| 023 | Vyxal 3 | 240112T170310Z | math sca |
| 060 | APL+WIN | 240112T141021Z | Graham |
| 021 | Charcoal | 240112T002352Z | Neil |
| 078 | Haskell | 240112T105713Z | matteo_c |
| 029 | Retina | 240112T000639Z | Neil |
| 023 | 05AB1E | 240112T083955Z | Kevin Cr |
| 064 | JavaScript ES6 | 240111T194111Z | Arnauld |
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]}}
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))
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
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>¬ṫ-Ẹ
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ÇÇ⁼
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]"
R, 39 bytes
\(x,`+`=cumsum)any((++x%%11>!x)[10:11])
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)
-1 bug from Nick Kennedy
Inversed output, 1 byte to invert
Vyxal 3, 23 bytes
9Θ2(DκṚꜝ×∑11%9z0JṚṙiJ}₌
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
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
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)