テンキーの騎士番号


33

標準テンキーのゼロ以外の数字の場合

789
456
123

チェスナイトを任意の桁に配置し、通常のL字型ジャンプを何回か実行して、正の10進整数をトレースすることを検討してください。このような方法で表現できる正の整数は何ですか?

それらの1つは38、ナイトがスタートして3、左と上に移動できるから8です。381そして383また可能です。

3ジャンプが行われない場合、それ自体が可能です(これは許可されています)。5も同様ですが、から他の数字に到達できない5ため、数字5が表示される唯一の数字です。

正の10進整数(必要に応じて文字列として取得できます)を取り、数値がテンキーの騎士によって記述された方法で表現できる場合は真理値を出力または返すプログラムまたは関数を記述しますが、そうでなければ出力しますfalsy値。

バイト単位の最短コードが優先されます。Tiebreakerは以前の回答です

真実:

1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 18, 38, 61, 81, 294, 349, 381, 383, 729, 767, 38183, 38383, 18349276, 183492761, 618349276

偽物:

10, 11, 50, 53, 55, 65, 95, 100, 180, 182, 184, 185, 186, 187, 188, 189, 209, 305, 2009, 5030, 3838384, 4838383, 183492760

2
今日のチェス騎士とは何ですか?:-D
ルイスメンドー

1
ヒント:数字を折り返し線として書き出すと、ナイトは常に時計回りに4スペースまたは4スペースカウンターをジャンプします。これが役立つかどうかはわかりません。
基金モニカの訴訟

3
@LuisMendoラッピング。同様に、を無限のリストとして扱う場合は78963214、繰り返し繰り返されます。距離を数えます–それは常に4通りです。私はもっ​​と明確にすべきであり、あなたはそれを円順に書く必要があると明示的に言ったはずです。
ファンドモニカの訴訟

@QPaysTaxesああ、私はあなたが円を意味すると思ったが、123...9。ごめんなさい
ルイスメンドー

@LuisMendo心配いりません。私が言ったように、私は私が何を意味するかについてもっと明確にすべきでした。
基金モニカの訴訟

回答:


16

ゼリー、19 15 14バイト

Doȷ’d3ạ2\P€=2P

オンラインでお試しください!または、すべてのテストケースを確認します

使い方

Doȷ’d3ạ2\P€=2P  Main link. Argument: n (integer)

D               Convert n to base 10 (digit array).
  ȷ             Yield 1000.
 o              Logical OR. This replaces each 0 with 1000.
   ’            Decrement each digit.
    d3          Divmod; replace each digit k with [k:3, k%3].
      ạ2\       Pairwise reduce by absolute difference.
                For each pair of adjacent digits [i, j], this computes
                [abs(i:3 - j:3), abs(i%3 - j%3)].
         P€     Compute the product of each result.
                n is a Numpad's Knight Number iff all products yield 2.
           =2   Compare each product with 2.
             P  Multiply the resulting Booleans.

18

Python 2、52バイト

f=lambda n:n<6or`n%100`in'18349276167294381'*f(n/10)

任意の2つの連続した数字が文字列にあることを確認します'18349276167294381'。連続した数字を取得するために、ではなくzip(`n`,`n`[1:])、最後の2桁を繰り返しチェックし、最後の数字を削除します。


13

網膜58 40バイト

このアイデアを提案してくれたSp3000に感謝します。

M&!`..
O%`.
A`16|18|27|29|34|38|49|67
^$

オンラインでお試しください!(テストスイート全体を一度に実行するために少し変更されています。)

プリント1truthyためと0falsy結果を得るために。

説明

M&!`..

のすべての重複する一致..、つまりすべての連続する数字のペアを見つけ、それらを改行で結合します。

O%`.

各行の数字を並べ替えて、半数のペアをチェックするだけで済むようにします。

A`16|18|27|29|34|38|49|67

有効な移動に対応するすべての行を削除します。

^$

この正規表現の一致をカウントします。つまり、すべての行が削除された場合、結果の空の文字列に1回一致します。そうでない場合、一致に失敗し、代わりにゼロが返されます。



7

ルビー、57バイト

匿名関数。引数は文字列です。

->n{(0..n.size).count{|i|!"16729438183492761"[n[i,2]]}<1}

テストスイートを使用したプログラム:

f=->n{(0..n.size).count{|i|!"16729438183492761"[n[i,2]]}<1}

a=%w{1 2 3 4 5 6 7 8 9 16 18 38 61 81 294 349 381 383 729 767 38183 38383 18349276 183492761 618349276
10 11 50 53 55 65 95 100 180 182 184 185 186 187 188 189 209 305 2009 5030 3838384 4838383 183492760}

a.each {|e|p [e, f[e]]}

可能なすべてのナイトの動きを文字列にエンコードし、入力内の2桁ごとにその文字列が存在するかどうかを確認しました。


ああ、その検索文字列でも17バイト節約できます。Retinaの回答にそれを使用しても構いませんか?
マーティンエンダー

頑張れ!ただクレジットを与えてください。
バリューインク

感謝しますが、Sp3000の提案に基づいてさらに短いソリューションになりました:)
マーティンエンダー

6

grep 58バイト

grep "^((?=18|16|29|27|34|38|49|43|61|67|72|76|81|83|94|92).)*.$"

本当に、grepを倒せないなら...


2
どちら5185EMIT 1あなたのコマンドラインで、一方で5truthyであり、かつ185falsyリストインチ
Guntram Blohmはモニカをサポートします

1
@GuntramBlohmを修正-通常の否定で迷子になった
Yakk

6

Haskell 46バイト

q=zip<*>tail
all(`elem`q"16729438183492761").q

使用例:all(`elem`q"16729438183492761").q $ "183492761"->True

仕組み:@Kevin Lauのanswerにある検索文字列を使用します。q文字列から隣接する文字のペアのリストを作成しますq "1672" -> [('1','6'),('6','7'),('7','2')]。入力からのすべてのペアがルックアップ文字列からのペアに含まれている場合、関数はtrueを返します。q1桁の入力を空のリストに変換するため、elem常に成功します。


なぜzip<*>tail反転したバージョンのように動作するのzip=<<tailですか?Applicativeが一般化するものを理解していないと思います。
xnor

@xnor:私はそれを使うだけです。<*> として定義され (<*>) f g x = f x (g x)ます。
nimi

6

JavaScript(ES6)、65 62バイト

s=>[...s].every((c,i)=>!i|"16729438183492761".match(s[i-1]+c))

trueまたはfalseを返します。以前は再帰的な解決策を試してみましたが、これは63バイトかかりmap、さらにreduceは73バイトかかりました。

編集:@ user81655のおかげで3バイトを保存しました。


うまくできませんでした、私の最善の試みは88バイトでした。ブラボー!
ナウアック

@ user81655あなたは、match代わりに動作します~search(しかし、どちらにしても、それは本当に手に負えません)と|置き換えることができます||(しかし、悲しいことに、再帰バージョンではありません)
ニール

@ user81655 !i|...match成功した場合、一致結果は2桁の単一の文字列の配列であり、|演算子は有効な整数に強制的に変換されるため、動作する方法について言及していました。
ニール

@ニールああ、そう。
user81655

6

C、85 81バイト

ゴルフ:

i;f(char*b){i=*b++-49;return*b?(*b=="8749x7214"[i]||*b=="6983x1632"[i])&&f(b):1;}

古い非再帰バージョン(85バイト):

i;f(char*b){for(;(i=*b++-49),*b&&*b=="8749x7214"[i]||*b=="6983x1632"[i];);return!*b;}

空白とメインプログラムを含む古いコード:

i;
f(char*b){
    for (; (i=*b++-49), *b     // i = index of digit + 1 in following arrays
        &&*b=="8749x7214"[i]   // 1st possible jump for 1..9
        ||*b=="6983x1632"[i];  // 2nd possible jump for 1..9
    );
    return !*b;
}

main(){
    char b[16];
    while(scanf("%s", b) == 1) printf("%d",f(b));
    return 0;
}

これは、標準入力を介してスペース区切りの数値を受け入れ、not-numpad-knightの場合は0を出力し、そうでない場合は1を出力します。

新しい81バイトの再帰バージョンは4バイトを削ります。


5

MATL38 37 29バイト

これは@QPaysTaxes ideaを使用します。

I:8JK5:7Pvj!Uttnqh?)d|2:EQm}h

出力は、2Dの複雑な空でない配列です。すべての値にゼロ以外の実部がある場合は真実であり、そうでない場合は偽です。

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


1
これも許可されていますか?
電卓

質問はを要求truthyまたはfalsy値ではなく、全体の配列。
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

2
@CatsAreFluffy これが真実/偽の定義です。MATLAB / Octaveの場合と同様に、MATLのすべての要素が真実である場合、配列は真実です。(
デニス

CC @ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
デニス


4

MATL、25 24 33 26バイト

@LuisMendoのおかげで1バイト削られました!
@Dennisがバグを発見し、修正しました!ありがとう!

'bSVYXbTUZW'j47-)d2^48\1=A

入力として整数を受け取ります。出力1/0。

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


@LuisMendo両方の点で、ありがとう!
ビーカー

@Dennis更新され、うまくいけば修正されます。ご協力いただきありがとうございます。
ビーカー

A最後に必要とは思わない。MATLのベクトルは、0を含まない限り真実です。-
デニス

4

C、140 92バイト

c;L(char*i){while(*i&&(!c||*i=="6743x1212"[c-49]||*i=="8989x7634"[c-49]))c=*i++;return !*i;}

ASCIIを想定

詳細は こちら

// valid transition from x to n[x-'1'][0 or 1]

int n[9][2] =
{
    {'6','8'},{'7','9'},{'4','8'},
    {'3','9'},{'x','x'},{'1','7'},
    {'2','6'},{'1','3'},{'2','4'}
};

// i is a pointer to where to start on a string

bool L(char * i)
{
    char c = 0;

    // move if not \0 and (not-first-char or is a valid move)

    while((*i) && (!c || (*i)==n[c-'1'][0] || (*i)==n[c-'1'][1]))
    {
        c = (*i++);
    }

    return !(*i); // success if it's \0
}

これらのルックアップテーブルは巨大です。すべての区切り文字を取り除き、代わりに文字列{,}[]としてエンコードすると、スコアを大幅に改善できますchar*。また、#define2回だけ使用する場合、費用対効果が高くないことに注意してください。削除すると4バイト節約されます。
tucuxi

@tucuxiのヒントに感謝し\0ます。配列内で未定義の動作が発生したため、92に下げることができたため、次のように置き換えましたx
Khaled.K

ニース-また、<s>oldscore</s> newscoreスコアの改善を反映するために編集するとき、および<!-- language-all: lang-c -->コードが構文の強調表示を修正する前に使用することを忘れないでください。私はまた、完全にループをドロップすることで、多少私のバイト数を減らすために管理
コビトイルカ

あなたの「詳細」は、ゴルフコードの単純な拡張とは非常に異なって見えます(nショートバージョンはどこにありますか?)。また、おそらく、ASCIIエンコードを想定していることに言及する必要があります。EBCDICマシンでは異なる数値を取得します。
トビーSpeight

@TobySpeight詳細なバージョンは、それが基本的に構築された方法を示すことになっているはい私はCの一般的なケースがあるASCIIと仮定しています
Khaled.K

3

ジュリア、51 49バイト

n->diff(["@1634@8725"...][digits(n)+1]).^2%48⊆1

検証

julia> f=n->diff(["@1634@8725"...][digits(n)+1]).^2%48⊆1
(anonymous function)

julia> all(map(f,(1,2,3,4,5,6,7,8,9,16,18,38,61,81,294,349,381,383,729,767,38183,38383,18349276,183492761,618349276)))
true

julia> any(map(f,(10,11,50,53,55,65,95,100,180,182,184,185,186,187,188,189,209,305,2009,5030,3838384,4838383,183492760)))
false

3

実際には、30バイト

;#pXZdX`Σ"67294381";'1+R+íu`Mπ

入力を文字列として受け取ります。trueの場合は正の整数を、falseの場合は0を出力します。

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

説明:

;#pXZdX`Σ"67294381";'1+R+íu`Mπ
                                 (implicit) push input
;#pXZdx                         push zip(n[:-1], n[1;]) (pairs of digits)
       `Σ"67294381";'1+R+íu`M   map:
        Σ                         join digits
         "67294381";'1+R+         push "16729438183492761" (the magic string used in many other solutions)
                         íu       0-based index (-1 if not found), increment so 0 is not found and >=1 is the 1-based index
                             π  product

3

PowerShell v2 +、105 96バイト

param($a)((1..$a.length|%{'27618349294381672'.IndexOf($a[$_-1]+$a[$_])+1})-join'*'|iex)-or$a-eq5

""文字の連続したペアのインデックスが有効な検索文字列にあることを確認することにより、入力(でカプセル化する必要があります)を反復処理します。ケビン・ラウにも似ようなものがあったようですが、私はこれを独自に思いつきました。文字列が見つからない場合、関数は戻る+1ため、これらの各インデックスにはが追加されます。これにより、「見つかりません」がに変わります。.IndexOf()-10

次に、-joinすべての結果の整数値を*でパイプし、それをパイプしますiex(に似ていますeval)。これは、インデックスのいずれかが見つからない場合、式全体がになることを意味し0ます。それは括弧と中にカプセル化されている-orと「D $a-eq5入力の特殊なケースのための"5"私達の結果の出力を達成します。

テスト実行

PS C:\Tools\Scripts\golfing> 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 18, 38, 61, 81, 294, 349, 381, 383, 729, 767, 38183, 38383, 18349276, 183492761, 618349276 | %{.\numpad-knight-numbers.ps1 "$_"}
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True

PS C:\Tools\Scripts\golfing> 10, 11, 50, 53, 55, 65, 95, 100, 180, 182, 184, 185, 186, 187, 188, 189, 209, 305, 2009, 5030, 3838384, 4838383, 183492760 | %{.\numpad-knight-numbers.ps1 "$_"}
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False

2

C、78バイト

char*a="9614397052";f(x){int b=x/10;return!b||abs(a[x%10]-a[b%10])%6==1&f(b);}

他のすべての人が入力を文字列として受け取っているため、整数で入力してみました。最下位桁(a%10)から再帰的に機能します。それが唯一の数字である場合、trueを返します。それ以外の場合、10桁(b%10)が単位桁から到達できない場合にのみtrueを返し、(再帰的に)入力の残りが同じテストを満たします。

到達可能性のテストは、ナイトのツアーを線形にエンコードし、ツアーの各桁をその位置(0〜7)に変換することで機能します。数字05には、位置9を割り当てます。これは他の位置からは切り離されています。次に、相互に到達可能な番号は1つ(mod 8)異なります。すなわちa[x%10]-a[b%10]、±1または±7のいずれかです。したがって、絶対差(mod 6)を1に対してテストします。

このソリューションは、Cに有効な文字エンコードで機能します(つまり、数字には0〜9の連続したコードがあります)。


1

Java 8、179 167バイト

数字パッドの整数(マイナス5と0)を円の中に配置します。lこれらの整数の円インデックスを保持します。2つのインデックスの差が+/- 3 mod 8である場合、それらのインデックスに対応するint間でナイトが移動します。注xですint[]

x->{if(x.length<2)return 1;int[] l={0,0,1,2,7,0,3,6,5,4};int o=l[x[1]];for(int i:x){int n=l[i];if(i%5==0||(Math.abs(n-o)!=3&&Math.abs(n-o)!=5))return 0;o=n;}return 1;}

更新

  • -11 [16-12-10]ラムダに切り替え
  • -1 [16-12-10]の<2代わりに使用==1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.