숫자 키패드의 기사 번호


33

표준 숫자 키패드 에서 0이 아닌 숫자

789
456
123

모든 숫자에 체스 기사 를 배치하고 양의 십진 정수를 추적하여 정상적인 L 자형 점프로 움직입니다. 그런 식으로 어떤 양의 정수를 표현할 수 있습니까?

그중 하나는 38기사가 시작해서 3왼쪽에서 위로 이동할 수 있기 때문 8입니다. 381그리고 383도 가능합니다.

3점프가 수행되지 않으면 자체적으로 가능합니다 (허용됨). 5또한 다른 숫자는에서 접근 할 수 5없으므로 숫자 5가 표시 되는 유일한 숫자 입니다.

양 진수 정수 취하는 프로그램이나 함수를 작성하고 인쇄 또는 리턴 (는 원하는 경우 문자열을 취할 수있다) truthy의 출력 수를 설명하는 방식으로 숫자 키패드에 나이트로 표현 될 수 있다면 값이지만 그렇지 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
Luis Mendo

1
힌트 : 줄 바꿈으로 숫자를 쓰면 기사는 항상 시계 방향으로 4 칸 또는 카운터로 4 칸 이동합니다. 이것이 도움이되는지 모르겠습니다.
기금 모니카의 소송

3
@LuisMendo 포장. 에서처럼, 당신이 치료하는 끝없는 목록으로 78963214, 반복해서 반복됩니다. 거리를 세십시오 – 항상 4 가지입니다. 나는 더 명확하고 명확하게 원순으로 작성해야한다고 말 했어야합니다.
기금 모니카의 소송

@QPaysTaxes 오, 나는 당신이 서클을 의미한다고 생각했지만 123...9. 죄송합니다
Luis Mendo

@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

파이썬 2, 52 바이트

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

두 개의 연속 숫자가 문자열에 있는지 확인합니다 '18349276167294381'. 을 수행하는 대신 연속 숫자를 얻으려면이 zip(`n`,`n`[1:])함수는 마지막 두 자리를 반복적으로 확인하고 마지막 자리를 제거합니다.


13

망막 , 58 40 바이트

이 아이디어를 제안한 Sp3000에 감사합니다.

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

온라인으로 사용해보십시오! 전체 테스트 스위트를 한 번에 실행하도록 약간 수정했습니다.

1진실하고 0잘못된 결과를 위해 인쇄 합니다.

설명

M&!`..

의 모든 겹치는 일치 항목 .., 즉 모든 연속 자릿수 쌍을 찾아서 줄 바꿈과 결합합니다.

O%`.

각 줄의 숫자를 정렬하여 반만 확인하면됩니다.

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

유효한 이동에 해당하는 모든 줄을 제거하십시오.

^$

이 정규식의 일치 항목을 계산하십시오. 즉, 모든 행이 제거되면 결과로 나오는 빈 문자열이 한 번 일치하고, 그렇지 않으면 일치하지 않고 대신 0이됩니다.



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

방금 가능한 모든 기사를 문자열로 인코딩하고 입력 내의 두 자리 숫자가 해당 문자열에 존재하는지 확인했습니다.


아, 그 검색 문자열은 17 바이트를 절약 할 것입니다. 레티 나 답변에 이걸 사용해도 될까요?
Martin Ender

해봐! 신용을 줘요
Value Ink

고맙지 만 Sp3000의 제안에 따라 더 짧은 솔루션으로 끝났습니다 :)
Martin Ender

6

grep 58 바이트

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

정말, grep을 이길 수 없다면 ...


2
진실 하고 거짓된 목록에있는 동안, 당신의 명령 줄을 사용 5하거나 185방출 하지 마십시오. 15185
Guntram Blohm은 Monica

1
@ 건 트램 블롬 (GuntramBlohm) 고정-정기적 인 부정으로 길을 잃었다
Yakk

6

하스켈 46 바이트

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

사용 예 : all(`elem`q"16729438183492761").q $ "183492761"->True

작동 방식 : @Kevin Lau 's answer 에서 찾은 조회 문자열을 사용합니다 . q문자열에서 인접한 문자 쌍의 목록을 만듭니다 (예 :) q "1672" -> [('1','6'),('6','7'),('7','2')]. 입력의 모든 쌍이 조회 문자열의 쌍으로 나타나면 true를 반환합니다. q단일 숫자 입력을 빈 목록으로 변환하므로 elem항상 성공합니다.


zip<*>tail반전 된 버전처럼 작동하는 이유는 무엇 zip=<<tail입니까? 나는 응용 프로그램이 일반화하는 것을 이해하지 못한다고 생각합니다.
xnor

@ xnor : 그냥 사용합니다. <*> 로 정의됩니다 (<*>) f g x = f x (g x) .
nimi

6

자바 스크립트 (ES6), 65 62 바이트

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

true 또는 false를 반환합니다. 이전에는 63 바이트를 사용하는 재귀 솔루션을 시도했지만 map심지어 reduce73 바이트를 사용했습니다.

편집 : @ user81655 덕분에 3 바이트가 절약되었습니다.


더 잘할 수 없었습니다. 최선의 시도는 88 바이트였습니다. 브라보!
Naouak

@ user81655 당신은 match그 대신에 ~search(그러나 어느 쪽이든, 실제로 는 미숙 한) 작동 하고 |대체 할 수 ||있지만 (재귀 버전에서는 슬프게도)
Neil

@ user81655 !i|...match일치하는 결과가 성공하면 두 자릿수의 단일 문자열 배열이므로 |연산자가 유효한 정수로 강제 변환 되기 때문에 작동 하는 방식을 언급하고 있습니다 .
Neil

@ 닐 아, 맞아.
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;
}

이것은 표준 입력을 통해 공백으로 구분 된 숫자를 받아들이고 숫자 키패드가 아닌 경우 0을 출력하고 그렇지 않으면 1을 출력합니다.

새로운 81 바이트 재귀 버전은 4 바이트를 면도합니다.


5

MATL , 38 37 29 바이트

이것은 @QPaysTaxes idea를 사용합니다 .

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

출력은 2D의 복잡한 비어 있지 않은 배열입니다. 모든 값이 0이 아닌 실제 부분을 가지면 진실이며 그렇지 않으면 거짓입니다.

온라인으로 사용해보십시오!


1
이것도 허용됩니까 ??
CalculatorFeline

문제는 요청 truthy 또는 falsy 값이 아닌 전체 배열입니다.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

2
@CatsAreFluffy 이것은 진실 / 거짓에 대한 우리의 정의입니다. MATLAB / Octave에서와 같이, 배열은 MATL에서 진실입니다. 모든 요소가 진실입니다. ( )
Dennis

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


4

MATL, 25 24 33 26 바이트

@LuisMendo 덕분에 1 바이트가 줄었습니다!
@Dennis는 버그를 찾아서 고쳤습니다! 감사!

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

정수를 입력으로받습니다. 1/0을 출력합니다.

온라인으로 사용해보십시오!


@LuisMendo 두 카운트 모두 맞습니다. 감사합니다!
비이커

@Dennis 업데이트되었으며 희망적으로 수정되었습니다. 당신의 도움을 주셔서 감사합니다.
비이커

나는 당신 A이 끝에 필요하다고 생각하지 않습니다 . MATL의 벡터는 0을 포함하지 않으면 진실입니다.
Dennis

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*대신 문자열 로 인코딩 하면 점수를 크게 향상시킬 수 있습니다 . 또한 #define두 번만 사용하면 비용 효율적이지 않습니다. 제거하면 4 바이트가 절약됩니다.
tucuxi

@tucuxi 팁에 감사드립니다 \0. 배열 내에서 정의되지 않은 동작을 일으켜 92 로 줄 x
였습니다.

또한 <s>oldscore</s> newscore점수 향상을 반영하기 위해 편집 할 때와 <!-- language-all: lang-c -->코드가 구문 강조를 수정하기 전에 사용하는 것을 잊지 마십시오 . 또한 루프를 완전히 삭제하여 바이트 수를 다소 줄일 수있었습니다.
tucuxi

귀하의 '상세 정보'는 골프 코드의 일반 확장과는 매우 다르게 보입니다 ( n짧은 버전은 어디에 있습니까?). 또한 ASCII 인코딩을 가정하고 있음을 언급해야 할 것입니다. EBCDIC 시스템에서 다른 숫자를 얻을 수 있습니다.
Toby 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

""순차 문자 쌍의 색인이 유효한 찾아보기 문자열에 있는지 확인 하여 입력을 통해 (캡슐화해야 함) 반복 합니다. 케빈 라우 (Kevin Lau)가 비슷한 것을 보았지만 나는 이것을 독립적으로 생각해 냈습니다. 문자열을 찾을 수 없으면 함수가 반환 +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)로 변환하여 작동합니다. 숫자 0및의 5경우 다른 위치와의 연결이 끊어진 위치 9를 지정합니다. 그런 다음 서로 연결할 수있는 숫자는 1 (mod 8) 씩 다릅니다. 즉 a[x%10]-a[b%10], ± 1 또는 ± 7입니다. 따라서 1에 대한 절대 차이 (mod 6)를 테스트합니다.

이 솔루션은 C에 유효한 모든 문자 인코딩에 적용됩니다 (예 : 숫자는 0에서 9까지의 연속 된 코드를 가짐).


1

자바 8, 179167 바이트

숫자 패드 정수 (마이너스 5와 0)를 원 안에 놓습니다. l이 정수의 원 인덱스를 유지합니다. 두 지수의 차이가 +/- 3 mod 8 인 경우 기사는 해당 지수에 해당하는 정수 사이에 이동합니다. 참고 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.