Un puzzle semi-palindrome


23

Un palindrome est un mot qui est son propre revers.

Maintenant, il y a des mots qui pourraient ressembler à des palindromes mais qui ne le sont pas. Par exemple , considérons le mot sheesh, sheeshn'est pas un palindrome parce que son inverse est hseehsdifférent, si l' on considère shcomme une seule lettre, il est est inverse sheesh. Ce genre de mot, nous l'appellerons semi-palindrome.

Plus précisément, un mot est un semi-palindrome si nous pouvons diviser le mot en un certain nombre de morceaux de sorte que lorsque l'ordre des morceaux est inversé, le mot d'origine est formé. (Pour sheeshces morceaux sont sh e e sh) Nous exigerons également qu'aucun morceau ne contienne des lettres des deux moitiés du mot (sinon chaque mot serait un semi-palindrome). Par exemple, ce rearn'est pas un semi-palindrome car il r ea ra un morceau ( ea) qui contient des lettres des deux côtés du mot d'origine. Nous considérons que le caractère central dans un mot de longueur impaire n'est sur aucun côté du mot, donc pour les mots de longueur impaire, le caractère central doit toujours être dans son propre bloc.

Votre tâche sera de prendre une liste d'entiers positifs et de déterminer s'il s'agit d'un semi-palindrome. Votre code doit produire deux valeurs inégales cohérentes, l'une si l'entrée est un semi-palindrome et l'autre sinon. Cependant, la séquence d'octets de votre code doit être elle- même un semi-palindrome .

Les réponses seront notées en octets avec moins d'octets étant mieux.

Cas de test

[] -> True
[1] -> True
[2,1,2] -> True
[3,4,2,2,3,4] -> True
[3,5,1,3,5] -> True
[1,2,3,1] -> False
[1,2,3,3,4,1] -> False
[11,44,1,1] -> False
[1,3,2,4,1,2,3] -> False

Programme pour générer plus de cas de test.


borrible a souligné que ceux-ci sont similaires aux palindromes de Smarandache généralisés . Donc, si vous voulez faire d'autres lectures, c'est un point de départ.


2
Pourquoi avez-vous défini des semi-palindromes à l'aide de chaînes, mais vos entrées sont des tableaux d'entiers? En plus d'être déroutant, cela signifie que nous ne pouvons pas tester notre code source à l'aide de notre propre programme.
BradC

@BradC Palindromes et similaires sont souvent expliqués en termes de mots, car c'est un peu plus facile à faire.
Erik the Outgolfer

@BradC Strings a tendance à introduire des cas de bord étranges, en particulier en termes de caractères par rapport aux octets. Je choisis le nombre car ils sont plus simples. Je pensais que les mots seraient plus faciles à des fins d'explication.
Wheat Wizard

2
Ces types de palindromes sont connus sous le nom de palindromes généralisés de Smarandache dans la littérature.
borrible

1
@RosLuP Oui, les "vrais" palindromes sont également des semi-palindromes, il suffit de traiter chaque caractère / entier tel quel, sans "segmentation" supplémentaire.
BradC

Réponses:


6

Retina 0.8.2 , 85 69 octets

M`^(.+,)*(\d+,)?(?<-1>\1)*$(?(1)^)|M`^(.+,)*(\d+,)?(?<-1>\1)*$(?(1)^)

Essayez-le en ligne! Explication:

M`

Sélectionne le mode Match. En fait, Retina utilise par défaut le mode Correspondance pour un programme sur une seule ligne, mais la deuxième copie du code correspondra toujours si ce n'est pour ces caractères supplémentaires.

^

Le match doit commencer au début.

(.+,)*

Capturez un certain nombre de séries de personnages. Chaque course doit se terminer par une virgule.

(\d+,)?

Faites éventuellement correspondre une série de chiffres et une virgule.

(?<-1>\1)*

Faites éventuellement correspondre toutes les captures dans l'ordre inverse, en les faisant apparaître au fur et à mesure de leur correspondance.

$

Le match doit se terminer à la fin.

(?(1)^)

Revenez en arrière, sauf si toutes les captures ont été sautées. Cela fonctionne en exigeant que la correspondance soit toujours au début de la chaîne si nous avons une capture non coupée, ce qui est impossible.


5

Gelée , 27 23 octets

ṖUṁ@Ƒ€ṚẸHḢŒŒHḢŒṖUṁ@Ƒ€ṚẸ

Renvoie 1 pour les semi-palindromes, 0 sinon.

Essayez-le en ligne!

Comment ça marche

ṖUṁ@Ƒ€ṚẸHḢŒŒHḢŒṖUṁ@Ƒ€ṚẸ  Main link. Argument: A (array)

          Π             Invalid token. Everything to its left is ignored.
           ŒH            Halve; divide A into two halves similar lengths. The middle
                         element (if there is one) goes into the first half.
             Ḣ           Head; extract the first half.
              ŒṖ         Generate all partitions of the first half.
                U        Upend; reverse each chunk of each partition.
                         Let's call the result C.

                     Ṛ   Yield R, A reversed.
                   Ƒ€    Fixed each; for each array P in C, call the link to the left
                         with arguments P and R.
                         Return 1 if the result is P, 0 if not.
                 ṁ@          Mold swapped; replace the n integers of C, in reading
                             order, with the first n integers of R.
                     Ẹ   Exists; check if one of the calls returned 1.

4

Python 2 , 157 153 147 147 143 octets

-4 octets grâce à tsh .

s=lambda x,i=0:len(x)<2or[]<x[i:]and(x[-i:]==x[:i])&s(x[i:-i])|s(x,i+1)
s=lambda x,i=0:len(x)<2or[]<x[i:]and(x[-i:]==x[:i])&s(x[i:-i])|s(x,i+1)

Essayez-le en ligne!


1
Modifiez x==x[::-1]pour len(x)<2enregistrer 2 * 2 octets; 143 octets
tsh

4

05AB1E , 59 47 43 41 octets

2äøø€.œ`âʒ`RQ}gĀIg_^q2äøø€.œ`âʒ`RQ}gĀIg_^

-12 octets grâce à @Emigna .

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

2ä               # Split the input into two parts
                 #  i.e. [3,4,2,0,2,3,4] → [[3,4,2,0],[2,3,4]]
  øø             # Zip twice without filler
                 # This will remove the middle item for odd-length inputs
                 #  i.e. [[3,4,2,0],[2,3,4]] → [[3,2],[4,3],[2,4]] → [[3,4,2],[2,3,4]]
    €.œ          #  Then take all possible partitions for each inner list
                 #   i.e. [[3,4,2],[2,3,4]]
                 #    → [[[[3],[4],[2]],[[3],[4,2]],[[3,4],[2]],[[3,4,2]]],
                 #       [[[2],[3],[4]],[[2],[3,4]],[[2,3],[4]],[[2,3,4]]]]
`                # Push both lists of partitions to the stack
 â               # Take the cartesian product (all possible combinations) of the partitions
                 #  i.e. [[[[3],[4],[2]],[[2],[3],[4]]],
                 #        [[[3],[4],[2]],[[2],[3,4]]],
                 #        ...,
                 #        [[[3,4,2]],[[2,3,4]]]]
  ʒ   }          # Filter this list of combinations by:
   `             #  Push both parts to the stack
    RQ           #  Check if the second list reversed, is equal to the first
                 #   i.e. [[3,4],[2]] and [[2],[3,4]] → 1 (truthy)
       gĀ        # After the filter, check if there are any combinations left
                 #  i.e. [[[[3,4],[2]],[[2],[3,4]]]] → 1 (truthy)
         Ig_     # Check if the length of the input was 0 (empty input-list edge-case)
                 #  i.e. [3,4,2,0,2,3,4] → 7 → 0 (falsey)
            ^    # Bitwise-XOR
                 #  i.e. 1 XOR 0 → 1 (truthy)
             q   # Stop the program (and then implicitly output the top of the stack)
2äøø€.œ`âʒ`RQ}gĀIg_^
                 # Everything after the `q` are no-ops to comply to the challenge rules

Vous pouvez contourner le problème avec des listes de longueur impaire avec øøε.œ} `, en économisant 6 octets. Vous semblez également avoir laissé 30 octets inutilisés dans ...
Emigna

@Emigna, les non-opérations à la fin doivent se conformer à l'exigence de source restreinte du défi
Kamil Drakari

@KamilDrakari: Ah oui. J'ai oublié cette partie. La bonne nouvelle est que la sauvegarde de 6 octets sera alors de 12 octets :)
Emigna

@Emigna Très intelligent avec l'astuce double zip. Je n'étais pas content de cette partie, mais c'est beaucoup mieux! Btw, puisque l'Elixir réécrit les commandes de 2 octets peuvent être utilisées avec au lieu de ε }. :)
Kevin Cruijssen

@KevinCruijssen: Ah cool. Je ne le savais pas.
Emigna

4

05AB1E , 37 octets

Utilise à peu près la même technique que Jonathan a inventée.

.œʒ€gηOZ;îå}εÂQ}ZĀqĀZ}QÂε}åî;ZOηg€ʒ.œ

Essayez-le en ligne!


.œʒ€gηOZ;îå}εÂQ}ZĀqĀZ}QÂε}åî;ZOηg€ʒ.œ

Programme complet. Reçoit une liste de STDIN, sort 1 ou 0 vers STDOUT.

.œʒ        }

Filtrez-gardez les partitions qui satisfont ...

   €gηOZ;îå

Cette condition: Les longueurs de chaque ( €g) sont stockées dans une liste, dont les préfixes ( η) sont ensuite additionnés ( O), nous donnant ainsi les sommes cumulées de la liste des longueurs. Ensuite, la moitié plafonnée du maximum de cette liste est poussée sur la pile - mais en conservant également la liste d'origine ( Z;î) et si elle se produit ( å) dans les sommes cumulées, la fonction retourne véridique.

εÂQ}

Pour chacun, comparez ( Q) a avec un inversé, qui sont poussés séparément sur la pile par Â. Renvoie une liste de 0 s et 1 s.

ZĀq

Maximum. Si l'un d'eux est véridique, alors 1 sinon 0 . Fin de l'exécution. Tout ce qui suit est complètement ignoré.


3

Python 2 , 275 251 205 octets

-24 octets grâce à @KevinCruijssen

-44 octets grâce à @PostLeftGhostHunter

-2 octets de plus grâce à @KevinCruijssen

def s(x):
 l=len(x)
 if l<2:return 1>0
 for i in range(1,l/2+1):
	if x[l-i:]==x[:i]:return s(x[i:l-i])
def s(x):
 l=len(x)
 if l<2:return 1>0
 for i in range(1,l/2+1):
	if x[l-i:]==x[:i]:return s(x[i:l-i])

Renvoie True pour le semi-palindrome, None sinon

Essayez-le en ligne!


1
Ou tout simplement revenir 1
Jo King

Pourquoi s (x) est-il défini deux fois?
Dr Y Wit du

Parce qu'ils disent compter comme palindrome ... mais est-il possible de définir une fonction avec le même nom ???
RosLuP

@RosLuP Oui, vous le pouvez. Le second écrase juste le premier
Jo King

3

Gelée ,  33  32 octets

-1 Merci à Erik l'Outgolfer
Merci également à Dennis pour une correction de bogue et pour avoir cherché à changer un détail d'implémentation dans Jelly.

ẸƇŒḂƇƊ$ƊĊHṀċÄẈṖŒŒṖẈÄċṀHĊƊ$ƊƇŒḂƇẸ

Les semi-palindromes donnent 1, d'autres donnent 0.

O(2n) en longueur d'entrée)

Ou consultez la suite de tests .

Les seuls morceaux sont les ŒḂs ({3 rd & 4 th } vs {29 th & 30 th } octets), juste pour permettre au code d'analyser.

Comment?

Tout le travail est effectué par le côté droit - le "lien principal":

ŒṖẈÄċṀHĊƊ$ƊƇŒḂƇẸ - Main Link: list
ŒṖ               - all partitions
           Ƈ     - filter keep those for which this is truthy (i.e. non-zero):
          Ɗ      -   last three links as a monad:
  Ẉ              -     length of each
         $       -     last two links as a monad:
   Ä             -       cumulative addition
        Ɗ        -       last three links as a monad:
     Ṁ           -         maximum
      H          -         halve
       Ċ         -         ceiling
    ċ            -     count
              Ƈ  - filter keep those for which this is truthy:
            ŒḂ   -   is palindrome?
               Ẹ - any?

3

Perl 6 , 87 79 octets

-8 octets avec quelques astuces de la réponse de Jo King

$!={/\s/&&/^(.+)\s[(.+)\s]*$0$/&&$1.$!}#$!={/\s/&&/^(.+)\s[(.+)\s]*$0$/&&$1.$!}

Essayez-le en ligne!

Réponse JavaScript du port de tsh. Renvoie deux objets Regex différents.


2

Rubis , 129 octets

f=->l{!l[1]||(1...l.size).any?{|x|l[0,x]==l[-x,x]&&f[l[x..~x]]}}#f=->l{!l[1]||(1...l.size).any?{|x|l[0,x]==l[-x,x]&&f[l[x..~x]]}}

Essayez-le en ligne!



1

C (gcc) (X86), 216 octets

p(L,a,n)int*a;{return n?(memcmp(a,a+L-n,n*4)|p(L-2*n,a+n,L/2-n))&&p(L,a,n-1):1<L;}
#define p(L,a)p(L,a,L/2)//p(L,a,n)int*a;{return n?(memcmp(a,a+L-n,n*4)|p(L-2*n,a+n,L/2-n))&&p(L,a,n-1):1<L;}
#define p(L,a)p(L,a,L/2)

Essayez-le en ligne!

p(L,a,n)renvoie 0 si le tableau ade longueur Lest un semi-palindrome, 1 sinon. Étant donné que tous les préfixes de longueur >nsont déjà vérifiés, il compare le préfixe de longueur navec le suffixe de longueur n. p(L,a)est le point d'entrée.

Malheureusement, la solution la plus intéressante est plus longue:

224 octets

(f(L,a,n))//#define p(L,a)(n=L/2,
int*a,n;
{return n?(memcmp(a,a+L-n,n*4)|f(L-2*n,a+n,L/2-n))&&f(L,a,n-1):1<L;}//{return n?(memcmp(a,a+L-n,n*4)|f(L-2*n,a+n,L/2-n))&&f(L,a,n-1):1<L;}
int*a,n;
#define p(L,a)(n=L/2,f(L,a,n))//(

Essayez-le en ligne!

Non golfé:

(f(L,a,n)) //#define p(L,a)(n=L/2,
int*a,n;
{
  return n 
    ? (memcmp(a, a+L-n, n*4) | f(L-2*n, a+n, L/2-n)) &&
      f(L,a,n-1)
    : 1 < L;
} // { ... } 
int*a,n;
#define p(L,a)(n=L/2,f(L,a,n)) //(

1

Japt , 66 octets


@¯X eUsXn}a1 "
ʧV?UÊ<2:ßUéV sVÑ
@¯X eUsXn}a1 "
ʧV?UÊ<2:ßUéV sVÑ

Interprète Japt

Grande amélioration de cette version, elle bat actuellement la plupart des langues pratiques. Fonctionne maintenant sur un tableau d'entiers puisque la méthode précédente avait un bogue.

Explication:

@        }a1         Find the first number n > 0 such that...
 ¯X                   the first n elements
     UsXn             and the last n elements
    e                 are the same

"
ʧV?UÊ<2:ßUéV sVÑ    String literal to make it a Semi-palindrome
@¯X eUsXn}a1 "

ʧV?                 If n >= length of input...
    UÊ<2              return true if the length is less than 2
        :            Otherwise...
          UéV         move n elements from the end of the input to the start
              sVÑ     remove the first 2*n elements
         ß            and repeat on the remaining elements

0

PHP 237 octets

function f($a){for($x=2>$c=count($a);++$i<=$c/2;)$x|=($s=array_slice)($a,0,$i)==$s($a,-$i)&f($s($a,$i,-$i));return$x;}#function f($a){for($x=2>$c=count($a);++$i<=$c/2;)$x|=($s=array_slice)($a,0,$i)==$s($a,-$i)&f($s($a,$i,-$i));return$x;}

fonction récursive, renvoie true(pour une entrée contenant moins de deux éléments) ou 1pour true,
0pour falsy. Essayez-le en ligne (contient une ventilation).

La longueur réelle du code est de 118 octets; semi-palindrome créé par duplication de code.

Pour de meilleures performances, remplacez &par &&et insérez !$x&&avant ++$i.


0

Scala, 252 octets

def^(s:Seq[Int]):Int={val l=s.size;if(l>1)(1 to l/2).map(i=>if(s.take(i)==s.takeRight(i))^(s.slice(i,l-i))else 0).max else 1}//def^(s:Seq[Int]):Int={val l=s.size;if(l>1)(1 to l/2).map(i=>if(s.take(i)==s.takeRight(i))^(s.slice(i,l-i))else 0).max else 1}

Essayez-le en ligne!

PS. Apparemment, la solution est 2 fois plus longue juste pour satisfaire une exigence selon laquelle le code source est également semi-palindrome.

PPS. Pas un candidat au code-golf mais une solution purement fonctionnelle utilisant la correspondance de modèles:

  def f(s:Seq[Int], i:Int=1):Int = {
    (s, i) match {
      case (Nil ,_) => 1
      case (Seq(_), _) => 1
      case (l, _) if l.take(i) == l.takeRight(i) => f(l.slice(i,l.size-i), 1)
      case (l, j) if j < l.size/2 => f(l, i+1)
      case (_, _) => 0
    }
  }

Le défi exige que votre code soit également un semi-palindrome. C'est le plus amusant du défi.
Wheat Wizard

@PostLeftGhostHunter, j'ai ajouté le code source original dans le commentaire pour satisfaire l'exigence. BTW, quel est le plaisir de faire du semi-palindrome de code source? Si je ne me trompe pas, chaque solution de ce fil serait deux fois plus courte sans cette exigence. Êtes-vous au courant d'une solution différente de celle-là?
Dr Y Wit du

0

Perl 6 , 81 octets

($!={/../&&/^(.+)(.*)$0$/&&$1.$!})o&chrs#($!={/../&&/^(.+)(.*)$0$/&&$1.$!})o&chrs

Essayez-le en ligne!

Renvoie l'expression régulière /../pour True et l'expression régulière/^(.+)(.*)$0$/ pour False. Fonctionne de manière similaire à la réponse de nwellnhof , mais convertit la liste en chaîne au préalable.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.