위치 인코딩에서 숫자 인식

Sep 13 2020

무한 그리드에서 원점을 시작하면 위 ( U), 아래 ( D), 왼쪽 ( L) 또는 오른쪽 ( R) 으로 미리 정해진 경로를 따릅니다 . 시작한 광장과 끝낸 광장을 포함하여 방문하는 모든 광장을 칠합니다. 이 방법을 사용하면 지침에 따라 숫자 6을 그릴 수 있습니다 RRDDLLUUUURR.

원점은 녹색 별표로 표시됩니다. 이것을 숫자 6 의 위치 인코딩 이라고합니다. 위치 인코딩은 고유하지 않습니다. 인코딩 LLUURRDDUULLUURR은 또한 일부 중복으로 숫자 6을 인코딩합니다.

경로에 이미 그린 사각형을 방문하면 그대로 두십시오.

도전

문자열로 취해진 0에서 9까지의 숫자 중 하나의 위치 인코딩이 주어지면 인코딩하는 숫자를 출력합니다.

모든 숫자는 \ 로 인코딩됩니다.$3\times5\$ 형식은 다음과 같습니다.

#     ###   ###   # #   ### 
#       #     #   # #   #   
#     ###   ###   ###   ### 
#     #       #     #     # 
#     ###   ###     #   ### 

###   ###   ###   ###   ###
#       #   # #   # #   # #
###     #   ###   ###   # #
# #     #   # #     #   # #
###     #   ###   ###   ###

참고 :

  • 제공된 위치 인코딩은 항상 위에 제공된 10 자리 숫자 중 하나에 정확하게 매핑됩니다. 입력 문자열은 유효합니다.
  • 숫자는 미러링되거나 회전되지 않습니다.
  • 인코딩에 중복이있을 수 있습니다 (예 :) LR.
  • 시작하는 사각형은 항상 그려져 있습니다.

테스트 케이스

Input                -> Output
DDDD                 -> 1
UUUU                 -> 1
DDUDDUDD             -> 1
DDUUUUDDUUDD         -> 1
LRRDDLLDDRLRR        -> 2
LDDRRLLUURRUULL      -> 2
RRDDLLRRDDLL         -> 3
LLRRUULLRLRRUUDULL   -> 3
LUUDDRRUUDDDD        -> 4
DDLLUUDDRRDD         -> 4
LLDDRRDDLL           -> 5
DLLRRUULLUURRLLRR    -> 5
RRDDLLUUUURR         -> 6
LLUURRDDUULLUURR     -> 6
RRDDLLUURRDDLLUUUURR -> 6
RRDDDD               -> 7
LLRRDDDD             -> 7
LUURRDDDDLLU         -> 8
RUULLUURRDDLLDD      -> 8
RRDDLLUURRDDDDLL     -> 9
DUDLRLLRRUULLRRUULLD -> 9
RRUUUULLDDD          -> 0
UUUUDDDDRRUUUULRDDDD -> 0

또한 목록 형식 :

[['DDDD', 1], ['UUUU', 1], ['DDUDDUDD', 1], ['DDUUUUDDUUDD', 1], ['LRRDDLLDDRLRR', 2], ['LDDRRLLUURRUULL', 2], ['RRDDLLRRDDLL', 3], ['LLRRUULLRLRRUUDULL', 3], ['LUUDDRRUUDDDD', 4], ['DDLLUUDDRRDD', 4], ['LLDDRRDDLL', 5], ['DLLRRUULLUURRLLRR', 5], ['RRDDLLUUUURR', 6], ['LLUURRDDUULLUURR', 6], ['RRDDLLUURRDDLLUUUURR', 6], ['RRDDDD', 7], ['LLRRDDDD', 7], ['LUURRDDDDLLU', 8], ['RUULLUURRDDLLDD', 8], ['RRDDLLUURRDDDDLL', 9], ['DUDLRLLRRUULLRRUULLD', 9], ['RRUUUULLDDD', 0], ['UUUUDDDDRRUUUULRDDDD', 0]]

득점

바이트 단위의 가장 짧은 코드가 이깁니다.

답변

18 Arnauld Sep 13 2020 at 16:38

JavaScript (Node.js) ,  89 ... 77  71 바이트

@KjetilS에서 제공하는 모듈로 체인을 사용하여 6 바이트를 절약했습니다.

s=>Buffer(s).map(c=>o|=p*=4**(c%5)/8,o=p=4**8)|(o/=o&-o)*321%3081%53%11

온라인으로 시도하십시오!

어떻게?

ASCII 코드 \$c\$방향 문자 모듈로 \$5\$\ 의 인덱스에 매핑하려면$\{0,1,2,3\}\$.

각 방향의 경우, 우리는 비트 마스크를 업데이트 \$p\$다른 비트 마스크에 방문 된 비트를 특정 량만큼을 이동 및 마크로 \$o\$.

 char. | ASCII | mod 5 | shift
-------+-------+-------+-------
  'U'  |   85  |   0   | >> 3
  'L'  |   76  |   1   | >> 1
  'R'  |   82  |   2   | << 1
  'D'  |   68  |   3   | << 3

편리하게도 이동은 곱하기 \$p\$ 으로:

$$\frac{4^{(c\bmod 5)}}{8}$$

우리는 둘 다 \$p\$및 \$o\$\로 설정$4^8=2^{16}\$. 이 값은 \ 이상 오른쪽으로 이동하지 않기 때문에 안전합니다.$4\times 3 + 2\times 1=14\$(예 : "UUUULL"를 사용하여 \$7\$또는 오른쪽 하단에서 왼쪽 상단 모서리로 이동하는 다른 경로). 마찬가지로, 우리는 절대로 \$14\$및 초과 할 수 없습니다 \$2^{30}\$. 그래서 둘 다 \$p\$및 \$o\$ 32 비트 값을 유지합니다.

숫자의 어느 셀이 시작점인지 모르기 때문에 \ 의 최종 값을 정규화합니다.$o\$ 모든 후행 0을 제거하여 :

o /= o & -o

숫자를 식별하는 고유 한 15 비트 키로 끝납니다.

 digit |   binary mask   | decimal
-------+-----------------+---------
   0   | 111101101101111 |  31599
   1   | 001001001001001 |   4681
   2   | 111001111100111 |  29671
   3   | 111100111100111 |  31207
   4   | 100100111101101 |  18925
   5   | 111100111001111 |  31183
   6   | 111101111001111 |  31695
   7   | 100100100100111 |  18727
   8   | 111101111101111 |  31727
   9   | 111100111101111 |  31215

180 ° 회전 된 숫자 모양의 이진 표현으로 볼 수 있습니다. 예를 들면 :

                       100    111
                       100    001
100 100 100 100 111 -> 100 -> 001 -> "7"
                       100    001
                       111    001

다음 함수를 적용하여 예상 숫자로 바꿉니다.

$$f(n)=\big(((n\times 321)\bmod 3081)\bmod 53\big)\bmod 11$$

13 Neil Sep 13 2020 at 16:35

차콜 , 70 65 63 60 58 43 38 바이트

F⁺SR«UMKVIΣκ✳ι1»≔↨KA²θ⎚§”←&Φ⁴.º!H”﹪θ⁹⁴

온라인으로 시도하십시오! 링크는 자세한 코드 버전입니다. 설명:

F⁺SR«

입력에 더미 명령어를 추가하여 양쪽 끝이 그려 지도록하고 명령어를 반복합니다.

UMKVIΣκ

각 셀의 이웃을 채 웁니다. (이는 PeekAll()그려진 셀만 반환하고 해당 위치는 반환하지 않기 때문에 그룹 69, 08및 을 구분할 수 없기 때문입니다 235.) 직각으로 인접한 각 셀은 1경로에있는 셀과 0다른 모든 셀에 대한 디지털 합계로 대체됩니다. 셀 (새롭거나 이전에 패딩되었는지 여부).

✳ι1»

리터럴 1s를 사용하여 경로를 그리고 적절한 방향으로 이동합니다.

≔↨KA²θ

그린 셀과 패딩 만 기록한 셀을 기록하고 이진수 인 것처럼 해석합니다.

⎚

캔버스를 지 웁니다.

§”←&Φ⁴.º!H”﹪θ⁹⁴

56 0817 934 2모듈로 94 이상에서 캡처 한 기본 2 숫자로 압축 된 조회 테이블 (공백이 중요 하지 않은 값)을 주기적으로 인덱싱 하고 결과를 출력합니다.

압축되지 않은 조회 테이블을 0473125869_동일한 바이트 수에 대해 모듈로 378을 취하여 11 바이트로 축소 하거나 8739651204모듈로 4207을 취하여 10 바이트 로 축소 할 수 있지만, 이것은 실제로 압축 후 1 바이트 더 길어 지므로 대신 캡처하면 2 진법이 아닌 5 진법의 숫자를 모듈로 579로 취 7269105348하면 동일한 바이트 수 에 대해 테이블에서 결과를 주기적으로 인덱싱 할 수 있습니다 .

숫자 디코딩의 예 : 그리기 RRDDDD결과 다음 캔버스가 생성됩니다.

 000
01110
 0010
  010
  010
  010
   0

0000111000100100100100이 값을 2 진수로 231716으로 읽은 다음 모듈로 94를 줄이면 6이 주어지며, 이는 조회 테이블에 (주기적으로) 인덱싱되어 7원하는 결과를 생성 합니다.

11 xash Sep 13 2020 at 19:49

J , 75 65 59 55 바이트

-10 조나 덕분에!

-6 Bubbler 덕분에!

-4 FrownyFrog 덕분에!

다음 위치의 비트 마스크로 숫자를 식별합니다.

#0# 
1 2 
#3# 
4 # 
###

따라서 8은 11111, 7은10100

'=)76.:;4?'i.4 u:2#.1,i.@5(e.>./-:@->:)0+/\@,3-2*5|3&u:

온라인으로 시도하십시오!

작동 원리

3-2*5|3&u:

에 매핑 DRLU합니다 -3 -1 1 3. (Arnauld에게 감사합니다!)

(>./…-…)0+/\@,

0 (그린 시작 타일)을 추가하고 모든 접두사를 절대 인덱스 (예 : 0 1 2 5 8 11 14. 인덱스가 음수 일 수 있으므로 가장 높은 숫자를 가져와 모든 인덱스에서 빼십시오.

i.@5(e.…-:@…>:)

1 3 5 7 9설정된 인덱스를 확인 합니다 : 1 0 1 0 0.

'=)76.:;4?'i.4 u:2#.1,

앞에 1이 추가 된 비트 마스크 (숫자가 ASCII에 깔끔하게 맞음)가 표에서 조회됩니다.

6 UnrelatedString Sep 13 2020 at 18:47

젤리 , 35 34 32 바이트

O%15Żı*ÄÆiḞ_Ṃ$‘ŒṬFḄ%29ị“ẆA⁻R§’D¤

온라인으로 시도하십시오!

-1 내 brainfart를 수정 Zgarb 덕분에

-2 조나단 앨런에게 감사의 말을 전하고 Ż공간을 제거하기 위해 재배치했습니다.

나는 내가 뭘하고 있는지 전혀 모르겠다. Ḟ‘ŒṬ해시 함수를 현명하게 선택하는 것이 필요하지 않은 것처럼 느껴지며 Arnauld의 JS 답변을 완전히 번역하는 것은 끔찍한 생각이 아닙니다. 나는 꽤 많은 멍청한 해시 함수를 시도해 보았고 모두 2 대 5에서 넘어졌지만 아마도 기본 변환을 계속 사용한다면 ...

       Ä          Cumulative sums of
     ı*           sqrt(-1) to the (vectorized) power of
O                 the codepoints of the input
 %15              mod 15 (U,D,L,R -> 10,8,1,7 ≡ 2,0,1,3 mod 4)
    Ż             with 0 prepended.
        Æi        a + bi -> [a, b],
          Ḟ       convert the floats to integers,
           _Ṃ$    and subtract the minimum.

‘                     Increment so that all indices are positive,
 ŒṬ                   then convert them to a multidimensional Boolean array,
   F                  flatten it,
    Ḅ                 convert from binary,
     %29              mod 29,
        ị             modular index into
                D¤    the decimal digits of
         “ẆA⁻R§’      813540020976.
4 KjetilS. Sep 13 2020 at 22:52

Perl 5 , 96 84 바이트

$s=0 x99;substr$s,$p+=ord()*9%45%7-3,1,1for$p=49,@F;$s=~/1.*1/;$_=$&*8%29014%1637%11

온라인으로 시도하십시오!

다소 미흡함 :

cat <<'.' > recognise.pl
$s=0 x99;                                   #init string of 100 zeros
substr$s,$p+=ord()*9%45%7-3,1,1for$p=49,@F; #replace 0 with 1 for each step of #input char, start at pos 49, -3 for U, 3 for D, -1 for L, #1 for R. ord() is ascii val of UDLR $s=~/1.*1/;           #find longest substring that starts and ends with 1, treat
                      #that string as a long int, i.e. 8 = 111101111101111
$_=$&*8%29014%1637%11 #modulus voodoo to get the digit
.
cat <<. | perl -F"" -apl recognise.pl
DDDD
UUUU
DDUDDUDD
DDUUUUDDUUDD
LRRDDLLDDRLRR
LDDRRLLUURRUULL
RRDDLLRRDDLL
LLRRUULLRLRRUUDULL
LUUDDRRUUDDDD
DDLLUUDDRRDD
LLDDRRDDLL
DLLRRUULLUURRLLRR
RRDDLLUUUURR
LLUURRDDUULLUURR
RRDDLLUURRDDLLUUUURR
RRDDDD
LLRRDDDD
LUURRDDDDLLU
RUULLUURRDDLLDD
RRDDLLUURRDDDDLL
DUDLRLLRRUULLRRUULLD
RRUUUULLDDD
UUUUDDDDRRUUUULRDDDD
.
4 CongChen Sep 14 2020 at 19:15

R , 314 바이트

안타깝게도 그다지 짧지 않은 것은 여기에서 추가 판독 가능성이 그만한 가치가없는 것 같습니다.

{f=pryr::f
f(w,{s=switch
l=f(t,t[length(t)])
a=f(t,s=0,c(t,l(t)+s))
v=f(c,s(c,U=-1,D=1,0))
h=f(c,s(c,L=-1,R=1,0))
m=f(l,b,x=0,{for(c in l)x=a(x,b(c))
    x})
z=el(strsplit(w,''))
x=m(z,h)
y=m(z,v)
p=x-min(x)
q=y-min(y)
r=p+q*3
u=unique(r)
d=trunc(10*(var(u)+median(u)))%%28
match(d,c(0,5,20,3,2,16,1,26,8,19))-1})}

온라인으로 시도하십시오!

다음에서 중간 계산 :

letters=list(
x1=c(0,3,6,9,12),
x2=c(0,1,2,5,6,7,8,9,12,13,14),
x3=c(0,1,2,5,6,7,8,11,12,13,14),
x4=c(0,2,3,5,6,7,8,11,14),
x5=c(0,1,2,3,6,7,8,11,12,13,14),
x6=c(0,1,2,3,6,7,8,9,11,12,13,14),
x7=c(0,1,2,5,8,11,14),
x8=c(0,1,2,3,5,6,7,8,9,11,12,13,14),
x9=c(0,1,2,3,5,6,7,8,11,12,13,14),
x0=c(0,1,2,3,5,6,8,9,11,12,13,14)
)
sapply(letters,function(letter){trunc(10*(var(letter)+median(letter)))%%28})
3 JonathanAllan Sep 14 2020 at 07:06

젤리 ,  31  28 바이트

예, Unrelated String 과 매우 유사 하지만 약간 다르며 완전히 독립적으로 발견되었습니다.

O%15Żı*ÄÆi_Ṃ$QṢ“X|cE’Dṭ⁽½ȯ¤ḥ

온라인으로 시도하십시오!

\ $ [0,9] \ $ 를 permute 할 필요를 제거하는 해시 내장에 대한 더 큰 솔트 ( \ $ 250 ^ 6 \ $ 미만 )가 발견되면 ( 가됩니다 ) 27 개 (또는 그 이하 ).“X|cE’Dṭ⁽½ȯ¤ḥ“?????’,⁵¤ḥ’

어떻게?

O%15Żı*ÄÆi_Ṃ$QṢ“X|cE’Dṭ⁽½ȯ¤ḥ - Link: listof characters
O%15                         - mod 15 of ordinals
    Ż                        - prepend a zero
     ı*                      - root(-1) raised to each of those
       Ä                     - cumulative sums
        Æi                   - convert each to [real, imaginary]
          _Ṃ$                - subtract of the minimum from each
             Q               - distinct values
              Ṣ              - sort
                          ¤  - nilad followed by link(s) as a nilad:
               “X|cE’        -   1398462570
                     D       -   to decimal digits (our domain)
                       ⁽½ȯ   -   3742 (our salt)
                       ṭ     -   tack -> [3742,[1,3,9,8,4,6,2,5,7,0]]
                           ḥ - hash (the sort results using that [salt, domain])

내장 해시 함수를 사용하지 않는 31 바이트의 이전 버전 ...

O%15Żı*ÄÆi_Ṃ$QṢFḞḌ%⁽¥Ƭị“ċḞƒø’D¤

\ 에서 정수를 산출하는 문자 목록을 허용하는 모나 딕 링크$[0,9]\$.

온라인으로 시도하십시오!

어떻게?

O%15Żı*ÄÆi_Ṃ$QṢFḞḌ%⁽¥Ƭị“ċḞƒø’D¤ - Link: listof characters O%15Żı*ÄÆi_Ṃ$QṢ                 - as above
               F                - flatten
                Ḟ               - floor (so Ḍ gives an integer rather than a float)
                 Ḍ              - convert from base ten
                  %⁽¥Ƭ          - modulo 2153
                       “ċḞƒø’D¤ - decimal digits of 3652914780
                      ị         - 1-indexed modulo index into
3 DominicvanEssen Sep 14 2020 at 20:47

R , 217 200 192 바이트

(또는 룩업 테이블없이 최종 숫자를 얻기 위해 Arnauld의 모듈로 체인을 훔쳐서 169 바이트 만 ...)

function(s,u=utf8ToInt){d=sapply(c(0,u(s)),`%in%`,x=u("DRUL"))
n=apply(d[1:2,]-d[3:4,],1,function(x)(y=cumsum(x))-min(y))
match(sum(2^unique(n[,1]+5*n[,2]))%%27%%11,c(0,4,7,10,8,5,2,3,9,1))-1}

온라인으로 시도하십시오!

어떻게? 원본 코드 (중요한 골프 변경 전 ...) :

recognize_digit=
function(s){
                                # first we 'construct' the digit from the encoding:
                                
 d=sapply(                      # d is direction of each step, calculated by...
    c("D","R","U","L"),         # ...using each letter...
    grepl,                      # ...as a regex...
          el(strsplit(s,'')))   # ...to search each letter of the encoding.
 m=matrix(!-40:40,9)            # m is a matrix big enough to fit the letters (9x9)
 m[                             # we set the elements of m, selected by...
   apply(d[,1:2]-d[,3:4],       # ...subtracting L from R, and U from D...
   2,                           # ...and for each of the L-R and U-D columns...
   cumsum)+5                    # ...calculating the cumulative sum +5, 
            ]=T                 # to 'TRUE'.  
 l=m[(c=t(which(m,T)))[1]+0:4,  # l is the 3x5 'letter' matrix, starting at the  
   c[2]+0:2]                    # first TRUE elment of m
                                
                                # now we have the digit in l, so we just have to
                                # recognize it: 
 match(                         # we find the match between...
  sum(l*2^(0:14))               # the number formed by using the pixels of the digit as bits...
   %%27%%11,                    # MOD 27 MOD 11 (reduces each number to a smaller number
  c(0,4,7,10,8,5,2,3,9,1))-1    # and the 'lookup' table of results for each digit.
}
3 KevinCruijssen Sep 14 2020 at 14:28

05AB1E , 36 35 바이트

•7‡šмÓ•žFDIÇv4y5%m8/*DŠ~s}\b0ÚC45%è

@Arnauld 의 78 바이트 버전의 포트이므로 그를 찬성 하도록하세요! (그의 78 → 77, 77 → 71 골프는 05AB1E에서 더 길어질 것입니다.)

온라인으로 시도 하거나 모든 테스트 사례를 확인하십시오 .

설명:

•7‡šмÓ•              # Push compressed integer 31846207905
 žF                  # Push builtin 16384 (2**14)
   D                 # Duplicate it
    I                # Push the input-string
     Ç               # Convert it to a list of codepoint integers
      v              # Loop over each codepoint `y`:
        y5%          #  Take `y` modulo-5
       4   m         #  Take 4 to the power this value
            8/       #  Divide it by 8
              *      #  Multiply it by the top of the stack
               D     #  Duplicate it
                Š    #  Tripleswap (a,b,c → c,a,b) the top three values on the stack
                 ~   #  Bitwise-OR the top two
                  s  #  And swap so the other value is at the top again
      }\             # After the loop: discard the top value
        b            # Convert the integer to binary
         0Ú          # Remove all leading/trailing 0s
           C         # Convert it from binary back to an integer
            45%      # Modulo-45
               è     # And index it into the digits of 31846207905 (0-based modulair)
                     # (after which the digit is output implicitly as result)

내이 05AB1E 팁을 참조하십시오 (섹션 얼마나 큰 정수를 압축하는 방법을? ) 이유를 이해하는 •7‡šмÓ•것입니다 31846207905.