Determine if a string is collapsible: Difference between revisions
m (→{{header|Python}}: Added the missing predicate – foregrounded in the task title, and already forgotten in the listing of tests.) |
m (→{{header|Python}}: Added predicate test output.) |
||
Line 1,347:
if __name__ == '__main__':
main()</lang>
{{Out}}
<pre>[False, True, True, True, True, True, True, True, True, False]</pre>
=={{header|Raku}}==
|
Revision as of 18:32, 9 June 2020
You are encouraged to solve this task according to the task description, using any language you may know.
Determine if a character string is collapsible.
And if so, collapse the string (by removing immediately repeated characters).
If a character string has immediately repeated character(s), the repeated characters are to be deleted (removed), but not the primary (1st) character(s).
An immediately repeated character is any character that is immediately followed by an
identical character (or characters). Another word choice could've been duplicated character, but that
might have ruled out (to some readers) triplicated characters ··· or more.
{This Rosetta Code task was inspired by a newly introduced (as of around November 2019) PL/I BIF: collapse.}
- Examples
In the following character string:
The better the 4-wheel drive, the further you'll be from help when ya get stuck!
Only the 2nd t, e, and l are repeated characters, indicated
by underscores (above), even though they (those characters) appear elsewhere in the character string.
So, after collapsing the string, the result would be:
The beter the 4-whel drive, the further you'l be from help when ya get stuck!
Another example:
In the following character string:
headmistressship
The "collapsed" string would be:
headmistreship
- Task
Write a subroutine/function/procedure/routine··· to locate repeated characters and collapse (delete) them from the character string. The character string can be processed from either direction.
Show all output here, on this page:
- the original string and its length
- the resultant string and its length
- the above strings should be "bracketed" with <<< and >>> (to delineate blanks)
- «««Guillemets may be used instead for "bracketing" for the more artistic programmers, shown used here»»»
Use (at least) the following five strings, all strings are length seventy-two (characters, including blanks), except the 1st string:
string number ╔╗ 1 ║╚═══════════════════════════════════════════════════════════════════════╗ ◄■■■■■■ a null string (length zero) 2 ║"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln ║ 3 ║..1111111111111111111111111111111111111111111111111111111111111117777888║ 4 ║I never give 'em hell, I just tell the truth, and they think it's hell. ║ 5 ║ --- Harry S Truman ║ ◄■■■■■■ has many repeated blanks ╚════════════════════════════════════════════════════════════════════════╝
- Related tasks
Ada
<lang Ada>with Ada.Text_IO; use Ada.Text_IO; procedure Test_Collapsible is
procedure Collapse (S : in String) is Res : String (1 .. S'Length); Len : Natural := 0; begin Put_Line ("Input = <<<" & S & ">>>, length =" & S'Length'Image); for I in S'Range loop if Len = 0 or else S(I) /= Res(Len) then Len := Len + 1; Res(Len) := S(I); end if; end loop; Put_Line ("Output = <<<" & Res (1 .. Len) & ">>>, length =" & Len'Image); end Collapse;
begin
Collapse (""); Collapse ("""If I were two-faced, would I be wearing this one?"" --- Abraham Lincoln "); Collapse ("..1111111111111111111111111111111111111111111111111111111111111117777888"); Collapse ("I never give 'em hell, I just tell the truth, and they think it's hell. "); Collapse (" --- Harry S Truman ");
end Test_Collapsible; </lang>
- Output:
Input = <<<>>>, length = 0 Output = <<<>>>, length = 0 Input = <<<"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln >>>, length = 72 Output = <<<"If I were two-faced, would I be wearing this one?" - Abraham Lincoln >>>, length = 70 Input = <<<..1111111111111111111111111111111111111111111111111111111111111117777888>>>, length = 72 Output = <<<.178>>>, length = 4 Input = <<<I never give 'em hell, I just tell the truth, and they think it's hell. >>>, length = 72 Output = <<<I never give 'em hel, I just tel the truth, and they think it's hel. >>>, length = 69 Input = <<< --- Harry S Truman >>>, length = 72 Output = <<< - Hary S Truman >>>, length = 17
AWK
<lang AWK>
- syntax: GAWK -f DETERMINE_IF_A_STRING_IS_COLLAPSIBLE.AWK
BEGIN {
for (i=1; i<=9; i++) { for (j=1; j<=i; j++) { arr[0] = arr[0] i } } arr[++n] = "" arr[++n] = "\"If I were two-faced, would I be wearing this one?\" --- Abraham Lincoln " arr[++n] = "..1111111111111111111111111111111111111111111111111111111111111117777888" arr[++n] = "I never give 'em hell, I just tell the truth, and they think it's hell. " arr[++n] = " --- Harry S Truman " arr[++n] = "The better the 4-wheel drive, the further you'll be from help when ya get stuck!" arr[++n] = "headmistressship" for (i=0; i<=n; i++) { main(arr[i]) } exit(0)
} function main(str, c,i,new_str,prev_c) {
for (i=1; i<=length(str); i++) { c = substr(str,i,1) if (prev_c != c) { prev_c = c new_str = new_str c } } printf("old: %2d <<<%s>>>\n",length(str),str) printf("new: %2d <<<%s>>>\n\n",length(new_str),new_str)
} </lang>
- Output:
old: 45 <<<122333444455555666666777777788888888999999999>>> new: 9 <<<123456789>>> old: 0 <<<>>> new: 0 <<<>>> old: 72 <<<"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln >>> new: 70 <<<"If I were two-faced, would I be wearing this one?" - Abraham Lincoln >>> old: 72 <<<..1111111111111111111111111111111111111111111111111111111111111117777888>>> new: 4 <<<.178>>> old: 72 <<<I never give 'em hell, I just tell the truth, and they think it's hell. >>> new: 69 <<<I never give 'em hel, I just tel the truth, and they think it's hel. >>> old: 72 <<< --- Harry S Truman >>> new: 17 <<< - Hary S Truman >>> old: 80 <<<The better the 4-wheel drive, the further you'll be from help when ya get stuck!>>> new: 77 <<<The beter the 4-whel drive, the further you'l be from help when ya get stuck!>>> old: 16 <<<headmistressship>>> new: 14 <<<headmistreship>>>
C
Identical implementation as in Determine_if_a_string_is_squeezable, as both tasks are very similar. The Lincoln quote contains backslashes to accommodate the double quotes via the command line. strcmpi is not part of the C Standard Library, thus comment out the definition in the code if testing on a system where it is already included.
<lang C>
- include<string.h>
- include<stdlib.h>
- include<stdio.h>
- define COLLAPSE 0
- define SQUEEZE 1
typedef struct charList{
char c; struct charList *next;
} charList;
/* Implementing strcmpi, the case insensitive string comparator, as it is not part of the C Standard Library.
Comment this out if testing on a compiler where it is already defined.
- /
int strcmpi(char* str1,char* str2){
int len1 = strlen(str1), len2 = strlen(str2), i;
if(len1!=len2){ return 1; }
else{ for(i=0;i<len1;i++){ if((str1[i]>='A'&&str1[i]<='Z')&&(str2[i]>='a'&&str2[i]<='z')&&(str2[i]-65!=str1[i])) return 1; else if((str2[i]>='A'&&str2[i]<='Z')&&(str1[i]>='a'&&str1[i]<='z')&&(str1[i]-65!=str2[i])) return 1; else if(str1[i]!=str2[i]) return 1; } }
return 0;
}
charList *strToCharList(char* str){
int len = strlen(str),i;
charList *list, *iterator, *nextChar;
list = (charList*)malloc(sizeof(charList)); list->c = str[0]; list->next = NULL;
iterator = list;
for(i=1;i<len;i++){ nextChar = (charList*)malloc(sizeof(charList)); nextChar->c = str[i]; nextChar->next = NULL;
iterator->next = nextChar; iterator = nextChar; }
return list;
}
char* charListToString(charList* list){
charList* iterator = list; int count = 0,i; char* str;
while(iterator!=NULL){ count++; iterator = iterator->next; }
str = (char*)malloc((count+1)*sizeof(char)); iterator = list;
for(i=0;i<count;i++){ str[i] = iterator->c; iterator = iterator->next; }
free(list); str[i] = '\0';
return str;
}
char* processString(char str[100],int operation, char squeezeChar){
charList *strList = strToCharList(str),*iterator = strList, *scout;
if(operation==SQUEEZE){ while(iterator!=NULL){ if(iterator->c==squeezeChar){ scout = iterator->next;
while(scout!=NULL && scout->c==squeezeChar){ iterator->next = scout->next; scout->next = NULL; free(scout); scout = iterator->next; } } iterator = iterator->next; } }
else{ while(iterator!=NULL && iterator->next!=NULL){ if(iterator->c == (iterator->next)->c){ scout = iterator->next; squeezeChar = iterator->c;
while(scout!=NULL && scout->c==squeezeChar){ iterator->next = scout->next; scout->next = NULL; free(scout); scout = iterator->next; } } iterator = iterator->next; } }
return charListToString(strList);
}
void printResults(char originalString[100], char finalString[100], int operation, char squeezeChar){
if(operation==SQUEEZE){ printf("Specified Operation : SQUEEZE\nTarget Character : %c",squeezeChar); }
else printf("Specified Operation : COLLAPSE");
printf("\nOriginal %c%c%c%s%c%c%c\nLength : %d",174,174,174,originalString,175,175,175,(int)strlen(originalString)); printf("\nFinal %c%c%c%s%c%c%c\nLength : %d\n",174,174,174,finalString,175,175,175,(int)strlen(finalString));
}
int main(int argc, char** argv){
int operation; char squeezeChar;
if(argc<3||argc>4){ printf("Usage : %s <SQUEEZE|COLLAPSE> <String to be processed> <Character to be squeezed, if operation is SQUEEZE>\n",argv[0]); return 0; }
if(strcmpi(argv[1],"SQUEEZE")==0 && argc!=4){ scanf("Please enter characted to be squeezed : %c",&squeezeChar); operation = SQUEEZE; }
else if(argc==4){ operation = SQUEEZE; squeezeChar = argv[3][0]; }
else if(strcmpi(argv[1],"COLLAPSE")==0){ operation = COLLAPSE; }
if(strlen(argv[2])<2){ printResults(argv[2],argv[2],operation,squeezeChar); }
else{ printResults(argv[2],processString(argv[2],operation,squeezeChar),operation,squeezeChar); } return 0;
} </lang> Output :
C:\My Projects\networks>a collapse "The better the 4-wheel drive, the further you'll be from help when ya get stuck!" Specified Operation : COLLAPSE Original «««The better the 4-wheel drive, the further you'll be from help when ya get stuck!»»» Length : 80 Final «««The beter the 4-whel drive, the further you'l be from help when ya get stuck!»»» Length : 77 C:\My Projects\networks>a collapse headmistressship Specified Operation : COLLAPSE Original «««headmistressship»»» Length : 16 Final «««headmistreship»»» Length : 14 C:\My Projects\networks>a collapse "" Specified Operation : COLLAPSE Original «««»»» Length : 0 Final «««»»» Length : 0 C:\My Projects\networks>a collapse "\"If I were two-faced, would I be wearing this one?\" --- Abraham Lincoln" Specified Operation : COLLAPSE Original «««"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln»»» Length : 71 Final «««"If I were two-faced, would I be wearing this one?" - Abraham Lincoln»»» Length : 69 C:\My Projects\networks>a collapse ..1111111111111111111111111111111111111111111111111111111111111117777888 Specified Operation : COLLAPSE Original «««..1111111111111111111111111111111111111111111111111111111111111117777888»»» Length : 72 Final «««.178»»» Length : 4 C:\My Projects\networks>a collapse "I never give 'em hell, I just tell the truth, and they think it's hell." Specified Operation : COLLAPSE Original «««I never give 'em hell, I just tell the truth, and they think it's hell.»»» Length : 71 Final «««I never give 'em hel, I just tel the truth, and they think it's hel.»»» Length : 68 C:\My Projects\networks>a collapse " --- Harry S Truman" Specified Operation : COLLAPSE Original ««« --- Harry S Truman»»» Length : 70 Final ««« - Hary S Truman»»» Length : 16
C#
<lang csharp>using System; using static System.Linq.Enumerable;
public class Program {
static void Main() { string[] input = { "", "The better the 4-wheel drive, the further you'll be from help when ya get stuck!", "headmistressship", "\"If I were two-faced, would I be wearing this one?\" --- Abraham Lincoln ", "..1111111111111111111111111111111111111111111111111111111111111117777888", "I never give 'em hell, I just tell the truth, and they think it's hell. ", " --- Harry S Truman " }; foreach (string s in input) { Console.WriteLine($"old: {s.Length} «««{s}»»»"); string c = Collapse(s); Console.WriteLine($"new: {c.Length} «««{c}»»»"); } }
static string Collapse(string s) => string.IsNullOrEmpty(s) ? "" : s[0] + new string(Range(1, s.Length - 1).Where(i => s[i] != s[i - 1]).Select(i => s[i]).ToArray());
}</lang>
- Output:
old: 0 «««»»» new: 0 «««»»» old: 80 «««The better the 4-wheel drive, the further you'll be from help when ya get stuck!»»» new: 77 «««The beter the 4-whel drive, the further you'l be from help when ya get stuck!»»» old: 16 «««headmistressship»»» new: 14 «««headmistreship»»» old: 72 «««"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln »»» new: 70 «««"If I were two-faced, would I be wearing this one?" - Abraham Lincoln »»» old: 72 «««..1111111111111111111111111111111111111111111111111111111111111117777888»»» new: 4 «««.178»»» old: 72 «««I never give 'em hell, I just tell the truth, and they think it's hell. »»» new: 69 «««I never give 'em hel, I just tel the truth, and they think it's hel. »»» old: 72 ««« --- Harry S Truman »»» new: 17 ««« - Hary S Truman »»»
C++
The solution is a straightforward application of the standard library function "unique". <lang cpp>#include <string>
- include <iostream>
- include <algorithm>
template<typename char_type> std::basic_string<char_type> collapse(std::basic_string<char_type> str) {
auto i = std::unique(str.begin(), str.end()); str.erase(i, str.end()); return str;
}
void test(const std::string& str) {
std::cout << "original string: <<<" << str << ">>>, length = " << str.length() << '\n'; std::string collapsed(collapse(str)); std::cout << "result string: <<<" << collapsed << ">>>, length = " << collapsed.length() << '\n'; std::cout << '\n';
}
int main(int argc, char** argv) {
test(""); test("\"If I were two-faced, would I be wearing this one?\" --- Abraham Lincoln "); test("..1111111111111111111111111111111111111111111111111111111111111117777888"); test("I never give 'em hell, I just tell the truth, and they think it's hell. "); test(" --- Harry S Truman "); return 0;
}</lang>
- Output:
original string: <<<>>>, length = 0 result string: <<<>>>, length = 0 original string: <<<"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln >>>, length = 72 result string: <<<"If I were two-faced, would I be wearing this one?" - Abraham Lincoln >>>, length = 70 original string: <<<..1111111111111111111111111111111111111111111111111111111111111117777888>>>, length = 72 result string: <<<.178>>>, length = 4 original string: <<<I never give 'em hell, I just tell the truth, and they think it's hell. >>>, length = 72 result string: <<<I never give 'em hel, I just tel the truth, and they think it's hel. >>>, length = 69 original string: <<< --- Harry S Truman >>>, length = 72 result string: <<< - Hary S Truman >>>, length = 17
Clojure
<lang Clojure> (defn collapse [s]
(let [runs (partition-by identity s)] (apply str (map first runs))))
(defn run-test [s]
(let [out (collapse s)] (str (format "Input: <<<%s>>> (len %d)\n" s (count s)) (format "becomes: <<<%s>>> (len %d)\n" out (count out)))))
</lang>
- Output:
Input: <<<>>> (len 0) becomes: <<<>>> (len 0) Input: <<<"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln >>> (len 72) becomes: <<<"If I were two-faced, would I be wearing this one?" - Abraham Lincoln >>> (len 70) Input: <<<..1111111111111111111111111111111111111111111111111111111111111117777888>>> (len 72) becomes: <<<.178>>> (len 4) Input: <<<I never give 'em hell, I just tell the truth, and they think it's hell. >>> (len 72) becomes: <<<I never give 'em hel, I just tel the truth, and they think it's hel. >>> (len 69) Input: <<< --- Harry S Truman >>> (len 72) becomes: <<< - Hary S Truman >>> (len 17)
D
<lang d>import std.stdio;
void collapsible(string s) {
writeln("old: <<<", s, ">>>, length = ", s.length);
write("new: <<<"); char last = '\0'; int len = 0; foreach (c; s) { if (c != last) { write(c); len++; } last = c; } writeln(">>>, length = ", len);
writeln;
}
void main() {
collapsible(``); collapsible(`"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln `); collapsible(`..1111111111111111111111111111111111111111111111111111111111111117777888`); collapsible(`I never give 'em hell, I just tell the truth, and they think it's hell. `); collapsible(` --- Harry S Truman `);
}</lang>
- Output:
old: <<<>>>, length = 0 new: <<<>>>, length = 0 old: <<<"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln >>>, length = 72 new: <<<"If I were two-faced, would I be wearing this one?" - Abraham Lincoln >>>, length = 70 old: <<<..1111111111111111111111111111111111111111111111111111111111111117777888>>>, length = 72 new: <<<.178>>>, length = 4 old: <<<I never give 'em hell, I just tell the truth, and they think it's hell. >>>, length = 72 new: <<<I never give 'em hel, I just tel the truth, and they think it's hel. >>>, length = 69 old: <<< --- Harry S Truman >>>, length = 72 new: <<< - Hary S Truman >>>, length = 17
F#
<lang fsharp> // Collapse a String. Nigel Galloway: June 9th., 2020 let collapse n=if String.length n=0 then None else
let fN=let mutable g=n.[0] in (fun n->if n=g then false else g<-n; true) let fG=n.[0..0]+System.String(n.[1..].ToCharArray()|>Array.filter fN) if fG.Length=n.Length then None else Some fG
let isCollapsible n=match colapse n with
Some g->printfn "<<<%s>>> (length %d) collapses to <<<%s>>> (length %d)" n n.Length g g.Length |_->printfn "<<<%s>>> (length %d) does not collapse" n n.Length
isCollapsible "" isCollapsible "\"If I were two-faced, would I be wearing this one?\" --- Abraham Lincoln " isCollapsible "..1111111111111111111111111111111111111111111111111111111111111117777888" isCollapsible "I never give 'em hell, I just tell the truth, and they think it's hell. " isCollapsible " --- Harry S Truman " isCollapsible "withoutConsecutivelyRepeatedCharacters" </lang>
- Output:
<<<>>> (length 0) does not colapse <<<"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln >>> (length 72) collapses to <<<"If I were two-faced, would I be wearing this one?" - Abraham Lincoln >>> (length 70) <<<..1111111111111111111111111111111111111111111111111111111111111117777888>>> (length 72) collapses to <<<.178>>> (length 4) <<<I never give 'em hell, I just tell the truth, and they think it's hell. >>> (length 72) collapses to <<<I never give 'em hel, I just tel the truth, and they think it's hel. >>> (length 69) <<< --- Harry S Truman >>> (length 72) collapses to <<< - Hary S Truman >>> (length 17) <<<withoutConsecutivelyRepeatedCharacters>>> (length 38) does not collapse
Factor
<lang factor>USING: formatting io kernel sbufs sequences strings ; IN: rosetta-code.string-collapse
- (collapse) ( str -- str )
unclip-slice 1string >sbuf [ over last over = [ drop ] [ suffix! ] if ] reduce >string ;
- collapse ( str -- str ) [ "" ] [ (collapse) ] if-empty ;
- .str ( str -- ) dup length "«««%s»»» (length %d)\n" printf ;
- show-collapse ( str -- )
[ "Before collapse: " write .str ] [ "After collapse: " write collapse .str ] bi nl ;
- collapse-demo ( -- )
{ "" "\"If I were two-faced, would I be wearing this one?\" --- Abraham Lincoln " "..1111111111111111111111111111111111111111111111111111111111111117777888" "I never give 'em hell, I just tell the truth, and they think it's hell. " " --- Harry S Truman " "The better the 4-wheel drive, the further you'll be from help when ya get stuck!" "headmistressship" "aardvark" "😍😀🙌💃😍😍😍🙌" } [ show-collapse ] each ;
MAIN: collapse-demo</lang>
- Output:
(Using some extra test cases from the Go entry.)
Before collapse: «««»»» (length 0) After collapse: «««»»» (length 0) Before collapse: «««"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln »»» (length 72) After collapse: «««"If I were two-faced, would I be wearing this one?" - Abraham Lincoln »»» (length 70) Before collapse: «««..1111111111111111111111111111111111111111111111111111111111111117777888»»» (length 72) After collapse: «««.178»»» (length 4) Before collapse: «««I never give 'em hell, I just tell the truth, and they think it's hell. »»» (length 72) After collapse: «««I never give 'em hel, I just tel the truth, and they think it's hel. »»» (length 69) Before collapse: ««« --- Harry S Truman »»» (length 72) After collapse: ««« - Hary S Truman »»» (length 17) Before collapse: «««The better the 4-wheel drive, the further you'll be from help when ya get stuck!»»» (length 80) After collapse: «««The beter the 4-whel drive, the further you'l be from help when ya get stuck!»»» (length 77) Before collapse: «««headmistressship»»» (length 16) After collapse: «««headmistreship»»» (length 14) Before collapse: «««aardvark»»» (length 8) After collapse: «««ardvark»»» (length 7) Before collapse: «««😍😀🙌💃😍😍😍🙌»»» (length 8) After collapse: «««😍😀🙌💃😍🙌»»» (length 6)
Go
<lang go>package main
import "fmt"
// Returns collapsed string, original and new lengths in // unicode code points (not normalized). func collapse(s string) (string, int, int) {
r := []rune(s) le, del := len(r), 0 for i := le - 2; i >= 0; i-- { if r[i] == r[i+1] { copy(r[i:], r[i+1:]) del++ } } if del == 0 { return s, le, le } r = r[:le-del] return string(r), le, len(r)
}
func main() {
strings:= []string { "", `"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln `, "..1111111111111111111111111111111111111111111111111111111111111117777888", "I never give 'em hell, I just tell the truth, and they think it's hell. ", " --- Harry S Truman ", "The better the 4-wheel drive, the further you'll be from help when ya get stuck!", "headmistressship", "aardvark", "😍😀🙌💃😍😍😍🙌", } for _, s := range strings { cs, olen, clen := collapse(s) fmt.Printf("original : length = %2d, string = «««%s»»»\n", olen, s) fmt.Printf("collapsed: length = %2d, string = «««%s»»»\n\n", clen, cs) }
}</lang>
- Output:
original : length = 0, string = «««»»» collapsed: length = 0, string = «««»»» original : length = 72, string = «««"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln »»» collapsed: length = 70, string = «««"If I were two-faced, would I be wearing this one?" - Abraham Lincoln »»» original : length = 72, string = «««..1111111111111111111111111111111111111111111111111111111111111117777888»»» collapsed: length = 4, string = «««.178»»» original : length = 72, string = «««I never give 'em hell, I just tell the truth, and they think it's hell. »»» collapsed: length = 69, string = «««I never give 'em hel, I just tel the truth, and they think it's hel. »»» original : length = 72, string = ««« --- Harry S Truman »»» collapsed: length = 17, string = ««« - Hary S Truman »»» original : length = 80, string = «««The better the 4-wheel drive, the further you'll be from help when ya get stuck!»»» collapsed: length = 77, string = «««The beter the 4-whel drive, the further you'l be from help when ya get stuck!»»» original : length = 16, string = «««headmistressship»»» collapsed: length = 14, string = «««headmistreship»»» original : length = 8, string = «««aardvark»»» collapsed: length = 7, string = «««ardvark»»» original : length = 8, string = «««😍😀🙌💃😍😍😍🙌»»» collapsed: length = 6, string = «««😍😀🙌💃😍🙌»»»
Haskell
<lang haskell>import Text.Printf (printf) import Data.Maybe (catMaybes) import Control.Monad (guard)
input :: [String] input = [ ""
, "The better the 4-wheel drive, the further you'll be from help when ya get stuck!" , "headmistressship" , "\"If I were two-faced, would I be wearing this one?\" --- Abraham Lincoln " , "..1111111111111111111111111111111111111111111111111111111111111117777888" , "I never give 'em hell, I just tell the truth, and they think it's hell. " , " --- Harry S Truman " , "😍😀🙌💃😍😍😍🙌" ]
collapse :: Eq a => [a] -> [a] collapse = catMaybes . (\xs -> zipWith (\a b -> guard (a /= b) >> a) (Nothing : xs) (xs <> [Nothing])) . map Just
main :: IO () main =
mapM_ (\(a, b) -> printf "old: %3d «««%s»»»\nnew: %3d «««%s»»»\n\n" (length a) a (length b) b) $ ((,) <*> collapse) <$> input</lang>
- Output:
old: 0 «««»»» new: 0 «««»»» old: 80 «««The better the 4-wheel drive, the further you'll be from help when ya get stuck!»»» new: 77 «««The beter the 4-whel drive, the further you'l be from help when ya get stuck!»»» old: 16 «««headmistressship»»» new: 14 «««headmistreship»»» old: 72 «««"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln »»» new: 70 «««"If I were two-faced, would I be wearing this one?" - Abraham Lincoln »»» old: 72 «««..1111111111111111111111111111111111111111111111111111111111111117777888»»» new: 4 «««.178»»» old: 72 «««I never give 'em hell, I just tell the truth, and they think it's hell. »»» new: 69 «««I never give 'em hel, I just tel the truth, and they think it's hel. »»» old: 72 ««« --- Harry S Truman »»» new: 17 ««« - Hary S Truman »»» old: 8 «««😍😀🙌💃😍😍😍🙌»»» new: 6 «««😍😀🙌💃😍🙌»»»
Note that we can also directly define a predicate, and a rewrite, in terms of Data.List group,
<lang haskell>import Data.List (group)
isCollapsible :: String -> Bool isCollapsible = any ((1 <) . length) . group
collapsed :: String -> String collapsed = map head . group</lang>
or, without imports, in terms of pattern matching:
<lang haskell>isCollapsible :: String -> Bool isCollapsible [] = False isCollapsible [_] = False isCollapsible (h:t@(x:_)) = h == x || isCollapsible t
collapsed :: String -> String collapsed [] = [] collapsed [x] = [x] collapsed (h:t@(x:_))
| h == x = collapsed t | otherwise = h : collapsed t</lang>
J
STRINGS =: <;._2]0 :0 "If I were two-faced, would I be wearing this one?" --- Abraham Lincoln ..1111111111111111111111111111111111111111111111111111111111111117777888 I never give 'em hell, I just tell the truth, and they think it's hell. --- Harry S Truman ) collapse =: (#~ (1 , 2 ~:/\ ])) ::(''"_) NB. copy dissimilar neighbors assert 1 2 3 2 3 1 2 1 -: collapse 1 2 3 2 2 2 2 3 1 1 2 2 1 NB. test task =: ,&(<@:(;~ (_6 + #)))&('<<<' , '>>>' ,~ ]) collapse NB. assemble the output task&> STRINGS NB. operate on the data +-----------------------------------------------------------------------------------+---------------------------------------------------------------------------------+ |+-+------+ |+-+------+ | ||0|<<<>>>| ||0|<<<>>>| | |+-+------+ |+-+------+ | +-----------------------------------------------------------------------------------+---------------------------------------------------------------------------------+ |+--+------------------------------------------------------------------------------+|+--+----------------------------------------------------------------------------+| ||72|<<<"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln >>>|||70|<<<"If I were two-faced, would I be wearing this one?" - Abraham Lincoln >>>|| |+--+------------------------------------------------------------------------------+|+--+----------------------------------------------------------------------------+| +-----------------------------------------------------------------------------------+---------------------------------------------------------------------------------+ |+--+------------------------------------------------------------------------------+|+-+----------+ | ||72|<<<..1111111111111111111111111111111111111111111111111111111111111117777888>>>|||4|<<<.178>>>| | |+--+------------------------------------------------------------------------------+|+-+----------+ | +-----------------------------------------------------------------------------------+---------------------------------------------------------------------------------+ |+--+------------------------------------------------------------------------------+|+--+---------------------------------------------------------------------------+ | ||72|<<<I never give 'em hell, I just tell the truth, and they think it's hell. >>>|||69|<<<I never give 'em hel, I just tel the truth, and they think it's hel. >>>| | |+--+------------------------------------------------------------------------------+|+--+---------------------------------------------------------------------------+ | +-----------------------------------------------------------------------------------+---------------------------------------------------------------------------------+ |+--+------------------------------------------------------------------------------+|+--+-----------------------+ | ||72|<<< --- Harry S Truman >>>|||17|<<< - Hary S Truman >>>| | |+--+------------------------------------------------------------------------------+|+--+-----------------------+ | +-----------------------------------------------------------------------------------+---------------------------------------------------------------------------------+
Java
<lang java> // Title: Determine if a string is collapsible
public class StringCollapsible {
public static void main(String[] args) { for ( String s : new String[] { "", "\"If I were two-faced, would I be wearing this one?\" --- Abraham Lincoln ", "..1111111111111111111111111111111111111111111111111111111111111117777888", "I never give 'em hell, I just tell the truth, and they think it's hell. ", " --- Harry S Truman ", "122333444455555666666777777788888888999999999", "The better the 4-wheel drive, the further you'll be from help when ya get stuck!", "headmistressship"}) { String result = collapse(s); System.out.printf("old: %2d <<<%s>>>%nnew: %2d <<<%s>>>%n%n", s.length(), s, result.length(), result); } } private static String collapse(String in) { StringBuilder sb = new StringBuilder(); for ( int i = 0 ; i < in.length() ; i++ ) { if ( i == 0 || in.charAt(i-1) != in.charAt(i) ) { sb.append(in.charAt(i)); } } return sb.toString(); }
} </lang>
- Output:
old: 0 <<<>>> new: 0 <<<>>> old: 72 <<<"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln >>> new: 70 <<<"If I were two-faced, would I be wearing this one?" - Abraham Lincoln >>> old: 72 <<<..1111111111111111111111111111111111111111111111111111111111111117777888>>> new: 4 <<<.178>>> old: 72 <<<I never give 'em hell, I just tell the truth, and they think it's hell. >>> new: 69 <<<I never give 'em hel, I just tel the truth, and they think it's hel. >>> old: 72 <<< --- Harry S Truman >>> new: 17 <<< - Hary S Truman >>> old: 45 <<<122333444455555666666777777788888888999999999>>> new: 9 <<<123456789>>> old: 80 <<<The better the 4-wheel drive, the further you'll be from help when ya get stuck!>>> new: 77 <<<The beter the 4-whel drive, the further you'l be from help when ya get stuck!>>> old: 16 <<<headmistressship>>> new: 14 <<<headmistreship>>>
Julia
<lang julia>const teststrings = [
"", """"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln """, "..1111111111111111111111111111111111111111111111111111111111111117777888", """I never give 'em hell, I just tell the truth, and they think it's hell. """, " --- Harry S Truman "]
function collapse(s)
len = length(s) if len < 2 return s, len, s, len end result = last = s[1] for c in s[2:end] if c != last last = c result *= c end end return s, len, result, length(result)
end
function testcollapse(arr)
for s in arr (s1, len1, s2, len2) = collapse(s) println("«««$s1»»» (length $len1)\n collapses to:\n«««$s2»»» (length $len2).\n") end
end
testcollapse(teststrings)
</lang>
- Output:
«««»»» (length 0) collapses to: «««»»» (length 0). «««"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln »»» (length 72) collapses to: «««"If I were two-faced, would I be wearing this one?" - Abraham Lincoln »»» (length 70). «««..1111111111111111111111111111111111111111111111111111111111111117777888»»» (length 72) collapses to: «««.178»»» (length 4). «««I never give 'em hell, I just tell the truth, and they think it's hell. »»» (length 72) collapses to: «««I never give 'em hel, I just tel the truth, and they think it's hel. »»» (length 69). ««« --- Harry S Truman »»» (length 72) collapses to: ««« - Hary S Truman »»» (length 17).
Condensed version:
<lang julia>const teststrings = [
"", """"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln """, "..1111111111111111111111111111111111111111111111111111111111111117777888", """I never give 'em hell, I just tell the truth, and they think it's hell. """, " --- Harry S Truman "]
collapse(s) = (t = isempty(s) ? "" : s[1:1]; for c in s if c != t[end] t *= c end; end; t)
for s in teststrings
n, t = length(s), collapse(s) println("«««$s»»» (length $n)\n collapses to:\n«««$t»»» (length $(length(t))).\n")
end </lang>
Kotlin
<lang scala>fun collapse(s: String): String {
val cs = StringBuilder() var last: Char = 0.toChar() for (c in s) { if (c != last) { cs.append(c) last = c } } return cs.toString()
}
fun main() {
val strings = arrayOf( "", "\"If I were two-faced, would I be wearing this one?\" --- Abraham Lincoln ", "..1111111111111111111111111111111111111111111111111111111111111117777888", "I never give 'em hell, I just tell the truth, and they think it's hell. ", " --- Harry S Truman ", "The better the 4-wheel drive, the further you'll be from help when ya get stuck!", "headmistressship", "aardvark" ) for (s in strings) { val c = collapse(s) println("original : length = ${s.length}, string = «««$s»»»") println("collapsed : length = ${c.length}, string = «««$c»»»") println() }
}</lang>
- Output:
original : length = 0, string = «««»»» collapsed : length = 0, string = «««»»» original : length = 72, string = «««"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln »»» collapsed : length = 70, string = «««"If I were two-faced, would I be wearing this one?" - Abraham Lincoln »»» original : length = 72, string = «««..1111111111111111111111111111111111111111111111111111111111111117777888»»» collapsed : length = 4, string = «««.178»»» original : length = 72, string = «««I never give 'em hell, I just tell the truth, and they think it's hell. »»» collapsed : length = 69, string = «««I never give 'em hel, I just tel the truth, and they think it's hel. »»» original : length = 72, string = ««« --- Harry S Truman »»» collapsed : length = 17, string = ««« - Hary S Truman »»» original : length = 80, string = «««The better the 4-wheel drive, the further you'll be from help when ya get stuck!»»» collapsed : length = 77, string = «««The beter the 4-whel drive, the further you'l be from help when ya get stuck!»»» original : length = 16, string = «««headmistressship»»» collapsed : length = 14, string = «««headmistreship»»» original : length = 8, string = «««aardvark»»» collapsed : length = 7, string = «««ardvark»»»
Perl
<lang perl>use strict; use warnings; use utf8; binmode STDOUT, ":utf8";
my @lines = split "\n", <<~'STRINGS';
"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln ..1111111111111111111111111111111111111111111111111111111111111117777888 I never give 'em hell, I just tell the truth, and they think it's hell. --- Harry S Truman The American people have a right to know if their president is a crook. --- Richard Nixon AАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA STRINGS
for (@lines) {
my $squish = s/(.)\1+/$1/gr; printf "\nLength: %2d <<<%s>>>\nCollapsible: %s\nLength: %2d <<<%s>>>\n", length($_), $_, $_ ne $squish ? 'True' : 'False', length($squish), $squish
}</lang>
- Output:
Length: 0 <<<>>> Collapsible: False Length: 0 <<<>>> Length: 72 <<<"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln >>> Collapsible: True Length: 70 <<<"If I were two-faced, would I be wearing this one?" - Abraham Lincoln >>> Length: 72 <<<..1111111111111111111111111111111111111111111111111111111111111117777888>>> Collapsible: True Length: 4 <<<.178>>> Length: 72 <<<I never give 'em hell, I just tell the truth, and they think it's hell. >>> Collapsible: True Length: 69 <<<I never give 'em hel, I just tel the truth, and they think it's hel. >>> Length: 72 <<< --- Harry S Truman >>> Collapsible: True Length: 17 <<< - Hary S Truman >>> Length: 72 <<<The American people have a right to know if their president is a crook. >>> Collapsible: True Length: 71 <<<The American people have a right to know if their president is a crok. >>> Length: 72 <<< --- Richard Nixon >>> Collapsible: True Length: 17 <<< - Richard Nixon >>> Length: 120 <<<AАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑ>>> Collapsible: False Length: 120 <<<AАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑ>>> Length: 72 <<<AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA>>> Collapsible: True Length: 1 <<<A>>>
Phix
There is already a builtin we can abuse for this. The documentation of unique() [added for 0.8.1] states:
`If "PRESORTED" is specified, but s is not actually sorted, then only adjacent duplicates are removed.`
If you don't have builtins/punique.e to hand, you may want to take a quick look at squeeze() in
[[1]], but obviously w/o ch.
<lang Phix>constant tests = {"",
`"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln `, "..1111111111111111111111111111111111111111111111111111111111111117777888", "I never give 'em hell, I just tell the truth, and they think it's hell. ", " --- Harry S Truman "}, fmt = """
length %2d input: <<<%s>>> length %2d output: <<<%s>>> """ for i=1 to length(tests) do
string ti = tests[i], ci = unique(ti, "PRESORTED") printf(1,fmt,{length(ti),ti,length(ci),ci})
end for</lang>
- Output:
length 0 input: <<<>>> length 0 output: <<<>>> length 72 input: <<<"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln >>> length 70 output: <<<"If I were two-faced, would I be wearing this one?" - Abraham Lincoln >>> length 72 input: <<<..1111111111111111111111111111111111111111111111111111111111111117777888>>> length 4 output: <<<.178>>> length 72 input: <<<I never give 'em hell, I just tell the truth, and they think it's hell. >>> length 69 output: <<<I never give 'em hel, I just tel the truth, and they think it's hel. >>> length 72 input: <<< --- Harry S Truman >>> length 17 output: <<< - Hary S Truman >>>
PHP
<lang PHP><?php
function collapseString($string) {
$previousChar = null; $collapse = ; $charArray = preg_split('//u', $string, -1, PREG_SPLIT_NO_EMPTY); for ($i = 0 ; $i < count($charArray) ; $i++) { $currentChar = $charArray[$i]; if ($previousChar !== $currentChar) { $collapse .= $charArray[$i]; } $previousChar = $currentChar; } return $collapse;
}
function isCollapsible($string) {
return ($string !== collapseString($string));
}
$strings = array(
, 'another non colapsing string', '"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln ', '..1111111111111111111111111111111111111111111111111111111111111117777888', "I never give 'em hell, I just tell the truth, and they think it's hell. ", ' --- Harry S Truman ', '0112223333444445555556666666777777778888888889999999999', "The better the 4-wheel drive, the further you'll be from help when ya get stuck!", 'headmistressship', "😍😀🙌💃😍😍😍🙌",
);
foreach ($strings as $original) {
echo 'Original : <<<', $original, '>>> (len=', mb_strlen($original), ')', PHP_EOL; if (isCollapsible($original)) { $collapse = collapseString($original); echo 'Collapse : <<<', $collapse, '>>> (len=', mb_strlen($collapse), ')', PHP_EOL, PHP_EOL; } else { echo 'Collapse : string is not collapsing...', PHP_EOL, PHP_EOL; }
}</lang>
- Output:
Original : <<<>>> (len=0) Collapse : string is not collapsing... Original : <<<another non colapsing string>>> (len=28) Collapse : string is not collapsing... Original : <<<"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln >>> (len=72) Collapse : <<<"If I were two-faced, would I be wearing this one?" - Abraham Lincoln >>> (len=70) Original : <<<..1111111111111111111111111111111111111111111111111111111111111117777888>>> (len=72) Collapse : <<<.178>>> (len=4) Original : <<<I never give 'em hell, I just tell the truth, and they think it's hell. >>> (len=72) Collapse : <<<I never give 'em hel, I just tel the truth, and they think it's hel. >>> (len=69) Original : <<< --- Harry S Truman >>> (len=72) Collapse : <<< - Hary S Truman >>> (len=17) Original : <<<0112223333444445555556666666777777778888888889999999999>>> (len=55) Collapse : <<<0123456789>>> (len=10) Original : <<<The better the 4-wheel drive, the further you'll be from help when ya get stuck!>>> (len=80) Collapse : <<<The beter the 4-whel drive, the further you'l be from help when ya get stuck!>>> (len=77) Original : <<<headmistressship>>> (len=16) Collapse : <<<headmistreship>>> (len=14) Original : <<<😍😀🙌💃😍😍😍🙌>>> (len=8) Collapse : <<<😍😀🙌💃😍🙌>>> (len=6)
Prolog
<lang prolog>collapse_( [], [] ). collapse_( [A], [A] ). collapse_( [A,A|T], R ) :- collapse_( [A|T], R ). collapse_( [A,B|T], [A|R] ) :- dif( A, B ), collapse_( [B|T], R ).
collapse( Str, Collapsed ) :-
string_chars( Str, Chars ), collapse_( Chars, Result ), string_chars( Collapsed, Result ).</lang>
- Output:
?- collapse("122333444455555666666777777788888888999999999", New). New = "123456789" . ?- collapse("", New). New = "" . ?- collapse("\"If I were two-faced, would I be wearing this one?\" --- Abraham Lincoln ", New). New = "\"If I were two-faced, would I be wearing this one?\" - Abraham Lincoln " . ?- collapse("..1111111111111111111111111111111111111111111111111111111111111117777888", New). New = ".178" . ?- collapse("I never give 'em hell, I just tell the truth, and they think it's hell. ", New). New = "I never give 'em hel, I just tel the truth, and they think it's hel. " . ?- collapse(" --- Harry S Truman ", New). New = " - Hary S Truman " . ?- collapse("The better the 4-wheel drive, the further you'll be from help when ya get stuck!", New). New = "The beter the 4-whel drive, the further you'l be from help when ya get stuck!" . 33 ?- collapse("headmistressship", New). New = "headmistreship" .
To determine if a string is collapsed or not, query if the result string is the same as the starting string. eg:
35 ?- S = "122333444455555666666777777788888888999999999", collapse(S,S). false. 37 ?- S = "123456789", collapse(S,S). S = "123456789" .
Python
<lang python>from itertools import groupby
def collapser(txt):
return .join(item for item, grp in groupby(txt))
if __name__ == '__main__':
strings = [ "", '"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln ', "..1111111111111111111111111111111111111111111111111111111111111117777888", "I never give 'em hell, I just tell the truth, and they think it's hell. ", " --- Harry S Truman ", "The better the 4-wheel drive, the further you'll be from help when ya get stuck!", "headmistressship", "aardvark", "😍😀🙌💃😍😍😍🙌", ] for txt in strings: this = "Original" print(f"\n{this:14} Size: {len(txt)} «««{txt}»»»" ) this = "Collapsed" sqz = collapser(txt) print(f"{this:>14} Size: {len(sqz)} «««{sqz}»»»" )</lang>
- Output:
Original Size: 0 «««»»» Collapsed Size: 0 «««»»» Original Size: 72 «««"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln »»» Collapsed Size: 70 «««"If I were two-faced, would I be wearing this one?" - Abraham Lincoln »»» Original Size: 72 «««..1111111111111111111111111111111111111111111111111111111111111117777888»»» Collapsed Size: 4 «««.178»»» Original Size: 72 «««I never give 'em hell, I just tell the truth, and they think it's hell. »»» Collapsed Size: 69 «««I never give 'em hel, I just tel the truth, and they think it's hel. »»» Original Size: 72 ««« --- Harry S Truman »»» Collapsed Size: 17 ««« - Hary S Truman »»» Original Size: 80 «««The better the 4-wheel drive, the further you'll be from help when ya get stuck!»»» Collapsed Size: 77 «««The beter the 4-whel drive, the further you'l be from help when ya get stuck!»»» Original Size: 16 «««headmistressship»»» Collapsed Size: 14 «««headmistreship»»» Original Size: 8 «««aardvark»»» Collapsed Size: 7 «««ardvark»»» Original Size: 8 «««😍😀🙌💃😍😍😍🙌»»» Collapsed Size: 6 «««😍😀🙌💃😍🙌»»»
and for the missing predicate, foregrounded in the task title, and already forgotten in the listing of tests:
<lang python>Determining if a string is collapsible
from operator import eq
- isCollapsible :: String -> Bool
def isCollapsible(s):
True if s contains any consecutively repeated characters. return False if 2 > len(s) else ( any(map(eq, s, s[1:])) )
- ------------------------- TEST --------------------------
- main :: IO ()
def main():
Determining whether each string is collapsible xs = [ "", '"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln ', "..1111111111111111111111111111111111111111111111111111111111111117777888", "I never give 'em hell, I just tell the truth, and they think it's hell. ", " --- Harry S Truman ", "The better the 4-wheel drive, the further you'll be from help when ya get stuck!", "headmistressship", "aardvark", "😍😀🙌💃😍😍😍🙌", "abcdefghijklmnopqrstuvwxyz" ] print([ isCollapsible(x) for x in xs ])
- MAIN ---
if __name__ == '__main__':
main()</lang>
- Output:
[False, True, True, True, True, True, True, True, True, False]
Raku
(formerly Perl 6)
Technically, the task is asking for a boolean. "Determine if a string is collapsible" is answerable with True/False, so return a boolean as well.
<lang perl6>map {
my $squish = .comb.squish.join; printf "\nLength: %2d <<<%s>>>\nCollapsible: %s\nLength: %2d <<<%s>>>\n", .chars, $_, .chars != $squish.chars, $squish.chars, $squish
}, lines
q:to/STRINGS/;
"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln ..1111111111111111111111111111111111111111111111111111111111111117777888 I never give 'em hell, I just tell the truth, and they think it's hell. --- Harry S Truman The American people have a right to know if their president is a crook. --- Richard Nixon AАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA STRINGS
</lang>
- Output:
Length: 0 <<<>>> Collapsible: False Length: 0 <<<>>> Length: 72 <<<"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln >>> Collapsible: True Length: 70 <<<"If I were two-faced, would I be wearing this one?" - Abraham Lincoln >>> Length: 72 <<<..1111111111111111111111111111111111111111111111111111111111111117777888>>> Collapsible: True Length: 4 <<<.178>>> Length: 72 <<<I never give 'em hell, I just tell the truth, and they think it's hell. >>> Collapsible: True Length: 69 <<<I never give 'em hel, I just tel the truth, and they think it's hel. >>> Length: 72 <<< --- Harry S Truman >>> Collapsible: True Length: 17 <<< - Hary S Truman >>> Length: 72 <<<The American people have a right to know if their president is a crook. >>> Collapsible: True Length: 71 <<<The American people have a right to know if their president is a crok. >>> Length: 72 <<< --- Richard Nixon >>> Collapsible: True Length: 17 <<< - Richard Nixon >>> Length: 72 <<<AАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑ>>> Collapsible: False Length: 72 <<<AАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑAАΑ>>> Length: 72 <<<AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA>>> Collapsible: True Length: 1 <<<A>>>
REXX
<lang rexx>/*REXX program "collapses" all immediately repeated characters in a string (or strings).*/ @.= /*define a default for the @. array. */ parse arg x /*obtain optional argument from the CL.*/ if x\= then @.1= x /*if user specified an arg, use that. */
else do; @.1= @.2= '"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln ' @.3= ..1111111111111111111111111111111111111111111111111111111111111117777888 @.4= "I never give 'em hell, I just tell the truth, and they think it's hell. " @.5= ' --- Harry S Truman ' end
do j=1; L= length(@.j) /*obtain the length of an array element*/ say copies('═', 105) /*show a separator line between outputs*/ if j>1 & L==0 then leave /*if arg is null and J>1, then leave. */ say ' length='right(L, 3) " input=«««" || @.j || '»»»' new= collapse(@.j) w= length(new) say ' length='right(w, 3) " output=«««" || new || '»»»' end /*j*/
exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ collapse: procedure; parse arg y 1 $ 2 /*get a value from arg; get 1st char. */
do k=2 to length(y) /*traipse through almost all the chars.*/ _= substr(y, k, 1) /*pick a character from Y*/ if _==right($, 1) then iterate /*Same character? Skip it.*/ $= $ || _ /*append char., it's diff.*/ end /*j*/ return $</lang>
- output when using the internal default inputs:
═════════════════════════════════════════════════════════════════════════════════════════════════════════ length= 0 input=«««»»» length= 0 output=«««»»» ═════════════════════════════════════════════════════════════════════════════════════════════════════════ length= 72 input=«««"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln »»» length= 70 output=«««"If I were two-faced, would I be wearing this one?" - Abraham Lincoln »»» ═════════════════════════════════════════════════════════════════════════════════════════════════════════ length= 72 input=«««..1111111111111111111111111111111111111111111111111111111111111117777888»»» length= 4 output=«««.178»»» ═════════════════════════════════════════════════════════════════════════════════════════════════════════ length= 72 input=«««I never give 'em hell, I just tell the truth, and they think it's hell. »»» length= 69 output=«««I never give 'em hel, I just tel the truth, and they think it's hel. »»» ═════════════════════════════════════════════════════════════════════════════════════════════════════════ length= 72 input=««« --- Harry S Truman »»» length= 17 output=««« - Hary S Truman »»» ═════════════════════════════════════════════════════════════════════════════════════════════════════════
Ruby
This is built in since at least a decade under the method name 'squeeze'. squeeze(" ") would only squeeze spaces. <lang ruby>strings = ["",
'"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln ', "..1111111111111111111111111111111111111111111111111111111111111117777888", "I never give 'em hell, I just tell the truth, and they think it's hell. ", " --- Harry S Truman ", "The better the 4-wheel drive, the further you'll be from help when ya get stuck!", "headmistressship", "aardvark", "😍😀🙌💃😍😍😍🙌",]
strings.each do |str|
puts "«««#{str}»»» (size #{str.size})" ssq = str.squeeze puts "«««#{ssq}»»» (size #{ssq.size})" puts
end </lang>
- Output:
«««»»» (size 0) «««»»» (size 0) «««"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln »»» (size 72) «««"If I were two-faced, would I be wearing this one?" - Abraham Lincoln »»» (size 70) «««..1111111111111111111111111111111111111111111111111111111111111117777888»»» (size 72) «««.178»»» (size 4) «««I never give 'em hell, I just tell the truth, and they think it's hell. »»» (size 72) «««I never give 'em hel, I just tel the truth, and they think it's hel. »»» (size 69) ««« --- Harry S Truman »»» (size 72) ««« - Hary S Truman »»» (size 17) «««The better the 4-wheel drive, the further you'll be from help when ya get stuck!»»» (size 80) «««The beter the 4-whel drive, the further you'l be from help when ya get stuck!»»» (size 77) «««headmistressship»»» (size 16) «««headmistreship»»» (size 14) «««aardvark»»» (size 8) «««ardvark»»» (size 7) «««😍😀🙌💃😍😍😍🙌»»» (size 8) «««😍😀🙌💃😍🙌»»» (size 6)
Rust
<lang rust>fn collapse_string(val: &str) -> String {
let mut output = String::new(); let mut chars = val.chars().peekable();
while let Some(c) = chars.next() { while let Some(&b) = chars.peek() { if b == c { chars.next(); } else { break; } }
output.push(c); }
output
}
fn main() {
let tests = [ "122333444455555666666777777788888888999999999", "", "\"If I were two-faced, would I be wearing this one?\" --- Abraham Lincoln ", "..1111111111111111111111111111111111111111111111111111111111111117777888", "I never give 'em hell, I just tell the truth, and they think it's hell. ", " --- Harry S Truman ", "The better the 4-wheel drive, the further you'll be from help when ya get stuck!", "headmistressship", ];
for s in &tests { println!("Old: {:>3} <<<{}>>>", s.len(), s); let collapsed = collapse_string(s); println!("New: {:>3} <<<{}>>>", collapsed.len(), collapsed);
println!(); }
}</lang>
- Output:
Old: 45 <<<122333444455555666666777777788888888999999999>>> New: 9 <<<123456789>>> Old: 0 <<<>>> New: 0 <<<>>> Old: 72 <<<"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln >>> New: 70 <<<"If I were two-faced, would I be wearing this one?" - Abraham Lincoln >>> Old: 72 <<<..1111111111111111111111111111111111111111111111111111111111111117777888>>> New: 4 <<<.178>>> Old: 72 <<<I never give 'em hell, I just tell the truth, and they think it's hell. >>> New: 69 <<<I never give 'em hel, I just tel the truth, and they think it's hel. >>> Old: 72 <<< --- Harry S Truman >>> New: 17 <<< - Hary S Truman >>> Old: 80 <<<The better the 4-wheel drive, the further you'll be from help when ya get stuck!>>> New: 77 <<<The beter the 4-whel drive, the further you'l be from help when ya get stuck!>>> Old: 16 <<<headmistressship>>> New: 14 <<<headmistreship>>>
Scala
Pure imperative programming 😃
<lang Scala>object CollapsibleString {
/**Collapse a string (if possible)*/ def collapseString (s : String) : String = { var res = s var isOver = false var i = 0 if(res.size == 0) res else while(!isOver){ if(res(i) == res(i+1)){ res = res.take(i) ++ res.drop(i+1) i-=1 } i+=1 if(i==res.size-1) isOver = true } res }
/**Check if a string is collapsible*/ def isCollapsible (s : String) : Boolean = collapseString(s).length != s.length
/**Display results as asked in the task*/ def reportResults (s : String) : String = { val sCollapsed = collapseString(s) val originalRes = "ORIGINAL : length = " + s.length() + ", string = «««" + s + "»»»" val collapsedRes = "COLLAPSED : length = " + sCollapsed.length() + ", string = «««" + sCollapsed + "»»»" //In order to avoid useless computations, the function isCollapsible isn't called if(s.length != sCollapsed.length) originalRes + "\n" + collapsedRes + "\n" + "This string IS collapsible !" else originalRes + "\n" + collapsedRes + "\n" + "This string is NOT collapsible !" }
def main(args: Array[String]): Unit = { println(reportResults("")) println("------------") println(reportResults("\"If I were two-faced, would I be wearing this one?\" --- Abraham Lincoln ")) println("------------") println(reportResults("..1111111111111111111111111111111111111111111111111111111111111117777888")) println("------------") println(reportResults("I never give 'em hell, I just tell the truth, and they think it's hell. ")) println("------------") println(reportResults(" --- Harry S Truman ")) println("------------") println(reportResults("The better the 4-wheel drive, the further you'll be from help when ya get stuck!")) println("------------") println(reportResults("headmistressship")) println("------------") println(reportResults("aardvark")) }
}</lang>
- Output:
ORIGINAL : length = 0, string = «««»»» COLLAPSED : length = 0, string = «««»»» This string is NOT collapsible ! ------------ ORIGINAL : length = 72, string = «««"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln »»» COLLAPSED : length = 70, string = «««"If I were two-faced, would I be wearing this one?" - Abraham Lincoln »»» This string IS collapsible ! ------------ ORIGINAL : length = 72, string = «««..1111111111111111111111111111111111111111111111111111111111111117777888»»» COLLAPSED : length = 4, string = «««.178»»» This string IS collapsible ! ------------ ORIGINAL : length = 72, string = «««I never give 'em hell, I just tell the truth, and they think it's hell. »»» COLLAPSED : length = 69, string = «««I never give 'em hel, I just tel the truth, and they think it's hel. »»» This string IS collapsible ! ------------ ORIGINAL : length = 72, string = ««« --- Harry S Truman »»» COLLAPSED : length = 17, string = ««« - Hary S Truman »»» This string IS collapsible ! ------------ ORIGINAL : length = 80, string = «««The better the 4-wheel drive, the further you'll be from help when ya get stuck!»»» COLLAPSED : length = 77, string = «««The beter the 4-whel drive, the further you'l be from help when ya get stuck!»»» This string IS collapsible ! ------------ ORIGINAL : length = 16, string = «««headmistressship»»» COLLAPSED : length = 14, string = «««headmistreship»»» This string IS collapsible ! ------------ ORIGINAL : length = 8, string = «««aardvark»»» COLLAPSED : length = 7, string = «««ardvark»»» This string IS collapsible !
Sidef
<lang ruby>func squeeze(str) {
str.gsub(/(.)\1+/, {|s1| s1 })
}
var strings = ["",
'"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln ', "..1111111111111111111111111111111111111111111111111111111111111117777888", "I never give 'em hell, I just tell the truth, and they think it's hell. ", " --- Harry S Truman ", "The better the 4-wheel drive, the further you'll be from help when ya get stuck!", "headmistressship", "aardvark", "😍😀🙌💃😍😍😍🙌"]
strings.each {|str|
var ssq = squeeze(str) say "«««#{str}»»» (length: #{str.len})" say "«««#{ssq}»»» (length: #{ssq.len})\n"
}</lang>
- Output:
«««»»» (length: 0) «««»»» (length: 0) «««"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln »»» (length: 72) «««"If I were two-faced, would I be wearing this one?" - Abraham Lincoln »»» (length: 70) «««..1111111111111111111111111111111111111111111111111111111111111117777888»»» (length: 72) «««.178»»» (length: 4) «««I never give 'em hell, I just tell the truth, and they think it's hell. »»» (length: 72) «««I never give 'em hel, I just tel the truth, and they think it's hel. »»» (length: 69) ««« --- Harry S Truman »»» (length: 72) ««« - Hary S Truman »»» (length: 17) «««The better the 4-wheel drive, the further you'll be from help when ya get stuck!»»» (length: 80) «««The beter the 4-whel drive, the further you'l be from help when ya get stuck!»»» (length: 77) «««headmistressship»»» (length: 16) «««headmistreship»»» (length: 14) «««aardvark»»» (length: 8) «««ardvark»»» (length: 7) «««😍😀🙌💃😍😍😍🙌»»» (length: 8) «««😍😀🙌💃😍🙌»»» (length: 6)
Swift
<lang Swift>let strings = [ "", #""If I were two-faced, would I be wearing this one?" --- Abraham Lincoln "#, "..1111111111111111111111111111111111111111111111111111111111111117777888", "I never give 'em hell, I just tell the truth, and they think it's hell. ", " --- Harry S Truman ", "The better the 4-wheel drive, the further you'll be from help when ya get stuck!", "headmistressship", "aardvark", "😍😀🙌💃😍😍😍🙌" ]
let collapsedStrings = strings.map { $0.replacingOccurrences( of: #"(.)\1*"#, with: "$1", options: .regularExpression)}
for (original, collapsed) in zip(strings, collapsedStrings) { print (String(format: "%03d «%@»\n%03d «%@»\n", original.count, original, collapsed.count, collapsed)) }</lang>
- Output:
000 «» 000 «» 072 «"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln » 070 «"If I were two-faced, would I be wearing this one?" - Abraham Lincoln » 072 «..1111111111111111111111111111111111111111111111111111111111111117777888» 004 «.178» 072 «I never give 'em hell, I just tell the truth, and they think it's hell. » 069 «I never give 'em hel, I just tel the truth, and they think it's hel. » 072 « --- Harry S Truman » 017 « - Hary S Truman » 080 «The better the 4-wheel drive, the further you'll be from help when ya get stuck!» 077 «The beter the 4-whel drive, the further you'l be from help when ya get stuck!» 016 «headmistressship» 014 «headmistreship» 008 «aardvark» 007 «ardvark» 008 «😍😀🙌💃😍😍😍🙌» 006 «😍😀🙌💃😍🙌»
Tcl
Please note the ;# ' comments, there appears to be a syntax hightlighting bug with RC <lang tcl>set test {
{} {"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln } {..1111111111111111111111111111111111111111111111111111111111111117777888} {I never give 'em hell, I just tell the truth, and they think it's hell. } ;# ' { --- Harry S Truman } {The better the 4-wheel drive, the further you'll be from help when ya get stuck!} ;# ' {headmistressship}
}
foreach {str} $test {
# Uses regexp lookbehind to detect repeated characters set sub [regsub -all {(.)(\1+)} $str {\1}]
# Output puts [format "Original (length %3d): %s" [string length $str] $str] puts [format "Subbed (length %3d): %s" [string length $sub] $sub] puts ----------------------
} </lang>
- Output:
Original (length 0): Subbed (length 0): ---------------------- Original (length 72): "If I were two-faced, would I be wearing this one?" --- Abraham Lincoln Subbed (length 70): "If I were two-faced, would I be wearing this one?" - Abraham Lincoln ---------------------- Original (length 72): ..1111111111111111111111111111111111111111111111111111111111111117777888 Subbed (length 4): .178 ---------------------- Original (length 72): I never give 'em hell, I just tell the truth, and they think it's hell. Subbed (length 69): I never give 'em hel, I just tel the truth, and they think it's hel. ---------------------- Original (length 72): --- Harry S Truman Subbed (length 17): - Hary S Truman ---------------------- Original (length 80): The better the 4-wheel drive, the further you'll be from help when ya get stuck! Subbed (length 77): The beter the 4-whel drive, the further you'l be from help when ya get stuck! ---------------------- Original (length 16): headmistressship Subbed (length 14): headmistreship ----------------------
Visual Basic .NET
<lang vbnet>Module Module1
Function Collapse(s As String) As String If String.IsNullOrEmpty(s) Then Return "" End If Return s(0) + New String(Enumerable.Range(1, s.Length - 1).Where(Function(i) s(i) <> s(i - 1)).Select(Function(i) s(i)).ToArray) End Function
Sub Main() Dim input() = { "", "The better the 4-wheel drive, the further you'll be from help when ya get stuck!", "headmistressship", ControlChars.Quote + "If I were two-faced, would I be wearing this one?" + ControlChars.Quote + " --- Abraham Lincoln ", "..1111111111111111111111111111111111111111111111111111111111111117777888", "I never give 'em hell, I just tell the truth, and they think it's hell. ", " --- Harry S Truman " } For Each s In input Console.WriteLine($"old: {s.Length} «««{s}»»»") Dim c = Collapse(s) Console.WriteLine($"new: {c.Length} «««{c}»»»") Next End Sub
End Module</lang>
- Output:
old: 0 «««»»» new: 0 «««»»» old: 80 «««The better the 4-wheel drive, the further you'll be from help when ya get stuck!»»» new: 77 «««The beter the 4-whel drive, the further you'l be from help when ya get stuck!»»» old: 16 «««headmistressship»»» new: 14 «««headmistreship»»» old: 72 «««"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln »»» new: 70 «««"If I were two-faced, would I be wearing this one?" - Abraham Lincoln »»» old: 72 «««..1111111111111111111111111111111111111111111111111111111111111117777888»»» new: 4 «««.178»»» old: 72 «««I never give 'em hell, I just tell the truth, and they think it's hell. »»» new: 69 «««I never give 'em hel, I just tel the truth, and they think it's hel. »»» old: 72 ««« --- Harry S Truman »»» new: 17 ««« - Hary S Truman »»»
Wren
<lang ecmascript>import "/fmt" for Fmt
// Returns collapsed string, original and new lengths in // unicode code points (not normalized). var collapse = Fn.new { |s|
var c = s.codePoints.toList var le = c.count if (le < 2) return [s, le, le] for (i in le-2..0) { if (c[i] == c[i+1]) c.removeAt(i) } var cc = c.reduce("") { |acc, cp| acc + String.fromCodePoint(cp) } return [cc, le, cc.count]
}
var strings = [
"", "\"If I were two-faced, would I be wearing this one?\" --- Abraham Lincoln ", "..1111111111111111111111111111111111111111111111111111111111111117777888", "I never give 'em hell, I just tell the truth, and they think it's hell. ", " --- Harry S Truman ", "The better the 4-wheel drive, the further you'll be from help when ya get stuck!", "headmistressship", "aardvark", "😍😀🙌💃😍😍😍🙌"
]
for (s in strings) {
var r = collapse.call(s) System.print("original : length = %(Fmt.d(2, r[1])), string = «««%(s)»»»") System.print("collapsed: length = %(Fmt.d(2, r[2])), string = «««%(r[0])»»»\n")
}</lang>
- Output:
original : length = 0, string = «««»»» collapsed: length = 0, string = «««»»» original : length = 72, string = «««"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln »»» collapsed: length = 70, string = «««"If I were two-faced, would I be wearing this one?" - Abraham Lincoln »»» original : length = 72, string = «««..1111111111111111111111111111111111111111111111111111111111111117777888»»» collapsed: length = 4, string = «««.178»»» original : length = 72, string = «««I never give 'em hell, I just tell the truth, and they think it's hell. »»» collapsed: length = 69, string = «««I never give 'em hel, I just tel the truth, and they think it's hel. »»» original : length = 72, string = ««« --- Harry S Truman »»» collapsed: length = 17, string = ««« - Hary S Truman »»» original : length = 80, string = «««The better the 4-wheel drive, the further you'll be from help when ya get stuck!»»» collapsed: length = 77, string = «««The beter the 4-whel drive, the further you'l be from help when ya get stuck!»»» original : length = 16, string = «««headmistressship»»» collapsed: length = 14, string = «««headmistreship»»» original : length = 8, string = «««aardvark»»» collapsed: length = 7, string = «««ardvark»»» original : length = 8, string = «««😍😀🙌💃😍😍😍🙌»»» collapsed: length = 6, string = «««😍😀🙌💃😍🙌»»»
zkl
<lang zkl>fcn collapsible(str){ // no Unicode
sink:=Sink(String); str.reduce('wrap(c1,c2){ if(c1!=c2) sink.write(c2); c2 },""); // prime with \0 cstr:=sink.close(); return(str.len()!=cstr.len(), cstr);
}</lang> <lang zkl>strings:= 0'^ "If I were two-faced, would I be wearing this one?" --- Abraham Lincoln ..1111111111111111111111111111111111111111111111111111111111111117777888 I never give 'em hell, I just tell the truth, and they think it's hell.
--- Harry S Truman
The American people have a right to know if their president is a crook.
--- Richard Nixon
The better the 4-wheel drive, the further you'll be from help when ya get stuck! headmistressship aardvark^ .split("\n");
- <<<
foreach s in (strings){
println("Before: %3d >>>%s<<<".fmt(s.len(),s)); _,cstr:=collapsible(s); println("After: %3d >>>%s<<<\n".fmt(cstr.len(),cstr));
}</lang>
- Output:
Before: 0 >>><<< After: 0 >>><<< Before: 72 >>>"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln <<< After: 70 >>>"If I were two-faced, would I be wearing this one?" - Abraham Lincoln <<< Before: 72 >>>..1111111111111111111111111111111111111111111111111111111111111117777888<<< After: 4 >>>.178<<< Before: 72 >>>I never give 'em hell, I just tell the truth, and they think it's hell. <<< After: 69 >>>I never give 'em hel, I just tel the truth, and they think it's hel. <<< Before: 72 >>> --- Harry S Truman <<< After: 17 >>> - Hary S Truman <<< Before: 72 >>>The American people have a right to know if their president is a crook. <<< After: 71 >>>The American people have a right to know if their president is a crok. <<< Before: 72 >>> --- Richard Nixon <<< After: 17 >>> - Richard Nixon <<< Before: 80 >>>The better the 4-wheel drive, the further you'll be from help when ya get stuck!<<< After: 77 >>>The beter the 4-whel drive, the further you'l be from help when ya get stuck!<<< Before: 16 >>>headmistressship<<< After: 14 >>>headmistreship<<< Before: 8 >>>aardvark<<< After: 7 >>>ardvark<<<