| Bytes | Lang | Time | Link |
|---|---|---|---|
| nan | Scala | 230724T133033Z | 138 Aspe |
| 065 | Scala 3 | 230729T103649Z | corvus_1 |
| 006 | Nibbles | 230727T144927Z | xigoi |
| 007 | Jelly | 230727T145403Z | xigoi |
| 038 | Ruby nl | 230724T230812Z | Value In |
| 055 | Python | 230724T122803Z | Gáb |
| 008 | Jelly | 230725T065857Z | Unrelate |
| 028 | Perl 5 pl | 230724T222049Z | Xcali |
| 011 | Pyth | 230724T182230Z | CursorCo |
| 095 | Swift 5.7 enablebareslashregex | 230724T131904Z | Bbrk24 |
| 006 | Thunno 2 | 230724T130755Z | The Thon |
| 006 | 05AB1E legacy | 230724T115511Z | Kevin Cr |
| 080 | Excel | 230724T112910Z | Jos Wool |
| 117 | JavaScript ES6 | 230724T110018Z | W D |
| 005 | Vyxal | 230724T093554Z | lyxal |
| 021 | Dyalog APL | 230724T100754Z | RubenVer |
| 019 | Charcoal | 230724T094730Z | Neil |
Scala, 139 61 bytes
Port of @Gábor Fekete's Python answer in Scala.
Golfed version. Attempt This Online!
Saved 78 bytes thanks to the comment of @corvus_192
var c="";def f(i:Any)={c+=i;(c+c(0))sliding 2 count(_=="AB")}
Ungolfed version. Attempt This Online!
import scala.collection.mutable.ArrayBuffer
object Main {
var c: ArrayBuffer[String] = ArrayBuffer()
def f(i: String): Int = {
if (c.isEmpty) {
c += i
}
else {
c = ArrayBuffer(c.head + i)
}
(c.head + c.head(0)).sliding(2).count(_ == "AB")
}
def main(args: Array[String]): Unit = {
val cases = Array(
("ABABA", 2),
("ABABA", 4),
("//", 0),
("BA", 1),
("BABA", 3),
("BB", 3),
("BAAAAB", 4),
("//", 0),
("AB", 1),
("AAA", 1),
("B", 2),
("AB", 3),
("//", 0),
("BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB", 1),
("A", 2),
("B", 2),
("A", 3),
("A", 3),
("B", 3),
("//", 0),
("BABABABABABAB", 6),
("A", 7)
)
for (caseValue <- cases) {
caseValue._1 match {
case "//" =>
println("=" * 15)
c = ArrayBuffer()
case _ =>
val t = f(caseValue._1)
println(caseValue._1 + " " + caseValue._2 + " ; result: " + t)
}
}
}
}
Scala 3, 65 bytes
_.scanLeft("")(_+_).tail.map(s=>(s+s(0))sliding 2 count(_=="AB"))
Nibbles, 6 bytes
`\$:/,`=+$$~
Works with any two distinct characters.
`\$:/,`=+$$~
For each p in
`\ : prefixes of
$ the input
, length of
`= $ group runs of identical elements in
+$ p concatenated
/ ~ floor-divided by 2
Jelly, 7 bytes
;\ŒgẈ:2
Port of my Nibbles answer.
;\ŒgẈ:2
;\ Concatenate all prefixes
For each concatenated prefix:
Œg Group runs of equal elements
Ẉ Length
:2 Floor divide by two
Ruby -nl, 40 38 bytes
a="#{a}#$_"
p (a+a[0]).scan('AB').size
ruby -nl # -n loops program over each line of input
# -l automatically trims trailing newlines
a=" " # Set a to...
#{a} # a, if already set (empty string otherwise)
#$_ # plus most recent line of input
(a+a[0]) # Get a plus its first character
.scan('AB').size # and count all instances of AB
p # Print that number
Python, 67 65 55 bytes
lambda i,c=[]:c.extend(i)or''.join(c+c[:1]).count('AB')
Using the default list argument to memorize the previous inputs.
edit: changed extend to append to save 2 bytes
edit: with the help of @Albert.Lang and @Jonathan Allan golfed an additional 10 bytes
Jelly, 9 8 bytes
;\µṙ1<)§
Something cleverer still feels possible. Takes input as shown in the test cases, since counting substring occurrences is actually pretty expensive anyways.
;\ Scan by concatenate, creating a list of each cumulative necklace.
µ ) For each:
ṙ1 rotate left once, and
§ count how many
< are less than in the corresponding original positions.
Pyth, 11 bytes
m/shBsd`T._
Uses characters "1" and "0" for "A" and "B" respectively.
Explanation
m/shBsd`T._Q # implicitly add Q
# implicitly assign Q = eval(input())
._Q # prefixes of Q
m # map over lambda d
sd # concatenate list of strings
hB # bifurcate into [str, first_char(str)]
s # concatenate list of strings
/ `T # count occurrences of "10"
Swift 5.7 -enable-bare-slash-regex, 95 bytes
{var x=""
return $0.map{x+=$0
return x.ranges(of:/AB/).count+("B"==x.first&&"A"==x.last ?1:0)}}
Try it on SwiftFiddle! Without the -enable-bare-slash-regex flag, the regex literal /AB/ would be spelled #/AB/# on macOS, or try!Regex("AB") on Linux, so the flag is obvious. SwiftFiddle enables it by default on Swift 5.7 and later.
The code should be fairly straightforward: append the new element to what's been seen so far, then count the ranges that match /AB/, and check whether it starts with "B" and ends with "A".
Thunno 2, 6 bytes
ƒıJẹTc
Uses 1 and 0, and checks for the substring 10, like Vyxal and 05AB1E.
Explanation
ƒıJẹTc # Implicit input
ƒı # Map over prefixes
Jẹ # Join and append first character
Tc # Count occurrences of "10"
# Implicit output
05AB1E (legacy), 6 bytes
ηJεĆT¢
I/O as a list. Uses characters 1 and 0 for A and B respectively.
Uses the legacy version of 05AB1E, because the new version of 05AB1E has a bug with multi-digit integers and the count builtin ¢, so it would require an additional § after the T.
Try it online! or verify all test cases.
Explanation:
η # Get the prefixes of the (implicit) input-list
J # Join each inner list together to a single string
ε # Map over each string:
Ć # Enclose; append its first character at the end
T¢ # Count how many times "10" occurs in this string
# (after which the list of counts is output implicitly as result)
Excel, 80 bytes
=MAP(SCAN("",A1#,LAMBDA(a,b,a&b)),LAMBDA(c,ROWS(TEXTSPLIT(RIGHT(c)&c,,"AB"))-1))
Input is vertical spilled range #A1.
JavaScript (ES6), 117 bytes
k=>{for(let i=1;i<=k.length;i++)console.log(((s=k.slice(0,i).join('')).match(/01/g)||[]).length+!(+s.at(-1)-~-s[0]))}
Uses 0 instead of A and 1 instead of B.
I could probably get rid of the first/last character special case by appending the first character at the end like Vyxal did using (k.slice(0,i).join('')+k[0][0]).match(/01/g) instead of (s=k.slice(0,i).join('')).match(/01/g) but I can't be bothered to rewrite my terrible explanation
Explained
// Take k ['01010', '01010']
// Convert it to s '01010'
// Then in the next loop s='0101001010'
// In s, count the occurences of 01
// Then count special case of first/last characters
// k has length N
k=>{for(let i=1;i<=k.length;i++) // Loop 'i' from 1 to N inclusive
console.log( // Output:
(
(s=k.slice(0,i).join('')) // Get bracelet up to current 'i'
.match(/01/g) // List of occurences of '01'
||[] // Default to empty list
).length // Get length
+
!(+s.at(-1)-~-s[0]) // Is +s.at(-1)-~-s[0] equal to 0?
// (implicitly) convert to number
)}
But what is !(+s.at(-1)-~-s[0])?
s.at(-1) is the last element of s, and for the rest... well... I just threw a bunch of random stuff in there until it worked; please don't tell my coding teacher
With test cases
const f=
k=>{for(let i=1;i<=k.length;i++)console.log(((s=k.slice(0,i).join('')).match(/01/g)||[]).length+!(+s.at(-1)-~-s[0]))}
`
ABABA => 2
ABABA => 4
//
BA => 1
BABA => 3
BB => 3
BAAAAB => 4
//
ABABA => 2
ABABA => 4
//
BA => 1
BABA => 3
BB => 3
BAAAAB => 4
//
AB => 1
AAA => 1
B => 2
AB => 3
//
BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB => 1
A => 2
B => 2
A => 3
A => 3
B => 3
//
BABABABABABAB => 6
A => 7
`.slice(1,-1).replaceAll('A','0').replaceAll('B','1').split('\n//\n').forEach(testCase => {
const parts = testCase.split('\n').map(x=>x.split(' => '));
const input_ = parts.map(x=>x[0]);
console.log('\n\nInput:',input_,'\nExpected output:');
parts.forEach(x=>console.log(+x[1]));
console.log('Output:');
f(input_);
});
Vyxal, 5 bytes
¦ƛǏ₀O
Uses the characters 1 and 0, checks for substring 10.
Explained
¦ƛǏ₀O
¦ƛ # To each prefix of the input:
Ǐ # Append the first character to the end
₀O # And count the number of instances of "10" in that
💎
Created with the help of Luminespire.
Dyalog APL, 21 bytes
{∇⍵,⍞⊣⎕←+/'AB'⍷⍵,⊃⍵}⍞
⍞ # Take a line from standard input, and pass it to the following function:
⎕← # print
+/ # how many times
'AB' # the string AB
⍷ # appears in
⍵,⊃⍵ # the string formed by concatenating the input and its first element
⊣ # , then,
∇ # call the same function
⍵,⍞ # passing the input concatenated with another line from standard input
💎
Created with the help of Luminespire.
Charcoal, 19 bytes
WS«≔⁺ωιωI№⁺ω§ω⁰ABD⎚
Try it online! Link is to verbose version of code. Fully interactive version, so when run from the command line it will prompt for the next piece of necklace and output the count of ABs so far. Explanation:
WS«
Keep accepting pieces but stop when an empty piece is entered.
≔⁺ωιω
Concatenate the piece to the necklace so far.
I№⁺ω§ω⁰ABD⎚
Output the number of ABs so far.