Usuń list, aby utworzyć palindrom

15

Problem

Powiedzmy, że słowo jest prawie palindromem, jeśli można usunąć jedną z jego liter, aby słowo stało się palindromem. Twoim zadaniem jest napisanie programu, który dla danego słowa określa, którą literę usunąć, aby uzyskać palindrom.

Wygrywa najkrótszy kod do wykonania tego w dowolnym języku programowania.

Wejście

Wprowadzanie składa się ze słowa składającego się z wielkich liter o długości od 2 do 1000 znaków.

Wynik

Wypisuje 1-indeksowaną pozycję (najbardziej wysunięta na lewo litera ma pozycję 1, następna ma pozycję 2 itd.) Litery, którą należy usunąć. Jeśli są możliwe wybory prowadzące do palindromu, wypisz dowolną z tych pozycji. Pamiętaj, że musisz usunąć literę, nawet jeśli dane słowo jest już palindromem. Jeśli dane słowo nie jest prawie palindromem, wypisz -1.


Przykład

Dane wejściowe:

racercar

może produkować dane wyjściowe:

5

ponieważ usunięcie 5litery th powoduje racecarpowstanie palindromu.

Również dane wejściowe

racecar

nadal może produkować dane wyjściowe

4

ponieważ usunięcie 4litery th do produkcji raccarjest nadal palindromem.

Użytkownik011001
źródło
5
Brak opublikowanych przykładów? A co wyprowadzić, jeśli nie można wprowadzić danych do Palindromu?
ProgrammerDan
3
@ Arm103 wciąż brakuje Ci przykładów, o których mówisz
Martin Ender
27
Ostrzeżenie: „(patrz przykład 3)”. Sugeruje to, że jest to praca domowa, ponieważ nigdy nie opublikowano żadnych przykładów.
Justin
3
@Quincunx Koniecznie przeczytaj także wątek na temat wysyłania Mathematica. :-)
Chris Jester-Young
3
To pytanie wydaje się nie na temat, ponieważ w pytaniu brakuje przykładu 3 .
devnull

Odpowiedzi:

10

J - 31 25 znaków

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

Bardzo standardowa taryfa dla J, więc zwrócę uwagę na fajne elementy.

  • Przysłówek \.nazywa Outfix . x u\. yusuwa wszelkie Infix długości xod yi stosuje usię do wyniku każdego usunięcia. Tutaj xjest 1, yjest łańcuchem wejściowym i ujest (-:|.)testem, czy łańcuch pasuje do jego odwrotności. Stąd rezultatem tego zastosowania \.jest lista boolean, 1 w miejsce każdego znaku, którego usunięcie powoduje, że dane wejściowe są palindromem.

  • I.tworzy listę wszystkich indeksów (0-origin) z góry tam, gdzie było 1. Dodanie 1 z 1+czyni te indeksy 1-origin. Jeśli żaden indeks nie był równy 1, lista jest pusta. Teraz staramy się wziąć ostatni element _1{. (Możemy wypisać dowolne z usuwalnych liter!) Jeśli to zadziała, wrócimy. Jeśli jednak lista była pusta, nie było żadnych elementów, więc {zgłasza błąd domeny, który łapiemy ::i zwracamy -1 z [.

Użycie (przypominamy, że NB.jest do komentarzy):

   (_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
algorytmshark
źródło
Powinienem nauczyć się J. Jakieś samouczki dla programisty python?
3ıʇǝɥʇuʎs
1
@Synthetica oficjalny jest dobry
John Dvorak
2
@Synthetica Nic specjalnie dla Pythonerów, ale J dla programistów C jest doskonałym źródłem informacji dla każdego, kto migruje z programowania imperatywnego.
algorytm
10

Python inny niż PHP (73):

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

Gdzie a to ciąg, który chcesz sprawdzić. Powoduje to jednak błąd, jeśli nie można go włączyć w palindromie. Zamiast tego możesz użyć

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

EDYCJA: Nie, czekaj, to działa!

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)

Dzięki, to rzeczywiście podnosi zawartość php tego skryptu o około 25% (właśnie tego chcesz, prawda?)

.ıʇǝɥʇuʎs
źródło
10
+1 za „Not PHP”;)
Martin Ender
1
<? php $ line = fgets (STDIN); ?>
User011001
2
@ User011001 Gdzie by to pasowało?
3ıʇǝɥʇuʎs
1
Można zapisać char każdy pisząc 1>0zamiast Truei usuwając przestrzeń pomiędzy ]i forpo...[::-1] for g...
Kaya
1
@Kaya Możesz po prostu użyć 1zamiast True. 1 == True, w sumie.
arshajii
5

Mathematica, 106 98 87 91 znaków

Wydaje mi się, że jestem trochę upośledzony długimi nazwami funkcji, ale takie problemy są dość zabawne w Mathematica:

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

Zgłasza pewne ostrzeżenia, ponieważ l_wzór pasuje również do wszystkich znaków w środku, na których Reversenie można operować. Ale hej, to działa!

Nieco golfisty:

f[s_] := 
  Append[
    Cases[
      Map[{#, Drop[Characters[s], {# }]} &, Range[StringLength[s]]], 
      {_, l_} /; l == Reverse[l]
    ], 
    {-1}
  ][[1, 1]]
Martin Ender
źródło
2
@ Arm103 Mógłbym, ale zostawię to komuś innemu. ;)
Martin Ender
2
@ Arm103 czekaj, czy to Twoja praca domowa?
John Dvorak,
2
@JanDvorak Istnieją kursy CS, które używają PHP? To byłoby przerażające.
Chris Jester-Young,
2
@ Arm103 nr. Nie możesz ;-)
John Dvorak
4
@JanDvorak hmmm, co to jest program w Mathematica?
Martin Ender
5

GolfScript, 28 26 znaków

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

Dziękujemy Peterowi za skrócenie o 2 znaki. Wypróbuj przypadki testowe online :

> "RACECAR" 
4
> "RAACECAR" 
2
> "RAAACECAR" 
-1
> "ABCC1BA" 
5
> "AAAAAA" 
1
> "ABCDE" 
-1
> "" 
-1
> "A" 
1
Howard
źródło
Chyba musi być krótsza droga, ale jej nie znalazłem.
Howard
RACECARjest nadal palindromem z literą E. Czy konieczne jest określenie znaku do usunięcia, gdy wprowadzane słowo jest już palindromem?
niepomyślnie
@unclemeat, tak. Przedostatnie zdanie specyfikacji.
Peter Taylor
Dlaczego -2]$-1=)? Na początku tego bloku masz najwyżej jeden przedmiot na stosie, więc możesz łatwo go skrócić -2]0=). (Lub o tej samej długości ]-2or). Nauczyłem się kochać orw szczególnych przypadkach).
Peter Taylor
2
@Howard Gdybym miał nikiel za każdym razem, gdy tak się czułem w sprawie Golfscript ...
algorytmshark
3

Rebol (81)

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

Przykładowe użycie w konsoli Rebol:

>> 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


Powyżej zwraca indeks ostatniego znalezionego palindromu. Alternatywnym rozwiązaniem (85 znaków), które zwraca każdy znaleziony palindrom, byłoby:

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

Więc do "racercar"tego zwróci listę [4 5].

draegtun
źródło
Jeśli używałeś dialektu Rebmu , pierwsze rozwiązanie ma tylko 37 znaków, mimo że jest to w zasadzie ten sam kod :-) Wywołaj jako rebmu / args „Rng01rpNl? A [ThdRMatCYaNieTrvCYt [Rn]] r” „racecar” . Zauważ, że dokumentacja Rebmu została ulepszona, a ostatnie zmiany nieco ją zaostrzyły ... wciąż szukając informacji zwrotnych, zanim wszyscy i ich D zaczną z niej korzystać. :-)
HostileFork mówi: nie ufaj
3

C #, 134 znaków

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);}

Wiem, że przegrywam :(, ale nadal było fajnie : D

Wersja do odczytu:

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); 
}
Will Newton
źródło
3
Fajna zabawa !!!!! :)
Almo
1
Gdzie jest Rzdefiniowane i używane w wersji golfowej ?
Szczoteczka do zębów
o tak, należy powiedzieć var R = s.Remove (i, 1). dobry połów
Will Newton
3

Stax , 8 10 bajtów

ú·àA÷¡%5Ñ╙

Uruchom i debuguj

Ten program pokazuje wszystkie oparte na 1 indeksy, które można usunąć z łańcucha, tworząc palindrom. A jeśli nie ma, pokazuje -1.

rekurencyjny
źródło
2
Daje to ostatni indeks zamiast -1, jeśli nie zostanie znaleziony palindrom (tzn. aaabbWyniki 5zamiast -1).
Kevin Cruijssen
1
@KevinCruijssen: Masz rację. Naprawiłem to kosztem 2 bajtów.
rekurencyjny
2

Rubin (61):

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

Tutaj masz rozwiązanie rubinowe. Zwróci pozycję znaku do usunięcia lub -1, jeśli nie da się tego zrobić.

Nie mogę się oprzeć wrażeniu, że można wprowadzić ulepszenia w sekcji dup i plasterek, ale wydaje się, że Ruby nie ma metody String, która usunie znak z określonego indeksu i zwróci nowy ciąg -__-.

Edytowane zgodnie z komentarzem, ty!

Mike Campbell
źródło
1
Możesz zaoszczędzić trochę miejsca, nie zawijając funkcji / metody. Jednak Twój kod obecnie zwraca indeks oparty na 0 (musi być oparty na 1) i musi również zwrócić, -1jeśli nie znaleziono palindromu.
draegtun
Naprawiono -1, dzięki. Nie jestem pewien, co masz na myśli, jeśli chodzi o zastosowanie tej metody, pomyślę.
Mike Campbell
Ok, wziąłem twoją radę na pokład i przepisałem ją :), ty.
Mike Campbell
Nie ma za co! Teraz jest o wiele lepiej :) +1
draegtun
2

05AB1E , 10 bajtów

gL.Δõs<ǝÂQ

Wypróbuj online lub sprawdź więcej przypadków testowych .

Wyjaśnienie:

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)
Kevin Cruijssen
źródło
2

Nie Python PHP ,85 83 81 bajtów

while($argn[$x])$s!=strrev($s=substr_replace($argn,'',$x++,1))?:die("$x");echo-1;
  • -2 bajty dzięki @ Night2!

Wypróbuj online!

Niepotrzebnie rekurencyjne:

PHP , 96 bajtów

function f($a,$b='',$d=1){return$a?$c==strrev($c=$b.$e=substr($a,1))?$d:f($e,$b.$a[0],$d+1):-1;}

Wypróbuj online!

640 KB
źródło
1

Haskell, 107 znaków:

(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]

W funkcji ( 85 znaków ):

(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]

oryginalna wersja bez golfa:

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
John Dvorak
źródło
1

C # (184 znaki)

Przyznaję, że nie jest to najlepszy język do gry w golfa ...

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);}}

Sformatowane i skomentowane:

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);
    }
}
Mormegil
źródło
1

C # (84 znaków)

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

Instrukcja LINQpad oczekuje, że zmienna ibędzie zawierać ciąg wejściowy. Dane wyjściowe są przechowywane w ozmiennej.

Oskar Sjöberg
źródło
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

Nazywany tak:

λ> f "racercar"
5
Flonk
źródło
1

Japt , 8 bajtów

a@jYÉ êS

Spróbuj

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?
Kudłaty
źródło
0

Haskell, 118 ° C

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

Nie golfowany:

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
Danmcardle
źródło
0

Galaretka , 17 14 bajtów

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

Wypróbuj online!

           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.

Ponieważ zmieniłem podejście wystarczająco szybko, aby stara wersja nie wyświetlała się w historii edycji, było to następujące: ŒPṚḊŒḂ€TṂ©’<La®o-

Niepowiązany ciąg
źródło
0

Brachylog , 24 bajty

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

Wypróbuj online!

Czuje się zdecydowanie za długo.

Mogą być dwa bajty krótsze, jeśli dane wyjściowe mogłyby być indeksowane 2 :

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

Dwie wcześniejsze i jeszcze gorsze iteracje:

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

Zastosowanie tej ostatniej zmiennej globalnej wymaga innego nagłówka testowego .

Niepowiązany ciąg
źródło
0

Python 3 , 71 bajtów

def f(s,i=1):n=s[:i-1]+s[i:];return(n==n[::-1])*i-(i>len(s))or f(s,i+1)

Wypróbuj online!

Zwraca 1-indeksowany znak, jeśli operacja może być wykonana i -1inaczej.

Jitse
źródło
0

C (gcc) , 180 168 159 157 140 139 bajtów

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;}

Wypróbuj online!

2 16 17 bajtów ogolonych dzięki pułapce cat! I jeszcze 3 bajty, ponieważ reguły mówią, że minimalna długość danych wejściowych wynosi 2 znaki, więc nie musisz sprawdzać pustych ciągów.

Nie golfowany:

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.
}
```
G. Sliepen
źródło
@ceilingcat To &&!++ppo prostu przebiegłe, aby wyjaśnić :)
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

To nie sprawdza, czy dane wejściowe (łańcuchy) są prawie palindromem, ale są wydajne czasowo i czytelne.

nicofmay
źródło
2
s[-(i+1)]można skrócić do s[-i-1]. Ponadto, nie jestem pewien, ale być może uda się wymienić if...else...zreturn i+1 if ... else len(s)-1
user12205
To działało w porządku .. Czy ktoś może wyjaśnić logikę tego?
Arindam Roychowdhury
Wymagane jest, aby wyprowadzał -1, jeśli wejście nie jest palindromem z dodatkową literą. Na przykład, jeśli s = "abcde"powinien zwrócić -1.
G. Sliepen,
-2

Mój pierwszy golf.

Jawa. ~ 1200 znaków w funkcjach głównych (i podrzędnych). Tak kochanie.

Najwyższa klasa i zastosowanie:

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

Główna funkcja:

   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;
   }

Podfunkcje:

   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();
   }
}

Pełna klasa:

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();
   }
}
aliteralmind
źródło
3
Nie pokazuje to próby gry w golfa.
mbomb007,