Créer une liste de nombres de serpents de moins de 50 000

24

Défi du nombre de serpents

Je me demande combien de nombres de serpents il y a entre 1 et 50 000?

Serpent sur un Nokia

Snaking Numbers, dans ce jeu, sont des chiffres qui peuvent être saisis sur un pavé numérique traditionnel (format ci-dessous) en déplaçant une touche vers le haut, le bas, la gauche ou la droite.

7 8 9
4 5 6
1 2 3
 0

Par exemple, si vous commencez par le chiffre 5, vous pouvez sélectionner 4, 6, 8 ou 2 comme prochain mouvement valide - cependant 7, 3, 9 et 1 sont hors limites car ils sont positionnés en diagonale par rapport à la clé actuelle . Donc, si vous en avez 5, puis 2, vos prochains choix de clés viables sont à nouveau 0, 1, 3 ou 5.

Dans cet exercice Code Golf, vous devez générer une liste de tous les nombres de serpents positifs entre 1 et 50k, ainsi qu'un décompte final de tous les nombres qui répondent au critère.

Règles

  1. Les nombres ne peuvent pas commencer par un zéro.
  2. Les nombres doivent être des entiers positifs entiers.
  3. Chaque numéro consécutif, lu de gauche à droite, doit "serpenter" autour du pavé numérique.
  4. Le serpent ne peut pas voyager en diagonale à travers les touches
  5. Le numéro 0 est accessible à partir des numéros 1 et 2
  6. Les numéros ne peuvent pas être jumelés (par exemple: 22)

Exemples de numéros de serpentage valides:

12369
45201
1254
10102
1
12
987

Exemples de numéros invalides

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

Selon les codes de golf normaux, l'objectif est le moins d'octets!

Selon mes calculs et mes règles, vous devriez avoir 670 nombres de serpents valides dans votre liste, plus 670 lui-même imprimé comme dernier numéro.

MightBeAlon
la source
2
La sortie doit-elle être triée? Ou est-ce autorisé dans n'importe quel ordre?
tsh
2
Étant donné que vous nous demandez de produire un ensemble fixe et fini d'entiers, je suggère d'inclure la liste complète dans la spécification.
Shaggy
En relation
Arnauld
4
Il s'agit d'un sous-ensemble de A215009 .
bigyihsuan
Serait-il correct d'imprimer le 670 en premier ?
dana

Réponses:

14

K (ngn / k) , 60 57 octets

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

Essayez-le en ligne!

!50000liste de 0..49999

1+ ajouter 1 à tous

{ }# filtre avec la fonction { }

10\x chiffres décimaux de l'argument

( )@ utiliser comme indices dans ...

  • !3 3 une paire de listes: (0 0 0 1 1 1 2 2 2;0 1 2 0 1 2 0 1 2)

  • 2* multipliez tout par 2

  • 0 1,'ajouter 0à la première liste et 1à la seconde

  • +transposer (paire de listes -> liste de paires). cela nous donne les coordonnées approximatives des boutons.

-':soustraire de chaque paire la paire précédente. utiliser 0 0comme élément imaginaire avant le premier.

1_ laissez tomber le premier

+ transposer

x*x:carré (attribuer xet multiplier par x). voici xune paire de listes - ∆xs et ∆ys

+/ additionner les deux listes (élément par élément)

5& min avec 5

3! mod 3

1= liste booléenne d'où il est égal à 1

*/ produit (booléen "et")

(x;#x: )faire une paire du résultat et la longueur ( #) du résultat

ngn
la source
9

Gelée ,  24  23 octets

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

Un programme complet qui imprime une liste de tous les résultats puis le nombre de résultats.

Essayez-le en ligne!

Comment?

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
la source
J'adorerais savoir comment celui-ci fonctionne. Avez-vous une chance de donner une ventilation?
MightBeAlon
1
@MightBeAlon fera plus tard ...
Jonathan Allan
Je suis curieux, comment 1.évalue- 1.5t-on?
Incarnation de l'ignorance
@EmbodimentofIgnorance lors de l'analyse littérale d'un chiffre manquant après un point est traité comme un cinq. Voir la dernière clause else de parse_literal dans interpreter.py
Jonathan Allan
7

Python 3 , 140 octets

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)

Essayez-le en ligne!

Je suis certain que quelqu'un pourra le faire avec une expression au lieu d'une chaîne de recherche.

Jitse
la source
7

Python 2 , 101 octets

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

Essayez-le en ligne!

Le nombre hexadécimal est décimal 10120214525632365878969854741, qui code pour chaque paire ordonnée de chiffres qui peuvent apparaître adjacents les uns aux autres.

sept négatif
la source
5

JavaScript (V8) ,  112106104  octets

Enregistré 2 octets grâce à @NahuelFouilleul

Un programme complet.

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

Essayez-le en ligne!

Ou 96 octets si nous pouvons sortir les nombres dans l'ordre inverse:

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

Essayez-le en ligne!

Arnauld
la source
fonctionne également en supprimant le dernier 3peut-être parce qu'il 36est déjà dans la chaîne
Nahuel Fouilleul
@NahuelFouilleul Bonne prise. Merci!
Arnauld
1
6589632145201478est également un octet plus court
Nahuel Fouilleul
4

Stax , 37 35 octets

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

Exécutez-le et déboguez-le sur staxlang.xyz!

C'était tellement agréable et court, jusqu'à ce qu'il ne soit pas.

Déballé (42 octets) et explication

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 code le clavier. Regardez des paires de chiffres adjacents. Peut-être que si je pouvais obtenir une alternative assez courte qui va dans les deux sens pour chaque paire, je pourrais couper les huit octets de {{om.

Sans ce 670 arrière, un simple filtre suffirait: f..!au lieu de {..C_Qf%p. Il pourrait y avoir une meilleure façon de gérer cette irrégularité. Dans les deux cas, ce comportement de plage de filtres n'est pas documenté.

Khuldraeseth na'Barya
la source
Désolé pour les lacunes de documentation. FWIW, celui-ci sera dans la prochaine version, 1.1.7. Vous pouvez voir un aperçu sur stax.tomtheisen.com , mais c'est un secret, alors ne le dites à personne. ;)
récursif
3

PHP , 145 octets

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;

Essayez-le en ligne!

Pour chaque numéro de 1 à 50 000, vérifie chaque chiffre de ce numéro de gauche à droite. Si tous les chiffres figurent dans la liste des chiffres valides du chiffre précédent, ce numéro est imprimé. À la fin, imprime un 670 codé en dur car il prend moins d'octets que de le compter.

Nuit2
la source
3

05AB1E , 23 octets

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

Essayez-le en ligne!

Port de Réponse de Jelly Jonathan Allan .

Grimmy
la source
1
Ah, intelligent de simplement compresser le 50000 en 3 octets. J'utilisais ₄50*ou 4°5*quand je faisais une tentative plus tôt. Et au début, je ne savais pas pourquoi vous aviez €OPau lieu de juste OP, mais ensuite j'ai réalisé que les nombres à un chiffre (être une liste vide après le üα) seraient alors à la [] → 0 → 0place de [] → [] → 1. :)
Kevin Cruijssen
1
@KevinCruijssen Pourquoi 4°5*quand vous le pouvez 5°;? Mais j'aime mieux ZAK. Et oui, ce cas de bord pour les nombres à un chiffre est une douleur.
Grimmy
3

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

-4 octets grâce à @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
la source
92
Xcali
merci en effet, trop compliqué car la première réponse fut un match positif
Nahuel Fouilleul
3

JavaScript (SpiderMonkey) , 179 173 151 129 octets

[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)

Essayez-le en ligne!

-22 octets merci à Arnauld -22 octets merci à dana

explication:

[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

@dana a également donné une solution de 123 octets si nous pouvons imprimer 670 en premier

[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
la source
@Arnauld merci J'ai oublié cette règle
jonatjano
129 ?
dana
123 si 640 peut être imprimé en premier.
dana
2

Stax , 28 26 octets

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

Exécuter et déboguer

Déballé, non golfé et commenté, il ressemble à ceci.

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.

Exécutez celui-ci

La sauce secrète est dans la chaîne littérale "{<f:[/T8Z". Après avoir brouillé tous les points de code ensemble, vous obtenez 12360102589147845690. Les paires ascendantes de cette chaîne sont les mouvements de serpent valides.

récursif
la source
1
15JJau lieu de 219Jfonctionnerait aussi bien, mais je ne pense pas que vous puissiez jouer au golf à partir de là à moins qu'il y ait une constante de 1 octet pour 15.
Arnauld
2

Haskell , 118 octets

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

Essayez-le en ligne!

Une première passe; Je ne suis pas bon en compression.

Le s=ne compte pas, car nous n'avons pas vraiment besoin de lier le résultat.

Code non golfé .

cole
la source
1

Fusain , 42 octets

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

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

≔ΦI…·¹×⁵⁰φ

Traitez la plage inclusive de 1à 50,000transtyper en chaîne.

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

Filtrez ceux qui ont des paires de chiffres non contenues dans la chaîne compressée 01478963202125458565236987410.

θILθ

Sortez le tableau restant et sa longueur.

Neil
la source
1

Perl 6 , 64 octets

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

Essayez-le en ligne!

Explication

{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
la source
Dommage qu'il ~>ne soit pas encore implémenté, sinon vous pourriez être en mesure de le faire avec seulement des opérateurs de chaîne, le champ de bits étant une chaîne
Jo King
1

Pyth , 68 65 45 octets

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

Essayez-le en ligne!

L'inspiration pour le processus de recherche révisé est venue de la réponse Stax de Khuldraeseth na'Barya , allez leur donner un vote positif!


Edit 2: réécrit pour enregistrer un tas d'octets, version précédente:

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

Edit: Golfed 3 bytes by using string lookups, previous version:

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