Xóa một chữ cái để tạo một bảng màu


15

Vấn đề

Hãy nói rằng một từ gần như là một palindrome nếu nó có thể loại bỏ một trong những bức thư của mình để từ đó trở thành một palindrome. Nhiệm vụ của bạn là viết một chương trình cho một từ đã cho xác định chữ cái nào cần xóa để lấy một bảng màu.

Mã ngắn nhất để làm điều này trong bất kỳ ngôn ngữ lập trình nào đều thắng.

Đầu vào

Đầu vào bao gồm một từ gồm các chữ cái viết hoa dài từ 2 đến 1000 ký tự.

Đầu ra

Xuất ra vị trí 1 chỉ mục (chữ cái ngoài cùng bên trái có vị trí 1, vị trí tiếp theo có vị trí 2 và vv) của chữ cái cần được loại bỏ. Nếu có những lựa chọn có thể dẫn đến palindrom, hãy xuất bất kỳ vị trí nào trong số đó. Lưu ý rằng bạn được yêu cầu xóa một chữ cái ngay cả khi từ đã cho đã là một bảng màu. Nếu từ đã cho gần như không phải là một bảng màu, hãy xuất -1.


Thí dụ

Đầu vào:

racercar

có thể tạo ra đầu ra:

5

bởi vì loại bỏ các 5chữ cái tạo ra racecar, đó là một palindrom.

Ngoài ra, đầu vào

racecar

vẫn có thể tạo ra đầu ra

4

bởi vì loại bỏ 4chữ thứ để sản xuất raccarvẫn là một bảng màu.


5
Không có ví dụ được đăng? Và những gì để đầu ra nếu không thể làm cho đầu vào thành một Palindrom?
Lập trình viên

3
@ Arm103 bạn vẫn còn thiếu các ví dụ bạn đang đề cập
Martin Ender

27
Cảnh báo: "(xem ví dụ 3)". Điều này cho thấy đây là bài tập về nhà vì không có ví dụ nào được đăng.
Justin

3
@Quincunx Hãy chắc chắn cũng đọc chủ đề trên bài nộp Mathicala. :-)
Chris Jester-Young

3
Câu hỏi này dường như lạc đề vì ví dụ 3 bị thiếu trong câu hỏi.
devnull

Câu trả lời:


10

J - 31 25 char

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

Giá vé tiêu chuẩn lớn cho J, vì vậy tôi sẽ chỉ ra các bit tuyệt vời.

  • Trạng từ \.được gọi là Outfix . x u\. yloại bỏ tất cả các trung tố có độ dài xtừ yvà áp dụng uđể kết quả của mỗi lần bị đuổi. Ở đây, xlà 1, ylà chuỗi đầu vào, và u(-:|.)một bài kiểm tra xem chuỗi có khớp với đảo ngược của nó không. Do đó, kết quả của ứng dụng \.này là một danh sách các booleans, 1 ở vị trí của mỗi ký tự có loại bỏ làm cho đầu vào trở thành một bảng màu.

  • I.tạo một danh sách tất cả các chỉ số (0 gốc) từ phía trên nơi có 1. Thêm 1 với 1+các chỉ số 1 gốc này. Nếu không có chỉ số nào là 1, danh sách trống. Bây giờ, chúng tôi cố gắng lấy phần tử cuối cùng với _1{. (Chúng tôi được phép xuất bất kỳ chữ cái nào!) Nếu cách này hoạt động, chúng tôi sẽ trả lại. Tuy nhiên, nếu danh sách trống, không có phần tử nào cả, do đó, {sẽ đưa ra một lỗi miền mà chúng ta bắt gặp ::và trả về -1 với [.

Cách sử dụng (nhớ lại đó NB.là cho ý kiế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

Tôi nên học J. Có hướng dẫn nào cho lập trình viên python không?
ɐɔıʇǝɥʇuʎs

1
@Synthetica là một chính thức là tốt
John Dvorak

2
@Synthetica Không có gì đặc biệt cho Pythoners, nhưng J cho C Lập trình viên là một tài nguyên tuyệt vời cho bất kỳ ai di chuyển từ lập trình mệnh lệnh.
thuật toán

10

Python không phải PHP (73):

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

Trong đó a là chuỗi bạn muốn kiểm tra. Tuy nhiên, điều này sẽ gây ra lỗi nếu bạn không thể biến nó thành một bảng màu. Thay vào đó, bạn có thể sử dụng

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: Không, chờ đã, nó hoạt động!

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)

Cảm ơn, điều này thực sự làm tăng nội dung php của kịch bản này lên khoảng 25% (đó là những gì bạn muốn, phải không?)


10
+1 cho "Không phải PHP";)
Martin Ender

1
<? php $ line = fgets (STDIN); ?>
Người dùng011001

2
@ User011001 Điều đó sẽ phù hợp ở đâu?
ɐɔıʇǝɥʇuʎs

1
Bạn có thể lưu một char mỗi bằng cách viết 1>0thay vì Truevà bằng cách xóa khoảng trắng giữa ]fortrong...[::-1] for g...
Kaya

1
@Kaya Bạn chỉ có thể sử dụng 1thay vì Truelà tốt. 1 == True, sau tất cả.
arshajii

5

Toán học, 106 98 87 91 ký tự

Tôi cho rằng tôi hơi bị khiếm khuyết bởi các tên hàm dài, nhưng các vấn đề như thế này khá thú vị trong Mathematica:

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

Nó đưa ra một số cảnh báo, bởi vì l_mô hình cũng phù hợp với tất cả các nhân vật bên trong, Reversekhông thể hoạt động. Nhưng này, nó hoạt động!

Hơi vô dụng:

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

2
@ Arm103 Tôi có thể, nhưng tôi sẽ để nó cho người khác. ;)
Martin Ender

2
@ Arm103 chờ đợi, đây có phải là bài tập về nhà của bạn?
John Dvorak

2
@JanDvorak Có các khóa học CS sử dụng PHP? Điều đó thật đáng sợ.
Chris Jester-Young

2
@ Arm103 không. Bạn không thể ;-)
John Dvorak

4
@JanDvorak hmmm, chương trình trong Mathematica là gì?
Martin Ender

5

GolfScript, 28 26 ký tự

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

Cảm ơn Peter đã rút ngắn 2 ký tự. Hãy thử các trường hợp thử nghiệm trực tuyến :

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

Đoán phải có một cách ngắn hơn nhưng tôi đã không tìm thấy nó.
Howard

RACECARvẫn là một palindrom với E. Có cần chỉ định một ký tự để loại bỏ không, khi từ được nhập vào đã là một palindrom?
tiết lộ

@unclemeat, vâng. Áp chót câu của spec.
Peter Taylor

Tại sao -2]$-1=)? Khi bắt đầu khối đó, bạn có nhiều nhất một mục trên ngăn xếp, vì vậy bạn có thể dễ dàng rút ngắn -2]0=). (Hoặc cho cùng một chiều dài ]-2or). Tôi đã học cách yêu ortrong những trường hợp đặc biệt).
Peter Taylor

2
@Howard Nếu tôi có niken mỗi lần tôi cảm thấy như vậy về Golfscript ...
thuật toán bắt đầu

3

Nổi loạn (81)

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

Ví dụ sử dụng trong bảng điều khiển 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


Trên chỉ số trả về của palindrom cuối cùng được tìm thấy. Một giải pháp thay thế (85 ký tự) trả về mọi bảng màu tìm thấy sẽ là:

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

Vì vậy, cho "racercar"điều này sẽ trở lại danh sách [4 5].


Nếu bạn đã sử dụng phương ngữ Rebmu thì giải pháp đầu tiên chỉ có 37 ký tự, mặc dù về cơ bản là cùng một mã :-) Gọi là rebmu / args "Rng01rpNl? A [ThdRMatCYaNieTrvCYt [Rn]]" "racecar" . Lưu ý rằng tài liệu Rebmu đã được cải thiện và những thay đổi gần đây đã thắt chặt nó một chút ... vẫn đang tìm kiếm phản hồi trước khi mọi người và D của họ bắt đầu sử dụng nó. :-)
HostileFork nói không tin tưởng SE

3

C #, 134 ký tự

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

Tôi biết tôi thua :( nhưng nó vẫn vui : D

Phiên bản dễ đọc:

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 vui vẻ !!!!! :)
Almo

1
Trong phiên bản golf, được Rxác định và sử dụng ở đâu?
Bàn chải đánh răng

oh yeah, nó sẽ nói var R = s.Remove (i, 1). bắt tốt
Will Newton

3

Stax , 8 10 byte

ú·àA÷¡%5Ñ╙

Chạy và gỡ lỗi nó

Chương trình này hiển thị tất cả các chỉ mục dựa trên 1 có thể được loại bỏ khỏi chuỗi để tạo thành một bảng màu. Và nếu không có, nó hiển thị -1.


2
Điều này xuất ra chỉ mục cuối cùng thay vì -1 nếu không tìm thấy palindrom (tức là aaabbđầu ra 5thay vì -1).
Kevin Cruijssen

1
@KevinCruijssen: Đúng vậy. Tôi đã sửa nó với chi phí là 2 byte.
đệ quy

2

Ruby (61):

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

Ở đây, có một giải pháp ruby. Nó sẽ trả về vị trí của ký tự cần loại bỏ hoặc -1 nếu không thể thực hiện được.

Tôi không thể không cảm thấy có sự cải thiện nào được thực hiện với phần dup và lát, nhưng Ruby dường như không có phương thức String sẽ loại bỏ một ký tự tại một chỉ mục cụ thể và trả về chuỗi mới -__-.

Chỉnh sửa theo nhận xét, ty!


1
Bạn có thể tiết kiệm một số không gian bằng cách không gói trong một hàm / phương thức. Tuy nhiên, mã của bạn hiện trả về chỉ mục dựa trên 0 (cần phải dựa trên 1) và nó cũng cần trả về -1nếu không tìm thấy bảng màu.
Drainegtun

Đã sửa -1, cảm ơn. Không chắc chắn những gì bạn có trong đầu liên quan đến việc đưa ra một phương pháp mặc dù, tôi sẽ có một suy nghĩ.
Mike Campbell

Ok, lấy lời khuyên của bạn trên tàu và viết lại :), ty.
Mike Campbell

Không có gì! Bây giờ thì tốt hơn nhiều rồi :) +1
Drainegtun

2

05AB1E , 10 byte

gL.Δõs<ǝÂQ

Hãy thử trực tuyến hoặc xác minh một số trường hợp thử nghiệm .

Giải trình:

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 ký tự:

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

Là một hàm ( 85 ký tự ):

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

phiên bản không có bản gốc:

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 ký tự)

Tôi thừa nhận đây không phải là ngôn ngữ tốt nhất để chơi 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);}}

Định dạng và nhận xét:

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 ký tự)

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

Câu lệnh LINQpad mong đợi biến ichứa chuỗi đầu vào. Đầu ra được lưu trữ trong obiến.


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

Được gọi như thế này:

λ> f "racercar"
5

1

Japt , 8 byte

a@jYÉ êS

Thử nó

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

Ung dung:

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

Thạch , 17 14 byte

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

Hãy thử trực tuyến!

           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.

Vì tôi đã thay đổi cách tiếp cận của mình đủ nhanh để phiên bản cũ không hiển thị trong lịch sử chỉnh sửa, nên đây là: ŒPṚḊŒḂ€TṂ©’<La®o-


0

Brachylog , 24 byte

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

Hãy thử trực tuyến!

Cảm thấy quá dài.

Có thể ngắn hơn hai byte nếu đầu ra có thể được lập chỉ mục 2 :

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

Hai lần lặp lại sớm hơn và thậm chí tệ hơn:

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

Việc sử dụng biến toàn cục sau này đòi hỏi một tiêu đề thử nghiệm khác .


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)

Hãy thử trực tuyến!

Trả về ký tự 1 chỉ mục nếu thao tác có thể được thực hiện và -1nếu không.




0

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

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

Try it online!

2 16 17 bytes shaved off thanks to ceilingcat! And 3 more bytes since the rules state the minimum length of the input is 2 characters, so don't have to check for empty strings.

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


2
s[-(i+1)]có thể rút ngắn thành s[-i-1]. Ngoài ra, tôi không chắc nhưng bạn có thể thay thế if...else...bằngreturn i+1 if ... else len(s)-1
user12205

Điều này hoạt động ổn .. Có ai có thể giải thích logic đằng sau này?
Arindam Roychowdhury

Yêu cầu là nó xuất ra -1 nếu đầu vào không phải là một bảng màu với một chữ cái phụ. Vì vậy, ví dụ, nếu s = "abcde", nó sẽ trả về -1.
G. Sliepen

-2

Mã đầu tiên của tôi - golf.

Java. ~ 1200 ký tự trong các chức năng chính (và phụ). Tuyệt! Em yêu.

Lớp đầu và cách sử dụng:

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

Chức năng chính:

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

Chức năng phụ:

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

Toàn lớp:

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
Điều này cho thấy không có nỗ lực chơi golf mã.
mbomb007
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.