Regrouper les nombres avec la même somme

12

Votre tâche consiste, étant donné une grille carrée de chiffres ( 0-9), à sortir l'une des façons dont les chiffres peuvent être regroupés de telle sorte que:

  1. Chaque chiffre fait partie d'un groupe exactement
  2. Tous les groupes ont le même nombre de chiffres
  3. Tous les groupes sont délimités par une forme semblable à un polygone (cela signifie que chaque chiffre du groupe est à côté de [gauche, droite, haut, bas] au moins un autre chiffre du même groupe, sauf si chaque groupe a 1 élément).
  4. Tous les groupes ont la même somme

La grille d'entrée sera toujours un carré: vous pouvez choisir n'importe quelle méthode d'entrée que vous souhaitez (y compris fournir des arguments à une fonction ou une méthode). De plus, l'entrée fournira le nombre de groupes dans lesquels votre programme doit regrouper les chiffres.

Exemple d'entrée:

Supposons que votre format d'entrée soit stringOfDigits numberOfGroups.

Un exemple d'entrée serait:

156790809 3

qui se traduirait par (une grille de sqrt(9) * sqrt(9))

1 5 6
7 9 0
8 0 9

que vous auriez à diviser en 3 groupes, dont chacun devrait avoir des 9 / 3 = 3éléments avec la même somme.

Sortie: La sortie doit être une chaîne de chiffres, avec des espaces optionnels et des retours à la ligne pour le formatage, chaque chiffre suivi d'une lettre a-zindiquant son groupe. Il devrait y avoir exactement des numberOfTotalDigits / numberOfGroupséléments dans chaque groupe. Vous n'aurez jamais à diviser quelque chose en plus de 26 groupes.

Exemple de sortie:

1a 5a 6b
7c 9a 0b
8c 0c 9b

Notez que remplacer tous les as par bs et bs par as est également valable. Tant que chaque groupe est désigné par une lettre distincte, la sortie est valide.

De plus, je m'attends à ce que la plupart des programmes produisent quelque chose du genre, car les sauts de ligne / espaces sont facultatifs:

1a5a6b7c9a0b8c0c9b

Dans ce cas, l'ajout de tous les chiffres du groupe a, bou cfait 15. De plus, tous les groupes sont liés par un polygone.

Sorties non valides:

1a 5a 6b
7c 9a 0c
8c 0b 9b

parce que les groupes ne forment pas de polygones (en particulier, le 6best isolé et 0cest également solitaire).

1a 5a 6b
7c 9a 0b
8c 0b 9b

parce que le groupe ba 4 éléments alors qu'il cn'en a que 2.

Etc.

S'il n'y a pas de solution valide, votre programme peut faire n'importe quoi (c'est-à-dire arrêter, planter, s'exécuter indéfiniment) mais si votre programme imprime Nonelorsqu'il n'y a pas de solution valide, -15à votre score.

S'il existe plusieurs solutions, il vous suffit d'en imprimer une, mais -20si votre programme les imprime toutes séparées par un délimiteur.

C'est le golf de code, donc le code le plus court (avec des bonus) gagne!

soktinpk
la source
Dans la première sortie invalide, je pense que vous voulez dire que le 6best isolé, pas le 0b.
Level River St
La rapidité de notre programme est-elle importante? Et si c'est trop lent pour valider si ça marche?
Beta Decay
156790889 3semble que cela devrait être156790809 3
isaacg

Réponses:

10

Pyth , 122 - 20 - 15 = 87

=Z/lzQ=ks^lz.5Jm]dUzL[-bk+bk?tb%bkb?hb%hbkb)FNJIgNZB~Jm+NksmybN;|jbS{msm+@zk@S*Z<GQxsdkUzfqSsTUz^fqsmv@*ZzbY/smvdzQJQ"None

Changements:

  • 130 -> 120: Passé à une entrée séparée par une nouvelle ligne.

  • 120 -> 134: correction d'un bug impliquant des groupes dont la taille n'était pas égale à la longueur latérale de la matrice.

  • 134 -> 120: imprime toutes les solutions, y compris celles équivalentes sous le renommage de groupe.

  • 120 -> 122: Correction d'un bug où seuls les chemins étaient générés, au lieu de tous les groupes légaux.

Essai:

pyth programs/sum_group.pyth <<< '156790809
3'
1a5a6b7c9a0b8c0c9b
1a5a6c7b9a0c8b0b9c
1b5b6a7c9b0a8c0c9a
1b5b6c7a9b0c8a0a9c
1c5c6a7b9c0a8b0b9a
1c5c6b7a9c0b8a0a9b


pyth programs/sum_group.pyth <<< '156790808
3'
None

pyth programs/sum_group.pyth <<< '1111     
2'
1a1a1b1b
1a1b1a1b
1b1a1b1a
1b1b1a1a

Explication:

Pyth code           (Pseudo)-Python code              Comments

(implicit)          z = input()                       z is the digit string
(implicit)          Q = eval(input())                 S is the number of groups
(implicit)          G = 'abcdefghijklmnopqrstuvwxyz'
=Z/lzQ              Z = len(z)/Q                      Z is the size of each group.
=ks^lz.5            k = int(len(z) ** .5)             k is the side length of the matrix.
Jm]dUz              J = map(lambda d:[d], range(len(z))) Locations are encoded as numbers.
L                   def y(b): return                  y will be the transition function.
 [-bQ                         [b-k,                   Move up - the row above is k less.
  +bQ                          b+k,                   Move down - the row below is k more.
  ?tb%bkb                      b-1 if b%k else b      Move left, unless at the left edge.
  ?hb%hbkb)                    b+1 if (b+1)%k else b] Move right, unless at right edge.
FNJ                 for N in J:                       This constructs the list of all
   IgNZB                       if N[Z-1]: break       Z-length connected groups.
   ~Jm+Nk                      J+=map(lambda k: N+[k],  Append to J the group of N +
      smybN                          sum(map(lambda b:  anything reachable from
                                     y(b),N)))        anywhere in N.
   ;                (end for)
|                   or                                Print first truthy thing between
 S{                 sorted(set(                       Unique elements in sorted order of
   ms               map(lambda b:sum(                 Map+sum over allowable combinations
     m+@zd          map(lambda d:z[d]+                Character in original digit string
       @S*Z<GQ      sorted(G[:Q]*Z)[                  Repeated and sorted early alphabet
        xsbd        sum(b).index(d)],                 At index of number in sum of groups
      Uz                range(len(z)))                Over possible indexes.
   f                filter(lambda T:                  To generate allowable combinations, 
                                                      we will filter all groups of Q paths.
    qSsTUz          sorted(sum(T)) == range(len(z))   Ensure all locations are visited.
    ^                                                 Combinations of
     f              filter(lambda Y:                  Filter over connected Z-length groups
      qsm           equal(sum(map(lambda k:           Sum of the values of the group
         v@*ZzkY    eval((z*Z)[k]),Y)                 In the original digit string
       /smvbzQ      sum(map(lambda b:eval(b),z))/Q    must equal the sum of all values in z
                                                      divided by the number of groups.
      J             J                                 Filter over connected Z-length groups
     Q              Q                                 Combinations of length Q
 "None              "None"                            If the above was empty, print "None"
isaacg
la source
9
"Pyth"? Vous avez mal orthographié "base64".
Ingo Bürk
4

JavaScript (ES6) 361 (376-15) 372

(Peut-être peut-on encore jouer un peu plus au golf)

En fonction, le premier paramètre est la chaîne de chiffres et le deuxième paramètre est le nombre de groupes.
C'est une recherche récursive naïve, arrêtant la première solution trouvée (pas de bonus -20).
Besoin de plus de cas de test pour vérifier les performances sur une entrée plus importante.

F=(g,n,l=g.length,i=w=Math.sqrt(l),o=s=h='',
  R=(g,p,k,j=l/n,t=s/n,v=0,h=String.fromCharCode(97+k))=>(
    t-=g[p],!(t<0)&&(
      g=[...g],g[p]=h,
      S=f=>g.some((c,p)=>c<':'&&f(p)),
      --j?S(p=>(g[p+1]==h|g[p-1]==h|g[p+w+1]==h|g[p-w-1]==h)?v=R(g,p,k,j,t):0)
      :t?0:k?S(p=>v=R(g,p,k-1)):v=g
    ),v
  )
)=>([for(c of g)(s-=-c,h+=--i?c:(i=w,c+':'))],h=R(g=h,-1,n,1))?h.map((c,p)=>o+=c!=':'?g[p]+c:'')&&o:'None'

Non golfé et expliqué

F=(g,n)=> 
{
  var l = g.length, // string size, group size is l/n 
      w = Math.sqrt(l), // width of grid
      s,i,h,o;

  // Build a new string in h, adding rows delimiters that will act as boundary markers  
  // At the same time calculate the total sum of all digits
  h='',  // Init string
  s = 0, // Init sum 
  i = w, // Init running counter for delimiters
  [for(c of g)(
    s -= -c, // compute sum using minus to avoid string concatenation
    h += --i ? c : (i=w, c+':') // add current char + delimiter when needed
  )];


  // Recursive search
  // Paramaters:
  // g : current grid array, during search used digits are replaced with group letters
  // p : current position
  // k : current group id (start at n, decreaseing)
  // j : current group size, start at l/n decreasing, at 0 goto next group id
  // t : current group sum value, start at s/n decreasing

  var R=(g,p,k,j,t)=> 
  {
    var v = 0, // init value to return is 0
        h = String.fromCharCode(97+k); // group letter from group

    t-=g[p]; // subtract current digit

    if (t<0) // exceed the sum value, return 0 to stop search and backtrak
      return 0;

    g=[...g]; // build a new array from orginal parameter
    g[p] = h; // mark current position

    // Utility function  to scan grid array
    // call worker function  f only for digit elements
    //   skipping group markers, row delimieters and out of grid values (that are undefined)  
    // Using .some will return ealry if f returns truthy  
    var S=f=>g.some((c,p)=>c<':'&&f(p));

    if (--j) // decrement current group size, if 0 then group completed
    { // if not 0
      // Scan grid to find cells adiacent to current group and call R for each 
      S( p => {
        if (g[p+1]==h|g[p-1]==h|g[p+w+1]==h|g[p-w-1]==h) // check if adiacent to a mark valued h
        {
          return v=R(g,p,k,j,t) // set v value and returns it
        }
      })
      // here v could be 0 or a full grid 
    }
    else
    {
      // special case: at first call, t is be NaN because p -1 (outside the grid)
      // to start a full grid serach
      if (t) // check if current reached 0
        return 0; // if not, return 0 to stop search and backtrak


      if (k) // check if current group completed
      {
        // if not at last group, recursive call to R to check next group 
        S( p => {
          // exec the call for each valid cell still in grid
          // params j and t start again at init values
          return v=R(g,p,k-1,l/n,s/n) // set value v and returns it
        })
        // here v could be 0 or a full grid 
      }
      else
      {
        return g; // all groups checked, search OK, return grid with all groups marked
      }
    }
    return v
  };
  g = h; // set g = h, so g has the row boundaries and all the digits

  h=R(h,-1,n,1); // first call with position -1 to and group size 1 to start a full grid search

  if (h) // h is the grid with group marked if search ok, else h is 0
  {
    o = ''; // init output string
    // build output string merging the group marks in h and the original digits in g
    h.map( (c,p) => o += c>':' ? g[p]+c: '') // cut delimiter ':'
    return o;
  }
  return 'None';
}

Test dans la console FireFox / FireBug

F("156790809",3) production 1c5c6b7a9c0b8a0a9b

F("156790819",3) production None

edc65
la source