Mezza retromarcia di una stringa binaria


12

Questa è una domanda di follow-up alla mia domanda su Puzzling.SE : ho chiesto se esiste una funzione f che associa le stringhe booleane alle stringhe booleane, in modo che f (f (b)) = reverse (b) per tutte le stringhe di input b . (Per inverso , intendo la funzione che inverte l'ordine dei bit.)

Il link sopra contiene una risposta positiva, con prova, della grande f '' , ma potresti voler ponderare la domanda da solo prima di guardare.

Implementare tale funzione f nel minor numero di byte possibile.

  • È possibile leggere l'input da STDIN o accettare un argomento della funzione; e scrivere la stringa del risultato su STDOUT o restituirla.

  • In entrambi i casi, è possibile lavorare con stringhe effettive di due byte o caratteri distinti di propria scelta (dire 0e 1, o \x00e \x01) o con matrici / elenchi di valori di verità e falsità . Scegli due valori e attenersi a quelli, però.

  • Il risultato di una singola applicazione di f deve essere una stringa binaria stessa: nessuna risposta sciocca come b -> if b starts with 'x' then reverse(b[1:]) else 'x' + b...

  • La tua funzione dovrebbe essere totale ; in particolare, l'input può essere la stringa vuota, oppure lunga un bit, ecc. Non esiste un limite superiore per la lunghezza della stringa.

  • Dovrebbe anche essere puro : non mantenere uno stato globale tra le chiamate di funzione; la stringa di input deve determinare completamente la stringa di output.


L'output può avere una lunghezza diversa rispetto all'input?
Luis Mendo,

Sicuro! (In realtà, altrimenti, la sfida è dimostrabile impossibile.)
Lynn

Deve funzionare per stringhe di lunghezza una o zero?
CalcolatriceFeline

Sì; la funzione deve essere totale. L'ho chiarito nella domanda!
Lynn

Risposte:



7

Python 2, 64 69 byte

def f(s):p=(s+s).find(s,1);return[s[~p::-1],s+s[:p]][len(s)/p%2]

Ungolfed:

def f(s):
    p = (s+s).find(s,1)
    n = len(s)/p
    return s[:p][::1|n%-2] * -~(n-1^1)

Questo trova il periodo della stringa, ovvero il minimo ptale che sè una stringa di lunghezza pripetuta nvolte (ho trovato un metodo golfy su SO). Quindi, se nè dispari, aggiunge un'altra ripetizione del periodo. Se nè pari, rimuove una ripetizione del periodo e lo inverte.

Grazie a @ Sp3000 per l'aiuto nell'implementazione della mappatura delle funzioni tra 1 <-> 2, 3 <-> 4, ecc.


... Quando verrà aggiornato il codice non salvato?
Calcolatrice

@CatsAreFluffy Non ho in programma di modificare il codice ungolfed in quanto utilizza la stessa idea con solo una banale differenza. L'inglese d'altra parte è aggiornato.
feersum

2

Perl, 49 47 byte

Include +2 per -lp

Basato sull'algoritmo molto bello di @ feersum

Esegui con input su STDIN, ad es

perl -lp halfreverse.pl <<< "101001"

halfreverse.pl:

/^(.+?)((\1\1?)*)$/;$_=$3eq$1?reverse$2:$_.$1

Spiegazione

/^               $/         Match the complete input string
  (.+?)                     Non-greedy match. Try only one digit at the start,
                            if that doesn't work try 2, then 3 etc. The string
                            being tried is remembered in backreference \1
       ((\1\1?)*)           Try to repeat \1 as many times as possible but
                            prefer in groups of 2. Fall back to only 1 at the
                            end of the string if the trailing part has an odd
                            number of \1 (so the total count is even)

   $3eq$1                   So the last match $3 equals the first match $1
         ?                  if and only if the total count is even
          reverse$2         If total count is even drop the first instance of
                   :        \1 and reverse
                    $_.$1   If total count is odd extend $_ by one instance
$_=                         Assign result

Come funziona??
Calcolatrice
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.