Palindrom yapmak için bir harfi kaldırma


15

Sorun

Diyelim ki bir kelimenin harflerinden birini kaldırmak ve böylece bir palindrom olmak için neredeyse bir palindrom. Göreviniz, belirli bir kelime için bir palindrom almak için hangi harfin kaldırılacağını belirleyen bir program yazmaktır.

Herhangi bir programlama dilinde bunu yapmak için en kısa kod kazanır.

Giriş

Giriş, 2 ila 1000 karakter uzunluğunda büyük harflerden oluşan bir kelimeden oluşur.

Çıktı

Çıkarılması gereken mektubun 1 dizinli konumunu (en soldaki harfin konumu 1, diğerinin konumu 2 vb.) Çıkarın. Palindrom'a götüren olası seçenekler varsa, bu konumlardan herhangi birini çıktılayın. Belirtilen sözcük zaten bir palindrom olsa bile bir harfi kaldırmanız gerektiğini unutmayın. Verilen kelime neredeyse bir palindrom değilse, çıktı -1.


Misal

Girdi:

racercar

çıktı üretebilir:

5

çünkü bu 5harfin kaldırılması racecarbir palindromdur.

Ayrıca, girdi

racecar

yine de çıktı üretebilir

4

çünkü 4üretmek raccariçin bu harfi kaldırmak hala bir palindrom.


5
Hiç örnek gönderilmedi mi? Peki bir Palindrome'a ​​giriş yapmak mümkün değilse ne çıkar?
ProgrammerDan

3
@ Arm103 hala bahsettiğiniz örnekleri kaçırıyorsunuz
Martin Ender

27
Uyarı: "(bkz. Örnek 3)". Bu, hiçbir örnek gönderilmediğinden bunun ödev olduğunu düşündürmektedir.
Justin

3
@Quincunx Mathematica sunumundaki konuyu da okuduğunuzdan emin olun. :-)
Chris Jester-Young

3
Örnek 3'te soru eksik olduğu için bu soru konu dışı görünüyor .
devnull

Yanıtlar:


10

J - 31 25 karakter

(_1{ ::[1+[:I.1(-:|.)\.])

J için büyük ölçüde standart ücret, bu yüzden sadece serin bitleri işaret edeceğim.

  • Zarf \.denir Outfix . x u\. yuzunluğunun her infix kaldırır xgelen yve geçerli uher kaldırma sonucuna. Burada, x1'dir, ygiriş dize ve ubir (-:|.)dize onun tersini eşleşip için bir test. Bu nedenle, bu uygulamanın sonucu \., kaldırılması girişi bir palindrom yapan her karakterin yerine 1 olan booleanların bir listesidir.

  • I.yukarıdan 1 olan tüm indekslerin (0 kökenli) bir listesini oluşturur. ile 1 eklenmesi 1+bu 1 kökenli indeksleri yapar. Hiçbir indeks 1 değilse, liste boştur. Şimdi, son elemanı birlikte almaya çalışıyoruz _1{. (Çıkarılabilir harflerden herhangi birinin çıktısına izin verilir!) Bu işe yararsa, geri döneriz. Ancak, liste boşsa, hiç öğe yoktu, bu yüzden {yakaladığımız ::ve -1 ile döndürdüğümüz bir etki alanı hatası atar [.

Kullanım ( NB.yorumlar için hatırlayın ):

   (_1{ ::[1+[:I.1(-:|.)\.]) 'RACECAR'    NB. remove the E
4
   (_1{ ::[1+[:I.1(-:|.)\.]) 'RAACECAR'   NB. remove an A
3
   (_1{ ::[1+[:I.1(-:|.)\.]) 'RAAACECAR'  NB. no valid removal
_1

J. Bir python programcısı için herhangi bir öğretici öğrenmek gerekir?
Aprıʇǝɥʇuʎs

1
@Synthetica resmi olan iyi
John Dvorak

2
@Synthetica Pythoners için özel bir şey yok, ancak C Programcılar için J , zorunlu programlamadan göç eden herkes için harika bir kaynak.
algorithmmshark

10

PHP Değil Python (73):

[a[:g]+a[g+1:]==(a[:g]+a[g+1:])[::-1] for g in range(len(a))].index(1)

A, kontrol etmek istediğiniz dizedir. Ancak bu, bir palindromda çeviremiyorsanız bir hata atar. Bunun yerine,

try:print [a[:g]+a[g+1:]==(a[:g]+a[g+1:])[::-1] for g in range(len(a))].index(True)
except ValueError:print -1

EDIT: Hayır, bekle, işe yarıyor!

try: eval("<?php $line = fgets(STDIN); ?>")
except: print [a[:g]+a[g+1:]==(a[:g]+a[g+1:])[::-1] for g in range(len(a))].index(1)

Teşekkürler, bu gerçekten bu betiğin php içeriğini yaklaşık% 25 artırıyor (istediğiniz bu, değil mi?)


10
"PHP Değil" için +1;)
Martin Ender

1
php $ line = fgets (STDIN); ?>
Kullanıcı011001

2
@ User011001 Bu nereye sığar?
Aprıʇǝɥʇuʎs

1
Sen yazarak her bir char kurtarabilecek 1>0yerine Trueve arasındaki boşluğu kaldırarak ]ve forde...[::-1] for g...
Kaya

1
@Kaya Bunun 1yerine de kullanabilirsiniz True. 1 == True, hepsinden sonra.
arshajii

5

Mathematica, 106 98 87 91 karakter

Uzun fonksiyon isimleriyle biraz özür dilerim, ancak bunun gibi problemler Mathematica'da oldukça eğlenceli:

f=Tr@Append[Position[c~Drop~{#}&/@Range@Length[c=Characters@#],l_/;l==Reverse@l,{1}],{-1}]&

Bazı uyarılar atar, çünkü l_desen aynı zamanda Reverseüzerinde çalışamayan tüm karakterlerle de eşleşir . Ama hey, işe yarıyor!

Biraz soluksuz:

f[s_] := 
  Append[
    Cases[
      Map[{#, Drop[Characters[s], {# }]} &, Range[StringLength[s]]], 
      {_, l_} /; l == Reverse[l]
    ], 
    {-1}
  ][[1, 1]]

2
@ Arm103 Yapabilirdim, ama başka birine bırakacağım. ;)
Martin Ender

2
@ Arm103 bekle, bu senin ödevin mi?
John Dvorak

2
@JanDvorak PHP kullanan CS dersleri var mı? Bu çok korkutucu olurdu.
Chris Jester-Young

2
@ Arm103 hayır.
John Dvorak

4
@ JanDvorak hmmm, Mathematica'da bir program nedir?
Martin Ender

5

GolfScript, 28 26 karakter

:I,,{)I/();\+.-1%=}?-2]0=)

Peter'a 2 karakter kısalttığı için teşekkürler. Test senaryolarını çevrimiçi deneyin :

> "RACECAR" 
4
> "RAACECAR" 
2
> "RAAACECAR" 
-1
> "ABCC1BA" 
5
> "AAAAAA" 
1
> "ABCDE" 
-1
> "" 
-1
> "A" 
1

Sanırım daha kısa bir yol olmalı ama bulamadım.
Howard

RACECARGirilen sözcük zaten bir palindrom olduğunda, kaldırılacak bir karakter belirtmek gerekli mi?
unclemeat

@unclemeat, evet. Şartnamenin sondan bir önceki cümle.
Peter Taylor

Neden -2]$-1=)? Bu bloğun başında yığın üzerinde en fazla bir öğe bulunur, böylece kolayca kısaltabilirsiniz -2]0=). (Ya da aynı uzunluk için. Özel durumlar ]-2or)için sevmeyi öğrendim or).
Peter Taylor

2
@Howard Her zaman için bir nikel olsaydı Golfscript hakkında bu şekilde hissettim ...
algorithmmshark

3

Asi (81)

r: -1 repeat i length? s[t: head remove at copy s i if t = reverse copy t[r: i]]r

Rebol konsolunda örnek kullanım:

>> s: "racercar"
== "racercar"

>> r: -1 repeat i length? s[t: head remove at copy s i if t = reverse copy t[r: i]]r
== 5

>> s: "1234"
== "1234"

>> r: -1 repeat i length? s[t: head remove at copy s i if t = reverse copy t[r: i]]r 
== -1


Yukarıda bulunan son palindromun dizinini döndürür. Bulunan her palindromu döndüren alternatif bir çözüm (85 karakter) şöyle olacaktır:

collect[repeat i length? s[t: head remove at copy s i if t = reverse copy t[keep i]]]

Yani bunun için "racercar"liste dönecekti [4 5].


Rebmu lehçesini kullandıysanız, temelde aynı kod olmasına rağmen ilk çözüm sadece 37 karakterdir :-) rebmu / args "Rng01rpNl? A [ThdRMatCYaNieTrvCYt [Rn]] r" "yarış arabası" olarak çağırın . Rebmu belgelerinin iyileştirildiğini ve son değişikliklerin biraz sıkılaştığını unutmayın ... yine de herkes ve D'si kullanmaya başlamadan önce geri bildirim almak istiyor . :-)
HostileFork SE

3

C #, 134 Karakter

static int F(string s,int i=0){if(i==s.Length)return-1;var R=s.Remove(i,1);return R.SequenceEqual(R.Reverse())?i+1:F(s,i+1);}

Kaybettiğimi biliyorum :( ama yine de eğlenceliydi : D

Okunabilir sürüm:

using System.Linq;

// namespace and class

static int PalindromeCharIndex(string str, int i = 0)
{
    if (i == str.Length) return -1;
    var removed = str.Remove(i, 1);
    return removed.SequenceEqual(removed.Reverse()) 
        ? i+1
        : PalindromeCharIndex(str, i + 1); 
}

3
Yay eğlenceli !!!!! :)
Almo

1
Golfçü versiyonda nerede Rtanımlanır ve kullanılır?
Diş Fırçası

oh evet, var R = s.Remove (i, 1) yazmalıdır. iyi yakalamak
Will Newton


2

Yakut (61):

(1..s.size+1).find{|i|b=s.dup;b.slice!(i-1);b.reverse==b}||-1

Burada yakut bir çözüm var. Kaldırılacak karakterin konumunu veya yapılamazsa -1 değerini döndürür.

Yardım edemiyorum ama dup ve dilim bölümü ile yapılacak iyileştirme olduğunu hissediyorum, ama Ruby belirli bir dizindeki bir karakteri kaldıracak ve yeni string -__- döndürecek bir String yöntemi var gibi görünmüyor.

Yoruma göre düzenlendi, ty!


1
Bir işlev / yöntemde kaydırma yapmadan alandan tasarruf edebilirsiniz. Ancak, kodunuz şu anda 0 tabanlı dizin döndürür (1 tabanlı olması gerekir) ve ayrıca -1palindrom bulunmazsa da döndürülmesi gerekir .
draegtun

Düzeltildi -1, teşekkürler. Aklınızda neler var bir yöntem olsa da emin değilim, bir düşünün.
Mike Campbell

Tamam, tavsiyeni gemiye alıp yeniden yazdım :), ty.
Mike Campbell

Rica ederim! Şimdi bu çok daha iyi :) +1
draegtun

2

05AB1E , 10 bayt

gL.Δõs<ǝÂQ

Çevrimiçi deneyin veya daha fazla test vakası doğrulayın .

Açıklama:

g           # Get the length of the (implicit) input-string
 L          # Create a list in the range [1,length]
          # Find the first value in this list which is truthy for:
            # (which will output -1 if none are truthy)
    õ       #  Push an empty string ""
     s      #  Swap to get the current integer of the find_first-loop
      <     #  Decrease it by 1 because 05AB1E has 0-based indexing
       ǝ    #  In the (implicit) input-String, replace the character at that index with
            #  the empty string ""
        Â   #  Then bifurcate the string (short for Duplicate & Reverse copy)
         Q  #  And check if the reversed copy is equal to the original string,
            #  So `ÂQ` basically checks if a string is a palindrome)
            # (after which the result is output implicitly)


1

Haskell, 107 karakter:

(x:y)!1=y;(x:y)!n=x:y!(n-1)
main=getLine>>= \s->print$head$filter(\n->s!n==reverse(s!n))[1..length s]++[-1]

İşlev olarak ( 85 karakter ):

(x:y)!1=y;(x:y)!n=x:y!(n-1)
f s=head$filter(\n->s!n==reverse(s!n))[1..length s]++[-1]

orijinal ungolfed versiyonu:

f str = case filter cp [1..length str] of
          x:_ -> x
          _   -> -1
    where cp n = palindrome $ cut n str
          cut (x:xs) 1 = xs
          cut (x:xs) n = x : cut xs (n-1)
          palindrome x = x == reverse x

1

C # (184 karakter)

Bu kod golf yapmak için en iyi dil değil itiraf ediyorum ...

using System.Linq;class C{static void Main(string[]a){int i=0,r=-1;while(i<a[0].Length){var x=a[0].Remove(i++,1);if(x==new string(x.Reverse().ToArray()))r=i;}System.Console.Write(r);}}

Biçimlendirilmiş ve yorumlanmış:

using System.Linq;

class C
{
    static void Main(string[] a)
    {
        int i = 0, r = -1;
        // try all positions
        while (i < a[0].Length)
        {
            // create a string with the i-th character removed
            var x = a[0].Remove(i++, 1);
            // and test if it is a palindrome
            if (x == new string(x.Reverse().ToArray())) r = i;
        }
        Console.Write(r);
    }
}

1

C # (84 Karakter)

int x=0,o=i.Select(c=>i.Remove(x++,1)).Any(s=>s.Reverse().SequenceEqual(s))?x:-1;

Değişkenin igiriş dizesini içermesini bekleyen LINQpad deyimi . Çıktı odeğişkende saklanır .


1

Haskell, 80

a%b|b<1=0-1|(\x->x==reverse x)$take(b-1)a++b`drop`a=b|1<2=a%(b-1)
f a=a%length a

Şöyle denir:

λ> f "racercar"
5

1

Japt , 8 bayt

a@jYÉ êS

Dene

a@jYÉ êS     :Implicit input of string
a            :Last 0-based index that returns true (or -1 if none do)
 @           :When passed through the following function as Y
  j          :  Remove the character in U at index
   YÉ        :    Y-1
      êS     :  Is palindrome?

0

Haskell, 118C

m s|f s==[]=(-1)|True=f s!!0
f s=[i|i<-[1..length s],r s i==(reverse$r s i)]
r s i=let(a,_:b)=splitAt (i-1) s in a++b

Ungolfed:

fix s
    |indices s==[] = (-1)
    |True = indices s!!0
indices s = [i|i<-[1..length s],remove s i==(reverse$remove s i)]
remove s i = let (a,_:b) = (splitAt (i-1) s) in a++b

0

Jöle , 17 14 bayt

ŒPṖLÐṀṚŒḂ€TXo-

Çevrimiçi deneyin!

           X      A random
          T       truthy index
ŒP                from the powerset of the input
  Ṗ               excluding the input
   LÐṀ            and all proper subsequences with non-maximal length
      Ṛ           reversed
       ŒḂ€        with each element replaced with whether or not it's a palindrome,
            o-    or -1.

Eski sürümün düzenleme geçmişinde görünmemesi için yaklaşımımı hızlı bir şekilde değiştirdiğim için, bu şuydu: ŒPṚḊŒḂ€TṂ©’<La®o-


0

Brachylog , 24 bayt

{l+₁≥.ℕ₂≜&↔⊇ᶠ↖.tT↔T∨0}-₁

Çevrimiçi deneyin!

Çok uzun geliyor.

Çıktı 2 dizinli olabilirse iki bayt daha kısa olabilir :

l+₁≥.ℕ₂≜&↔⊇ᶠ↖.tT↔T∨_1

İki önceki ve daha da kötüsü yineleme:

ẹ~c₃C⟨hct⟩P↔P∧C;Ȯ⟨kt⟩hl<|∧_1
l>X⁰ℕ≜<.&{iI¬tX⁰∧Ih}ᶠP↔P∨_1

İkincisinin genel bir değişken kullanması farklı bir test başlığı gerektirir .





0

C (GCC) , 180 168 159 157 140 139 bayt

f(char*s){int j=strlen(s),m=j--/2,p=-1,i=0;for(;p&&i<m;)p=s[i++]^s[j--]&&!++p?s[i]-s[j+1]?s[i-1]-s[j]?p:j--+2:i++:p;return p<0?m+1:p?p:-1;}

Çevrimiçi deneyin!

2 16 17 bayt tavan kedisi sayesinde traş! Kurallar, girişin minimum uzunluğunun 2 karakter olduğunu belirttiği için 3 bayt daha, bu nedenle boş dizeleri kontrol etmek zorunda değilsiniz.

Ungolfed:

f(char *s) {
  int j = strlen(s);             // j = length of input
  int m = j-- / 2;               // m = midpoint of string,
                                 // j = index of right character
  int p = -1;                    // p = position of extra character
                                 //     -1 means no extra character found yet
                                 //     0 means invalid input
  int i = 0;                     // i = index of left character

  for (; p && i < m; i++) {      // loop over the string from both sides,
                                 // as long as the input is valid.
    p = s[i] ^ s[j--]            // if (left character != right character
        && !++p ?                //     and we didn't remove a character yet*)
          s[i + 1] - s[j + 1] ?  //   if (left+1 char != right char)
            s[i] - s[j] ?        //     if (left char != right-1 char)
              p                  //       do nothing,
            :                    //     else
              j-- + 2            //       remove right char.
          :                      //   else
            ++i                  //       remove left char.
        :                        // else
          p;                     //     do nothing, or:
                                 //     *the input is marked invalid 
  } 

  return p < 0 ?                 // if (input valid and we didn't remove a character yet)
           m + 1                 //   return the midpoint character,
         :                       // else
           p ?                   //   if (we did remove a character)
             p                   //     return that character,
           :                     //   else
             -1;                 //     the input was invalid.
}
```

@ceilingcat Bu &&!++paçıklamak için sadece dolambaçlı :)
G. Sliepen

-1

Python, 84

for i in range(len(s)):
    if s[i]!=s[-(i+1)]:
        if s[i]!=s[-(i+2)]:
            return i+1
        else:
            return len(s)-i

Bu giriş (dize) neredeyse palindrom olduğunu, ancak zaman verimli ve okunabilir olduğunu kontrol etmez.


2
s[-(i+1)]kısaltılabilir s[-i-1]. Ayrıca, emin değilim ama yerine mümkün olabilir if...else...ilereturn i+1 if ... else len(s)-1
user12205

Bu işe yaradı ... Bunun arkasındaki mantığı açıklayan var mı?
Arindam Roychowdhury

Gereksinim, giriş fazladan harf içeren bir palindrom değilse -1 çıktısını almasıdır. Yani, örneğin, s = "abcde"-1 döndürmelidir.
G. Sliepen

-2

İlk kod golfüm.

Java. Ana (ve alt) fonksiyonlarda ~ 1200 karakter. Evet bebeğim.

Üst sınıf ve kullanım:

public class ElimOneCharForPalindrome  {
   public static final void main(String[] ignored)  {
      System.out.println(getEliminateForPalindromeIndex("racercar"));
      System.out.println(getEliminateForPalindromeIndex("racecar"));
   }

Ana işlevi:

   public static final int getEliminateForPalindromeIndex(String oneCharAway_fromPalindrome)  {
      for(int i = 0; i < oneCharAway_fromPalindrome.length(); i++)  {
         String strMinus1Char = oneCharAway_fromPalindrome.substring(0, i) + oneCharAway_fromPalindrome.substring(i + 1);

         String half1 = getFirstHalf(strMinus1Char);
         String half2Reversed = getSecondHalfReversed(strMinus1Char);

         if(half1.length() != half2Reversed.length())  {
            //One half is exactly one character longer
            if(half1.length() > half2Reversed.length())  {
               half1 = half1.substring(0, (half1.length() - 1));
            }  else  {
               half2Reversed = half2Reversed.substring(0, (half2Reversed.length() - 1));
            }
         }

         //System.out.println(i + " " + strMinus1Char + " --> " + half1 + " / " + half2Reversed + "  (minus the singular [non-mirrored] character in the middle, if any)");

         if(half1.equals(half2Reversed))  {
            return  i;
         }
      }
      return  -1;
   }

Alt fonksiyonlar:

   public static final String getFirstHalf(String whole_word)  {
      return  whole_word.substring(0, whole_word.length() / 2);
   }
   public static final String getSecondHalfReversed(String whole_word)  {
      return  new StringBuilder(whole_word.substring(whole_word.length() / 2)).reverse().toString();
   }
}

Tam sınıf:

public class ElimOneCharForPalindrome  {
   public static final void main(String[] ignored)  {
      System.out.println(getEliminateForPalindromeIndex("racercar"));
      System.out.println(getEliminateForPalindromeIndex("racecar"));
   }
   public static final int getEliminateForPalindromeIndex(String oneCharAway_fromPalindrome)  {
      for(int i = 0; i < oneCharAway_fromPalindrome.length(); i++)  {
         String strMinus1Char = oneCharAway_fromPalindrome.substring(0, i) + oneCharAway_fromPalindrome.substring(i + 1);

         String half1 = getFirstHalf(strMinus1Char);
         String half2Reversed = getSecondHalfReversed(strMinus1Char);

         if(half1.length() != half2Reversed.length())  {
            //One half is exactly one character longer
            if(half1.length() > half2Reversed.length())  {
               half1 = half1.substring(0, (half1.length() - 1));
            }  else  {
               half2Reversed = half2Reversed.substring(0, (half2Reversed.length() - 1));
            }
         }

         //System.out.println(i + " " + strMinus1Char + " --> " + half1 + " / " + half2Reversed + "  (minus the singular [non-mirrored] character in the middle, if any)");

         if(half1.equals(half2Reversed))  {
            return  i;
         }
      }
      return  -1;
   }
   public static final String getFirstHalf(String whole_word)  {
      return  whole_word.substring(0, whole_word.length() / 2);
   }
   public static final String getSecondHalfReversed(String whole_word)  {
      return  new StringBuilder(whole_word.substring(whole_word.length() / 2)).reverse().toString();
   }
}

3
Bu, kodu golf oynamak için hiçbir girişim göstermez.
mbomb007
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.