# ABC correlation

ABC correlation
You are encouraged to solve this task according to the task description, using any language you may know.

Taken from this video at the time stamp of 9:02

Get a string/input and store it into a variable or something and compare the amount of "a", "b" and "c" . Other characters like "r", "h" or "5" MUST be ignored. If the amount of "a"'s, "b"'s and "c"'s are equal return true. Otherwise return false

## ABC

Just prompting for words and reporting the ones that are "abc" words.

```HOW TO REPORT is.abc.word word:
IF "a"#word <> "b"#word: FAIL
IF "b"#word <> "c"#word: FAIL
SUCCEED

PUT "x" IN word
WHILE word <> "":
IF word <> "":
IF is.abc.word word:
WRITE word, " is an ""abc"" word" /```
Output:

Testing with the following words (one per line, followed by blank lines): aluminium abc internet adb cda blank black mercury venus earth mars jupiter saturn uranus neptune pluto

```abc is an "abc" word
internet is an "abc" word
black is an "abc" word
venus is an "abc" word
jupiter is an "abc" word
neptune is an "abc" word
pluto is an "abc" word
```

```-- Rosetta Code Task written in Ada
-- ABC correlation
-- https://rosettacode.org/wiki/ABC_correlation
--
-- Assuming only lower case letters ('a' to 'z');
-- other ASCII characters encountered will be ignored
--
-- This was inspired by the Ada solution to ABC_Words
-- and the Raku solution to this task
--
-- Assumes the existence of the file "unixdict.txt" (or a symlink
-- to it) coexists with the Ada executable
--
-- July 2024, R. B. E. (preamble comments last updated 04 August 2024)

procedure ABC_Correlation is

function Test_Word (S : String) return Boolean is
Count_A : Natural := 0;
Count_B : Natural := 0;
Count_C : Natural := 0;
P1      : constant String := "" & 'a';
P2      : constant String := "" & 'b';
P3      : constant String := "" & 'c';
begin
Count_A := Count_A + Ada.Strings.Fixed.Count (Source  => S, Pattern => P1);
Count_B := Count_B + Ada.Strings.Fixed.Count (Source  => S, Pattern => P2);
Count_C := Count_C + Ada.Strings.Fixed.Count (Source  => S, Pattern => P3);
if ((Count_A = Count_B) and then (Count_A = Count_C) and then (Count_A > 0)) then
return True;
else
return False;
end if;
end Test_Word;

Filename : constant String := "unixdict.txt";
File     : File_Type;

begin
Open (File, In_File, Filename);
while not End_Of_File (File) loop
declare
Word : constant String := Get_Line (File);
begin
if Test_Word (Word) then
Put_Line (Word);
end if;
end; -- declare
end loop;
Close (File);
end ABC_Correlation;
```
Output:
```abc
abduct
abject
abscess
absence
acerbity
aerobic
alberich
albrecht
aminobenzoic
archbishop
ascribe
bach
bachelor
bacilli
bacillus
back
backdrop
backfill
background
backlog
backorder
backside
backstop
backup
backwood
bacon
bacterium
balcony
balletic
baltic
bankruptcy
basic
basidiomycetes
basophilic
batch
batchelder
bausch
beach
beacon
beatific
beatrice
becalm
became
because
beckman
beecham
bellyache
benchmark
benefactor
beneficial
beneficiary
bianco
bicentennial
bichromate
bidirectional
bifocal
bifurcate
biharmonic
bimetallic
bimolecular
binocular
binuclear
birdwatch
birthplace
bismarck
bivouac
black
blacken
blackfeet
blackout
blacksmith
blackstone
blackwell
blanc
blanch
blanche
bleach
blockage
bluejacket
boca
boldface
boniface
bookcase
borosilicate
botanic
boxcar
brace
bracelet
bracken
bracket
brackish
bract
brainchild
brainchildren
branch
breach
bricklay
bricklayer
bricklaying
briefcase
britannic
broach
bronchial
bronchiolar
bucharest
buchenwald
buchwald
buckaroo
buckwheat
bullwhack
bushwhack
cab
cabdriver
cabin
cabinet
cabinetry
cable
cabot
caleb
caliber
calibre
camber
cambridge
campbell
canterbury
carbide
carbine
carboloy
carbon
carbone
carbonium
carbonyl
carborundum
carboxy
carboy
carburetor
carib
caribou
carob
casebook
catbird
celebrant
celebrate
cerebral
cerebrate
chablis
chamber
chambers
charybdis
chilblain
childbear
chipboard
clamber
clipboard
cobalt
cobra
codebreak
cognizable
collapsible
collarbone
colombia
columbia
combat
combatted
combinate
combination
combinator
commensurable
committable
compatible
compellable
compensable
conferrable
connubial
controllable
coralberry
corroborate
crab
cranberry
crossbar
crowbait
cuba
culpable
cultivable
cumberland
cupboard
debacle
debauch
debauchery
decomposable
delectable
depreciable
despicable
diabetic
diabolic
discriminable
dissociable
disturbance
duplicable
educable
emblematic
embrace
enforceable
enunciable
evocable
excisable
excusable
execrable
exercisable
explicable
extricable
fabric
feedback
fluorocarbon
fullback
hackberry
hebraic
hecatomb
hecuba
hibachi
horseback
humpback
hydrocarbon
iambic
imperceivable
incommensurable
incommutable
incompatible
incomputable
incondensable
inconsiderable
inconsolable
incontestable
incontrollable
incorporable
incubate
inculpable
indecipherable
indecomposable
indiscoverable
ineducable
ineluctable
inexcusable
inexplicable
inextricable
inscrutable
irrecoverable
irrevocable
jackboot
jacob
jacobi
jacobite
jacobs
jacobsen
jacobson
jacobus
judicable
justiciable
knuckleball
kochab
licensable
linebacker
lubricant
lubricate
macbeth
matchbook
metabolic
microbial
mobcap
nabisco
noticeable
obduracy
obfuscate
obfuscatory
obstacle
obstinacy
offenbach
piggyback
placebo
precipitable
problematic
pronounceable
publication
pullback
recombinant
remembrance
republican
revocable
rockabye
rollback
scab
scabious
scabrous
scarborough
schnabel
schwab
scoreboard
scramble
scrapbook
screwball
screwbean
scrutable
scuba
semblance
serviceable
setback
sociable
strabismic
subtracter
switchboard
syllabic
tablecloth
throwback
transcribe
turtleback
umbilical
vocable
voiceband
wingback
zellerbach
```

## ALGOL 68

Inspired by the Raku sample - uses the same input file and prints only the words with 2 or more as, bs and cs. Sadly, unixdict appears not to have any such words.
Defines and uses a general letter counting operator and an operator to check the counts are all the same.

Note, the source of the RC ALGOL 68-files library (files.incl.a68) is on a separate page on Rosetta Code - see the above link.

```BEGIN # find words that contain equal numbers of "a", "b" and "c" characters #
# and print those that contain at least 2 of each                      #

PR read "files.incl.a68" PR                     # include file utilities #

# returns the couunts of each character in c that is in s                #
PRIO COUNT = 5;
OP   COUNT = ( STRING s, c )[]INT:
BEGIN
[ LWB c : UPB c ]INT result; FOR i FROM LWB c TO UPB c DO result[ i ] := 0 OD;
FOR i FROM LWB s TO UPB s DO
INT c pos := 0;
IF char in string( s[ i ], c pos, c ) THEN result[ c pos ] +:= 1 FI
OD;
result
END # COUNT # ;
# returns TRUE if all elements of a are equal, FALSE otherwise           #
OP   EQUAL = ( []INT a )BOOL:
IF LWB a >= UPB a THEN TRUE                        # 0 or 1 element #
ELSE
INT v = a[ LWB a ];
BOOL same := TRUE;
FOR i FROM LWB a + 1 TO UPB a WHILE same := v = a[ i ] DO SKIP OD;
same
FI # same # ;

# prints word if the number of "a", "b" and "c" in it are equal and      #
# there are at least two of each                                         #
# returns TRUE if word is such an "abc" word, FALSE otherwise            #
PROC show abc word = ( STRING word, INT count so far )BOOL:
IF  []INT abc counts = word COUNT "abc";
IF abc counts[ LWB abc counts ] < 2 THEN FALSE ELSE EQUAL abc counts FI
THEN print( ( word, newline ) );
TRUE
ELSE FALSE
FI # show abc word # ;

IF   INT w count = "words_alpha.txt" EACHLINE show abc word;
w count < 0
THEN print( ( "Unable to open unixdict.txt", newline ) )
ELSE print( ( newline, "found ", whole( w count, 0 ), " words", newline ) )
FI

END```
Output:
```abboccato
beccabunga
blackback
bombacaceous
brachiocubital
buccolabial
cabbalistic
subbrachycephaly
subcarbonaceous

found 10 words
```

## BASIC

### BASIC256

Translation of: FreeBASIC
```while True
input string "Enter a string or 'q' to quit: ", s
if s = "q" then exit while
res = areAbcCountsEqual(s)
print "The counts of 'a', 'b', 'c' are ";
if res then
print "equal."
else
print "not equal."
end if
print
end while
end

function areAbcCountsEqual (s)
a = 0: b = 0: c = 0
s = lower(s)
for i = 1 to length(s)
if mid(s, i, 1) = "a" then
a += 1
else
if mid(s, i, 1) = "b" then
b += 1
else
if mid(s, i, 1) = "c" then c += 1
end if
end if
next i
return (a = b) and (b = c)
end function
```

### FreeBASIC

```Function areAbcCountsEqual(s As String) As Boolean
Dim As Uinteger i, a = 0, b = 0, c = 0
s = Lcase(s)
For i = 0 To Len(s) - 1
If s[i] = Asc("a") Then
a += 1
Elseif s[i] = Asc("b") Then
b += 1
Elseif s[i] = Asc("c") Then
c += 1
End If
Next
Return (a = b) And (b = c)
End Function

Do
Dim As String s
Line Input "Enter a string or 'q' to quit: ", s
If s = "q" Then Exit Do
Dim As Boolean res = areAbcCountsEqual(s)
Print "The counts of 'a', 'b', 'c' are ";
Print Iif(res, "", "not "); !"equal.\n"
Loop

Sleep
```
Output:

Sample session:

```Enter a string or 'q' to quit: aaabbbccc
The counts of 'a', 'b', 'c' are equal.

Enter a string or 'q' to quit: AAABBbCcc
The counts of 'a', 'b', 'c' are equal.

Enter a string or 'q' to quit: abracadabra
The counts of 'a', 'b', 'c' are not equal.

Enter a string or 'q' to quit: q```

#### Using generators and a counter

```Function equal_abcs(word As String, min As Integer = 1) As Boolean
' Return true if the number of a's, b's and c's in _word_ are equal
' and _word_ contains at least _min_ a's.
Dim As Uinteger i, a = 0, b = 0, c = 0
For i = 0 To Len(word) - 1
Select Case word[i]
Case Asc("a")
a += 1
Case Asc("b")
b += 1
Case Asc("c")
c += 1
End Select
Next
Return (a = b) And (b = c) And (a >= min)
End Function

Sub equal_abc_words(words() As String, min As Integer, result() As String)
' Generate words from _words_ where equal_abcs(word) is true.
For i As Integer = 0 To Ubound(words)
If equal_abcs(words(i), min) Then
Redim Preserve result(Ubound(result) + 1)
result(Ubound(result)) = words(i)
End If
Next
End Sub

' From user input
Dim As String word
Line Input "Equal a's, b's and c's in: ", word
Print equal_abcs(word)
Print

' All words from words_alpha.txt that have an equal number of a's, b's and c's and have more than one of each.
Dim As String words()
Open "i:\words_alpha.txt" For Input As #1
Do While Not Eof(1)
Dim As String linea
Line Input #1, linea
Redim Preserve words(Ubound(words) + 1)
words(Ubound(words)) = linea
Loop
Close #1

Dim As String result()
equal_abc_words(words(), 2, result())
For i As Uinteger = 0 To Ubound(result)
Print result(i)
Next

Sleep
```
Output:
`Same as Python entry.`

### QBasic

Translation of: FreeBASIC
Works with: QBasic version 1.1
Works with: QuickBasic version 4.5
Works with: QB64
```DO
DIM s AS STRING
INPUT "Enter a string or 'q' to quit: ", s
IF s = "q" THEN EXIT DO
DIM res AS INTEGER
res = areAbcCountsEqual(s)
PRINT "The counts of 'a', 'b', 'c' are ";
IF res THEN
PRINT "equal."
ELSE
PRINT "not equal."
END IF
PRINT
LOOP

FUNCTION areAbcCountsEqual (s AS STRING)
a = 0: b = 0: c = 0
s = LCASE\$(s)
FOR i = 1 TO LEN(s)
IF MID\$(s, i, 1) = "a" THEN
a = a + 1
ELSEIF MID\$(s, i, 1) = "b" THEN
b = b + 1
ELSEIF MID\$(s, i, 1) = "c" THEN
c = c + 1
END IF
NEXT i
areAbcCountsEqual = (a = b) AND (b = c)
END FUNCTION
```

### QB64

The QBasic solution works without any changes.

### Yabasic

Translation of: FreeBASIC
```do
input "Enter a string or 'q' to quit: " s\$
if s\$ = "q"  break
res = areAbcCountsEqual(s\$)
print "The counts of 'a', 'b', 'c' are ";
if res then print "equal.\n" else print "not equal.\n": fi
loop
end

sub areAbcCountsEqual (s\$)
local a, b ,c, i
a = 0: b = 0: c = 0
s\$ = lower\$(s\$)
for i = 1 to len(s\$)
if mid\$(s\$, i, 1) = "a" then
a = a + 1
elseif mid\$(s\$, i, 1) = "b" then
b = b + 1
elseif mid\$(s\$, i, 1) = "c" then
c = c + 1
end if
next i
return (a = b) and (b = c)
end sub
```

## BQN

```Abc ← (1=≠∘⍷)(+˝=⌜)⟜"abc"

Abc¨ "cab"‿"ac"‿"cabac"‿"ubaccabo"‿"is"
```
Output:
`⟨ 1 0 0 1 1 ⟩`

## Brainf***

```>++++++++[-<++++++++++++>]<+>>>,[<<<[->+
>+<<]>[-<+>]>[->-<]<->>[[->>+<<]>>-]>+<+
[-<<+]>>[-],]>>>>>[-<+<<+>>>]<[-<->]<<[-
<->]>[[-]<<[-]+>>]<<<+>[<->[-]++++++[->+
++++++++++++<]>.<]<[+++++++[->++++++++++
+<]>+.<][   brainf+++ was a mistake.   ]
```

## C++

```#include <string>
using namespace std;
bool countabc(string s)
{
unsigned int a = 0;
unsigned int b = 0;
unsigned int c = 0;
for(unsigned int i = 0; i < s.size(); i++)
{
if(s[i] == 'a')
{
a++;
}
if(s[i] == 'b')
{
b++;
}
if(s[i] == 'c')
{
c++;
}
}
return (a == b) && (b == c);
}
```

## Common Lisp

```(defun count-abc (string)
(= (count #\a string)
(count #\b string)
(count #\c string)))
```

## EasyLang

```func abc_word s\$ .
for c\$ in strchars s\$
if c\$ = "a"
a += 1
elif c\$ = "b"
b += 1
elif c\$ = "c"
c += 1
.
.
return if a = b and a = c
.
words\$ = "aluminium abc internet adb cda blank black mercury venus earth mars jupiter saturn uranus neptune pluto"
for w\$ in strsplit words\$ " "
if abc_word w\$ = 1
write w\$ & " "
.
.
```
Output:
```abc internet black venus jupiter neptune pluto
```

## F#

```// ABC correlation. Nigel Galloway: August 8th., 2024
let countChars n g=let k=Seq.zip (n|>List.distinct) (Seq.initInfinite id)|>Map.ofSeq
let r=Array.zeroCreate (k.Count)
g|>Seq.iter(fun g->match k.TryFind g with Some n->r[n]<-r[n]+1 |_->())
k.Keys|>Seq.map(fun n->n,r[k[n]])|>Map.ofSeq
let abc:string -> Map<char,int>=countChars ['a';'b';'c']
let predicate n=let _,g=Map.minKeyValue n in g>1 && Map.forall(fun n->(=)g) n
```
Output:
```abboccato
beccabunga
blackback
bombacaceous
brachiocubital
buccolabial
cabbalistic
subbrachycephaly
subcarbonaceous
```

## Forth

```variable #a   variable #b   variable #c
: 1+!   1 swap +! ;
: init   0 #a ! 0 #b ! 0 #c ! ;
: for/chars   chars over + swap ;
: ?count   rot c@ rot = if 1+! else drop then ;
: ?a   [char] a #a ?count ;
: ?b   [char] b #b ?count ;
: ?c   [char] c #c ?count ;
: equal?   #a @ #b @ = #b @ #c @ = and ;
: countabc   init for/chars do i ?a i ?b i ?c loop equal? ;
```

expects input as an argument, such as in

```: tester   s" aabbcc" countabc ;
```

## FutureBasic

```window 1,@"ABC correlation"

local fn areAbcCountsEqual(s As str255) As Boolean
short i, a = 0, b = 0, c = 0
CFStringRef cfString

cfString = fn stringwithpascalstring(s)
s = fn stringpascalstring(cfString)

For i = 1 To Len\$(s)
If mid\$(s,i,1) = "a"
a += 1
Else if mid\$(s,i,1) = "b"
b += 1
Else if mid\$(s,i,1) = "c"
c += 1
end If
end if
end if
next i

end fn = (a = b) && (b = c)

bool q

Do
CFStringRef s = @""
// Enter any combination or quantity of abc in any order.
// All other letters or numbers are ignored exept q to quit.
s = input %(10, 400), @"Enter a string or 'q' to quit: ", @"abcABCq", YES,, 0

If fn stringpascalstring(s) = "q" then end

bool res

if len(s) <> 0
res = fn areAbcCountsEqual(fn stringpascalstring(s))
if res = _true
Print "The counts of 'a', 'b', 'c' are equal"
else
Print "The counts of 'a', 'b', 'c' are NOT equal"
end if
end if

until q```

## JavaScript

```        // Since all strings in JavaScript are iterable, it was simple to loop over it, counting each case.
// When trying to determin if there is an equal amount, compare a's to b's and b's to c's is enough.
// To Determin if they're all equal.

function abcCorrelation(characterSequence) {
let countOfAs = 0, countOfBs = 0, countOfCs = 0;

for (const character of characterSequence){
if (character.toLowerCase() === 'a') countOfAs++;
else if (character.toLowerCase() === 'b') countOfBs++;
else if (character.toLowerCase() === 'c') countOfCs++;
}

return countOfAs === countOfBs && countOfBs === countOfCs;
}
```

## jq

Works with jq, the C implementation of jq

Works with gojq, the Go implementation of jq

Works with jaq, the Rust implementation of jq

The program presented here avoids counting quite diligently though not strenuously. For example, if the number of "a"s is so great that simple arithmetic would make it impossible for there to be the same number of "b"s and "c"s, the conclusion is drawn without further ado.

With the three functions defined below, one could use the following top-level program to proceed as per the task description:

```inputs | abc
```

That is, this would just emit a simple true or false response to each input.

In the following, by contrast, we'll make a transcript of the interaction more readable.

```def count(stream): reduce stream as \$x (0; .+1);

def sameCount(stream):
if . == false then false
else . as \$n
| first(
foreach (stream,null) as \$x ({i:0};
if \$x == null then .emit = (\$n == .i)
else .i += 1
| if .i > \$n then .emit = false end
end )
| select(.emit != null).emit  )
end;

# Report true or false as the counts of "a", "b" and "c" are equal.
def abc:
tostring
| length as \$n
| [explode[] | [.] | implode] as \$s
| count(\$s[] | select(. == "a"))
| if (3 * .) > \$n then false
else sameCount(\$s[] | select(. == "b")) and sameCount(\$s[] | select(. == "c"))
end;

inputs
| if abc then "\(.) is an \"abc\" word"
else "\(.) is NOT an \"abc\" word"
end```
Output:

To make the nature of the interaction clear, we'll invoke jq with the -r option but without the -R option, e.g. like so: jq -nrf abc-correlation.jq

```"aluminium"
aluminium is NOT an "abc" word
"abc"
abc is an "abc" word
"internet"
internet is an "abc" word
adb is NOT an "abc" word
"cda"
cda is NOT an "abc" word
"blank"
blank is NOT an "abc" word
"black"
black is an "abc" word
"mercury"
mercury is NOT an "abc" word
"venus"
venus is an "abc" word
"earth"
earth is NOT an "abc" word
"mars"
mars is NOT an "abc" word
"jupiter"
jupiter is an "abc" word
"saturn"
saturn is NOT an "abc" word
"uranus"
uranus is NOT an "abc" word
"neptune"
neptune is an "abc" word
"pluto"
pluto is an "abc" word
```

## Julia

```""" A simple one-liner fitting the task but lacking flexibility. """
simplesamecounts(s) = allequal(map(c -> count(==(c), s), ['a', 'b', 'c']))

"""
A more sophisticated `samecounts` function, which allows user to specify target,
whether the counting must find a least one target letter in the text, and
whether to respect or ignore letter case.

samecounts(text, chars = ['a', 'b', 'c']; casesensitive = true, mincount = 0)

Count each occurence in text of all characters in chars, return true if the
counts are all equal, otherwise returns false. Return value may be modified by
the `casesensitive` and `mincount` arguments.

`text`: A string or similar char vector to search.

`chars`: A vector of characters. Counts are of all characters in this array.
Defaults to 'a', 'b', and 'c'.

`casesensitive`: This named argument specifies whether counts are case sensitive.
Defaults to true (case sensitive, so 'A' is not counted for 'a').

`mincount`: This named argument, when < 1, as in 0 (default), specifies whether
all counts found being zero is considered a true result (default
when < 1) or whether such a result returns false. In addition,
if mincount is > 1, all letters must be found as a count of
`mincount` or greater in order for the function to return true.
"""
function samecounts(text, chars = ['a', 'b', 'c']; casesensitive = true, mincount = 0)
(isempty(text) || isempty(chars)) && return mincount < 1
if !casesensitive
text = lowercase(text)
chars = map(lowercase, chars)
end
counts = map(ch -> count(==(ch), text), chars)
return counts[begin] >= mincount && allequal(counts)
end

@show simplesamecounts("back")
@show samecounts("back")
@show simplesamecounts("Back")
@show samecounts("Back", casesensitive = false)
@show simplesamecounts("")
@show samecounts("", mincount = 1)
@show simplesamecounts("gone")
@show samecounts("gone", mincount = 1)

samecounts(s, mincount = 1) && println(s)
end

const rakuwords = split(read("words_alpha.txt", String), r"\s+")
for s in rakuwords
samecounts(s, mincount = 2) && println(s)
end
```
Output:
```simplesamecounts("back") = true
samecounts("back") = true
simplesamecounts("Back") = false
samecounts("Back", casesensitive = false) = true
simplesamecounts("") = true
samecounts("", mincount = 1) = false
simplesamecounts("gone") = true
samecounts("gone", mincount = 1) = false
```

The remainder of the output is of results as in the Ada example, followed by results as in the Raku example.

## K

```t: {1=#?3#+/"abc"=/:x}

t' ("cab"; "cabac"; ""; "ac"; "ubaccabo"; "is")
```
Output:
`1 0 1 0 1 1`

## Nu

```def abc [] {
(parse -r '([abc])').capture0 | (uniq -c).count | get -i 0 1 2
| \$in.0 == \$in.1 and \$in.1 == \$in.2
}```

## PascalABC.NET

This task uses countChars from Words with more than 3 ez

```// ABC correlation. Nigel Galloway: September 3rd., 2024
function predicate(g:Sequence of (integer,integer);m:integer):boolean;
begin
result:=false; if g.First[0]<m then exit;
foreach n:(integer,integer) in g do if n[1]<>n[0] then exit; result:=true;
end;
begin
foreach s:string in System.IO.File.ReadLines('words_alpha.txt') do if predicate(countChars('abc',s).Values.Pairwise,2) then println(s);
end.
```
Output:
```abboccato
beccabunga
blackback
bombacaceous
brachiocubital
buccolabial
cabbalistic
subbrachycephaly
subcarbonaceous
```

## Phix

```with javascript_semantics
function abc(string word)
integer na = length(filter(word,"=",'a'))
return na>0 and na=length(filter(word,"=",'b'))
and na=length(filter(word,"=",'c'))
end function
?join(shorten(filter(unix_dict(),abc),"words",3),",")
```

```"abc,abduct,abject,...,voiceband,wingback,zellerbach, (326 words)"
```

## Python

```a=0
b=0
c=0
for i in input("string with 'a', 'b' and 'c'\n"):
if i=="a":
a+=1
if i=="b":
b+=1
if i=="c":
c+=1
print("Amout of letters:")
print(f"a:{a}")
print(f"b:{b}")
print(f"c:{c}")
if a==b and b==c:
print("True")
else:
print("False")
```

Output:

```string with 'a', 'b' and 'c'
abc
Amout of letters:
a:1
b:1
c:1
True
```

### Using generators and a counter

```from collections import Counter
from typing import Iterable
from typing import Iterator

def equal_abcs(word: str, n: int = 0) -> bool:
"""Return true if the number of a's, b's and c's in _word_ are equal
and _word_ contains at least _n_ a's.
"""
counter = Counter(a=0, b=0, c=0)
counter.update(c for c in word if c in ("a", "b", "c"))
return len(set(counter.values())) == 1 and counter["a"] >= n

def equal_abc_words(words: Iterable[str], n: int = 2) -> Iterator[str]:
"""Generate words from _words_ where equal_abcs(word, n) is true."""
return (word for word in words if equal_abcs(word, n))

if __name__ == "__main__":
# From user input
word = input("Equal a's, b's and c's in: ")
print(equal_abcs(word))

print("")

# All words from words_alpha.txt that have an equal number of a's, b's and
# c's and have more than one of each.
#
# Assumes https://github.com/dwyl/english-words/blob/master/words_alpha.txt
# exists in the current working directory.
with open("words_alpha.txt") as fd:
words = (line.strip() for line in fd)
for word in equal_abc_words(words, n=2):
print(word)
```
Output:
```Equal a's, b's and c's in: abcc
False

abboccato
beccabunga
blackback
bombacaceous
brachiocubital
buccolabial
cabbalistic
subbrachycephaly
subcarbonaceous
```

## Raku

I've elected to do 'or something' as specified in the task instructions. Rather than just feeding a few words in to check if there are equal counts of 'a', 'b', and 'c'; instead, reads in the words_alpha.txt word list and returns the words that have equal counts of 'a', 'b', and 'c', and, (to make things a little less verbose,) have more than one of each.

```.say for 'words_alpha.txt'.IO.lines.race.grep({+(my \b = .comb.Bag)<a> > 1 and [==] b<a b c>}) X~ " True";
```
Output:
```abboccato True
beccabunga True
blackback True
bombacaceous True
brachiocubital True
buccolabial True
cabbalistic True
subbrachycephaly True
subcarbonaceous True
```

## RPL

Works with: RPL version HP-49C
```« { 0 0 0 }
1 PICK3 SIZE FOR j
"ABCabc" PICK3 j DUP SUB
IF POS THEN LASTARG 1 - 3 MOD 1 + DUP2 GET 1 + PUT END
NEXT
NIP ΔLIST { 0 0 } ==
» 'ABC?' STO     @ ( "string" → boolean )
```
```{ "Black" "Abacus" } 1 « ABC? » DOLIST
```
Output:
```1: { 1. 0. }
```

## Wren

Library: wren-ioutil
Library: wren-str

I've assumed that the counts are not case sensitive and that the strings may contain other characters apart from 'a', 'b' and 'c'. Only non-empty strings are considered.

```import "./ioutil" for Input, FileUtil
import "./str" for Str

var areAbcCountsEqual = Fn.new { |s, checkCase|
var a = 0
var b = 0
var c = 0
if (checkCase) s = Str.lower(s)
for (ch in s) {
if (ch == "a") {
a = a + 1
} else if (ch == "b") {
b = b + 1
} else if (ch == "c") {
c = c + 1
}
}
return a == b && b == c
}

while (true) {
var s = Input.text("Enter a string or 'q' to quit: ", 1)
if (s == "q") break
var res = areAbcCountsEqual.call(s, true)
System.print("The counts of 'a', 'b', 'c' are %(res ? "equal" : "not equal").\n")
}

var words = FileUtil.readLines("unixdict.txt") // local copy
var c = words.count { |w| w.contains("a") && areAbcCountsEqual.call(w, false) }
System.print("\nThere are %(c) words in unixdict.txt which have at least one 'a' and equal numbers of 'a', 'b' and 'c'.")

words = FileUtil.readLines("words_alpha.txt") // local copy
var eligible = words.where { |w|
var a = Str.occurs(w, "a")
if (a < 2) return false
var b = Str.occurs(w, "b")
if (a != b) return false
return b == Str.occurs(w, "c")
}
System.print("\nWords in words_alpha.txt which contain equal numbers of 'a', 'b' and 'c' and at least two of each of them (%(eligible.count) such words found):")
System.print(eligible.join("\n"))
```
Output:

Sample session:

```Enter a string or 'q' to quit: aaabbbccc
The counts of 'a', 'b', 'c' are equal.

Enter a string or 'q' to quit: AAABBbCcc
The counts of 'a', 'b', 'c' are equal.

Enter a string or 'q' to quit: abracadabra
The counts of 'a', 'b', 'c' are not equal.

Enter a string or 'q' to quit: q

There are 326 words in unixdict.txt which have at least one 'a' and equal numbers of 'a', 'b' and 'c'.

Words in words_alpha.txt which contain equal numbers of 'a', 'b' and 'c' and at least two of each of them (10 such words found):
abboccato
beccabunga
blackback
bombacaceous
brachiocubital
buccolabial
cabbalistic
subbrachycephaly
subcarbonaceous
```

## XPL0

This shows words in words_alpha.txt that have two each of a's b's and c's.

```string 0;                               \use zero-terminated strings
char Let, Cnt(3), Word(100);
int  I, J, Ch, Len;
def  LF=\$0A, CR=\$0D, EOF=\$1A;
[FSet(FOpen("words_alpha.txt", 0), ^I); \set dictionary file to device 3
OpenI(3);
repeat  I:= 0;
loop    [repeat Ch:= ChIn(3) until Ch # CR;     \remove possible CR
if Ch=LF or Ch=EOF then quit;
Word(I):= Ch;
I:= I+1;
];
Word(I):= 0;                    \terminate string
Len:= I;
Let:= "abc";
for J:= 0 to 2 do Cnt(J):= 0;
for I:= 0 to Len-1 do
for J:= 0 to 2 do
if Word(I) = Let(J) then Cnt(J):= Cnt(J)+1;
if Cnt(0)=2 & Cnt(1)=2 & Cnt(2)=2 then
[Text(0, Word);  CrLf(0)];
until   Ch = EOF;
]```
Output:
```abboccato