İkili dizenin yarısını tersine çevirme


12

Bu benim için bir takip sorudur Puzzling.SE soru : bir işlev var mı diye sordum f böylece Boole dizelerine Boole dizeleri haritalama f (f (b)) = (b) ters tüm girişindeki dizeleri için b . ( Tersine , bitlerin sırasını tersine çeviren işlevi kastediyorum.)

Yukarıdaki bağlantı büyük f tarafından kanıtla olumlu bir cevap içeriyor '' , ancak bakmadan önce soruyu kendiniz düşünmek isteyebilirsiniz.

Böyle bir f işlevini olabildiğince az bayt olarak uygulayın.

  • STDIN'den girişi okuyabilir veya bir işlev argümanı alabilirsiniz; ve sonuç dizesini STDOUT'a yazın veya döndürün.

  • Her iki şekilde de, seçtiğiniz iki ayrı bayt veya karakter gerçek dizeleri (söylemek birlikte çalışabilir 0ve 1ya \x00ve \x01) ya da dizilerle / listeleri truthy ve falsy değerler . İki değer seçin ve bunlara sadık kalın.

  • Tek bir uygulamanın sonucu f gerekir ikili dize kendisi olmak: hayır saçma cevaplar gibi b -> if b starts with 'x' then reverse(b[1:]) else 'x' + b...

  • İşleviniz toplam olmalıdır ; özellikle, girdi boş dize veya bir bit uzunluğunda, vb. olabilir. Dizenin uzunluğu için üst sınır yoktur.

  • Ayrıca saf olmalıdır : işlev çağrıları arasında herhangi bir küresel durum bulundurmayın; giriş dizesi, çıkış dizesini tamamen belirlemelidir.


Çıktı girişten farklı uzunlukta olabilir mi?
— Luis Mendo

Elbette! (Aslında, aksi takdirde, meydan okuma imkansızdır.)
— Lynn

Bir veya sıfır uzunluktaki dizeler için çalışması gerekir mi?
— CalculatorFeline

Evet; fonksiyonun toplam olması gerekir. Bunu soruda açıklığa kavuştum!
— Lynn

Yanıtlar:



7

Python 2, 64 69 bayt

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)

Bu, dizenin periyodunu, yani tekrarlanan sürelerin uzunluğunun bir dizisi pgibi minimum bulur ( SO'da golf yöntemini buldum ). Sonra tuhafsa, dönemin bir tekrarını ekler. Eğer hatta, bu sürenin bir tekrarını ortadan kaldırır ve onu tersine çevirir.spnnn

1 <-> 2, 3 <-> 4, vb. Arasındaki fonksiyon eşlemenin uygulanmasına yardımcı olduğu için @ Sp3000 sayesinde.


... Çözülmemiş kod ne zaman güncellenecek?
— CalculatorFeline

@CatsAreFluffy Sadece önemsiz bir farkla aynı fikri kullandığından ungolfed kodunu değiştirmek için bir planım yok. Öte yandan İngilizce günceldir.
— feersum

2

Perl, 49 47 bayt

İçin +2 içerir -lp

@ Feersum'un çok güzel algoritmasına dayanarak

STDIN'de girişle çalıştırın, örn.

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

halfreverse.pl:

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

açıklama

/^               $/         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

O nasıl çalışır??
— CalculatorFeline
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.