Determine if a string is collapsible: Difference between revisions

From Rosetta Code
Content added Content deleted
(JavaScript added)
(Added Racket implementation)
Line 2,514: Line 2,514:




</pre>

=={{header|Racket}}==

<lang Racket>#lang racket

(define (collapse text)
(if (< (string-length text) 2)
text
(string-append
(if (equal? (substring text 0 1) (substring text 1 2))
"" (substring text 0 1))
(collapse (substring text 1)))))

; Test cases
(define tcs
'(""
"\"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 ([text tcs])
(let ([collapsed (collapse text)])
(display (format "Original (size ~a): «««~a»»»\nCollapsed (size ~a): «««~a»»»\n\n"
(string-length text) text
(string-length collapsed) collapsed))))
</lang>
{{out}}
<pre>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): «««😍😀🙌💃😍🙌»»»
</pre>
</pre>



Revision as of 04:05, 27 August 2021

Task
Determine if a string is collapsible
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
        ╚════════════════════════════════════════════════════════════════════════╝
Other tasks related to string operations:
Metrics
Counting
Remove/replace
Anagrams/Derangements/shuffling
Find/Search/Determine
Formatting
Song lyrics/poems/Mad Libs/phrases
Tokenize
Sequences



8080 Assembly

<lang 8080asm>bdos: equ 5 puts: equ 9 org 100h jmp main ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Collapse the $-terminated string at [HL] colaps: mov b,m ; B = last character seen inx h ; First character never collapses mov d,h ; DE = output pointer mov e,l mov a,b ; Empty string? cpi '$' rz ; Then do nothing cloop: mov a,m ; Get character inx h ; Advance pointer cmp b ; Same as last one? jz cloop ; Then keep scanning mov b,a ; Otherwise, it is a new one stax d ; Store it, inx d ; and increment output pointer. cpi '$' ; Reached the end? jnz cloop ; If not, next character ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Code to print the output in the required format main: lxi h,strs ; List of string pointers loop: mov e,m ; DE = string pointer inx h mov d,m inx h mov a,e ; If zero, end ora d rz push h ; Keep the list pointer push d ; Keep the string pointer call brstr ; Print original string in brackets pop h ; Retrieve string pointer push h call colaps ; Collapse the string pop d ; Retrieve string pointer call brstr ; Print the collapsed string in brackets pop h ; Retrieve the list pointer jmp loop ; Next string ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Print string at DE in brackets with length brstr: push d ; Store string pointer mvi c,puts ; Print opening brackets lxi d,open call bdos pop d ; Print original string push d mvi c,puts call bdos mvi c,puts ; Print closing brackets lxi d,close call bdos pop h call strlen ; Find string length mov a,b jmp prnum ; Print string length ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Figure out the length of a string (max 255) strlen: mvi b,0 ; Counter mvi a,'$' ; Terminator sloop: cmp m ; Reached the end yet? rz ; If so, stop inr b ; If not, increment counter, inx h ; and pointer, jmp sloop ; and check next byte. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Print number in A as decimal prnum: lxi d,num ; End of number string prdgt: mvi b,-1 ; Quotient ploop: inr b ; Increment quotient sui 10 ; Subtract 10 jnc ploop ; Subtract until negative adi '0'+10 ; Make ASCII digit dcx d ; Store in number string stax d mov a,b ; If more digits, ana a jnz prdgt ; find next digit mvi c,puts ; When done, print string jmp bdos ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Formatting strings open: db '<<<$' close: db '>>> $' db '***' num: db 13,10,'$' ;;; Input strings strs: dw str1,str2,str3,str4,str5,0 str1: db '$' ; Empty string str2: db '"If I were two-faced, would I be wearing ' db 'this one?" --- Abraham Lincoln $' str3: db '..111111111111111111111111111111111111111' db '1111111111111111111111117777888$' str4: db 'I never give ',39,'em hell, I just tell the truth, ' db 'and they think it',39,'s hell. $' str5: db ' ' db ' --- Harry S Truman $'</lang>

Output:
<<<>>> 0
<<<>>> 0
<<<"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln >>> 72
<<<"If I were two-faced, would I be wearing this one?" - Abraham Lincoln >>> 70
<<<..1111111111111111111111111111111111111111111111111111111111111117777888>>> 72
<<<.178>>> 4
<<<I never give 'em hell, I just tell the truth, and they think it's hell. >>> 72
<<<I never give 'em hel, I just tel the truth, and they think it's hel. >>> 69
<<<                                                    --- Harry S Truman  >>> 72
<<< - Hary S Truman >>> 17


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

ALGOL 68

<lang algol68>BEGIN

   # returns a collapsed version of s                                    #
   #         i.e. s with adjacent duplicate characters removed           #
   PROC collapse = ( STRING s )STRING:
       IF s = ""
       THEN ""   # empty string                                          #
       ELSE      # non-empty string                                      #
           [ LWB s : UPB s ]CHAR result;
           INT     r pos   := LWB result;
           result[ r pos ] := s[ LWB s ];
           FOR s pos FROM LWB s + 1 TO UPB s DO
               IF result[ r pos ] /= s[ s pos ] THEN
                  r pos +:= 1;
                  result[ r pos ] := s[ s pos ]
               FI
           OD;
           result[ LWB result : r pos ]
       FI # callapse # ;   
   # task test cases                                                     #
   []STRING 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  "
                    );
   FOR t pos FROM LWB tests TO UPB tests DO
       STRING s = tests[ t pos ];
       STRING c = collapse( s );
       print( ( "       <<<", s, ">>> (length ", whole( ( UPB s + 1 ) - LWB s, 0 ), ")", newline ) );
       print( ( "result <<<", c, ">>> (length ", whole( ( UPB c + 1 ) - LWB c, 0 ), ")", newline ) )
   OD

END </lang>

Output:
       <<<>>> (length 0)
result <<<>>> (length 0)
       <<<"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln >>> (length 72)
result <<<"If I were two-faced, would I be wearing this one?" - Abraham Lincoln >>> (length 70)
       <<<..1111111111111111111111111111111111111111111111111111111111111117777888>>> (length 72)
result <<<.178>>> (length 4)
       <<<I never give 'em hell, I just tell the truth, and they think it's hell. >>> (length 72)
result <<<I never give 'em hel, I just tel the truth, and they think it's hel. >>> (length 69)
       <<<                                                    --- Harry S Truman  >>> (length 72)
result <<< - Hary S Truman >>> (length 17)

APL

Works with: Dyalog APL

<lang APL>task←{

  ⍝ Collapse a string
  collapse←{(1,¯1↓⍵≠1⌽⍵)/⍵}
  ⍝ Given a function ⍺⍺, display a string in brackets,
  ⍝ along with its length, and do the same for the result
  ⍝ of applying ⍺⍺ to the string.
  display←{
     bracket←{(⍕⍴⍵),' «««',⍵,'»»»'}
     ↑(⊂bracket ⍵),(⊂bracket ⍺⍺ ⍵)
  }
  ⍝ Strings from the task
  s1←
  s2←'"If I were two-faced, would I be wearing this one?"'
  s2,←' --- Abraham Lincoln '
  s3←'..1111111111111111111111111111111111111111111111111'
  s3,←'111111111111117777888'
  s4←'I never give em hell, I just tell the truth, '
  s4,←'and they think its hell. '
  s5←'                                             '
  s5,←'       --- Harry S Truman  '
  strs←s1 s2 s3 s4 s5
  ⍝ Collapse each string and display it as specified
  ↑collapse display¨ strs

}</lang>

Output:
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 »»»                                                       

AutoHotkey

<lang AutoHotkey>collapsible_string(str){ for i, ch in StrSplit(str){ if (ch <> prev) res .= ch prev := ch } return "original string:`t" StrLen(str) " characters`t«««" str "»»»`nresultant string:`t" StrLen(res) " characters`t«««" res "»»»" }</lang> Examples:<lang AutoHotkey>data := ["" , """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 "] for i, v in data MsgBox % := collapsible_string(v) return</lang>

Outputs:

-----------------------------------------
original string:	0 characters	«««»»»
resultant string:	0 characters	«««»»»
-----------------------------------------
original string:	72 characters	«««"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln »»»
resultant string:	70 characters	«««"If I were two-faced, would I be wearing this one?" - Abraham Lincoln »»»
-----------------------------------------
original string:	72 characters	«««..1111111111111111111111111111111111111111111111111111111111111117777888»»»
resultant string:	4 characters	«««.178»»»
-----------------------------------------
original string:	72 characters	«««I never give 'em hell, I just tell the truth, and they think it's hell. »»»
resultant string:	69 characters	«««I never give 'em hel, I just tel the truth, and they think it's hel. »»»
-----------------------------------------
original string:	72 characters	«««                                                    --- Harry S Truman  »»»
resultant string:	17 characters	««« - Hary S Truman »»»
-----------------------------------------

AWK

<lang AWK>

  1. 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>>>

BaCon

<lang bacon>DATA "" DATA "\"If I were two-faced, would I be wearing this one?\" --- Abraham Lincoln " DATA "..1111111111111111111111111111111111111111111111111111111111111117777888" DATA "I never give 'em hell, I just tell the truth, and they think it's hell. " DATA " --- Harry S Truman " DATA "The better the 4-wheel drive, the further you'll be from help when ya get stuck!" DATA "headmistressship"

DOTIMES 7

   READ x$
   found = 0
   PRINT "<<<", x$, ">>> - length: ", LEN(x$)
   PRINT "<<<";
   FOR y = 1 TO LEN(x$)
       IF MID$(x$, y, 1) <> MID$(x$, y+1, 1) THEN
           PRINT MID$(x$, y, 1);
           INCR found
       ENDIF
   NEXT
   PRINT ">>> - length: ", found

DONE</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

BASIC

<lang basic>10 READ N% 20 FOR A% = 1 TO N% 30 READ I$: GOSUB 100 40 PRINT LEN(I$); "<<<"; I$; ">>>" 50 PRINT LEN(O$); "<<<"; O$; ">>>" 55 PRINT 60 NEXT 70 END 100 REM Collapse I$ into O$ 105 IF I$="" THEN O$=I$: RETURN 110 O$=SPACE$(LEN(I$)) 120 P$=LEFT$(I$,1) 130 MID$(O$,1,1)=P$ 140 O%=2 150 FOR I%=2 TO LEN(I$) 160 C$=MID$(I$,I%,1) 170 IF P$<>C$ THEN MID$(O$,O%,1)=C$: O%=O%+1: P$=C$ 180 NEXT 190 O$=LEFT$(O$,O%-1) 200 RETURN 400 DATA 5: REM There are 5 strings 410 DATA "" 420 DATA "'If I were two-faced, would I be wearing this one?' --- Abraham Lincoln " 430 DATA "..1111111111111111111111111111111111111111111111111111111111111117777888" 440 DATA "I never give 'em hell, I just tell the truth, and they think it's hell. " 450 DATA " --- Harry S Truman "</lang>

Output:
 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 >>>

BCPL

<lang bcpl>get "libhdr"

// Collapse a string let collapse(in, out) = valof $( let o = 0

   for i = 1 to in%0
       unless i>1 & in%i = in%(i-1)
       $(  o := o + 1
           out%o := in%i
       $)
   out%0 := o
   resultis out

$)

// Print string with brackets and length let brackets(s) be

   writef("%N: <<<%S>>>*N", s%0, s)

// Print original and collapsed version let show(s) be $( let v = vec 1+255/BYTESPERWORD

   brackets(s)
   brackets(collapse(s, v))
   wrch('*N')

$)

let start() be $( show("")

   show("*"If I were two-faced, would I be wearing this one?*" --- Abraham Lincoln ")
   show("..1111111111111111111111111111111111111111111111111111111111111111111788")
   show("I never give 'em hell, I just tell the truth, and they think it's hell. ")
   show("                                                     --- Harry S Truman ")

$)</lang>

Output:
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: <<<..1111111111111111111111111111111111111111111111111111111111111111111788>>>
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 >>>

Bracmat

<lang Bracmat> ( colapse

 =   previous
   .   str
     $ ( vap
       $ ( (
           =
             .   !arg:!previous&
               | !arg:?previous
           )
         . !arg
         )
       )
 )

& ( testcolapse

 =   len
   .   (len=.@(!arg:? [?arg)&!arg)
     & out$(str$(««« !arg "»»» " len$!arg))
     & colapse$!arg:?arg
     & out$(str$(««« !arg "»»» " len$!arg))
 )

& testcolapse$ & testcolapse

 $ "\"If I were two-faced, would I be wearing this one?\" --- Abraham Lincoln "

& testcolapse

 $ "..1111111111111111111111111111111111111111111111111111111111111117777888"

& testcolapse

 $ "I never give 'em hell, I just tell the truth, and they think it's hell. "

& testcolapse

 $ "                                                    --- Harry S Truman  "</lang>

Output

«««»»» 0
«««»»» 0
«««"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln »»» 72
«««"If I were two-faced, would I be wearing this one?" - Abraham Lincoln »»» 70
«««..1111111111111111111111111111111111111111111111111111111111111117777888»»» 72
«««.178»»» 4
«««I never give 'em hell, I just tell the truth, and they think it's hell. »»» 72
«««I never give 'em hel, I just tel the truth, and they think it's hel. »»» 69
«««                                                    --- Harry S Truman  »»» 72
««« - Hary S Truman »»» 17

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>

  1. include<string.h>
  2. include<stdlib.h>
  3. include<stdio.h>
  1. define COLLAPSE 0
  2. 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>

  1. include <iostream>
  2. 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)

Cowgol

<lang cowgol>include "cowgol.coh"; include "strings.coh";

  1. Collapse the string at in, and store the result in the given buffer

sub collapse(in: [uint8], out: [uint8]) is

   var ch := [in];
   in := @next in; 
   loop
       if ch == 0 then
           [out] := 0;
           return;
       elseif [in] != ch then
           [out] := ch;
           out := @next out;
           ch := [in];
       end if;
       in := @next in;
   end loop;

end sub;

  1. Given a string, collapse it and print all required output

sub show(str: [uint8]) is

   sub bracket_length(str: [uint8]) is
       print_i32(StrLen(str) as uint32);
       print(" <<<");
       print(str);
       print(">>>");
       print_nl();
   end sub;
   
   var buf: uint8[256];
   collapse(str, &buf[0]);
   bracket_length(str);
   bracket_length(&buf[0]);
   print_nl();

end sub;

  1. Strings from the task

var strings: [uint8][] := { "", "\"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 " };

  1. Collapse and print each string

var i: @indexof strings := 0; while i < @sizeof strings loop

   show(strings[i]);
   i := i + 1;

end loop;</lang>

Output:
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 >>>

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

Delphi

Translation of: D

<lang Delphi> program Determine_if_a_string_is_collapsible;

{$APPTYPE CONSOLE}

uses

 System.SysUtils;

procedure collapsible(s: string); var

 c, last: char;
 len: Integer;

begin

 writeln('old: <<<', s, '>>>, length = ', s.length);
 write('new: <<<');
 last := #0;
 len := 0;
 for c in s do
 begin
   if c <> last then
   begin
     write(c);
     inc(len);
   end;
   last := c;
 end;
 writeln('>>>, length = ', len, #10);

end;

begin

 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 its hell. ');
 collapsible('                                                    --- Harry S Truman  ');
 readln;

end.</lang>

F#

<lang fsharp> // Collapse a String. Nigel Galloway: June 9th., 2020 //As per the task description a function which 'determines if a character string is collapsible' by testing if any consecutive characters are the same. let isCollapsible n=n|>Seq.pairwise|>Seq.tryFind(fun(n,g)->n=g) //As per the task description a function which 'if the string is collapsable, collapses the string (by removing immediately repeated characters). let collapse n=match isCollapsible n with

               Some _->let i=Seq.head n
                       let fN=let mutable g=i in (fun n->if n=g then false else g<-n; true)
                       let g=System.String([|yield i;yield! Seq.tail n|>Seq.filter fN|])
                       printfn "<<<%s>>> (length %d) colapses to <<<%s>>> (length %d)" n n.Length g g.Length
              |     _->printfn "<<<%s>>> (length %d) does not colapse" n n.Length

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 " collapse "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)


FreeBASIC

Translation of: BASIC

<lang freebasic>Const numCad = 5 Data "" Data "'If I were two-faced, would I be wearing this one?' --- Abraham Lincoln " Data "..1111111111111111111111111111111111111111111111111111111111111117777888" Data "I never give 'em hell, I just tell the truth, and they think it's hell. " Data " --- Harry S Truman "

Dim Shared As String cadIN, cadOUT

Sub Collapse

   Dim As String a, b
   If cadIN = "" Then cadOUT = cadIN: Exit Sub
   cadOUT = Space(Len(cadIN))
   a = Left(cadIN,1)
   Mid(cadOUT,1,1) = a
   Dim As Integer txtOUT = 2
   For i As Integer = 2 To Len(cadIN)
       b = Mid(cadIN,i,1)
       If a <> b Then Mid(cadOUT,txtOUT,1) = b: txtOUT += 1: a = b
   Next i
   cadOUT = Left(cadOUT,txtOUT-1)

End Sub

For j As Integer = 1 To numCad

   Read cadIN
   Collapse
   Print " <<<"; cadIN; ">>> (longitud "; Len(cadIN); _
   !")\n    se pliega a:\n <<<"; cadOUT; ">>> (longitud "; Len(cadOUT); !")\n"

Next j Sleep </lang>

Output:
 <<<>>> (longitud  0)
    se pliega a:
 <<<>>> (longitud  0)

 <<<'If I were two-faced, would I be wearing this one?' --- Abraham Lincoln >>> (longitud  72)
    se pliega a:
 <<<'If I were two-faced, would I be wearing this one?' - Abraham Lincoln >>> (longitud  70)

 <<<..1111111111111111111111111111111111111111111111111111111111111117777888>>> (longitud  72)
    se pliega a:
 <<<.178>>> (longitud  4)

 <<<I never give 'em hell, I just tell the truth, and they think it's hell. >>> (longitud  72)
    se pliega a:
 <<<I never give 'em hel, I just tel the truth, and they think it's hel. >>> (longitud  69)

 <<<                                                    --- Harry S Truman  >>> (longitud  72)
    se pliega a:
 <<< - Hary S Truman >>> (longitud  17)


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 = «««😍😀🙌💃😍🙌»»»

Groovy

Translation of: Java

<lang groovy>class StringCollapsible {

   static void main(String[] args) {
       for ( String s : [
               "",
               "\"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 input) {
       StringBuilder sb = new StringBuilder()
       for ( int i = 0 ; i < input.length() ; i++ ) {
           if ( i == 0 || input.charAt(i-1) != input.charAt(i) ) {
               sb.append(input.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>>>

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>>>

JavaScript

<lang javaScript> String.prototype.collapse = function() {

 let str = this;
 for (let i = 0; i < str.length; i++) {
   while (str[i] == str[i+1]) str = str.substr(0,i) + str.substr(i+1);
 }
 return str;

}

// testing 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  '

]; for (let i = 0; i < strings.length; i++) {

 let str = strings[i], col = str.collapse();
 console.log(`«««${str}»»» (${str.length})`);
 console.log(`«««${col}»»» (${col.length})`);

} </lang>

Output:

«««»»» (0) «««»»» (0) «««"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln »»» (72) «««"If I were two-faced, would I be wearing this one?" - Abraham Lincoln »»» (70) «««..1111111111111111111111111111111111111111111111111111111111111117777888»»» (72) «««.178»»» (4) «««I never give 'em hell, I just tell the truth, and they think it's hell. »»» (72) «««I never give 'em hel, I just tel the truth, and they think it's hel. »»» (69) «««  --- Harry S Truman  »»» (72) ««« - Hary S Truman »»» (17)

jq

Here we can use the Unix-like `uniq` function defined on (JSON) arrays to define `collapse` on (JSON) strings: <lang jq># Input: an array

  1. Output: a stream

def uniq: foreach .[] as $x ({x:nan, y:.[0]}; {x:$x, y:.x}; select(.x != .y) | .x);

def collapse: explode | [uniq] | implode; </lang>

The program for the given task can now be written in three lines:

<lang jq>def Guillemets: "«««\(.)»»»";

"Original: \(Guillemets) has length \(length)", (collapse | "Collapsed \(Guillemets) has length \(length)") </lang>

Using the following invocation on the five "raw" (i.e. unquoted) strings yields the results as shown:

   jq -Rrf program.jq raw.txt

<lang sh>Original: «««»»» has length 0 Collapsed «««»»» has length 0 Original: «««"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln »»» has length 72 Collapsed «««"If I were two-faced, would I be wearing this one?" - Abraham Lincoln »»» has length 70 Original: «««..1111111111111111111111111111111111111111111111111111111111111117777888»»» has length 72 Collapsed «««.178»»» has length 4 Original: «««I never give 'em hell, I just tell the truth, and they think it's hell. »»» has length 72 Collapsed «««I never give 'em hel, I just tel the truth, and they think it's hel. »»» has length 69 Original: «««  --- Harry S Truman  »»» has length 72 Collapsed ««« - Hary S Truman »»» has length 17</lang>


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

Translation of: Go

<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»»»

Lua

Translation of: C#

<lang lua>function collapse(s)

   local ns = ""
   local last = nil
   for c in s:gmatch"." do
       if last then
           if last ~= c then
               ns = ns .. c
           end
           last = c
       else
           ns = ns .. c
           last = c
       end
   end
   return ns

end

function test(s)

   print("old: " .. s:len() .. " <<<" .. s .. ">>>")
   local a = collapse(s)
   print("new: " .. a:len() .. " <<<" .. a .. ">>>")

end

function main()

   test("")
   test("The better the 4-wheel drive, the further you'll be from help when ya get stuck!")
   test("headmistressship")
   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  ")

end

main()</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 >>>

Mathematica / Wolfram Language

<lang Mathematica>ClearAll[StringCollapse] StringCollapse[s_String] := FixedPoint[StringReplace[y_ ~~ y_ :> y], s] 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 "}; Do[

Print["«««" <> s <> "»»»"];
Print["Length = ", StringLength[s]];
Print["«««" <> StringCollapse[s] <> "»»»"];
Print["Length = ", StringLength[StringCollapse[s]]]
,
{s, strings}
]</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

MATLAB / Octave

<lang Matlab> function r = collapse(s)

 ix=find((s(1:end-1)==s(2:end))+1;
 r=s;
 r(ix)=[];     
 fprintf(1,'Input:  <<<%s>>>  length: %d\n',s,length(s));
 fprintf(1,'Output: <<<%s>>>  length: %d\n',r,length(r));
 fprintf(1,'Character to be squeezed: "%s"\n',c);

end


collapse(, ' ') collapse('║╚═══════════════════════════════════════════════════════════════════════╗', '-') collapse('║"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln ║', '7') collapse('║..1111111111111111111111111111111111111111111111111111111111111117777888║', '.') collapse('║I never give em hell, I just tell the truth, and they think its hell. ║', '.') collapse('║ --- Harry S Truman ║', '.') collapse('║ --- Harry S Truman ║', '-') collapse('║ --- Harry S Truman ║', 'r')

</lang>

Output:
Input:  <<<>>>  length: 0
Output: <<<>>>  length: 0
ans = 
Input:  <<<║╚═══════════════════════════════════════════════════════════════════════╗>>>  length: 222
Output: <<<║╚═══════════════════════════════════════════════════════════════════════╗>>>  length: 222
ans = ║╚═══════════════════════════════════════════════════════════════════════╗
Input:  <<<║"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln ║>>>  length: 78
Output: <<<║"If I were two-faced, would I be wearing this one?" - Abraham Lincoln ║>>>  length: 76
ans = ║"If I were two-faced, would I be wearing this one?" - Abraham Lincoln ║
Input:  <<<║..1111111111111111111111111111111111111111111111111111111111111117777888║>>>  length: 78
Output: <<<║.178║>>>  length: 10
ans = ║.178║
Input:  <<<║I never give 'em hell, I just tell the truth, and they think it's hell. ║>>>  length: 78
Output: <<<║I never give 'em hel, I just tel the truth, and they think it's hel. ║>>>  length: 75
ans = ║I never give 'em hel, I just tel the truth, and they think it's hel. ║
Input:  <<<║                                                    --- Harry S Truman  ║>>>  length: 78
Output: <<<║ - Hary S Truman ║>>>  length: 23
ans = ║ - Hary S Truman ║
Input:  <<<║                                                    --- Harry S Truman  ║>>>  length: 78
Output: <<<║ - Hary S Truman ║>>>  length: 23
ans = ║ - Hary S Truman ║
Input:  <<<║                                                    --- Harry S Truman  ║>>>  length: 78
Output: <<<║ - Hary S Truman ║>>>  length: 23
ans = ║ - Hary S Truman ║
PASSES 1 out of 1 test

Nim

<lang Nim>import unicode, strformat

proc collapse(s: string) =

 let original = s.toRunes
 echo fmt"Original:  length = {original.len}, string = «««{s}»»»"
 var previous = Rune(0)
 var collapsed: seq[Rune]
 for rune in original:
   if rune != previous:
     collapsed.add(rune)
     previous = rune
 echo fmt"Collapsed: length = {collapsed.len}, string = «««{collapsed}»»»"
 echo ""


const 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:

 s.collapse()</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 = «««😍😀🙌💃😍🙌»»»

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

function collapsible(string t) -- sequence utf32 = utf8_to_utf32(t) -- maybe -- for i=2 to length(utf32) do -- """ -- if utf32[i]=utf32[i-1] then -- """

   for i=2 to length(t) do
       if t[i]=t[i-1] then
           return true
       end if
   end for
   return false

end function

puts(1,"\nAs predicate: ") for i=1 to length(tests) do

   printf(1,"%t ",collapsible(tests[i]))

end for puts(1,"\n")</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 >>>

As predicate: false true true true true

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)

PL/M

Because of the limited character set supported by the PL/M-80 compiler, uppercase letters have been substituted for lowercase letters, the question mark for the period, and the single quotation mark for the double quotation mark. This has no other effect on the output. While it would be possible to write the ASCII values as numbers, this would make the code less clear. The COLLAPSE procedure compares bytes and would be fine with any 8-bit input.

<lang plm>100H: BDOS: PROCEDURE (FN, ARG); DECLARE FN BYTE, ARG ADDRESS; GO TO 5; END BDOS; EXIT: PROCEDURE; CALL BDOS(0,0); END EXIT; PRINT: PROCEDURE (S); DECLARE S ADDRESS; CALL BDOS(9, S); END PRINT;

/* PRINT NUMBER */ PRINT$NUMBER: PROCEDURE (N);

   DECLARE S (6) BYTE INITIAL ('.....$');
   DECLARE (N, P) ADDRESS, C BASED P BYTE;
   P = .S(5);

DIGIT:

   P = P - 1;
   C = N MOD 10 + '0';
   N = N / 10;
   IF N > 0 THEN GO TO DIGIT;
   CALL PRINT(P);

END PRINT$NUMBER;

/* STRING LENGTH */ STR$LEN: PROCEDURE (STR) ADDRESS;

   DECLARE (STR, I) ADDRESS, S BASED STR BYTE;
   I = 0;
   DO WHILE S(I) <> '$';
       I = I + 1;
   END;
   RETURN I;

END STR$LEN;

/* COLLAPSE */ COLLAPSE: PROCEDURE (IN, OUT);

   DECLARE (IN, OUT) ADDRESS, (I BASED IN, O BASED OUT, C) BYTE;
   C = I;
   DO WHILE C <> '$';
       IN = IN + 1;
       IF I <> C THEN DO;
           O = C;
           OUT = OUT + 1;
           C = I;
       END;
   END;
   O = '$';

END COLLAPSE;

/* PRINT STRING AND LENGTH WITH BRACKETS */ PRINT$BRACKETS: PROCEDURE (S);

   DECLARE S ADDRESS;
   CALL PRINT$NUMBER(STR$LEN(S));
   CALL PRINT(.' <<<$');
   CALL PRINT(S);
   CALL PRINT(.('>>>',13,10,'$'));

END PRINT$BRACKETS;

/* GIVEN A STRING, PRINT IT AND ITS COLLAPSED FORM */ SHOW: PROCEDURE (S);

   DECLARE S ADDRESS, BUFFER (256) BYTE;
   CALL COLLAPSE(S, .BUFFER);
   CALL PRINT$BRACKETS(S);
   CALL PRINT$BRACKETS(.BUFFER);
   CALL PRINT(.(13,10,'$'));

END SHOW;

/* STRINGS FROM THE TASK */ DECLARE X (5) ADDRESS; X(0)=.'$'; X(1)=.(IF I WERE TWO-FACED, WOULD I BE WEARING ',

      'THIS ONE. --- ABRAHAM LINCOLN $');

X(2)=.('..111111111111111111111111111111111111111',

      '1111111111111111111111117777888$');

X(3)=.('I NEVER GIVE EM HELL, I JUST TELL THE TR',

      'UTH, AND THEY THINK ITS HELL. $');

X(4)=.(' ',

      '            --- HARRY S TRUMAN $');
      

DECLARE I BYTE; DO I=0 TO LAST(X);

   CALL SHOW(X(I));

END; CALL EXIT; EOF </lang>

Output:
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 >>>

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" .

PureBasic

<lang PureBasic>EnableExplicit DataSection

 STR1:
 Data.s ""
 STR2:
 Data.s "'If I were two-faced, would I be wearing this one?' --- Abraham Lincoln "
 STR3:
 Data.s "..1111111111111111111111111111111111111111111111111111111111111117777888"
 STR4:
 Data.s "I never give 'em hell, I just tell the truth, and they think it's hell. "
 STR5:
 Data.s "                                                    --- Harry S Truman  "

EndDataSection

Procedure.s collapse(txt$)

 Define *c.Character=@txt$, last.c=0, result$
 While *c\c
   If *c\c<>last
     result$+Chr(*c\c)
     last=*c\c
   EndIf
   *c+SizeOf(Character)
 Wend
 ProcedureReturn result$

EndProcedure

OpenConsole("") Define *p_data=?STR1, buf$ While *p_data<=?STR4+StringByteLength(PeekS(?STR4))+2

 buf$=PeekS(*p_data)
 PrintN("Before collapse: «««"+buf$+"»»» (length: "+Str(Len(buf$))+")")
 buf$=collapse(PeekS(*p_data))
 PrintN("After  collapse: «««"+buf$+~"»»» (length: "+Str(Len(buf$))+~")\n")
 *p_data+StringByteLength(PeekS(*p_data))+2

Wend Input()</lang>

Output:
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)

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


  1. 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:]))
   )


  1. ------------------------- TEST --------------------------
  2. 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
   ])


  1. MAIN ---

if __name__ == '__main__':

   main()</lang>
Output:
[False, True, True, True, True, True, True, True, True, False]

Quackery

<lang Quackery> [ false -1 rot

   witheach
     [ 2dup = iff
         [ drop dip not 
           conclude ]
       else nip ]
   drop ]                       is collapsible ( $ --> b )

 [ [] -1 rot
   witheach 
     [ 2dup = iff drop
       else
         [ nip dup dip join ] ]
   drop ]                       is collapse    ( $ --> $ )
 [ dup collapsible iff 
     [ dup collapse 
       swap 2 ] 
   else 
     [ say "(Not collapsible.)" cr
       1 ]
   times 
     [ say "<<<" 
       dup echo$ 
       say ">>>" cr 
       say "   Length: " 
       size echo
       say " characters" cr cr ]
   cr ]                         is task     ( $ -->   )

$ "" task $ '"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln ' task $ "..1111111111111111111111111111111111111111111111111111111111111117777888" task $ "I never give 'em hell, I just tell the truth, and they think it's hell. " task $ " --- Harry S Truman " task</lang>

Output:
(Not collapsible.)
<<<>>>
   Length: 0 characters


<<<"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln >>>
   Length: 72 characters

<<<"If I were two-faced, would I be wearing this one?" - Abraham Lincoln >>>
   Length: 70 characters


<<<..1111111111111111111111111111111111111111111111111111111111111117777888>>>
   Length: 72 characters

<<<.178>>>
   Length: 4 characters


<<<I never give 'em hell, I just tell the truth, and they think it's hell. >>>
   Length: 72 characters

<<<I never give 'em hel, I just tel the truth, and they think it's hel. >>>
   Length: 69 characters


<<<                                                    --- Harry S Truman  >>>
   Length: 72 characters

<<< - Hary S Truman >>>
   Length: 17 characters


Racket

<lang Racket>#lang racket

(define (collapse text)

 (if (< (string-length text) 2)
     text
     (string-append
      (if (equal? (substring text 0 1) (substring text 1 2))
          "" (substring text 0 1))
      (collapse (substring text 1)))))
Test cases

(define tcs

 '(""
   "\"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 ([text tcs])

 (let ([collapsed (collapse text)])
   (display (format "Original  (size ~a): «««~a»»»\nCollapsed (size ~a): «««~a»»»\n\n"
                    (string-length text) text
                    (string-length collapsed) collapsed))))

</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): «««😍😀🙌💃😍🙌»»»

Raku

(formerly Perl 6)

Works with: Rakudo version 2019.07.1

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. */
    new= collapse(@.j)
    say 'string' word("isn't is",1+collapsible) 'collapsible' /*display semaphore value*/
    say '    length='right(L, 3)     "   input=«««"  ||  @.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 expose collapsible; parse arg y 1 $ 2 /*get the 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  (1st arg). */
           if _==right($, 1)  then iterate      /*Is this the same character?  Skip it.*/
           $= $ || _                            /*append the character, it's different.*/
           end   /*j*/
         collapsible= y\==$;       return $     /*set boolean to  true  if collapsible.*/</lang>
output   when using the internal default inputs:
═════════════════════════════════════════════════════════════════════════════════════════════════════════
string isn't collapsible
    length=  0    input=«««»»»
    length=  0   output=«««»»»
═════════════════════════════════════════════════════════════════════════════════════════════════════════
string is collapsible
    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 »»»
═════════════════════════════════════════════════════════════════════════════════════════════════════════
string is collapsible
    length= 72    input=«««..1111111111111111111111111111111111111111111111111111111111111117777888»»»
    length=  4   output=«««.178»»»
═════════════════════════════════════════════════════════════════════════════════════════════════════════
string is collapsible
    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. »»»
═════════════════════════════════════════════════════════════════════════════════════════════════════════
string is collapsible
    length= 72    input=«««                                                   ---  Harry S Truman  »»»
    length= 17   output=««« - Hary S Truman »»»
═════════════════════════════════════════════════════════════════════════════════════════════════════════

Ring

<lang ring> load "stdlib.ring"

see "working..." + nl + nl str = ["The better the 4-wheel drive, the further you'll be from help when ya get stuck!",

      "I never give 'em hell, I just tell the truth, and they think it's hell.",
      "..1111111111111111111111111111111111111111111111111111111111111117777888"]

strsave = str for n = 1 to len(str)

   for m = 1 to len(str[n])-1
       if substr(str[n],m,1) = substr(str[n],m+1,1)
          str[n] = left(str[n],m) + right(str[n],len(str[n])-m-1)
          for p = len(str[n]) to 2 step -1
              if substr(str[n],p,1) = substr(str[n],p-1,1)
                 str[n] = left(str[n],p-1) + right(str[n],len(str[n])-p)
              ok
          next
       ok
    next

next

for n = 1 to len(str)

   see "" + len(strsave[n]) + "«««" + strsave[n] + "»»»" + nl
   see "" + len(str[n]) + "«««" + str[n] + "»»»" + nl + nl

next

see "done..." + nl </lang> Output:

working...

80«««The better the 4-wheel drive, the further you'll be from help when ya get stuck!»»»
77«««The beter the 4-whel drive, the further you'l be from help when ya get stuck!»»»

71«««I never give 'em hell, I just tell the truth, and they think it's hell.»»»
68«««I never give 'em hel, I just tel the truth, and they think it's hel.»»»

72«««..1111111111111111111111111111111111111111111111111111111111111117777888»»»
4«««.178»»»

done...

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)

Smalltalk

Works with: Smalltalk/X

<lang smalltalk>#(

 'The better the 4-wheel drive, the further youll be from help when ya get stuck!'
 'headmistressship'
 'aardvark'
 '😍😀🙌💃😍😍😍🙌'

) do:[:eachWord |

 |shortened|
 shortened := 
   String streamContents:[:out |
       eachWord inject:nil into:[:prev :this |
           prev ~= this ifTrue:[out nextPut:this].
           this
       ]
   ].
 Transcript 
   showCR:( eachWord,'(length:',eachWord size,')' );
   showCR:( shortened,'(length:',shortened size,')' ). 

]</lang>

Output:
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

Translation of: C#

<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 »»»

VBA

Function : <lang vb>Function Collapse(strIn As String) As String Dim i As Long, strOut As String

   If Len(strIn) > 0 Then
       strOut = Mid$(strIn, 1, 1)
       For i = 2 To Len(strIn)
           If Mid$(strIn, i, 1) <> Mid$(strIn, i - 1, 1) Then
               strOut = strOut & Mid$(strIn, i, 1)
           End If
       Next i
   End If
   Collapse = strOut

End Function</lang> To Call : <lang vb>Sub CallCollapse() Dim S As String

   S = vbNullString
   Debug.Print "String : <<<" & S & ">>>", "Lenght : " & Len(S)
   Debug.Print "Collapsed : <<<" & Collapse(S) & ">>>", "Lenght : " & Len(Collapse(S))
   S = """If I were two-faced, would I be wearing this one?"" --- Abraham Lincoln "
   Debug.Print "String : <<<" & S & ">>>", "Lenght : " & Len(S)
   Debug.Print "Collapsed : <<<" & Collapse(S) & ">>>", "Lenght : " & Len(Collapse(S))
   S = "..1111111111111111111111111111111111111111111111111111111111111117777888"
   Debug.Print "String : <<<" & S & ">>>", "Lenght : " & Len(S)
   Debug.Print "Collapsed : <<<" & Collapse(S) & ">>>", "Lenght : " & Len(Collapse(S))
   S = "I never give 'em hell, I just tell the truth, and they think it's hell. "
   Debug.Print "String : <<<" & S & ">>>", "Lenght : " & Len(S)
   Debug.Print "Collapsed : <<<" & Collapse(S) & ">>>", "Lenght : " & Len(Collapse(S))
   S = "                                                    --- Harry S Truman  "
   Debug.Print "String : <<<" & S & ">>>", "Lenght : " & Len(S)
   Debug.Print "Collapsed : <<<" & Collapse(S) & ">>>", "Lenght : " & Len(Collapse(S))

End Sub</lang>

Output:
String : <<<>>>             Lenght : 0
Collapsed : <<<>>>          Lenght : 0
String : <<<"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln >>>           Lenght : 72
Collapsed : <<<"If I were two-faced, would I be wearing this one?" - Abraham Lincoln >>>          Lenght : 70
String : <<<..1111111111111111111111111111111111111111111111111111111111111117777888>>>           Lenght : 72
Collapsed : <<<.178>>>      Lenght : 4
String : <<<I never give 'em hell, I just tell the truth, and they think it's hell. >>>           Lenght : 72
Collapsed : <<<I never give 'em hel, I just tel the truth, and they think it's hel. >>>           Lenght : 69
String : <<<                                                    --- Harry S Truman  >>>           Lenght : 72
Collapsed : <<< - Hary S Truman >>>       Lenght : 17

Wren

Translation of: Go
Library: Wren-fmt

<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");

  1. <<<

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<<<