Mon "trou de clé" m'ennuie! Aidez-moi à trouver un minimum de touches

13

Remerciements à @ Agawa001 pour avoir posé cette question.

Explication

Mon nouveau "keybore" n'a que 2 boutons, à savoir +et -.

Le numéro en mémoire commence à 0.

Chaque pression consécutive sur +ou -incrémentera / décrémentera la mémoire exactement pour combien de fois elle a été pressée consécutivement.

Par conséquent, si vous appuyez +4 fois, la première fois, il ajoute 1, la deuxième fois, il ajoute 2, la troisième fois, il ajoute 3, la quatrième fois, il ajoute 4, ce qui vous donne 10(dix).

Maintenant, si vous appuyez -3 fois, la première fois, il soustrait 1, la deuxième fois 2, la troisième fois 3, vous laissant avec 4(quatre).

TL; DR

Étant donné une chaîne de + et -, divisez-la à chaque changement de caractère. Ensuite, chaque chaîne résultante de m +symboles ajoute le m-ème numéro de triangle, et chaque chaîne de n -symboles soustrait le n-ème triangle.

Procédure pas à pas

Maintenant, si vous ne comprenez toujours pas, je vais vous montrer comment +++--+--crée 1.

Program   | Counter | Memory
----------------------------
          |  0      | 0
+         | +1      | 1
++        | +2      | 3
+++       | +3      | 6
+++-      | -1      | 5
+++--     | -2      | 3
+++--+    | +1      | 4
+++--+-   | -1      | 3
+++--+--  | -2      | 1

Tâche

  • Vous prendrez un entier positif en entrée, soit comme argument fonctionnel, soit depuis STDIN.
  • Ensuite, vous afficherez / imprimerez le nombre minimum de touches nécessaires pour créer ce nombre en utilisant la méthode ci-dessus.

Cas de test

Étant donné que le réarrangement des séquences +ou -donne le même nombre, pour chacun de ces groupes, seule la séquence lexicographiquement la plus ancienne est répertoriée.

Input | Output | Possible corresponding sequences
-------------------------------------------------
    4 |      5 | -+++-
    6 |      3 | +++
    9 |      5 | ++++-
   11 |      7 | +++-+++
   12 |      7 | +++++--, ++++-++
   19 |      8 | -++++++-
   39 |     12 | +++++++++---
   40 |     13 | +++++++++---+, ++++++++-+++-
   45 |      9 | +++++++++
   97 |     20 | ++++++++++++++--+---, +++++++++++++-++++--, ++++++++++++-++++++-
  361 |     34 | ++++++++++++++++++++++++++-+++-+++

Des ressources supplémentaires

Notation

C'est du . La solution la plus courte en octets gagne.

Leaky Nun
la source
9
Est-ce à dire que ... vous êtes percé?
busukxuan
Je pense que vous êtes d'accord avec 10 cas de test maintenant (y compris le mien).
Erik the Outgolfer
@ ΈρικΚωνσταντόπουλος Le cas de test 12 a été ajouté, avec une légère modification (puisque +++++--c'est aussi une alternative, mais j'ai supprimé ++-++++car c'est équivalent à ++++-++). J'ai encore un cas de plus que j'aimerais ajouter plus tard au cas où quelqu'un trouverait une solution efficace, si je réussis à la générer.
Sp3000
@ Sp3000, je ne voulais pas être ++-++++supprimé. De plus, c'était MON montage, pas le vôtre.
Erik the Outgolfer
@ ΈρικΚωνσταντόπουλος Une seule solution de chaque ensemble de solutions équivalentes est répertoriée - je pensais que si toutes les solutions minimales étaient répertoriées, les cas de test seraient inutilement longs (il y a 6 solutions pour 40 et 17 solutions pour 97). Je m'excuse si cette intention n'était pas claire. Vous manquiez aussi +++++--(ou, de manière équivalente --+++++), c'est pourquoi j'ai ressenti le besoin de modifier en premier lieu.
Sp3000

Réponses:

2

Python 2, 119 octets

def g(n,i=0,s=''):
 c=x=t=0
 for d in s:C=int(d)*2-1;t=(c==C)*t+1;c=C;x+=c*t
 return(x==n)*len(s)or g(n,i+1,bin(i)[3:])

Approche par force brute très lente. La troisième ligne calcule le score d'une chaîne x; les autres lignes bouclent sur toutes les chaînes binaires possibles jusqu'à ce que celle dont le score est égal à l'argument soit trouvée.

@Leaky a économisé trois octets!

Lynn
la source
s/x==n and len/(x==n)*len/
Leaky Nun
Cela pourrait économiser quelques octets pour se débarrasser de la sdivision répétée, comme ceci:def f(n): \n while n>0:print n%2;n/=2
Leaky Nun
2

Pyth, 25 octets

ffqyQ.as-Mc*RhdY2{s.pM./T

Essayez-le en ligne.

Ceci est extrêmement inefficace et manque de mémoire pour f(n)≥ 11. Il calcule f(22)= 10 en environ 10 secondes sur mon ordinateur portable.

Explication

  • À partir de 1, parcourez les nombres T. ( f)
    • Générez toutes les partitions de T. ( ./T)
    • Générez toutes les permutations de celles-ci. ( .pM)
    • Aplatissez la liste. ( s)
    • Unifiez la liste. ( {) Cette étape pourrait être supprimée, mais elle rend le code beaucoup plus rapide.
    • Filtrer les permutations résultantes des partitions: ( f)
      • Multipliez chaque numéro dde la partition ( *R) par lui-même plus un ( hd). Cela donne le double du nombre à ajouter / soustraire au résultat.
      • Coupez la liste en parties de longueur 2. ( c2)
      • Soustrayez tout deuxième nombre de ces parties du deuxième nombre. ( -M)
      • Additionnez les résultats. Cela donne le double du nombre résultant si la permutation de partition a été interprétée comme le nombre d'additions, puis de soustractions, etc.
      • Prenez la valeur absolue. ( .a) Si le résultat était négatif, l'échange des additions et des soustractions obtient le résultat positif.
      • Vérifiez si le résultat est égal au double de l'entrée. ( qyQ) Dans ce cas, la permutation de partition est correcte, renvoyez-la.
    • Si le filtre renvoyait des résultats, il y avait une solution de longueur T. Retour et impression T.
PurkkaKoodari
la source
2

MATL , 43 29 octets

E:"@TFEqZ^!"@Y'tQ**s]vGE=a?@.

C'est inefficace en mémoire et en temps. Le compilateur en ligne peut gérer jusqu'à l'entrée 45uniquement.

Essayez-le en ligne!

Voici une version modifiée avec tous les cas de test jusqu'à 40(cela prend presque une minute dans le compilateur en ligne).

Explication

Cela teste toutes les séquences de touches possibles de chaque longueur, par ordre de longueur croissante, jusqu'à ce qu'une séquence valide soit trouvée.

E:       % Range [1 2 ... 2*N] where N is implicit input. The required sequence length is
         % less than 2*N, so this is enough
"        % For each
  @      %   Push current value: length of sequence
  TFEq   %   Push array [1 -1]
  Z^     %   Cartesian power. Gives all possible sequences of 1, -1 of that length
  !      %   Transpose. Each sequence is now a row
  "      %   For each sequence
    @    %     Push current sequence
    Y'   %     Run-length decoding: Pushes an array of values 1 and -1, and then an
         %     array of run-lengths
    tQ*  %     Duplicate, add 1, multiply. Gives twice the triangular number for each run
    *    %     Multiply element-wise by 1 or -1 to produce correct sign
    s    %     Sum of array. This is the number produced by the current sequence
  ]      %   End for
  v      %   Concatenate all numbers into an array
  GE=a   %   True if any of those numbers equals twice the input
  ?      %   If so
    @    %     Push current sequence length. This is the final result
    .    %     Break loop
         %   End if
         % End for
         % Implicit display
Luis Mendo
la source
@ Sp3000 J'en ai ajouté un aussi, donc, pour référence, 4, 6, 9 et 19 sont les cas de test référencés, dans l'ordre.
Erik the Outgolfer
1

Python, 105100 octets

Utilise une recherche étendue inefficace.

def k(n):
 m=t=l=0;h=[]
 while m-n:o=1-2*(t>0);(m,t,l),*h=h+[(m+t-o,t-o,l+1),(m+o,o,l+1)]
 return l
  • h est une liste utilisée comme file d'attente
  • m est la valeur de la séquence en tête de liste
  • t est le dernier numéro ajouté à m
  • l est la longueur de la séquence qui a généré m
  • o est +/- 1, le signe est en face du signe de t

Edit: Leaky Nun a rasé cinq octets.

RootTwo
la source
s/m,t,l,h=0,0,0,[]/m=t=l=0,h=[]/
Leaky Nun
s/while m!=n/while m-n/
Leaky Nun