完全パリンドローム三角形


18

文字列を考えてください160615051。次のように「三角化」できます。

  1
 606
15051

そして、各行は回文です。また、境界線上の各側面も回文であることに注意してください。

  1  |   1   |   
 6   |    6  |      
1    |     1 | 15051 

したがって、この文字列は完全な回文三角形とみなすことができます。100この場合、高度については心配しないでください。回文型である必要はありません。

入力: 0x20〜0x7Eの印刷可能なASCII文字列。これは、文字配列、単一の文字列、またはASCIIコードポイントの配列です。入力は常に三角測量できます(つまり、その長さは常に完全な正方形になります)。

出力:文字列が完全な回文三角形の場合は真理値、それ以外の場合は偽値。

テストケース

input => output

1 => true
A => true
AAAA => true
nope => false
{{}} => false
1101 => true
1011 => false
1202 => false
111110001 => true
160615051 => true
160625052 => false
1111111111111111 => true
1121123211234321123454321 => true
HHeHHeleHHellleHHellolleH => true
HellolleHHellleHHeleHHeHH => false
111111111111111111111111111111111111 => true
abcbdefeddefgfedbcdefedcbabcdefedcba => true

回答:


10

ゼリー14 12バイト

J’ƲœṗZ⁻¦µU⁼

オンラインでお試しください!

バックグラウンド

入力文字列の0から始まるインデックスを調べることから始めます。

 H  H  e  H  H  e  l  e  H  H  e  l  l  l  e  H  H  e  l  l  o  l  l  e  H
 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

三角形の行を取得するために、我々はインデックスの前に文字列を分割することができる1+ 3 = 4 11 + 3 + 5 = 9、及び1 + 3 + 5 + 7 = 16。ので、(N + 1)²=n²+(2N + 1)、これらの和を正確インデックスリスト内の正、完璧な正方形です。文字列も0の前に分割する場合、これは完全な正方形であるすべての0ベースのインデックスの前に分割するのと同じくらい簡単です。

分割後、次の文字列を取得します。

""
"H"
"HeH"
"HeleH"
"HellleH"
"HellolleH"

次に、最初の空の文字列を最初の列のすべての文字に置き換えます。

"HHHHH"
"H"
"HeH"
"HeleH"
"HellleH"
"HellolleH"

タスクは、すべての文字列を反転して同じ文字列配列が生成されるかどうかをチェックするようになりました。

使い方

最初にJ入力文字列のすべての1ベースのインデックスを生成しJ、次にそれらをデクリメントしてすべての0ベースのインデックスを生成します。Ʋすべての0ベースのインデックスの直角度をテストします。上記の例では、これにより次のブール配列が生成されます。

 1  1  0  0  1  0  0  0  0  1  0  0  0  0  0  0  1  0  0  0  0  0  0  0  0

次に、œṗ入力文字列を分割するために呼び出します。たとえば、

 H  H  e  H  H  e  l  e  H  H  e  l  l  l  e  H  H  e  l  l  o  l  l  e  H

すべて1の前(実際には、すべての真実の要素)。この例では、次の文字列配列が生成されます。

['', 
 'H',
 'HeH',
 'HeleH',
 'HellleH',
 'HellolleH'
]

Z⁻¦間違いなくこの答えの中で最も興味深い部分です。Z1¦最初に、より簡単なものを分析しましょう。

¦あるスパース迅速に。具体的1Zはこの場合、スタックから2つのリンクを消費します。最初にZ引数に適用されます:前からの文字列配列。Zあるジップ原子と列により文字列配列/ 2Dの文字列を読み出し、得

['HHHHH',
 'eeee',
 'Hlll',
 'ell',
 'Hlo',
 'el',
 'Hl',
 'e',
 'H'
]

以前は入力文字列の左側で、文字列配列の最初のが最初の文字列になりました。

ここ¦1、単一のインデックス1を覗いて見つけます。したがって、元の文字列配列の最初の文字列は、Z;の戻り値の最初の文字列に置き換えられます。他のインデックスの文字列は影響を受けません。

['HHHHH',
 'H',
 'HeH',
 'HeleH',
 'HellleH',
 'HellolleH'
]

この配列をAと呼びましょう。

Z⁻¦代わりに使用しましたがZ1¦、これには違いはありません。文字列配列と入力文字列の不等式を比較し、等しくないため1を返します。2つの違いは、2 Z⁻¦項であるということです。つまり、のœṗZ⁻¦代わりに書くことができœṗ¹Z1¦ます。これは、dyad(œṗ)に続くモナド(œṗ¹Z1¦)がフォークである(モナドがチェーンの引数/入力文字列に適用され、戻り値がに正しい引数として渡されるœṗ)一方で、dyadの後に別のダイアドが続くためです(またはチェーンの最後)はフックです。つまり、その正しい引数はチェーンの引数です。

あとは、回文性をチェックするだけです。µ引数がAである新しい(単項)チェーンを開始します。upend原子U逆転するすべての文字列A(ただし、Aそのもの)、その後で結果を比較するA平等のために。返されるブール値1は、完全な回文三角形を示します。他の文字列は0を返します


私は本当にゼリーの読み方を学ぶべきです。(説明してください?)
CAD97

1
回答を編集しました。
デニス

6

Japt25 21 17バイト

@obarakonのおかげで2バイト節約

ò@°T ¬v1
pUmg)eêP

オンラインでテストしてください!

使い方

 ò@  ° T ¬ v1   // Implicit: U = input string, T = 0
UòXY{++T q v1}  // First line; reset U to the result of this line.
UòXY{        }  // Partition U at indices where
     ++T q      //   the square root of T incremented
           v1   //   is divisible by 1.
                // This breaks U at square indices, giving rows of 1, 3, 5, ... chars.
 pUmg)eêP
UpUmg)eêP
  Umg           // Take the first char of every item of U.
Up   )          // Append this to U.
      e         // Check that every item in the resulting array
       êP       // is a palindrome.
                // Implicit: output result of last expression

私たちがチェックする必要はありません両方の側面を。側面が同じでない場合、行の少なくとも1つは回文ではありません。


この複数行のことは、Japtの新機能ですか?
ルーク

@Lukeはい、火曜日に追加しました。これを披露する最初のチャンスです:
ETHproductions

私のゴルフのヒントを気にしないでください。すべての行がパリンドロームであったかどうかを確認するだけで、正しい結果が得られ
ルーク


4

ゼリー18 16バイト

J²‘Ṭœṗ⁸ZḢ$ṭ$ŒḂ€Ạ

オンラインでお試しください!

些細ではあるがそれほど明白ではないJonathan Allanに感謝-2バイトの節約。


私の三角形構造を使用してバイトの保存:JƲ0;œṗ⁸ZḢ$ṭ$ŒḂ€Ạ
ジョナサン・アラン

...実際には分割以来、「最短ジップ」だろう、嘘でそのアイデアを組み合わせて、別のバイトを保存:J²‘Ṭœṗ⁸ZḢ$ṭ$ŒḂ€Ạ
ジョナサン・アラン

@JonathanAllanうーん...なぜ私は必要なの½ですか?今でJはもっと理にかなっています...
エリックアウトゴルファー

3

JavaScript(ES6)、112バイト

f=(s,n=1,t='',u='',g=([...a])=>''+a==a.reverse())=>s?g(s.slice(0,n))&f(s.slice(n),n+2,t+s[0],u+s[n-1]):g(t)&g(u)

tu最後にテストできるように側面を収集します。


2

C#、184バイト

using System.Linq;
b=a=>string.Concat(a.Reverse())==a
f=>{string c=f[0]+"",d=c,e="";for(int i=1,k=1,s=f.Length;i<s;)
{c+=f[i];d+=f[(i+=k+=2)-1];e=f.Substring(s-k);}return b(c)&b(d)&b(e);}

パリンドロームの部分に到達するまで、解決策は良さそうだと思った

ゴルフされていないバージョン:

Func<string, bool> b = a => string.Concat(a.Reverse()) == a;
        Func<string, bool> func = f => {

            string c = f[0] + "", d = c, e = "";

            for (int i = 1, k = 1, s = f.Length; i < s;) {
                c += f[i];
                d += f[(i += k += 2) - 1];
                e = f.Substring(s - k);
            }

            return b(c) & b(d) & b(e);
        };

e=..forループ行に移動してバイトを節約できますか?改行をバイトカウントにカウントする必要はないので、そうではないと想定しています。
TheLethalCoder

いいえ、改行をカウントしていません。eをループに入れることはできません。returnステートメントで必要です。
-LiefdeWen

私はこのような意味....; i < s;e = f.Substring(s - k)){c+=....
-TheLethalCoder

2

Java 8、358 301バイト

import java.util.*;s->{List<String>l=new Stack();for(int i=0,p=1,t=1;p<=s.length();p+=t+=2)l.add(s.substring(i,i=p));String a="",b=a;for(String q:l){a+=q.charAt(0);b+=q.charAt(q.length()-1);}return p(a)&p(b)&p(l.get(l.size()-1));}boolean p(String s){return s.equals(new StringBuffer(s).reverse()+"");}

入力はa String、出力はbooleanです。

説明:

ここで試してみてください。

import java.util.*;               // Required import for List and Stack

s->{                              // Method (1) with String parameter and boolean return-type
  List<String>l=new Stack();      //  Create a String-list
  for(int i=0,p=1,t=1;            //  Initialize some index/counter integers
      p<=s.length();              //  Loop (1) over the String in sections
      p+=t+=2)                    //    And increase `p` like this after every iteration: 1,4,9,16,25,etc.
    l.add(s.substring(i,i=p));    //   And add a substring-section to the list (0,1 -> 1,4 -> 4,9 -> 9,16 -> etc.)
                                  //  End of loop (1) (implicit / single-line body)
  String a="",b=a;                //  Two temp Strings
  for(String q:l){                //  Loop (2) over the list
    a+=q.charAt(0);               //   And append the first character to String `a`
    b+=q.charAt(q.length()-1);    //   And the last character to String `b`
  }                               //  End of loop (2)
  return p(a)                     //  Return if String `a` is a palindrome
        &p(b)                     //   as well as String `b`
        &p(l.get(l.size()-1));    //   as well as the last String in the list
}                                 // End of method (1)

boolean p(String s){              // Method (2) with String parameter and boolean return-type
  return s.equals(new StringBuffer(s).reverse()+"");
                                  //  Return if this String is a palindrome
}                                 // End of method (2)

1

ゼリー 20  21 バイト

+2バイト-バギーコードをリリースしました:(
-1バイト-奇数の整数のような成形から正方形インデックスでのパーティション分割に移動しました

JƲ0;œṗ⁸ZḢ$ṭ$ŒḂ€Ạ

文字のリストを受け入れ、1(Truthy)または0(Falsey)を返すモナドリンク。
注:これは、入力を平方長に制限する仕様の一部を使用します。

オンラインでお試しください!またはテストスイートを見る

これは、すべての行が回文である場合、1つの「サイド」のみがチェック()が必要ですが、Erik the Outgolferはすでにこの事実に気付き、回答で使用していることに注意することで、17バイトに簡略化できますJƲ0;œṗ⁸ZḢ$ṭ$ŒḂ€Ạ私は保存彼らに三角形の構成方法を与えているように、そこにバイト。

さらに、左の引数()に過剰がある場合でも、真のインデックスでのパーティション分割は気にしないことに注意することで、16バイトに改善できますJ²‘Ṭœṗ⁸ZḢ$ṭ$ŒḂ€Ạ

どうやって?

JƲ0;œṗµ2BịЀ⁸Z;⁸ŒḂ€Ạ - Link: list, a      e.g. "abcbazxza"
J                     - range of length of a  = [1,2,3,4,5,6,7,8,9]
 Ʋ                   - is square? (vectorises) [1,0,0,1,0,0,0,0,1]
   0;                 - prepend a zero        [0,1,0,0,1,0,0,0,0,1]
     œṗ               - partition a at 1s     ["a","bcb","azxza"]
       µ              - monadic chain separation, call that t
        2B            - 2 in binary = [1,0]
             ⁸        - chain's left argument, t
          ịЀ         - map with index into    ["aa","bb","aa"] (1st and last of each of t)
              Z       - transpose              ["aba","aba"] (left and right "sides" of t)
               ;⁸     - concatenate t          ["aba","aba","a","bcb","azxza"]
                 ŒḂ€  - palindromic? for €ach  [1,1,1,1,1]
                    Ạ - all?                   1

1
くそ、私はちょうどゼリーの答えをしようとしていました。技術的には私のものが間違っていて、2倍の長さのように...いい仕事:):P
HyperNeutrino

「真実のインデックスでのパーティション分割は、左の引数に過剰がある場合でも気にしない」ことに注意してください。
エリックアウトゴルファー

1

Mathematica、156バイト

B=StringTake;Count[PalindromeQ/@Join[A=Table[B[#,{i^2+1,(i+1)^2}],{i,0,(s=Sqrt@StringLength@#)-1}],{StringJoin@Table[B[A[[i]],1],{i,Length@A}]}],True]==s+1&


入力

["1101"]


あなたは置き換えることはできませんIf[<stuff>, True, False]だけで<stuff>?そして、私And@@(...)はより短いと思いますCount[...,True]==s。これはまたs、変数として定義する必要がないことを意味します。
木ではない

待って、これは実際に対角線をテストしますか?いくつかのテストケース("1202"および"160625052")で誤検出が発生しています。
木ではない

すべての問題が修正されました
-J42161217


1

Java、136バイト

l->{for(int i=0,j,k=1;i<l.size();i=j,k+=2)if(!l.subList(i,j=i+k).equals(l.subList(i,j).asReversed().toList()))return false;return true;}

MutableList<Character>Eclipseコレクションからを使用します

Function<MutableList<Character>, Boolean> func = l->{
   for(int i=0,j,k=1;i<l.size();i=j,k+=2)  // `i` is the start index, `j` is the end index, `k` increments by 2
       if(!l.subList(i,j=i+k).equals( //Check that the first partition equals
           l.subList(i,j).asReversed().toList())  // The same sublist reversed
       )
       return false;
   return true;
};


0

Excel VBA、87バイト

セルから入力を受け取り[A1]、VBEイミディエイトウィンドウに出力する匿名VBEイミディエイトウィンドウ関数

k=1:For i=1To[Len(A1)^.5]:s=Mid([A1],j+1,i*2-1):j=j+i*2-1:k=k*(s=StrReverse(s)):Next:?k

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.