Praming Puzles & Colf: Condense a String


25

Avendo trascorso un po 'di tempo su questo sito, sono venuto a godermi le cose il più breve possibile. Questo potrebbe essere il motivo per cui recentemente sono stato offeso dalle stringhe contenenti gli stessi caratteri più di una volta. Il tuo compito è scrivere una funzione o un programma che condensa una determinata stringa in base alle seguenti regole:

  • Inizia con una condensazione 0 , ovvero cerca la prima coppia (più a sinistra) degli stessi caratteri con altri 0 caratteri tra di loro. Se viene trovata una tale coppia, rimuovere uno dei due caratteri e riavviare l'algoritmo eseguendo un'altra 0-condensa . Se non viene trovata tale coppia, procedere con il passaggio successivo. Esempi:
    programming-C0-> programing
    aabbcc-C0-> abbcc
    test-C0->test

  • Quindi esegui 1 condensazione , ovvero cerca la prima coppia di stessi personaggi con 1 altro carattere tra di loro. Se viene trovata una tale coppia, rimuovine uno e tutti i caratteri tra loro e riavvia con una condensazione 0 . Se non viene trovata tale coppia, procedere con il passaggio successivo. Esempi:
    abacac-C1-> acac
    java-C1->ja

  • Continuare con una condensa 2 e così via fino a una condensa con n che sia la lunghezza della stringa originale, ogni volta il riavvio dopo una condensa rimuove alcune lettere. Esempi:
    programing-C2-> praming
    abcdafg-C3->afg

La stringa risultante si chiama condensata e contiene ogni carattere al massimo una volta.


Ingresso:

Una stringa in minuscolo di caratteri ASCII stampabili.

Produzione:

La stringa condensata secondo le regole sopra.

Esempi:

examples     -> es
programming  -> praming
puzzles      -> puzles
codegolf     -> colf
andromeda    -> a
abcbaccbabcb -> acb
if(x==1):x++ -> if(x+
fnabnfun     -> fun
abcdefae     -> abcde

Esempi dettagliati per chiarire come funziona l'algoritmo:

fnabnfun -C0-> fnabnfun -C1-> fnabnfun -C2-> fnfun -C0-> fnfun -C1-> fun -C0-> fun 
 -C1-> fun -C2-> ... -C8-> fun

abcbaccbabcb -C0-> abcbacbabcb -C0-> abcbacbabcb -C1-> abacbabcb -C0-> abacbabcb 
 -C1-> acbabcb -C0-> acbabcb -C1-> acbcb -C0-> acbcb -C1-> acb -C0-> acb 
 -C1-> ... -C12-> acb

Il tuo approccio non deve implementare l'algoritmo dall'alto fintanto che la tua soluzione e l'algoritmo restituiscono lo stesso output per tutti gli input consentiti. Questa è una sfida di .


Grazie a @Linus per i commenti utili sulla sandbox!


Il caso di test di @MartinEnder Riley è ancora necessario, perché è l'unico su cui la mia soluzione Retina non funziona.
mbomb007,

@ mbomb007 Ah, capisco. Buon punto.
Martin Ender,

La stringa di input conterrà mai caratteri non stampabili come gli spazi?
mbomb007,

@ mbomb007 No, assumere solo caratteri ASCII stampabili va bene.
Laikoni,

@ mbomb007 Tuttavia, per quanto ne so, uno spazio è considerato un carattere ASCII stampabile, ad esempio qui .
Laikoni,

Risposte:


6

JavaScript (ES6), 74 byte

f=
(s,n=0,m=s.match(`(.).{${n}}\\1`))=>s[n]?m?f(s.replace(...m)):f(s,n+1):s
;
<input oninput=o.textContent=f(this.value)><pre id=o>


Molto bello, più corto di quello che avrei pensato.
ETHproductions,

5

Perl, 38 31 30 29 byte

Questo dovrebbe lasciare le lingue non golf molto indietro ...

-1 per $-[0] grazie a Riley

-1 per @{-} grazie a Dada

Include +1 per -p

Dare input su STDIN

condense.pl:

#!/usr/bin/perl -p
s/(.)\K.{@{-}}\1// while/./g

Questa versione da 27 byte dovrebbe funzionare ma non funziona perché il perl non si interpola @-in una regex (vedi /programming/39521060/why-are-etc-not-interpolated-in-strings )

#!/usr/bin/perl -p
s/(.)\K.{@-}\1// while/./g

Come funziona la @{\@-}parte? Ho pensato che @-contenesse gli indici di ogni partita, quindi come "conta" su ogni iterazione. Inoltre, se stampi @{\@-}prima e dopo ogni sostituzione, stampa solo 1 o 2.
Riley,

1
@Riley L' /./gavanzamento di 1 nella stringa ogni volta, tranne quando la stringa cambia, quindi viene reimpostata su 0. Se si stampa @-dopo il /./gma prima che la s///si vedrà salire (utilizzare un test in cui la stringa rimanente è abbastanza grande)
Ton Hospel,

La stampa $-[0]fornisce i numeri che mi aspetterei. Si @{\@-}comporta come a $-[0]causa del contesto regex ma non quando si stampa per qualche motivo? $-[0]è un byte più breve di @{\@-}se sono uguali.
Riley,

"@{\@-}"non è lo stesso di @{\@-}(senza ").
Riley,

@Riley No, ma "@{\@-}"è lo stesso di "@-". E questo dovrebbe valere anche per una sostituzione regex ma non lo è. Allo stesso modo $-[0]dovrebbe funzionare ma non lo fa. PS: Probabilmente in qualche modo avevi applicato il contesto scalare a @-quando hai fatto la tua stampa, quindi hai sempre ottenuto 1 o 2
Ton Hospel,

3

CJam , 35 byte

rL{_,{{(_@_@#I={I)>]sj}*}h]s}fI}j

Provalo online!


rL{                            }j   | run recursion on input
   _,{                      }fI     | for I from 0 to length(input)
      {                 }h]s        | one pass & clean up
       (_@                          | slice and store leading element A
          _@#I={      }*            | if next A is I steps away
                I)>                 | slice off I+1 element
                   ]sj              | clean up & recursion

È possibile visualizzare le singole condense inserendoed


2

Python 2, 117 104 101 byte

Esegui ricorsivamente le sostituzioni necessarie. Costruisco la regex in modo dinamico.

import re
def f(s,i=0):t=re.sub(r"(.)%s\1"%("."*i),r"\1",s);e=s==t;return i>len(t)and t or f(t,i*e+e)

Provalo online


Le due linee di ritorno possono essere condensate return i>len(t) and t or s!=t and f(t) or f(t,i+1)per una rete di -4 byte
Quelklef,

Altri 2 byte possono essere eliminati modificandolo inreturn t if i>len(t)else s!=t and f(t)or f(t,i+1))
Quelklef,

Ancora di più e=s==t;return i>len(t)and t or f(t,i*e+e)e poi puoi rimuovere i=0nella definizione della funzione, ma dovrai chiamare con 0 start.
Quelklef,

Presumo che i quattro spazi siano lì non perché li stai usando quattro, ma perché SE li espande automaticamente. In caso contrario, è possibile modificare tutti gli spazi in una delle schede o in uno spazio singolo per -9 byte.
Fondi Monica's Lawsuit,

@Quelklef Il meta proibisce di prendere parametri aggiuntivi.
mbomb007,

1

Perl 53 52

Include +1 per -p

for($i=0;$i<length;){$i=(s/(.).{$i}\1/\1/)?0:$i+1;}

Provalo su ideone .


1

Mathematica, 101 byte

NestWhile[i=0;StringReplace[#,a_~~_~RepeatedNull~i++~~a_:>a,1]&,#,SameQ,2,ByteCount@#]&~FixedPoint~#&

Dovrebbe esserci un modo per ridurre questo ...


1

PHP, 90 byte

for($s=$argv[$c=1];$s[$i=++$i*!$c];)$s=preg_replace("#(.).{{$i}}\\1#","$1",$s,1,$c);echo$s;

o 92 byte

for($s=$argv[1];$s[$i];$i=++$i*!$c)$s=preg_replace("#(.).{".+$i."}\\1#","$1",$s,1,$c);echo$s;   

1
1) prima versione: +$ianziché $i+=0(-2). 2) forloop invece di whilepuò salvare due byte e consentire di rimuovere curlys (-4). 3) $i=++$i*!$canziché $i=$c?0:$i+1(-1). 4) \\2non è necessario, rimuovere le parentesi (-2). 5) Puoi consentire il limite 9invece che 1per la velocità (+0)
Tito

@Titus idee molto buone. Non avevo visto questo grazie
Jörg Hülsermann,

Ora che ci ripenso ... +$inon funziona in ogni caso. Prova hammer. PHP non si lamenta delle parentesi graffe vuote nella regex; ma non corrisponde come desiderato. A proposito: conto 91, non 90. Ma prova il nuovo 1)for($s=$argv[$c=1];$s[$i=++$i*!$c];)
Tito

@Titus Sì, torno a $i+=0e proverò la tua proposta in seguito. Cosa significa martello?
Jörg Hülsermann,

@Titus va bene lo stesso problema se puzzleo qualcos'altro, (.)//1ma va bene con la tua proposta o il$i´=0
Jörg Hülsermann

1

Ruby, 75 anni 64 57 byte

(56 byte di codice + p opzione della riga di comando.)

Utilizzo dell'interpolazione di stringhe all'interno di una regex per controllare la lunghezza delle corrispondenze sostituite.

i=0
~/(.).{#{i}}\1/?sub($&,$1)&&i=0: i+=1while i<$_.size

Test:

$ ruby -p condense.rb <<< fnabnfun
fun

1

Haskell , 97 88 byte

(0?)
(a:s)!(b:t)|a==b=a:t|1<3=a:s!t
s!_=s
m?s|length s<m=s|a<-s!drop m s=sum[m+1|a==s]?a

Provalo online!


Vecchia versione di 97 byte:

(a:s)!(b:t)|a==b=a:t|1<3=a:s!t
s!_=s
m?s|length s==m=s|a<-s!drop m s=(last$0:[m+1|a==s])?a
c=(0?)

Provalo su ideone .

Spiegazione:

(a:s)!(b:t)|a==b = a:t         --perform condensation
           |1<3  = a:s!t       --recursively compare further
 s   ! _         = s           --no condensation performed

La (!)funzione esegue una condensa n quando viene data una stringa una volta intera e una volta con i primi n caratteri rimossi, ad esempio abcdbee cdbeper una condensazione 2, confrontando ricorsivamente i due caratteri iniziali.

m?s|length s==m   = s         --stop before performing length-s-condensation
   |a <- s!drop m s           --a is the m-condensation of s
    = (last$0:[m+1|a==s])?a   --disguised conditional:
                              -- if a==s       if the m-condensation did not change s
                              -- then (m+1)?a  then perform m+1-condensation
                              -- else 0?a      else restart with a 0-condensation

c=(0?)                        -- main function, initialise m with 0
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.