Split a character string based on change of character: Difference between revisions
Split a character string based on change of character (view source)
Revision as of 23:20, 16 June 2024
, 10 days agoAdd Uiua
(Split a character string based on change of character en BASIC256) |
(Add Uiua) |
||
(39 intermediate revisions by 22 users not shown) | |||
Line 31:
{{trans|C++}}
<
V res = ‘’
L(ch) input
Line 39:
R res
print(split(‘gHHH5YY++///\’, ‘, ’))</
{{out}}
Line 47:
=={{header|8080 Assembly}}==
<
jmp demo
;;; Split the string under DE on changing characters,
Line 76:
jmp 5
string: db 'gHHH5YY++///',5Ch,'$'
out: equ $</
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
=={{header|8086 Assembly}}==
<
org 100h
section .text
Line 114:
string: db 'gHHH5YY++///\$'
section .bss
buf: resb 32</
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
Line 120:
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<syntaxhighlight lang="aarch64 assembly">
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program splitcar64.s */
Line 219:
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</syntaxhighlight>
{{Output}}<pre> gg, HHH, 5, YY, ++, ///, \ </pre>
=={{header|Action!}}==
<
BYTE i
CHAR curr,last
Line 251:
Test("gHHH5YY++///\")
Test("gHHH 5++,,,///\")
RETURN</
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Split_a_character_string_based_on_change_of_character.png Screenshot from Atari 8-bit computer]
Line 263:
=={{header|Ada}}==
<
with Ada.Text_IO;
procedure Split is
Line 280:
Print_Tokens ("gHHH5YY+++");
end split;
</syntaxhighlight>
=={{header|ALGOL 68}}==
<syntaxhighlight lang="algol68">BEGIN
# returns s with ", " added between each change of character #
PROC split on characters = ( STRING s )STRING:
Line 295 ⟶ 294:
[ 3 * ( ( UPB s - LWB s ) + 1 ) ]CHAR result;
INT r pos := LWB result;
CHAR s char := s[ LWB s ];
FOR s pos FROM LWB s TO UPB s DO
Line 313 ⟶ 311:
print( ( split on characters( "gHHH5YY++///\" ), newline ) )
END</
{{out}}
<pre>
g, HHH, 5, YY, ++, ///, \
</pre>
=={{header|Amazing Hopper}}==
VERSION 1: string
<syntaxhighlight lang="c">
#include <basico.h>
#define INICIO 1
#define CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"+-/ \\:,;:_*"
algoritmo
objetivo = "gHHH5YY\"\"++ ///,,,\\", indice=0
largo=0, sublargo=0, v=0
#( largo = len(indice:=(onechar(CHARS,objetivo))) )
t=0, nuevo=""
para cada caracter ( v, indice, largo )
#(t = replicate(v, sublargo := ((poschar(INICIO, v, objetivo) - 1 ) ) ))
#(nuevo = cat( cat(nuevo, t), ", "))
objetivo+=sublargo
siguiente
nuevo -= 2
imprimir( "NEW STRING=\n", nuevo,NL)
terminar
</syntaxhighlight>
{{out}}
<pre>
$ hopper3 basica/splitrep.bas
NEW STRING=
g, HHH, 5, YY, "", ++, , ///, ,,,, \
</pre>
VERSION 2: arrays
<syntaxhighlight lang="c">
#include <basico.h>
#define INICIO 1
#define CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"+-/ \\:,;:_*"
algoritmo
objetivo = "gHHH5YY\"\"++ ///,,,,\\", indice=0
largo=0, sublargo=0, lista={}, v=0
#( largo = len(indice:=(onechar(CHARS,objetivo))) )
para cada caracter ( v, indice, largo )
#( replicate(v, sublargo := ((poschar(INICIO, v, objetivo) - 1 ))))
meter en( lista )
objetivo+=sublargo
siguiente
imprimir( "LISTA=\n", lista, NL )
terminar
</syntaxhighlight>
{{out}}
<pre>
$ hopper3 basica/splitrep2.bas
LISTA=
g,HHH,5,YY,"",++, ,///,,,,,,\
</pre>
=={{header|ANSI BASIC}}==
{{works with|Decimal BASIC}}
<syntaxhighlight lang="basic">REM >split
DECLARE EXTERNAL FUNCTION FN_split$
Line 338 ⟶ 404:
NEXT i
LET FN_split$ = split$
END FUNCTION</
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
Line 344 ⟶ 410:
=={{header|APL}}==
{{works with|Dyalog APL}}
<
{{out}}
<pre> split 'gHHH5YY++///\'
Line 352 ⟶ 418:
===Functional===
{{Trans|JavaScript}}
<
map(curry(intercalate)'s |λ|(""), ¬
group("gHHH5YY++///\\")))
Line 468 ⟶ 534:
{}
end if
end tail</
{{Out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
Line 474 ⟶ 540:
===Straightforward===
(Also case-sensitve.)
<
set len to (count input)
if (len < 2) then return input
Line 497 ⟶ 563:
-- Test code:
splitAtCharacterChanges("gHHH5YY++///\\")</
{{output}}
<
===ASObjC===
<
use framework "Foundation"
Line 514 ⟶ 580:
-- Test code:
splitAtCharacterChanges("gHHH5YY++///\\")</
{{output}}
<
=={{header|ARM Assembly}}==
Line 523 ⟶ 589:
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
/* ARM assembly Raspberry PI */
/* program splitcar.s */
Line 641 ⟶ 707:
output : gg, HHH, 5, YY, ++, ///, \
</syntaxhighlight>
=={{header|Arturo}}==
<
loop split {gHHH5YY++///\} 'ch [
if? or? empty? current
Line 654 ⟶ 720:
]
'parts ++ current
print parts</
{{out}}
Line 661 ⟶ 727:
=={{header|AutoHotkey}}==
<
for i, v in StrSplit(str)
res .= (v=prev) ? v : (res?", " :"") v , prev := v
return res
}</
Examples:<
MsgBox % Split_Change(str)</
Outputs:<pre>g, HHH, 5, YY, ++, ///, \</pre>
===RegEx Version===
<
return RegExReplace(str, "(.)\1*(?!$)", "$0, ")
}</
Examples:<
MsgBox % Split_Change(str)</
Outputs:<pre>g, HHH, 5, YY, ++, ///, \</pre>
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f SPLIT_A_CHARACTER_STRING_BASED_ON_CHANGE_OF_CHARACTER.AWK
BEGIN {
Line 697 ⟶ 763:
return(new_str)
}
</syntaxhighlight>
{{out}}
<pre>
Line 706 ⟶ 772:
=={{header|BaCon}}==
Literal strings in BaCon are passed to the C compiler as they are; a backslash therefore needs to be escaped.
<
c$ = LEFT$(txt$, 1)
Line 717 ⟶ 783:
END IF
PRINT d$;
NEXT</
{{out}}
<pre>
Line 724 ⟶ 790:
=={{header|BASIC256}}==
<
next i
end function
print split$("gHHH5YY++///\")</
=={{header|BBC BASIC}}==
<
PRINT FN_split( "gHHH5YY++///\" )
END
Line 753 ⟶ 819:
split$ += d$
NEXT
= split$</
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
=={{header|BQN}}==
<syntaxhighlight lang="bqn">Split ← (+`⊏⊸»⊸≠)⊸⊔
Join ← {∾⟜𝕨⊸∾´𝕩}
", " Join⟜Split "gHHH5YY++///\"</syntaxhighlight>
{{out}}
<pre>"g, HHH, 5, YY, ++, ///, \"</pre>
=={{header|C}}==
<
#include <stdlib.h>
#include <string.h>
Line 781 ⟶ 855:
*(counter--)='\0';
return realloc(result,strlen(result));
}</
{{out}}
<pre>
Line 788 ⟶ 862:
=={{header|C sharp}}==
<
using System.Linq;
using System.Collections.Generic;
Line 819 ⟶ 893:
public static string Delimit<T>(this IEnumerable<T> source, string separator = "") => string.Join(separator ?? "", source);
}</
{{out}}
<pre>
Line 826 ⟶ 900:
=={{header|C++}}==
<
// Solution for http://rosettacode.org/wiki/Split_a_character_string_based_on_change_of_character
#include<string>
Line 843 ⟶ 917:
int main(){
std::cout << split("gHHH5 ))YY++,,,///\\", ", ") << std::endl;
}</
{{out}}
<pre>g, HHH, 5, , )), YY, ++, ,,,, ///, \</pre>
=={{header|Clojure}}==
<
(println (clojure.string/join ", " (map first (re-seq #"(.)\1*" s)))))
(print-cchanges "gHHH5YY++///\\")
</syntaxhighlight>
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
=={{header|CLU}}==
<
split_on_change = iter (s: string) yields (string)
part: string := ""
Line 884 ⟶ 958:
end
stream$putl(po, rslt)
end start_up</
{{out}}
<pre>g, HHH, 5, YYY, ++, ///, \</pre>
=={{header|COBOL}}==
<syntaxhighlight lang="cobol">
identification division.
program-id. split-ch.
Line 951 ⟶ 1,025:
end program split-ch.
</syntaxhighlight>
{{out}}
<pre>
Line 965 ⟶ 1,039:
=={{header|Common Lisp}}==
<
(loop :for prev := nil :then c
:for c :across string
Line 971 ⟶ 1,045:
(split "gHHH5YY++///\\")
</syntaxhighlight>
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
Line 977 ⟶ 1,051:
Doing more work that what's being ask, the following solution builds a list of strings then output it:
<
(flet ((make-buffer ()
(make-array 0 :element-type 'character :adjustable t :fill-pointer t)))
Line 991 ⟶ 1,065:
(format t "~{~A~^, ~}"(nreverse result)))))
(split "gHHH5YY++///\\")</
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
=={{header|Cowgol}}==
<
sub split(in: [uint8], buf: [uint8]): (out: [uint8]) is
Line 1,016 ⟶ 1,090:
print(split("gHHH5YY++//\\", &buf[0]));
print_nl();</
{{out}}
<pre>g, HHH, 5, YY, ++, //, \</pre>
Line 1,022 ⟶ 1,096:
=={{header|D}}==
<
void main() {
Line 1,036 ⟶ 1,110:
}
writeln();
}</
{{output}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
<syntaxhighlight lang="Delphi">
function SplitStringCharChange(S: string): string;
{Split string whenever the previous char is different from the current one}
var I: integer;
var C: char;
begin
Result:='';
{Copy string to output}
for I:=1 to Length(S) do
begin
Result:=Result+S[I];
{Appended ", " if the next char is different}
if (I<Length(S)) and (S[I]<>S[I+1]) then Result:=Result+', ';
end;
end;
procedure ShowSplitString(Memo: TMemo);
const S1 = 'gHHH5YY++///\';
var S2: string;
begin
Memo.Lines.Add(S1);
S2:=SplitStringCharChange(S1);
Memo.Lines.Add(S2);
end;
</syntaxhighlight>
{{out}}
<pre>
gHHH5YY++///\
g, HHH, 5, YY, ++, ///, \
Elapsed Time: 1.767 ms.
</pre>
=={{header|Dyalect}}==
<
var c
var str = ""
var last = this.
for n in 0..last {
if c && this[n] != c {
Line 1,055 ⟶ 1,170:
str += c
}
str
}
print("gHHH5YY++///\\".
{{out}}
Line 1,067 ⟶ 1,182:
=={{header|EasyLang}}==
<syntaxhighlight lang="text">
a$ = "gHHH5YY++///\\"
a$[] = strchars a$
cp$ = a$[
for c$ in a$[]
if c$ <> cp$
s$ &= ", "
cp$ = c$
.
s$ &= c$
.
print s$
</syntaxhighlight>
{{out}}
<pre>
Line 1,084 ⟶ 1,201:
=={{header|Elixir}}==
<
IO.puts " input string: #{str}"
String.graphemes(str)
Line 1,092 ⟶ 1,209:
end
split.("gHHH5YY++///\\")</
{{out}}
Line 1,101 ⟶ 1,218:
=={{header|F_Sharp|F#}}==
<
let splitRuns s = Regex("""(.)\1*""").Matches(s) |> Seq.cast<Match> |> Seq.map (fun m -> m.Value) |> Seq.toList
printfn "%A" (splitRuns """gHHH5YY++///\""")</
{{out}}
<pre>["g"; "HHH"; "5"; "YY"; "++"; "///"; "\"]</pre>
=={{header|Factor}}==
<
"gHHH5YY++///\\"
"aaabbccccdeeff" [ [ = ] monotonic-split ", " join print ] bi@</
{{out}}
<pre>
Line 1,119 ⟶ 1,236:
=={{header|Forth}}==
{{works with|Gforth|0.7.3}}
<
: C@A+ A @ C@ [ 1 CHARS ]L A +! ;
: SPLIT. ( c-addr u --) SWAP A ! A @ C@
Line 1,131 ⟶ 1,248:
s" gHHH5YY++///\" TEST
s" gHHH5 ))YY++,,,///\" TEST
BYE</
{{out}}
<pre>input: gHHH5YY++///\
Line 1,145 ⟶ 1,262:
If the problem were to be solved by writing a "main line" only, there would have to be a declaration of the text variable there but since a subroutine can receive a CHARACTER variable of any size (the actual size is passed as a secret parameter), this can be dodged.
For this example a DO-loop stepping along the text is convenient, but in a larger context it would probably be most useful to work along the text with fingers L1 and L2 marking the start and finish positions of each sequence. <
Can't display the inserted commas in a different colour so as not to look like any commas in TEXT.
CHARACTER*(*) TEXT !The text.
Line 1,165 ⟶ 1,282:
PROGRAM POKE
CALL SPLATTER("gHHH5YY++///\") !The example given.
END</
Unfortunately, the syntax highlighter has failed to notice the terminating quote character, presumably because the preceding backslash might be an "escape sequence" trigger, a facility ''not'' used in Fortran text ''literals'' except possibly as a later modernist option.
Line 1,174 ⟶ 1,291:
=={{header|FreeBASIC}}==
<
if len(instring) < 2 then return instring
dim as string ret = left(instring,1)
Line 1,182 ⟶ 1,299:
next i
return ret
end function</
=={{header|Frink}}==
<syntaxhighlight lang="frink">s = "gHHH5YY++///\\"
println[join[", ", map[getFunction["first", 1], s =~ %r/((.)\2*)/g]]]</syntaxhighlight>
{{out}}
<pre>
g, HHH, 5, YY, ++, ///, \
</pre>
=={{header|FutureBasic}}==
FB can process either Pascal strings (slowly being deprecated), or Apple's Core Foundation CFStrings (and Objective-C NSStrings). Here's the old-school Pascal string function:
<syntaxhighlight lang="text">
local fn SplitString( inputStr as Str255 ) as Str255
Str255 resultStr
NSUInteger i
if len$( inputStr ) < 2 then resultStr = inputStr : exit fn
resultStr = left$( inputStr, 1 )
for i = 2 to len$( inputStr )
if mid$( inputStr, i, 1 ) <> mid$( inputStr, i - 1, 1 ) then resultStr = resultStr + ", "
resultStr = resultStr + mid$(inputStr, i, 1)
next
end fn = resultStr
window 1
print fn SplitString( "gHHH5YY++///\" )
HandleEvents
</syntaxhighlight>
And here's the recommended CFString counterpart:
<syntaxhighlight lang="text">
local fn SplitString( inputStr as CFStringRef ) as CFStringRef
NSUInteger i
unichar chr, lastChr = fn StringCharacterAtIndex( inputStr, 0 )
CFMutableStringRef resultStr = fn MutableStringWithCapacity(0)
for i = 0 to len( inputStr ) - 1
chr = fn StringCharacterAtIndex( inputStr, i )
if ( chr != lastChr ) then MutableStringAppendString( resultStr, @", " )
MutableStringAppendString( resultStr, mid( inputStr, i, 1 ) )
lastChr = chr
next
end fn = resultStr
window 1
print fn SplitString( @"gHHH5YY++///\\" )
HandleEvents
</syntaxhighlight>
'''Output for either function:'''
<pre>
g, HHH, 5, YY, ++, ///, \
</pre>
=={{header|Go}}==
Treating "character" as a byte:
<
import (
Line 1,212 ⟶ 1,384:
}
return b.String()
}</
{{out}}
<pre>
g, HHH, 5, YY, ++, ///, \
</pre>
=={{header|Haskell}}==
<
main :: IO ()
main = putStrLn $ intercalate ", " (group "gHHH5YY++///\\")</
{{Out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
or as a hand-written fold:
<syntaxhighlight lang="haskell">import Data.List (intercalate)
import Data.Bool (bool)
charGroups :: String -> [String]
charGroups =
let go (a, b) (s, groups)
| a == b = (b : s, groups)
| otherwise =
( [a],
bool s [b] (null s) : groups
)
in uncurry (:) . foldr go ([], []) . (zip <*> tail)
main :: IO ()
main =
putStrLn $ intercalate ", " $ charGroups "gHHH5YY++///\\"</syntaxhighlight>
<pre>g, HHH, 5, YY, ++, ///, \</pre>
or in terms of '''span''':
<syntaxhighlight lang="haskell">import Data.List (intercalate)
charGroups :: String -> [String]
charGroups [] = []
charGroups (c : cs) =
let (xs, ys) = span (c ==) cs
in (c : xs) : charGroups ys
main :: IO ()
main =
putStrLn $ intercalate ", " $ charGroups "gHHH5YY++///\\"</syntaxhighlight>
{{Out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
=={{header|IS-BASIC}}==
<
110 PRINT S$(1);
120 FOR I=2 TO LEN(S$)
Line 1,235 ⟶ 1,442:
140 PRINT S$(I);
150 NEXT
160 PRINT</
=={{header|J}}==
'''Solution:'''
<
delimitChars=: ', ' joinstring splitChars</
'''Example Usage:'''
<
g, HHH, 5, YY, ++, ///, \</
=={{header|Java}}==
You can use a regular expression to capture every character preceded by 0 or more of itself.
<syntaxhighlight lang="java">
import java.util.regex.Matcher;
import java.util.regex.Pattern;
</syntaxhighlight>
<syntaxhighlight lang="java">
String split(String string) {
Pattern pattern = Pattern.compile("(.)\\1*");
Matcher matcher = pattern.matcher(string);
StringBuilder strings = new StringBuilder();
int index = 0;
while (matcher.find()) {
if (index++ != 0)
strings.append(", ");
strings.append(matcher.group());
}
return strings.toString();
}
</syntaxhighlight>
<pre>
g, HHH, 5, YY, ++, ///, \
</pre>
<br />
An alternate demonstration
<syntaxhighlight lang="java">package org.rosettacode;
import java.util.ArrayList;
Line 1,311 ⟶ 1,541:
return output.toString();
}
}</
{{Out}}
Line 1,319 ⟶ 1,549:
===ES6===
{{Trans|Haskell}}
<
"use strict";
Line 1,375 ⟶ 1,605:
// MAIN ---
return main();
})();</
{{Out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
Or, in terms of a general `span` function:
<syntaxhighlight lang="javascript">(() => {
"use strict";
// -------- STRING SPLIT ON CHARACTER CHANGES --------
// charGroups :: String -> [String]
const charGroups = s =>
// The characters of s split at each point where
// consecutive characters differ.
0 < s.length ? (() => {
const
c = s[0],
[xs, ys] = span(x => c === x)([
...s.slice(1)
]);
return [
[c, ...xs], ...charGroups(ys)
]
.map(zs => [...zs].join(""));
})() : "";
// ---------------------- TEST -----------------------
// main :: IO()
const main = () =>
charGroups("gHHH5YY++///\\")
.join(", ");
// --------------------- GENERIC ---------------------
// span :: (a -> Bool) -> [a] -> ([a], [a])
const span = p =>
// Longest prefix of xs consisting of elements which
// all satisfy p, tupled with the remainder of xs.
xs => {
const i = xs.findIndex(x => !p(x));
return -1 !== i ? [
xs.slice(0, i),
xs.slice(i)
] : [xs, []];
};
// MAIN ---
return main();
})();</syntaxhighlight>
{{Out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
=={{header|jq}}==
<
# output: a stream of runs
def runs:
Line 1,392 ⟶ 1,675:
end;
"gHHH5YY++///\\" | [runs] | join(", ")</
{{out}}
Using the -r ("raw output") command-line option of jq:
Line 1,401 ⟶ 1,684:
Starting with
<
;'Split a string based on change of character, in Jsish';
Line 1,422 ⟶ 1,705:
;splitOnChange('aaa');
;splitOnChange('aaaba');
;splitOnChange('gH HH5YY++//,/\\');</
Then
Line 1,431 ⟶ 1,714:
Giving
<
;'Split a string based on change of character, in Jsish';
Line 1,464 ⟶ 1,747:
splitOnChange('gH HH5YY++//,/\') ==> g, H, , HH, 5, YY, ++, //, ,, /, \
=!EXPECTEND!=
*/</
Which tests as:
Line 1,482 ⟶ 1,765:
=={{header|Julia}}==
<
using IterTools
str = "gHHH5YY++///\\"
sep = map(join, groupby(identity, str))
println("string: $str\nseparated: ", join(sep, ", "))</
{{out}}
<pre>string: gHHH5YY++///\
separated: g, HHH, 5, YY, ++, ///, \</pre>
=={{header|K}}==
<syntaxhighlight lang="k">split: {(&~=':x)_x}
","/ split "gHHH5YY++///\\"</syntaxhighlight>
{{out}}
<pre>"g,HHH,5,YY,++,///,\\"</pre>
=={{header|Kotlin}}==
<
fun splitOnChange(s: String): String {
Line 1,508 ⟶ 1,798:
val s = """gHHH5YY++///\"""
println(splitOnChange(s))
}</
{{out}}
<pre>
g, HHH, 5, YY, ++, ///, \
</pre>
=== Using fold() ===
<syntaxhighlight lang="kotlin">
fun splitOnChange(src: String): String =
src.fold("") { acc, c ->
if (acc.isEmpty() || acc.last() == c) "$acc$c" else "$acc, $c"
}
fun main() {
splitOnChange("""gHHH5YY++///\""").also { println(it)}
}
</syntaxhighlight>
{{out}}
<pre>
Line 1,516 ⟶ 1,822:
=={{header|Lambdatalk}}==
<
{def mysplit
{def mysplit.r
Line 1,530 ⟶ 1,836:
{mysplit gHHH5YY++///\}
-> g HHH 5 YY ++ /// \
</syntaxhighlight>
=={{header|Lua}}==
Note that the backslash must be quoted as a double backslash as Lua uses C-like escape sequences.
<
local outStr, nextChar = inStr:sub(1, 1)
for pos = 2, #inStr do
Line 1,546 ⟶ 1,852:
end
print(charSplit("gHHH5YY++///\\"))</
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
Line 1,552 ⟶ 1,858:
'''Alternative:'''
Simply scan difference in reverse order and insert delimiter in place, the loop counter i will not update with length of s.
<
for i=#s,2,-1 do
if s:sub(i,i)~=s:sub(i-1,i-1) then
Line 1,559 ⟶ 1,865:
end
return s
end</
=={{header|Ksh}}==
<
#!/bin/ksh
Line 1,597 ⟶ 1,903:
print "Original: ${str}"
print " Split: $(_splitonchg "${str}" "${delim}")"
</syntaxhighlight>
{{out}}<pre>
Original: gHHH5YY++///\
Line 1,605 ⟶ 1,911:
Stack New open a new stack object as current stack, and keep the old one. After the end of block execution old stack get back as current stack. Data statement push to bottom (we read from top, so using data we get a FIFO type). Letter$ pops a string or raise an error if no string found at the top of stack.
<syntaxhighlight lang="m2000 interpreter">
Module PrintParts(splitthis$) {
Def string m$, p$
Line 1,627 ⟶ 1,933:
}
PrintParts "gHHH5YY++///\"
</syntaxhighlight>
=={{header|Maple}}==
Added an additional backlash to escape the \ character at the end.
<
local start,i,len;
start := 1;
Line 1,643 ⟶ 1,949:
printf("%s", str[start..len]);
end proc;
splitChange("gHHH5YY++///\\");</
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
Line 1,649 ⟶ 1,955:
=={{header|Mathematica}}/{{header|Wolfram Language}}==
The backslash (\) must be escaped with another backslash when defining the string.
<
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
=={{header|MiniScript}}==
<
output = []
lastLetter = s[0]
Line 1,662 ⟶ 1,968:
lastLetter = letter
end for
print output.join("")</
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
=={{header|Modula-2}}==
<
FROM Terminal IMPORT Write,WriteString,WriteLn,ReadChar;
Line 1,691 ⟶ 1,997:
ReadChar
END CharacterChange.</
{{out}}
<pre>g
Line 1,702 ⟶ 2,008:
=={{header|Nim}}==
<
result = ""
Line 1,721 ⟶ 2,027:
assert splitOnDiff("""gHHH5YY++///\""") == """g, HHH, 5, YY, ++, ///, \"""
echo splitOnDiff("""gHHH5YY++///\""")</
{{output}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
=={{header|ooRexx}}==
<
If str=='' Then str= 'gHHH5YY++///\' /*Not specified? Then use the default.*/
i=1
Line 1,739 ⟶ 2,045:
i=j
End
Say ol</
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
=={{header|Pascal}}==
<
{$IFDEF FPC}
{$MODE DELPHI}{$COPERATORS ON}
Line 1,774 ⟶ 2,080:
BEGIN
writeln(SplitAtChars(TestString));
end.</
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
=={{header|Perl}}==
<
use warnings;
use feature 'say';
Line 1,793 ⟶ 2,099:
}
say "Orginal: $string\n Split: 「" . join('」, 「', @S) . "」\n";
}</
{{out}}
<pre>Orginal: gHHH5YY++///\
Line 1,802 ⟶ 2,108:
=={{header|Phix}}==
<!--<
<span style="color: #008080;">function</span> <span style="color: #000000;">split_on_change</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
Line 1,820 ⟶ 2,126:
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">split_on_change</span><span style="color: #0000FF;">(</span><span style="color: #008000;">`gHHH5YY++///\`</span><span style="color: #0000FF;">))</span>
<!--</
{{Out}}
<pre>
g, HHH, 5, YY, ++, ///, \
</pre>
=={{header|Phixmonti}}==
<syntaxhighlight lang="Phixmonti">/# Rosetta Code problem: https://rosettacode.org/wiki/Split_a_character_string_based_on_change_of_character
by Galileo, 11/2022 #/
include ..\Utilitys.pmt
""
"gHHH5YY++///\" 1 get >ps
len for get
dup tps == if
rot swap chain swap
else
ps> drop >ps
swap ", " tps chain chain swap
endif
endfor
pstack</syntaxhighlight>
{{out}}
<pre>
["g, HHH, 5, YY, ++, ///, \", "gHHH5YY++///\"]
=== Press any key to exit ===</pre>
=={{header|PicoLisp}}==
<
(let (Str (chop Str) Fin)
(glue
Line 1,836 ⟶ 2,167:
(conc Fin (cons X))
(link (setq Fin (cons X))) ) ) ) ) ) )
(prinl (splitme "gHHH5YY++///\\"))</
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
=={{header|Pike}}==
<syntaxhighlight lang="pike">
string input = "gHHH5YY++///\\"; // \ needs escaping
string last_char;
Line 1,851 ⟶ 2,182:
}
</syntaxhighlight>
{{Out}}
<pre>
Line 1,861 ⟶ 2,192:
After executing the following code, for example:
<
Slap a rider on the string.</
The rider looks like this:
<
Source: "abcdef"
Token: ""</
Now when we <code>Bump the rider.</code>, it looks like this:
<
Source: "bcdef"
Token: "a"</
Another bump, and:
<
Source: "cdef"
Token: "ab"</
Now let's say we have a complete token and want to start a new one. We can
Line 1,883 ⟶ 2,214:
and now the rider looks like this:
<
Source: "cdef"
Token: ""</
And that's all there is to it.
<
Start up.
Split "gHHH5YY++///\" into some string things by change of character.
Line 1,924 ⟶ 2,255:
If the string thing's next is not nil, write ", " on the console without advancing.
Put the string thing's next into the string thing.
Repeat.</
{{out}}
<pre>
Line 1,932 ⟶ 2,263:
=={{header|PowerShell}}==
{{trans|BBC BASIC}}
<syntaxhighlight lang="powershell">
function Split-String ([string]$String)
{
Line 1,953 ⟶ 2,284:
$splitString
}
</syntaxhighlight>
<syntaxhighlight lang="powershell">
Split-String "gHHH5YY++///\"
</syntaxhighlight>
{{Out}}
<pre>
Line 1,963 ⟶ 2,294:
=={{header|PureBasic}}==
<
Define *p.Character = @s$,
c_buf.c = *p\c
Line 1,981 ⟶ 2,312:
splitstring("gHHH5YY++///\")
Input()
EndIf</
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
Line 1,989 ⟶ 2,320:
===Python3.6+===
Using [[https://docs.python.org/3.6/library/itertools.html#itertools.groupby itertools.groupby]].
<
def splitter(text):
Line 1,996 ⟶ 2,327:
if __name__ == '__main__':
txt = 'gHHH5YY++///\\' # Note backslash is the Python escape char.
print(f'Input: {txt}\nSplit: {splitter(txt)}')</
{{out}}
Line 2,003 ⟶ 2,334:
===Python: Using zip===
<
return (''.join(x + ('' if x == nxt else ', ')
for x, nxt in zip(txt, txt[1:] + txt[-1])))
Line 2,009 ⟶ 2,340:
if __name__ == '__main__':
txt = 'gHHH5YY++///\\'
print(splitterz(txt))</
{{out}}
Line 2,015 ⟶ 2,346:
===Python2===
<
try: input = raw_input
Line 2,025 ⟶ 2,356:
groups.append(''.join(g))
print(' input string: %s' % s)
print(' output string: %s' % ', '.join(groups))</
{{out}} when using the default input:
<pre>
Line 2,033 ⟶ 2,364:
=={{header|Quackery}}==
<
iff size done
behead swap
Line 2,048 ⟶ 2,379:
dip [ $ ", " join ]
recurse join ] is runs$ ( $ --> $ )
</syntaxhighlight>
'''Testing in Quackery shell.'''
<pre>/O> $ "gHHH5YY++///\" runs$ echo$
Line 2,058 ⟶ 2,389:
=={{header|Racket}}==
{{trans|Python}}
<
(define (split-strings-on-change s)
(map list->string (group-by values (string->list s) char=?)))
Line 2,066 ⟶ 2,397:
<
)
", "))</
{{out}}
Line 2,075 ⟶ 2,406:
{{works with|Rakudo|2017.05}}
<syntaxhighlight lang="raku"
# Testing:
Line 2,082 ⟶ 2,413:
put 'Original: ', $string;
put ' Split: ', group-chars($string).join(', ');
}</
{{out}}
Line 2,110 ⟶ 2,441:
=={{header|REXX}}==
===version 1===
<
parse arg str /*obtain optional arguments from the CL*/
if str=='' then str= 'gHHH5YY++///\' /*Not specified? Then use the default.*/
Line 2,120 ⟶ 2,451:
end /*j*/ /* [↓] keep peeling chars until done. */
say ' input string: ' str /*display the original string & output.*/
say ' output string: ' $ /*stick a fork in it, we're all done. */</
{{out|output|text= when using the default input:}}
<pre>
Line 2,128 ⟶ 2,459:
===version 2===
<
Parse arg str /*obtain optional arguments from the CL*/
if str=='' then str= 'gHHH5YY++///\' /*Not specified? Then use the default.*/
Line 2,147 ⟶ 2,478:
result=result||x
say ' input string: ' input
say ' output string: ' result </
{{out]]
<pre> input string: gHHH5YY++///\
Line 2,153 ⟶ 2,484:
=={{header|Ring}}==
<
see split("gHHH5YY++///\")
Line 2,168 ⟶ 2,499:
next
return split
</syntaxhighlight>
Output:
<pre>
g, HHH, 5, YY, ++, ///, \
</pre>
=={{header|RPL}}==
≪ → text
≪ "" text 1 1 SUB
1 text SIZE '''FOR''' j
text j DUP SUB
'''IF''' DUP2 ≠ '''THEN''' SWAP DROP ", " OVER + '''END'''
ROT SWAP + SWAP
'''NEXT '''DROP
≫ ≫ ‘<span style="color:blue">COMASPLT</span>’ STO
=={{header|Ruby}}==
<
puts " input string: #{str}"
s = str.chars.chunk(&:itself).map{|_,a| a.join}.join(", ")
Line 2,182 ⟶ 2,523:
end
split("gHHH5YY++///\\")</
{{out}}
Line 2,191 ⟶ 2,532:
=={{header|Rust}}==
<
let chars: Vec<_> = string.chars().collect();
let mut result = Vec::new();
Line 2,224 ⟶ 2,565:
println!("input string: {}", test_string);
println!("output string: {}", splitter(test_string));
}</
{{out}}
Line 2,237 ⟶ 2,578:
===Alternate using IterTools===
<
pub fn split_text(s: &str) -> Vec<String> {
Line 2,257 ⟶ 2,598:
}
}
</syntaxhighlight>
=={{header|Scala}}==
<
// based on a change of character (left to right).
// See https://rosettacode.org/wiki/Split_a_character_string_based_on_change_of_character#Scala
Line 2,267 ⟶ 2,608:
(s + 'X').sliding(2).map(pair => pair.head + (if (pair.head != pair.last) ", " else "")).mkString("")
println(runLengthSplit("""gHHH5YY++///\"""))</
{{Out}}See it in running in your browser by [https://scalafiddle.io/sf/c4dp8GT/2 ScalaFiddle (JavaScript)]
or by [https://scastie.scala-lang.org/mDoBS77YSG2Z7w5xdAPzcw Scastie (JVM)].
<syntaxhighlight lang="scala">
def runLengthSplit(s:String):List[String] = {
def recursiveSplit(acc:List[String], rest:String): List[String] = rest match {
Line 2,286 ⟶ 2,627:
val result = runLengthSplit("""gHHH5YY++///\""")
println(result.mkString(","))
</syntaxhighlight>
{{Out}}
<pre>
Line 2,293 ⟶ 2,634:
=={{header|Sed}}==
<
Output:
g, HHH, 5, YY, ++, ///, \
=={{header|Sidef}}==
<
gather {
while (var match = (str =~ /((.)\g{-1}*)/g)) {
Line 2,306 ⟶ 2,647:
}
say group(ARGV[0] \\ 'gHHH5YY++///\\').join(', ')</
{{out}}
<pre>
g, HHH, 5, YY, ++, ///, \
</pre>
=={{header|SNOBOL4}}==
{{works with|SNOBOL4, SPITBOL for Linux}}
<syntaxhighlight lang="snobol4">
* Program: split_on_change_of_character.sbl
* To run: sbl split_on_change_of_character.sbl
* Description: Split a (character) string into comma (plus a blank)
* delimited strings based on a change of character (left to right).
*
* Blanks should be treated as any other character
* (except they are problematic to display clearly).
* The same applies to commas.
*
* For instance, the string:
*
* gHHH5YY++///\
* should be split and show:
*
* g, HHH, 5, YY, ++, ///, \
* Comment: Tested using the Spitbol for Linux version of SNOBOL4
lf = substr(&alphabet,11,1) ;* New line or line feed
* Function split_cc will split a string on a change of character.
define('split_cc(s)tchar,target,post')
:(split_cc_end)
split_cc
tchar = substr(s,1,1) :f(freturn)
split_cc_pat = span(*tchar) . target (rpos(0) | len(1) . tchar rem) . post
split_cc2
s ? split_cc_pat = post :f(split_cc3)
split_cc = (ident(split_cc) target, split_cc ', ' target) :s(split_cc2)
split_cc3
:(return)
split_cc_end
test_string = "gHHH5YY++///\"
output = test_string lf
split_string = split_cc(test_string)
output = split_string
END</syntaxhighlight>
{{out}}
<pre>
gHHH5YY++///\
g, HHH, 5, YY, ++, ///, \
</pre>
=={{header|Standard ML}}==
<
* Head-Tail implementation of grouping
*)
Line 2,322 ⟶ 2,711:
fun group xs = group' nil xs
fun groupString str = String.concatWith ", " (map implode (group (explode str)))</
{{out}}
Line 2,330 ⟶ 2,719:
=={{header|Swift}}==
<
func splitOnChanges() -> [String] {
guard !isEmpty else {
Line 2,356 ⟶ 2,745:
}
print("gHHH5YY++///\\".splitOnChanges().joined(separator: ", "))</
{{out}}
Line 2,363 ⟶ 2,752:
=={{header|Tailspin}}==
<
composer splitEquals
<reps> <nextReps>*
Line 2,371 ⟶ 2,760:
'gHHH5YY++///\' -> splitEquals -> !OUT::write
</syntaxhighlight>
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
Line 2,377 ⟶ 2,766:
=={{header|tbas}}==
{{Trans|BBC BASIC}}
<
DIM c$, d$, split$, i%
c$ = LEFT$(s$, 1)
Line 2,393 ⟶ 2,782:
PRINT SPLITUNIQUE$("gHHH5YY++///\")
END</
=={{header|Tcl}}==
This is most concise with regular expressions. Note well the two steps: it could be achieved in one very clever regexp, but being that clever is usually a bad idea (for both readability and performance, in this case).
<
regsub -all {(.)\1*} $string {\0, } string
regsub {, $} $string {} string
puts $string</
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
=={{header|Transd}}==
The task doesn't state explicitly about the order in which substrings should be
displayed. So, here are two variants: one is order-preserving, the other is not
order-preserving.
<syntaxhighlight lang="Scheme">#lang transd
MainModule: {
s: "gHHH5YY++///\\",
_start: (λ
(with res ""
(for c in (split s "") do
(if (neq Char(c) (back res)) (+= res ", "))
(+= res c))
(textout res))
(lout "Second variant: ")
(for v in (values (group-by (split s ""))) do
(textout (if @idx ", ") (join v "")))
)
}</syntaxhighlight>
{{out}}
<pre>
g, HHH, 5, YY, ++, ///, \
Second variant:
++, ///, 5, HHH, YY, \, g
</pre>
=={{header|Uiua}}==
{{works with|Uiua|0.11.1}}
<syntaxhighlight lang="uiua">
&p/$"_, _"⊜□+1⊸⊛ "gHHH5YY++///\\"
</syntaxhighlight>
{{out}}
<pre>
g, HHH, 5, YY, ++, ///, \
</pre>
=={{header|VBA}}==
<syntaxhighlight lang="vb">
Option Explicit
Line 2,444 ⟶ 2,871:
Split_Special = R
End Function
</syntaxhighlight>
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
=={{header|V (Vlang)}}==
<syntaxhighlight lang="v (vlang)">fn main() {
println(splitter('gHHH5YY++///\\')) \\ The "\" character needs to be escaped.
}
fn splitter(text string) string {
mut check := text.substr(0, 1)
mut new_text, mut temp := '', ''
for index, _ in text {
temp = text.substr(index, index + 1)
if temp != check {
new_text = new_text + ', '
check = temp
}
new_text = new_text + temp
}
return new_text
}
</syntaxhighlight>
{{out}}
<pre>
g, HHH, 5, YY, ++, ///, \
</pre>
=={{header|Wren}}==
<
if (s.count == 0) return ""
var res = []
Line 2,468 ⟶ 2,920:
var s = "gHHH5YY++///\\"
System.print(split.call(s))</
{{out}}
Line 2,476 ⟶ 2,928:
=={{header|XLISP}}==
<
(defun delim (old-list new-list current-char)
(if (null old-list)
Line 2,487 ⟶ 2,939:
(list->string (delim (string->list s) '() (car (string->list s)))) )
(display (delimit "gHHH5YY++///\\")) ;; NB. The "\" character needs to be escaped</
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
=={{header|XPL0}}==
<
char S;
[S:= "gHHH5YY++///\";
Line 2,500 ⟶ 2,952:
S:= S+1;
];
]</
{{out}}
Line 2,506 ⟶ 2,958:
g, HHH, 5, YY, ++, ///, \
</pre>
=={{header|Yabasic}}==
<syntaxhighlight lang="freebasic">sub esplit$(instring$)
if len(instring$) < 2 return instring$
ret$ = left$(instring$,1)
for i = 2 to len(instring$)
if mid$(instring$,i,1) <> mid$(instring$, i - 1, 1) ret$ = ret$ + ", "
ret$ = ret$ + mid$(instring$, i, 1)
next i
return ret$
end sub
print esplit$("gHHH5YY++///\\")</syntaxhighlight>
=={{header|Z80 Assembly}}==
<
Terminator equ 0 ;marks the end of a string
org &8000
Line 2,550 ⟶ 3,015:
StringA:
byte "gHHH5YY++///\",0</
{{out}}
Line 2,558 ⟶ 3,023:
=={{header|zkl}}==
<
C,out := str[0],Sink(C);
foreach c in (str[1,*]){ out.write(if(c==C) c else String(", ",C=c)) }
out.close();
}
group("gHHH5YY++///\\").println();</
{{out}}
<pre>
Line 2,570 ⟶ 3,035:
=={{header|ZX Spectrum Basic}}==
<
20 LET c$=s$(1)
30 LET n$=c$
Line 2,578 ⟶ 3,043:
70 LET c$=s$(i)
80 NEXT i
90 PRINT n$</
{{out}}
<pre>g, HHH, 5, YY, ++, ///, \</pre>
|