Eine binäre Zeichenfolge halb umkehren

12

Dies ist eine Folgefrage meiner Puzzling.SE Frage : Ich fragte , ob es eine Funktion ist f Mapping Boolean Strings Boolean Strings, so dass f (f (b)) = reverse (b) für alle Eingabezeichenfolgen b . ( Umgekehrt meine ich die Funktion, die die Reihenfolge der Bits umkehrt.)

Der obige Link enthält eine positive Antwort mit Beweis durch das große F '' , aber Sie möchten die Frage vielleicht selbst überdenken, bevor Sie sie sich ansehen.

Implementieren Sie eine solche Funktion f in möglichst wenigen Bytes.

  • Sie können entweder Eingaben von STDIN lesen oder ein Funktionsargument verwenden. und schreiben Sie entweder die Ergebniszeichenfolge nach STDOUT oder geben Sie sie zurück.

  • In beiden Fällen können Sie mit tatsächlichen Zeichenfolgen aus zwei unterschiedlichen Bytes oder Zeichen Ihrer Wahl (z. B. 0und 1, oder \x00und \x01) oder mit Arrays / Listen mit wahren und falschen Werten arbeiten . Wählen Sie zwei Werte und bleiben Sie dabei.

  • Das Ergebnis einer einzelnen Anwendung von f muss selbst eine Binärzeichenfolge sein: keine dummen Antworten wie b -> if b starts with 'x' then reverse(b[1:]) else 'x' + b...

  • Ihre Funktion sollte total sein ; Insbesondere kann die Eingabe eine leere Zeichenfolge oder ein Bit lang sein. Es gibt keine Obergrenze für die Länge der Zeichenfolge.

  • Es sollte auch rein sein : Behalten Sie keinen globalen Status zwischen Funktionsaufrufen bei; Die Eingabezeichenfolge muss die Ausgabezeichenfolge vollständig bestimmen.

Lynn
quelle
Kann die Ausgabe eine andere Länge als die Eingabe haben?
Luis Mendo
Sicher! (In der Tat, sonst ist die Herausforderung nachweislich unmöglich.)
Lynn
Muss es für Zeichenketten der Länge eins oder null funktionieren?
CalculatorFeline
Ja; Die Funktion muss total sein. Ich habe dies in der Frage geklärt!
Lynn
1
Verbunden.
Martin Ender

Antworten:

7

Python 2, 64-69 Bytes

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)

Dies findet die Periode der Saite, dh die minimale p, sdie eine Saite ist, die sich mehrmals pwiederholt n(ich habe eine Golfmethode für SO gefunden). Wenn ndann ungerade ist, wird eine weitere Wiederholung der Periode hinzugefügt. Wennn es gerade ist, wird eine Wiederholung der Periode entfernt und umgekehrt.

Vielen Dank an @ Sp3000 für die Unterstützung bei der Implementierung der Funktionszuordnung zwischen 1 <-> 2, 3 <-> 4 usw.

Feersum
quelle
... Wann wird der ungolfed Code aktualisiert?
CalculatorFeline
@CatsAreFluffy Ich habe nicht vor, den ungolfed Code zu ändern, da er die gleiche Idee verwendet, nur mit einem geringfügigen Unterschied. Die Engländer hingegen sind auf dem neuesten Stand.
Feersum
2

Perl, 49 47 Bytes

Beinhaltet +2 für -lp

Basierend auf @ feersums sehr schönem Algorithmus

Mit Eingabe auf STDIN ausführen, z

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

halfreverse.pl:

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

Erläuterung

/^               $/         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
Tonne Hospel
quelle
Wie funktioniert es??
CalculatorFeline