Hapus surat untuk membuat palindrome

15

Masalah

Katakanlah sebuah kata hampir merupakan palindrom jika memungkinkan untuk menghapus salah satu hurufnya sehingga kata tersebut menjadi palindrom. Tugas Anda adalah menulis program yang untuk kata tertentu menentukan huruf mana yang harus dihapus untuk mendapatkan palindrom.

Kode terpendek untuk melakukan ini dalam bahasa pemrograman apa pun yang menang.

Memasukkan

Input terdiri dari kata huruf besar dari 2 hingga 1000 karakter.

Keluaran

Keluarkan posisi 1-diindeks (huruf paling kiri memiliki posisi 1, yang berikutnya memiliki posisi 2 dan seterusnya) dari surat yang harus dihapus. Jika ada pilihan yang memungkinkan yang mengarah ke palindrome, output salah satu dari posisi itu. Perhatikan bahwa Anda diharuskan untuk menghapus surat meskipun kata yang diberikan sudah palindrom. Jika kata yang diberikan hampir tidak merupakan palindrom, output -1.


Contoh

Input:

racercar

mungkin menghasilkan output:

5

karena mengeluarkan 5huruf th menghasilkan racecar, yang merupakan palindrome.

Juga, input

racecar

masih bisa menghasilkan output

4

karena menghapus 4huruf ke-menghasilkan raccarmasih palindrome.

Pengguna011001
sumber
5
Tidak ada contoh yang diposting? Dan apa yang harus dihasilkan jika tidak memungkinkan untuk membuat input menjadi Palindrome?
ProgrammerDan
3
@ Arm103 Anda masih melewatkan contoh-contoh yang Anda maksud
Martin Ender
27
Peringatan: "(lihat contoh 3)". Ini menunjukkan bahwa ini adalah pekerjaan rumah karena tidak ada contoh yang pernah diposting.
Justin
3
@ Quincunx Pastikan untuk membaca utas tentang pengiriman Mathematica juga. :-)
Chris Jester-Young
3
Pertanyaan ini tampaknya di luar topik karena contoh 3 hilang dari pertanyaan.
devnull

Jawaban:

10

J - 31 25 char

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

Sebagian besar tarif standar untuk J, jadi saya hanya akan menunjukkan bit keren.

  • Kata keterangan \. disebut Outfix . x u\. ymenghapus setiap infiks panjang xdari ydan berlaku uuntuk hasil setiap penghapusan. Di sini, xadalah 1, yadalah string input, dan umerupakan (-:|.), tes untuk apakah string cocok dengan kebalikannya. Oleh karena itu hasil dari aplikasi ini \.adalah daftar boolean, 1 di tempat masing-masing karakter yang penghapusannya membuat input menjadi palindrom.

  • I.membuat daftar semua indeks (0-asal) dari atas di mana ada 1. Menambahkan 1 dengan 1+membuat indeks 1-asal ini. Jika tidak ada indeks 1, daftar kosong. Sekarang, kami mencoba mengambil elemen terakhir _1{. (Kami diizinkan untuk mengeluarkan huruf yang bisa dilepas!) Jika ini berhasil, kami kembali. Namun, jika daftar itu kosong, tidak ada elemen sama sekali, jadi {melempar kesalahan domain yang kami tangkap ::dan mengembalikan -1 dengan [.

Penggunaan (ingat NB.untuk komentar):

   (_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
algoritme hiu
sumber
Saya harus belajar J. Ada tutorial untuk programmer python?
ɐɔıʇǝɥʇu
1
@ Sintetica yang resmi itu bagus
John Dvorak
2
@ Sintetica Tidak ada yang khusus untuk Pythoners, tetapi J for C Programmer adalah sumber yang bagus untuk siapa saja yang bermigrasi dari pemrograman imperatif.
algorithmshark
10

Bukan-PHP Python (73):

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

Di mana a adalah string yang ingin Anda periksa. Ini, bagaimanapun, melempar kesalahan jika Anda tidak dapat mengubahnya dalam palindrome. Sebaliknya, Anda bisa menggunakannya

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: Tidak, tunggu, itu berhasil!

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)

Terima kasih, ini memang meningkatkan isi php skrip ini sekitar 25% (itu yang Anda inginkan, kan?)

ɐɔıʇǝɥʇu
sumber
10
+1 untuk "Bukan PHP";)
Martin Ender
1
<? php $ line = fgets (STDIN); ?>
User011001
2
@ User011001 Di mana itu cocok?
ɐɔıʇǝɥʇu
1
Anda dapat menyimpan masing-masing char dengan menulis 1>0alih-alih Truedan dengan menghapus spasi di antara ]dan fordi...[::-1] for g...
Kaya
1
@Kaya Anda cukup menggunakan 1saja True. 1 == True, Lagipula.
arshajii
5

Mathematica, 106 98 87 91 karakter

Saya kira saya sedikit cacat oleh nama fungsi yang panjang, tetapi masalah seperti ini cukup menyenangkan di Mathematica:

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

Itu melempar beberapa peringatan, karena l_polanya juga cocok dengan semua karakter di dalamnya, yang Reversetidak dapat beroperasi. Tapi hei, itu berhasil!

Agak tidak terserang:

f[s_] := 
  Append[
    Cases[
      Map[{#, Drop[Characters[s], {# }]} &, Range[StringLength[s]]], 
      {_, l_} /; l == Reverse[l]
    ], 
    {-1}
  ][[1, 1]]
Martin Ender
sumber
2
@ Arm103 saya bisa, tapi saya akan menyerahkannya kepada orang lain. ;)
Martin Ender
2
@ Arm103 tunggu, apakah ini pekerjaan rumah Anda?
John Dvorak
2
@ JanDvorak Ada kursus CS yang menggunakan PHP? Itu akan menakutkan.
Chris Jester-Young
2
@ Arm103 no. Anda tidak bisa ;-)
John Dvorak
4
@ JanDvorak hmmm, apa itu program di Mathematica?
Martin Ender
5

GolfScript, 28 26 karakter

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

Terima kasih kepada Peter untuk menyingkat 2 karakter. Coba test case online :

> "RACECAR" 
4
> "RAACECAR" 
2
> "RAAACECAR" 
-1
> "ABCC1BA" 
5
> "AAAAAA" 
1
> "ABCDE" 
-1
> "" 
-1
> "A" 
1
Howard
sumber
Mungkin ada cara yang lebih pendek tapi saya tidak menemukannya.
Howard
RACECARmasih palindrome dengan E. Apakah perlu menentukan karakter untuk dihapus, ketika kata yang dimasukkan sudah merupakan palindrom?
hapus klasifikasi
@ bahasa inggris, ya. Kalimat terakhir dari spec.
Peter Taylor
Mengapa -2]$-1=)? Pada awal blok itu Anda memiliki paling banyak satu item di tumpukan, sehingga Anda dapat dengan mudah menyingkatnya menjadi -2]0=). (Atau untuk panjang yang sama ]-2or),. Saya telah belajar untuk mencintai orkasus-kasus khusus).
Peter Taylor
2
@Howard Jika saya memiliki nikel untuk setiap kali saya merasa seperti itu tentang Golfscript ...
algorithmshark
3

Rebol (81)

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

Contoh penggunaan di konsol 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


Di atas indeks pengembalian palindrom terakhir ditemukan. Solusi alternatif (85 karakter) yang mengembalikan setiap palindrom yang ditemukan adalah:

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

Jadi untuk "racercar"ini akan mengembalikan daftar [4 5].

draegtun
sumber
Jika Anda menggunakan dialek Rebmu solusi pertama hanya 37 karakter, meskipun pada dasarnya kode yang sama :-) Gunakan sebagai Gunakan rebmu / args "Rng01rpNl? A [ThdRMatCYaNieTrvCYt [Rn]] r" "racecar" . Perhatikan bahwa dokumentasi Rebmu telah ditingkatkan, dan perubahan terbaru sedikit memperketatnya ... masih mencari umpan balik sebelum semua orang dan D mereka mulai menggunakannya. :-)
HostileFork bilang jangan percaya 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);}

Saya tahu saya kehilangan :( tapi itu tetap menyenangkan : D

Versi yang dapat dibaca:

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
sumber
3
Yay menyenangkan !!!!! :)
Almo
1
Dalam versi golf, di mana Rdidefinisikan dan digunakan?
Sikat gigi
oh ya, seharusnya mengatakan var R = s.Remove (i, 1). tangkapan bagus
Will Newton
3

Stax , 8 10 byte

ú·àA÷¡%5Ñ╙

Jalankan dan debug itu

Program ini menunjukkan semua indeks berbasis 1 yang dapat dihapus dari string untuk membentuk palindrome. Dan jika tidak ada, itu menunjukkan -1.

rekursif
sumber
2
Ini menampilkan indeks terakhir dan bukan -1 jika tidak ada palindrome yang ditemukan (yaitu aaabbkeluaran 5alih-alih -1).
Kevin Cruijssen
1
@KevinCruijssen: Benar sekali. Saya memperbaikinya dengan biaya 2 byte.
rekursif
2

Ruby (61):

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

Di sini, ada solusi ruby. Ini akan mengembalikan posisi karakter untuk dihapus atau -1 jika tidak dapat dilakukan.

Saya tidak dapat membantu tetapi merasa ada perbaikan yang harus dilakukan dengan bagian dup dan slice, tetapi Ruby tampaknya tidak memiliki metode String yang akan menghapus karakter pada indeks tertentu dan mengembalikan string baru -__-.

Diedit sesuai komentar, ty!

Mike Campbell
sumber
1
Anda dapat menghemat ruang dengan tidak membungkus fungsi / metode. Namun kode Anda saat ini mengembalikan indeks berbasis 0 (harus berbasis 1) dan juga perlu kembali -1jika tidak ada palindrome yang ditemukan.
draegtun
Memperbaiki -1, terima kasih. Namun, tidak yakin apa yang ada dalam pikiran Anda tentang mengeluarkannya, saya akan memikirkannya.
Mike Campbell
Oke, terima saran Anda di papan tulis dan tulis ulang :), ty.
Mike Campbell
Sama-sama! Nah, itu jauh lebih baik :) +1
draegtun
2

05AB1E , 10 byte

gL.Δõs<ǝÂQ

Cobalah secara online atau verifikasi beberapa kasus uji lagi .

Penjelasan:

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

Bukan PythonPHP ,85 83 81 byte

while($argn[$x])$s!=strrev($s=substr_replace($argn,'',$x++,1))?:die("$x");echo-1;
  • -2 byte terima kasih kepada @ Night2!

Cobalah online!

Rekursif yang tidak perlu:

PHP , 96 byte

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

Cobalah online!

640KB
sumber
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]

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

versi ungolfed asli:

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

C # (184 karakter)

Saya akui ini bukan bahasa terbaik untuk melakukan kode-golf ...

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

Diformat dan dikomentari:

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

C # (84 Karakter)

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

Pernyataan LINQpad mengharapkan variabel iberisi string input. Output disimpan dalam ovariabel.

Oskar Sjöberg
sumber
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

Disebut seperti ini:

λ> f "racercar"
5
Flonk
sumber
1

Japt , 8 byte

a@jYÉ êS

Cobalah

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?
Shaggy
sumber
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

Tidak Disatukan:

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

Jelly , 17 14 byte

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

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

Karena saya mengubah pendekatan saya dengan cukup cepat sehingga versi lama tidak muncul di edit history, itu adalah ini: ŒPṚḊŒḂ€TṂ©’<La®o-

String yang tidak terkait
sumber
0

Brachylog , 24 byte

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

Cobalah online!

Terasa terlalu lama.

Bisa jadi dua byte lebih pendek jika outputnya bisa diindeks 2 :

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

Dua iterasi sebelumnya dan bahkan lebih buruk:

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

Penggunaan variabel global yang terakhir memerlukan header pengujian yang berbeda .

String yang tidak terkait
sumber
0

Python 3 , 71 byte

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

Cobalah online!

Mengembalikan karakter 1-diindeks jika operasi dapat dilakukan dan -1sebaliknya.

Jitse
sumber
0

Bahasa Wolfram (Mathematica) , 56 byte

FirstCase[Range@Tr[1^#],a_/;PalindromeQ@Delete[#,a],-1]&

Cobalah online!

Mengambil input sebagai daftar karakter. Untuk input string, tambahkan @*Characters.

PalindromeQdiperkenalkan pada tahun 2015. Biaya alternatif +4 byte .

attinat
sumber
0

C (gcc) , 180 168 159 157 140 139 byte

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

Cobalah online!

2 16 17 bytes mencukur berkat ceilingcat! Dan 3 byte lagi karena aturan menyatakan panjang minimum input adalah 2 karakter, jadi tidak perlu memeriksa string kosong.

Tidak Disatukan:

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
sumber
@ceilingcat That &&!++p is just devious to explain :)
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

This does not check is the input (string s) is almost palindrome, but is time efficient and readable.

nicofmay
sumber
2
s[-(i+1)] can be shortened to s[-i-1]. Also, I'm not sure but you may be able to replace the if...else... with return i+1 if ... else len(s)-1
user12205
This worked alright..Can anyone explain the logic behind this ?
Arindam Roychowdhury
The requirement is that it outputs -1 if the input is not a palindrome with an extra letter. So for example, if s = "abcde", it should return -1.
G. Sliepen
-2

My first code-golf.

Java. ~1200 characters in the main (and sub) functions. Yeah baby.

Class top and usage:

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

The main function:

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

Sub-functions:

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

Full class:

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
sumber
3
This shows no attempt at golfing the code.
mbomb007