| Bytes | Lang | Time | Link |
|---|---|---|---|
| 057 | # Kotlin | 241127T040731Z | Joon Yor |
| 016 | Haskell + hgl | 241029T154525Z | Wheat Wi |
| 015 | Uiua | 241010T205921Z | noodle p |
| 037 | AWK | 241028T164519Z | xrs |
| 013 | iogii | 241031T012712Z | Darren S |
| 019 | K ngn/k | 241029T114544Z | gurditsb |
| 073 | PHP | 241012T155608Z | LucianDe |
| 014 | Uiua | 241014T235914Z | janMakos |
| 240 | Javascript | 241013T152856Z | jdt |
| 055 | C gcc | 241011T171507Z | jdt |
| 060 | Racket | 241013T171411Z | mehbark |
| 012 | Pyth | 241012T210357Z | Mr. Xcod |
| 028 | Zsh | 241012T004325Z | GammaFun |
| 019 | J | 241011T231409Z | south |
| 034 | Haskell | 241011T215806Z | Antonio |
| 020 | Perl 5 p0 | 241010T220238Z | Xcali |
| 013 | Retina 0.8.2 | 241010T214755Z | Neil |
| 056 | Google Sheets | 241011T142125Z | z.. |
| 014 | Japt mx | 241010T190412Z | Shaggy |
| 050 | C# .NET Core | 241011T132545Z | Mayube |
| 033 | Bash+coreutils | 241011T122320Z | Themooni |
| 011 | Vyxal 3.3.0 d | 241010T212338Z | noodle p |
| 069 | Red | 241011T075757Z | Galen Iv |
| 013 | 05AB1E | 241011T070533Z | Kevin Cr |
| 043 | R | 241010T194550Z | pajonk |
| 037 | Python 3 | 241011T002308Z | Lucenapo |
| 017 | APLDyalog Unicode | 241011T020029Z | akamayu |
| 120 | Dart | 241011T010232Z | Redz |
| 041 | Arturo | 241010T233903Z | chunes |
| 014 | Vyxal | 241010T215945Z | emanresu |
| 014 | Charcoal | 241010T214553Z | Neil |
| 044 | JavaScript V8 | 241010T202154Z | doubleun |
| 045 | Google Sheets | 241010T193521Z | doubleun |
| 029 | APL+WIN | 241010T193010Z | Graham |
| 013 | Jelly | 241010T192113Z | Jonathan |
| 049 | JavaScript ES6 | 241010T192724Z | Arnauld |
| 015 | MATL | 241010T190850Z | Luis Men |
| 050 | JavaScript Node.js | 241010T184724Z | l4m2 |
# Kotlin, 57 bytes
val f={s:String->"ij.;!?::".map{c->s.count{it==c}}.sum()}
Or if you don't count bytes for lambda declarations:
Kotlin 1.3 or older, 44 bytes
{s->"ij.;!?::".map{c->s.count{it==c}}.sum()}
Where val f:(String)->Int= is the header.
Kotlin 1.4+, 40 bytes
{s->"ij.;!?::".sumOf{c->s.count{it==c}}}
Again, val f:(String)->Int= as the header.
sumOf was introduced in Kotlin 1.4+
Haskell + hgl, 16 bytes
mF$fce"ij.;?!::"
Explanation
Counts the number of times each character in the string occurs in the string ij.;?!:: and sums them.
Reflection
Very simple answer, so can't expect much in the way of improvements to hgl. However I do think it could potentially be useful to have mF<fce (equivalently cnT<eqo) as a built in function. This essentially counts the number of equal pairs between two lists, and is extremely similar to how ca already works.
Uiua, 18 15 bytes
/+♭⊞="ij.::;!?"
Try it: Uiua pad
Explanation: Sum of the flattened equality table of the input with "ij.::;!?".
AWK, 59 48 37 bytes
$0=gsub(/[ij\.;!\?]/,x)+2*gsub(/:/,x)
$0= # set output to
gsub(/[ij\.;!\?]/,x) # get count of subs
+2*gsub(/:/,x) # 2 for colon
awk -F '' '{for(;++i<=NF;x+=$i~/:/)x+=$i~/[ij\.;!\?:]/}$0=x'
BEGIN{FS=X}{for(;++i<=NF;x+=$i~/:/)x+=$i~/[ij\.;!\?:]/}$0=x
awk -F '' # split characters
{for(;++i<=NF; # for each character
x+=$i~/:/) # add one for the colon
x+=$i~/[ij\.;!\?:]/} # add one if it matches
$0=x # print
iogii, 13 bytes
rq__"ij.;!?::
Repeat the input so that the following eQual check is essentially a cartesian product instead of element by element, then sum and sum again.
The string of dot characters is placed at the end so it can be unterminated, it becomes the left arg to equal using iogii's rotation trick.
PHP, 98 74 73 bytes
$f=fn($i)=>preg_replace(['/:/','/[ij.;!?]/'],['.'],$i,-1,$c)!==null?$c:0;
PHP, 87 bytes
$f=fn($i)=>str_replace(str_split('ij.;!?'),'',str_replace(':','..',$i),$c)!==null?$c:0;
Replacing : with .. inspired from @GammaFunction.
Note: in case of null return from replacement, maybe we should use 'N/A' instead of 0 for preg_replace;
Uiua, 14 bytes
⧻⊚⊞="ij.;!?::"
Explanation
⊞=: The outer product of equality between the literal"ij.;!?::", and the input⧻⊚: count where elements equal one (true)
Javascript - 290 242 240 bytes
Counting the dots on a canvas.
s=>[...s].map(a=>{for(x=document.createElement`canvas`.getContext`2d`,x.font="40Q A",x.fillText(a,10,50),d=x.getImageData(i=0,0,99,99).data;++i<1e4;)t+=d[j=i*4+3]>9&&g(j,p=0)<25},t=0,g=i=>d[i]?g(i+4,p++,d[i]=0,g(i-4),g(i+396),g(i-396)):p)|t
-45-46 bytes thanks to @Shaggy!
C (gcc), 64 56 55 bytes
-8 bytes thanks to @AZTECCO!
-1 byte thanks to @ceilingcat!
f(int*a){a=*a?(*a-58?!!index("ij.;!?",*a):2)+f(++a):0;}
Racket, 60 bytes
(λ(s'(curryr regexp-match* s)`length)(+`'"[ij.;!?:]"`'":"))
Takes a string and runs a regexp twice, nothing fancy, but I'm pleased with the garble of symbols. Heavily relies on default arguments, which write and some formatting elucidates:
(λ (s [quote (curryr regexp-match* s)] [quasiquote length])
(+ (quasiquote (quote "[ij.;!?:]")) (quasiquote (quote ":"))))
Zsh, 28 bytes
<<<${#${1//:/..}//[^ij;.!?]}
Replace : with .., then remove all non-dot characters and print the string length
J, 19 bytes
1#.1#.'ij.::;!?'=/]
Works the same as most.
1#.1#.'ij.::;!?'=/]
] NB. input string
'ij.::;!?' NB. string literal
=/ NB. equality table
1#. NB. sum rows
1#. NB. sum resulting list
Retina 0.8.2, 14 13 bytes
:
..
[!.;?ij]
Try it online! Link includes test cases. Explanation: :s are "rotated", then the relevant characters are counted which produces the desired result. Edit: Saved 1 byte thanks to @m90.
Google Sheets, 56 bytes
=LEN(REGEXREPLACE(SUBSTITUTE(A1,":","ii"),"[^ij.;!?]",))
Japt -mx, 17 16 15 14 bytes
This could be 12 bytes in v2 but there seems to be a bug with S.è(x) that only counts a maximum of 1 occurrence of x.
Takes input as an array of characters.
"!.::;?ij"oU Ê
"..."oU Ê :Implicit map of each U in the input array
"..." :The necessary characters, with : duplicated
oU :Keep only those characters that appear in U
Ê :Length
:Implicit output of sum of resulting array
C# (.NET Core), 50 bytes
s=>Regex.Replace(s,"(:)|[^!?;:.ij]","$1$1").Length
I tried to find a shorter/more interesting solution but the regex approach works really well.
Bash+coreutils, 33 bytes
tr -cd ij.\;!?<<<${1//:/..}|wc -c
Is also optimal for zsh, I think.
explanation:
${1//:/..} #replace all : with .. in first argument
<<< #and pass it to standard input of...
tr -cd ij.\;!? # from stdin, output only characters specified to stdout
|wc -c # pass stdout to stdin of: count chars in stdin
#implicit output stdout to terminal
Vyxal 3.3.0 d, 11 bytes
ᵒ="ij.::;!?
I downgraded to Vyxal 3.3.0 because that's the most recent version which still supports Nilad moving, a feature which was removed because it makes debugging super annoying but makes this program a byte shorter because it lets me move the string to the end of the line instead of having it at the front, saving a byte on the closing quotation mark.
The logic is super simple: Take the outer product of equality with the string ij.::;!?, and d deeply sums the result.
05AB1E, 13 bytes
"!.::;?ij"S¢O
Try it online or verify all test cases.
Explanation:
"!.::;?ij" # Push this string (note the "::")
S # Convert it to a list of characters
¢ # Count each of those characters in the (implicit) input-string
O # Sum the counts together
# (after which the result is output implicitly)
Unfortunately, the shortest compressed version of this character-list I could find is 1 byte longer: •м€2Q¸Ü•žQÅв¢O. Also, there are some minor variations possible for the same byte-count: ":!.;?ij"Ć€¢O or "!.;?ij:"¤ª¢O.
R, 43 bytes
\(s)nchar(gsub("(:)|[^ij.;!?]","\\1\\1",s))
Port of @doubleunary's Google Sheets answer.
R, 48 44 bytes
Edit: -4 bytes porting @Luis Mendo's MATL answer.
\(s)sum(outer(utf8ToInt("ij.;!?::"),s,`==`))
Takes input as a vector of character codes.
APL(Dyalog Unicode), 17 bytes SBCS
A 2 train that counts set bits in the equality table between input and string ::ij.;!?.
≢∘⍸∘.=∘'::ij.;!?'
Dart, 120 bytes
main(List<String>y,{i=0,j=0,x}){x=y[0];for(;i<x.length;i++){if('ij.;!?'.contains(x[i]))j++;if(x[i]==':')j+=2;}print(j);}
Only takes one string at a time.
Vyxal, 14 bytes
`ij.::;!?`fvO∑
O # Count in input
fv # Each of
`ij.::;!?` # String "ij.::;!?"
∑ # sum counts
Charcoal, 14 bytes
IΣE!.::;?ij№θι
Try it online! Link is to verbose version of code. Explanation:
!.::;?ij Literal string `!.::;?ij`
E Map over characters
№ Count of
ι Current character
θ In input string
Σ Take the sum
I Cast to string
Implicitly print
JavaScript (V8), 44 bytes
t=>t.replace(/(:)|[^ij.;!?]/g,'$1$1').length
Port of my Google Sheets answer.
(-1 thanks to emanresu A)
Google Sheets, 45 bytes
=len(regexreplace(A1,"(:)|[^ij.;!?]","$1$1"))
Put the text string in cell A1 and the formula in cell B1.

(-1 thanks to emanresu A)
APL+WIN, 29 bytes
Prompts for string:
(+/s∊'ij.;!?.')+2×+/(s←⎕)∊':'
Jelly, 14 13 bytes
ċⱮ“::ij.;!?”S
A monadic Link that accepts a list of characters and yields the number of dots.
How?
ċⱮ“::ij.;!?”S - Link: list of characters, T
“::ij.;!?” - list of characters -> "::ij.;!?"
Ɱ - map with:
ċ - {T} count {char}
S - sum
JavaScript (ES6), 49 bytes
Expects an array of characters.
a=>a.map(c=>t+=c==":"?2:/[ij.;!?]/.test(c),t=0)|t
MATL, 15 bytes
0h'ij.;!?::'!=z
Try it online! Or verify all test cases.
How it works
0h % Implicit input. Attach character 0. This is needed to avoid empty string
'ij.;!?::' % Push this string. Note that ':' appears twice
! % Transpose into a column vector
= % Matrix of all pair-wise comparisons
z % Number of non-zeros. Implicit display