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
Task:
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 <> "":
READ word RAW
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
Ada
-- 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)
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Fixed;
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 blockade 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 brocade 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 cornbread 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 roadblock rockabye rollback scab scabious scabrous scarborough schnabel schwab scoreboard scramble scrapbook screwball screwbean scrutable scuba semblance serviceable setback sociable strabismic subtracter switchblade 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 bambocciade beccabunga blackback bombacaceous brachiocubital buccolabial cabbalistic subbrachycephaly subcarbonaceous found 10 words
BASIC
BASIC256
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
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
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
System.IO.File.ReadLines "words_alpha.txt"|>Seq.filter(abc>>predicate)|>Seq.iter(printfn "%s")
- Output:
abboccato bambocciade 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" 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)
const adawords = split(read("unixdict.txt", String), r"\s+")
for s in adawords
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 bambocciade 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),",")
Output (matching that of Ada):
"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 bambocciade 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 bambocciade True beccabunga True blackback True bombacaceous True brachiocubital True buccolabial True cabbalistic True subbrachycephaly True subcarbonaceous True
RPL
« { 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
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 bambocciade 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 bambocciade beccabunga blackback bombacaceous brachiocubital buccolabial cabbalistic subbrachycephaly subcarbonaceous