Crie uma lista de números serpenteantes abaixo de 50.000

24

Snaking Number Challenge

Gostaria de saber quantos números serpenteantes existem entre 1 e 50.000?

Cobra em um Nokia

Números serpentes, neste jogo, são números que podem ser digitados em um teclado numérico tradicional (formato abaixo) movendo uma tecla para cima, para baixo, para a esquerda ou para a direita.

7 8 9
4 5 6
1 2 3
 0

Por exemplo, se você começar com o número 5, poderá selecionar 4, 6, 8 ou 2 como sua próxima jogada válida - no entanto, 7, 3, 9 e 1 estão fora dos limites, pois estão posicionados na diagonal em relação à tecla atual . Portanto, se você tiver 5 e 2, suas próximas opções de teclas viáveis ​​serão 0, 1, 3 ou 5 novamente.

Neste exercício do Code Golf, você deve produzir uma lista de todos os números positivos de serpentina entre 1 e 50k, juntamente com uma contagem final de todos os números que atendem ao critério.

Regras

  1. Os números não podem começar com um zero.
  2. Os números devem ser inteiros positivos inteiros.
  3. Cada número consecutivo, lido da esquerda para a direita, deve "serpentear" ao redor do teclado numérico.
  4. A cobra não pode viajar na diagonal pelas teclas
  5. O número 0 pode ser acessado pelos números 1 e 2
  6. Os números não podem ser emparelhados (por exemplo: 22)

Exemplos de números de serpentes válidos:

12369
45201
1254
10102
1
12
987

Exemplos de números inválidos

1238 - 8 is not connected
0001 - multiple leading 0s
0101 - leading 0
159  - snake cannot travel diagonally
4556 - duplicate 5

De acordo com o Code Golfs normal, o objetivo é o menor número de bytes!

De acordo com as minhas regras e matemática, você deve ter 670 números válidos na lista e mais 670 em si como o último número.

MightBeAlon
fonte
2
A saída deve ser classificada? Ou é permitido em qualquer ordem?
tsh
2
Como você está nos pedindo para produzir um conjunto fixo e finito de números inteiros, sugiro incluir a lista completa nas especificações.
Shaggy
Related
Arnauld
4
Este é um subconjunto do A215009 .
bigyihsuan
Seria bom imprimir 670 primeiro ?
dana

Respostas:

14

K (ngn / k) , 60 57 bytes

(x;#x:{*/1=3!5&+/x*x:+1_-':(+0 1,'2*!3 3)@10\x}#1+!50000)

Experimente online!

!50000lista de 0..49999

1+ adicione 1 a todos

{ }# filtrar com a função { }

10\x dígitos decimais do argumento

( )@ use como índices em ...

  • !3 3 um par de listas: (0 0 0 1 1 1 2 2 2;0 1 2 0 1 2 0 1 2)

  • 2* multiplique tudo por 2

  • 0 1,'anexar 0à primeira lista e1 à segunda

  • +transpor (par de listas -> lista de pares). isso nos dá as cordas de botão aproximadas.

-':subtrair de cada par o par anterior. usar0 0 como um elemento imaginário antes do primeiro.

1_ largar o primeiro

+ transpor

x*x:quadrado (atribuir xe multiplicar por x). Aquix está um par de listas - xs e ys

+/ somar as duas listas (elemento por elemento)

5& min com 5

3! mod 3

1= lista booleana de onde é igual a 1

*/ produto (booleano "e")

(x;#x: )faça um par do resultado e o comprimento ( #) do resultado

ngn
fonte
9

Geléia ,  24  23 bytes

5ȷ4µDo1.’d3ZIASĊ’ẸµÐḟṄL

Um programa completo que imprime uma lista de todos os resultados e, em seguida, o número de resultados.

Experimente online!

Quão?

5ȷ4µDo1.’d3ZIASĊ’ẸµÐḟṄL - Main Link: no arguments
5ȷ4                     - 5*10^4 = 50000
   µ              µÐḟ   - filter discard those for which this is truthy:
                        -                  e.g.: 8520        ... or           4559 
    D                   -   decimal digits       [8,5,2,0]                    [4,5,5,9]
      1.                -   literal 1.5
     o                  -   logical OR           [8,5,2,1.5]                  [4,5,5,9]
        ’               -   decrement            [7,4,1,0.5]                  [3,4,4,8]
         d3             -   div-mod by 3         [[2,1],[1,1],[0,1],[0,0.5]]  [[1,0],[1,1],[1,1],[2,2]]
           Z            -   transpose            [[2,1,0,0],[1,1,1,0.5]]      [[1,1,1,2],[0,1,1,2]]
            I           -   deltas               [[-1,-1,0],[0,0,-0.5]]       [[0,0,1],[1,0,1]]
             A          -   absolute value       [[1,1,0],[0,0,0.5]]          [[0,0,1],[1,0,1]]
              S         -   sum (vectorises)     [1,1,0.5]                    [1,0,2]
               Ċ        -   ceiling              [1,1,1]                      [1,0,2]
                ’       -   decrement            [0,0,0]                      [0,-1,1]
                 Ẹ      -   any?                 0 (i.e. keep)                1 (i.e. discard)
                     Ṅ  - print and yield
                      L - length
                        - implicit print
Jonathan Allan
fonte
Eu adoraria saber como este funciona. Alguma chance de você dar um colapso?
MightBeAlon
11
@MightBeAlon fará mais tarde ...
Jonathan Allan
Estou curioso, como 1.avalia a 1.5?
Modalidade de ignorância
@EmbodimentofIgnorance durante a análise literal de um dígito ausente após um período é tratado como sendo cinco. Veja a cláusula final else de parse_literal em interpreteter.py
Jonathan Allan
7

Python 3 , 140 bytes

f=lambda s:''==s[1:]or s[1]in'10021234562216565878 43 749 9   5  8'[int(s[0])::10]and f(s[1:])
print(*filter(f,map(str,range(1,50000))),670)

Experimente online!

Estou certo de que alguém será capaz de fazer isso com uma expressão em vez de uma string de pesquisa.

Jitse
fonte
7

Python 2 , 101 bytes

print[n for n in range(1,50000)if all(`n`[i:i+2]in`0x20b33ec8bc49a10589e76b15`for i in range(4))],670

Experimente online!

O número hexadecimal é decimal 10120214525632365878969854741, que codifica todos os pares ordenados de dígitos que podem aparecer adjacentes um ao outro.

sete negativos
fonte
5

JavaScript (V8) ,  112 106  104 bytes

Guardado 2 bytes graças a @NahuelFouilleul

Um programa completo.

for(n=0;++n<5e4;)[...n+''].every(x=>'6589632145201478'.match(x+p+'|'+p+(p=x)),p='')&&print(n)
print(670)

Experimente online!

Ou 96 bytes, se pudermos emitir os números na ordem inversa:

for(n=5e4;n--;)[...n+''].every(x=>'6589632145201478'.match(x+p+'|'+p+(p=x)),p='')&&print(n||670)

Experimente online!

Arnauld
fonte
funciona também removendo o último 3talvez porque 36já esteja na string
Nahuel Fouilleul
@NahuelFouilleul Good catch. Obrigado!
Arnauld
11
também 6589632145201478é um byte mais curto
Nahuel Fouilleul
4

Stax , 37 35 bytes

ü╞╡~▄ⁿ♪eµïê◙ü╔ï▼ΔJr¥æ≤PH╟♀I♣Δz8─¶Γ╞Ç▓

Execute e depure-o em staxlang.xyz!

Foi tão agradável e curto, até que não foi.

Descompactado (42 bytes) e explicação

49999{E2B{{om"#qYY>!(AFI"%A|E2B{{om-C_Qf%p
49999{                                 f      Filter range [1..49999]:
      E2B                                       All adjacent pairs of digits
         {{om                                   Each sorted
             "#qYY>!(AFI"%A|                    Literal 2012365478963258741
                            E2B{{om             Pairs of digits, each sorted
                                   -            Set difference
                                    C           Cancel block execution if any remain
                                     _Q         Print current value
                                        %p    Print length

2012365478963258741 codifica o teclado. Veja pares de dígitos adjacentes. Talvez se eu pudesse obter uma alternativa decentemente curta que fosse nas duas direções para cada par, eu poderia cortar os oito bytes de{{om .

Sem esse 670 à direita, um filtro simples seria suficiente: em f..!vez de {..C_Qf%p. Pode haver uma maneira melhor de lidar com essa irregularidade. Nos dois casos, esse comportamento do intervalo de filtro não é documentado.

Khuldraeseth na'Barya
fonte
Desculpe pelas lacunas na documentação. FWIW, esse será no próximo lançamento, 1.1.7. Você pode ver uma prévia em stax.tomtheisen.com , mas é um segredo, portanto não conte a ninguém. ;)
recursivo em
3

PHP , 145 bytes

for(;$i++<5e4;$f&&print$i._)for($f=1,$l=b;''<$d=("$i")[$$i++];$l=$d)$f&=$l>a||strstr([12,240,1053,26,157,2468,359,48,579,68][$l],$d)>'';echo 670;

Experimente online!

Para cada número de 1 a 50.000, verifica todos os dígitos desse número da esquerda para a direita. Se todos os dígitos estiverem na lista de dígitos válidos do dígito anterior, esse número será impresso. No final, imprime um 670 codificado permanentemente, uma vez que leva menos bytes do que realmente conta.

Night2
fonte
3

05AB1E , 23 bytes

ŽÅKLʒSÌYX;:3‰üαï€OP}=g=

Experimente online!

Resposta da geléia do porto de Jonathan Allan .

Grimmy
fonte
11
Ah, esperto de comprimir os 50000 em 3 bytes. Eu estava usando ₄50*ou 4°5*quando estava fazendo uma tentativa anteriormente. E, a princípio, fiquei confuso por que você tinha, e €OPnão apenas OP, mas então percebi que os números de um dígito (sendo uma lista vazia depois da üα) seriam em [] → 0 → 0vez de [] → [] → 1. :)
Kevin Cruijssen
11
@KevinCruijssen Por que 4°5*quando você pode 5°;? Eu gosto mais do ZAK. E sim, esse argumento de ponta para números de um dígito é uma dor.
Grimmy 29/08
3

Perl 5 (-M5.01 ), 96 , 92 bytes

-4 bytes graças a @Xcali

$r=join"|",map$t++."[^$_]",12,240,1350,26,157,2648,359,48,579,68;map/$r/||say,1..5e4;say 670

TIO

Nahuel Fouilleul
fonte
92
Xcali
obrigado de fato, muito complicado porque a primeira resposta foi positiva
Nahuel Fouilleul
3

JavaScript (SpiderMonkey) , 179 173 151 129 bytes

[12,240,1350,26,157,2468,359,48,579,68].map((_,i,l)=>i&&(f=(v,t)=>print(v)|v<5e3&&[...l[t]+''].map(k=>f(v+k,k)))(i,i)),print(670)

Experimente online!

-22 bytes graças a Arnauld -22 bytes graças a dana

explicação:

[12,240,1350,26,157,2468,359,48,579,68] 
// an array where keys are current position and values, the possible destinations
.map((_,i,l)=>                    // loop over it
    i&&(                          // if key is not 0
        f=(v,t)=>                 // create a function
                 print(v)|        // which print the value
                          v<5e3&& // and if the limit is not attained
                                 [...l[t]+''].map(k=>f(v+k,k)) 
                    // recurcively call itself with for each destinations
                                                              )(i,i)),
                    // make the first call with each digit
print(670) // finally print 670

A @dana também forneceu uma solução de 123 bytes se pudermos imprimir 670 primeiro

[21,420,5310,62,751,8642,953,84,975,86].map((_,i,a)=>(f=(v,t)=>print(i?v:640)|i&v<5e3&&[...a[t]+''].map(k=>f(v+k,k)))(i,i))
jonatjano
fonte
@ Arnauld obrigado esqueci esta regra
jonatjano
129 ?
dana
123 se 640 puder ser impresso primeiro.
dana
2

Ruby , 99 bytes

1.upto(5e4){|n|w,*x=n.digits;x.all?{|d|[6,21,43,68,162,340,552,272,672,320][w][w=d]>0}&&p(n)}
p 670

Experimente online!

GB
fonte
2

Stax , 28 26 bytes

Δh┤♣É╦&·é╝n$K»à¶▲v═NÆ;↨m≥8

Execute e depure

Descompactado, não jogado e comentado, parece com isso.

G               Call to unbalanced trailing '}', then resume here
670P            Print 670
}               Call target
219J            219 squared (47961)
f               Filter 1-based range by the rest of the program; implicitly output
  $2B           Convert to string and get adjacent pairs; e.g. 213 -> ["21", "13"]
  O             Push 1 under list of pairs
  F             Iterate over pairs, using the rest of the program
    o           Order each pair; e.g. "21" -> "12"
    "{<f:[/T8Z" string literal with code points [123 60 102 58 91 47 84 56 90]
    $           concate as string i.e. "12360102589147845690"
    s#          How many times does the current pair appear in the constant string?
    *           Multiply this by running total.  Any zero will cause the result to be zero.

Execute este

O molho secreto está na cadeia literal "{<f:[/T8Z". Depois de juntar todos os pontos de código juntos, você obtém 12360102589147845690. Os pares ascendentes nesta cadeia são os movimentos válidos da cobra.

recursivo
fonte
11
15JJem vez de 219Jfuncionaria também, mas não acho que você possa obter qualquer byte a partir daí, a menos que haja uma constante de 1 byte 15.
Arnauld
2

Haskell , 118 bytes

(filter(and.(zipWith elem.tail<*>map f).show)[1..50000],670)
f c=words"12 024 0135 26 157 2468 359 48 579 68"!!read[c]

Experimente online!

Um primeiro passe; Eu não sou bom em compressão.

o s= não conta, já que não precisamos vincular o resultado.

Código não destruído .

Cole
fonte
1

Carvão , 42 bytes

≔ΦI…·¹×⁵⁰φ⬤ι№”)¶∧XRτ_ΠGêR⁵m⎇λ”✂ιμ⁺²μ¹θθILθ

Experimente online! Link é a versão detalhada do código. Explicação:

≔ΦI…·¹×⁵⁰φ

Processe o intervalo inclusivo de 1para 50,000converter em sequência.

⬤ι№”)¶∧XRτ_ΠGêR⁵m⎇λ”✂ιμ⁺²μ¹θ

Filtre os que possuem pares de dígitos não contidos na sequência compactada 01478963202125458565236987410.

θILθ

Saída da matriz restante e seu comprimento.

Neil
fonte
1

Perl 6 , 64 bytes

{670,grep {[+&](:36<12HGX91H8VCL3MG0FDVQ>X+>m:ov/../)%2},1..5e4}

Experimente online!

Explicação

{670,grep {...},1..5e4}  # Meet questionable output requirements

# Actual decision problem

     :36<12HGX91H8VCL3MG0FDVQ>  # Bit field of allowed transitions
                                # encoded in base 36
                                 m:ov/../  # All 2-digit substrings
                              X+>  # Right shift by each substring
                                   # (implicitly converted to an integer)
[+&](                                    )  # Binary and
                                          %2  # Modulo 2
Nwellnhof
fonte
É uma pena que ~>ainda não tenha sido implementado; caso contrário, você poderá fazer isso apenas com operadores de string, com o campo de bits sendo uma string
Jo King
1

Pitão , 68 65 45 bytes

l
f.Am}dCtB+J`65874589632012541_PJCtB`TS50000

Experimente online!

A inspiração para o processo de pesquisa revisado veio da resposta Stax de Khuldraeseth na'Barya , dê um eles!


Edit 2: Rewrote para salvar um monte de bytes, versão anterior:

l
f.Am}ed@c"12 024 0135 26 157 2468 359 48 579 68";shdCtB`TS50000

Edit: Golfed 3 bytes usando pesquisas de string, versão anterior:

l
f.Am}ed@sMMc"12 024 0135 26 157 2468 359 48 579 68";hdCtBjT;S50000
Sok
fonte